updated header
[libfirm] / ir / opt / gvn_pre.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Global Value Numbering Partial Redundancy Elimination
23  *          (VanDrunen Hosking 2004)
24  * @author  Michael Beck, Rubino Geiss
25  * @version $Id$
26  * @summary
27  *
28  * Currently completely broken because our stes so NOT preserve
29  * the topological sort!
30  */
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <assert.h>
36
37 #include "irgraph_t.h"
38 #include "irgwalk.h"
39 #include "irdom.h"
40 #include "irouts.h"
41 #include "pset.h"
42 #include "set.h"
43 #include "irgopt.h"
44 #include "iropt_t.h"
45 #include "irprintf.h"
46 #include "irnode_t.h"
47 #include "ircons.h"
48 #include "irgmod.h"
49 #include "debug.h"
50 #include "gvn_pre.h"
51 #include "xmalloc.h"
52
53 /** The debug module handle. */
54 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
55
56
57 /** A value set. */
58 typedef struct set value_set;
59
60 /** A node set. */
61 typedef struct pset node_set;
62
63 /** An entry in the value set. */
64 typedef struct value_entry {
65   ir_node *node;  /**< the node */
66   ir_node *value; /**< the value of the node */
67 } value_entry;
68
69 /** Additional info we need for every block. */
70 typedef struct block_info {
71   node_set *nodes;      /**< The set of nodes per block. */
72   value_set *avail_out; /**< The Avail_out set for a block. */
73   node_set *antic_in;   /**< The Antic_in set for a block. */
74   value_set *new_set;   /**< The set of all new values for a block. */
75   ir_node *avail;       /**< The get_map(avail, block) result. */
76   int not_found;        /**< Non-zero, if avail was not found in this block. */
77   struct block_info *next;  /**< Links all entries, so we can recover the sets easily. */
78 } block_info;
79
80 /**
81  * A pair of nodes that must be exchanged.
82  * We must defer the exchange because our hash-sets cannot
83  * find an already replace node else.
84  */
85 typedef struct elim_pair {
86   ir_node *old_node;      /**< The old node that will be replaced. */
87   ir_node *new_node;      /**< The new node. */
88   struct elim_pair *next; /**< Links all entries in a list. */
89 } elim_pair;
90
91 /** The environment for the GVN-PRE algorithm */
92 typedef struct pre_env {
93   struct obstack *obst;   /**< The obstack to allocate on. */
94   node_set *trans_set;    /**< The set of all translated values. */
95   ir_node *start_block;   /**< The start block of the current graph. */
96   ir_node *end_block;     /**< The end block of the current graph */
97   block_info *list;       /**< Links all block info entires for easier recovery. */
98   elim_pair *pairs;       /**< A list of node pairs that must be eliminated. */
99   char changes;           /**< Non-zero, if calculation of Antic_in has changed. */
100   char first_iter;        /**< non-zero for first iteration */
101 } pre_env;
102
103 /* ----------  Functions for Node sets ---------- */
104
105 #define node_set_first(s)       pset_first(s)
106 #define node_set_next(s)        pset_next(s)
107 #define node_set_break(s)       pset_break(s)
108 #define node_set_foreach(v, s)  for ((v) = node_set_first(s); (v); (v) = node_set_next(s))
109
110 /**
111  * Creates a new node set.
112  */
113 static node_set *new_node_set(void) {
114   return new_pset(identities_cmp, 8);
115 }
116
117 /**
118  * Deletes a node set.
119  */
120 static void del_node_set(node_set *set) {
121   del_pset(set);
122 }
123
124 /**
125  * Add a node to the set.
126  */
127 static ir_node *node_add(node_set *set, ir_node *node) {
128   return identify_remember(set, node);
129 }
130
131 /**
132  * Remove a node from a node set.
133  */
134 static void node_set_remove(node_set *set, ir_node *node) {
135   pset_remove(set, node, ir_node_hash(node));
136 }
137
138 /**
139  * Return the number of entries in a node set.
140  */
141 static int node_set_count(node_set *set) {
142   return pset_count(set);
143 }
144
145 #if 0
146 /** computes dst = dst \/ src for node sets */
147 static void node_union(node_set *dst, node_set *src)
148 {
149   ir_node *entry;
150   node_set_foreach(entry, src) {
151     node_add(dst, entry);
152   }
153 }
154 #endif
155
156 /**
157  * Lookup a node in a node set.
158  */
159 static ir_node *node_lookup(node_set *set, ir_node *n)
160 {
161   return pset_find(set, n, ir_node_hash(n));
162 }
163
164
165 /* ----------  Functions for Value sets ---------- */
166
167 #define value_set_foreach(v, s) for ((v) = set_first(s); (v); (v) = set_next(s))
168
169 /**
170  * calculate a hash value for a value represented by a node
171  */
172 static unsigned value_hash(ir_node *value) {
173   return ir_node_hash(value);
174 }
175
176 /**
177  * Compare two value entries.
178  */
179 static int value_cmp(const void *elt, const void *key, size_t size)
180 {
181   const value_entry *e1 = elt;
182   const value_entry *e2 = key;
183
184   return identities_cmp(e1->value, e2->value);
185 }
186
187 /** Create a new value set. */
188 static value_set *new_value_set(void) {
189   return new_set(value_cmp, 8);
190 }
191
192 /** Deletes a value set. */
193 static void del_value_set(value_set *set) {
194   del_set(set);
195 }
196
197 /**
198  * Add a node node representing the value value to the set.
199  */
200 static value_entry *value_add(value_set *set, ir_node *node, ir_node *value)
201 {
202   value_entry key;
203   key.node  = node;
204   key.value = value;
205   return set_insert(set, &key, sizeof(key), value_hash(value));
206 }
207
208 /** computes dst = dst \/ src for value sets */
209 static void value_union(value_set *dst, value_set *src)
210 {
211   value_entry *entry;
212   value_set_foreach(entry, src)
213     value_add(dst, entry->node, entry->value);
214 }
215
216 /** computes dst = dst \/ (value_set)src for value sets */
217 static void value_union_nodes(value_set *dst, node_set *src)
218 {
219   ir_node *n;
220   node_set_foreach(n, src)
221     value_add(dst, n, n);
222 }
223
224 /**
225  * Lookup a value in a value set.
226  */
227 static ir_node *value_lookup(value_set *value_set, ir_node *n)
228 {
229   value_entry key, *e;
230
231   key.value = n;
232   e = set_find(value_set, &key, sizeof(key), value_hash(n));
233   return e ? e->node : NULL;
234 }
235
236 /**
237  * Add or replace a value in a set by an node computing the same
238  * value in a dominator block.
239  *
240  * @return non-zero if a replacement took place
241  */
242 static int value_add_or_replace(value_set *set, ir_node *node, ir_node *value)
243 {
244   value_entry *e = value_add(set, node, value);
245
246   if (e->node != node) {
247     /* node must dominate old one here */
248     assert(block_dominates(get_nodes_block(node), get_nodes_block(e->node)));
249
250     e->node = node;
251     return 1;
252   }
253   return 0;
254 }
255
256 /**
257  * Returns non-zero if a node is movable.
258  */
259 static int is_nice_value(ir_node *n) {
260   ir_mode *mode;
261
262   while (is_Proj(n))
263     n = get_Proj_pred(n);
264   mode = get_irn_mode(n);
265   /*
266    * FIXME: For now, we cannot handle Div/even if it's movable.
267    * That should be fixed.
268    */
269   if (!mode_is_data(mode))
270     return 0;
271   if (is_irn_constlike(n))
272     return 0;
273   return (get_irn_pinned(n) != op_pin_state_pinned);
274 }
275
276 #ifdef DEBUG_libfirm
277 /**
278  * Dump a set.
279  */
280 static void dump_node_set(node_set *set, char *txt, ir_node *block)
281 {
282   ir_node *n;
283   int i;
284
285   DB((dbg, LEVEL_2, "%s(%+F) = {\n", txt, block));
286   i = 0;
287   node_set_foreach(n, set) {
288     if ((i & 3) == 3)
289       DB((dbg, LEVEL_2, "\n"));
290     DB((dbg, LEVEL_2, " %+F,", n));
291     ++i;
292   }
293   DB((dbg, LEVEL_2, "\n}\n"));
294 }  /* dump_set */
295
296 /**
297  * Dump a value set.
298  */
299 static void dump_value_set(value_set *set, char *txt, ir_node *block)
300 {
301   value_entry *e;
302   int i;
303
304   DB((dbg, LEVEL_2, "%s(%+F) = {\n", txt, block));
305   i = 0;
306   value_set_foreach(e, set) {
307     if ((i & 3) == 3)
308       DB((dbg, LEVEL_2, "\n"));
309     if (e->node != e->value)
310       DB((dbg, LEVEL_2, " %+F(%+F),", e->node, e->value));
311     else
312       DB((dbg, LEVEL_2, " %+F,", e->node));
313     ++i;
314   }
315   DB((dbg, LEVEL_2, "\n}\n"));
316 }  /* dump_set */
317
318 #else
319 #define dump_node_set(set, txt, block)
320 #define dump_value_set(set, txt, block)
321 #endif /* DEBUG_libfirm */
322
323
324 /**
325  * Return the block info of a block
326  */
327 static block_info *get_block_info(ir_node *block) {
328   return get_irn_link(block);
329 }
330
331 /**
332  * Computes Avail_out(block):
333  *
334  * Avail_in(block)  = Avail_out(dom(block))
335  * Avail_out(block) = Avail_in(block) \/ Nodes(block)
336  *
337  * Precondition:
338  *  This function must be called in the top-down dominance order:
339  *  Then, it computes Leader(Nodes(block)) instead of Nodes(block) !
340  */
341 static void compute_avail_top_down(ir_node *block, void *ctx)
342 {
343   pre_env *env = ctx;
344   block_info *dom_info;
345   block_info *info = get_block_info(block);
346   ir_node *dom_blk;
347
348   /* we don't need the end block Avail */
349   if (block == env->end_block)
350     return;
351
352   /*
353    * First add all nodes from the dominator.
354    * This must be done to ensure that Antic_out contains the leader
355    * for every node. The root has no dominator.
356    */
357   if (block != env->start_block) {
358     dom_blk = get_Block_idom(block);
359     assert(is_Block(dom_blk));
360
361     dom_info = get_block_info(dom_blk);
362     assert(dom_info);
363
364     value_union(info->avail_out, dom_info->avail_out);
365   }
366   value_union_nodes(info->avail_out, info->nodes);
367
368   dump_value_set(info->avail_out, "Avail_out", block);
369 }
370
371 /**
372  * returns non-zero if a tree node must be copied because of
373  * a phi_translate.
374  */
375 static int need_copy(ir_node *node, ir_node *block)
376 {
377   int i, arity;
378
379   /* Phi always stop the recursion */
380   if (is_Phi(node))
381     return get_irn_intra_n(node, -1) == block;
382
383   if (! is_nice_value(node))
384     return 0;
385
386   /* check predecessor */
387   arity = get_irn_intra_arity(node);
388   for (i = 0; i < arity; ++i) {
389     ir_node *pred     = get_irn_intra_n(node, i);
390     ir_node *local_bl = get_irn_intra_n(pred, -1);
391     ir_node *leader   = value_lookup(get_block_info(local_bl)->avail_out, pred);
392
393     pred = leader != NULL ? leader : pred;
394     if (need_copy(pred, block))
395       return 1;
396   }
397   return 0;
398 }
399
400 /**
401  * Translate a node
402  */
403 static ir_node *translate(ir_node *node, ir_node *block, int pos, pre_env *env)
404 {
405   int i, arity, need_new;
406   ir_node *res, *nn, **in;
407
408   /* Phi always stop the recursion */
409   if (is_Phi(node)) {
410     if (get_irn_intra_n(node, -1) == block)
411       return get_Phi_pred(node, pos);
412     return node;
413   }
414
415   if (! is_nice_value(node))
416     return node;
417
418   arity = get_irn_intra_arity(node);
419   if (arity > 0) {
420     NEW_ARR_A(ir_node *, in, arity);
421     i = arity - 1;
422     need_new = 0;
423     do {
424       ir_node *pred = get_irn_intra_n(node, i);
425       ir_node *pred_blk = get_irn_intra_n(pred, -1);
426       ir_node *leader = value_lookup(get_block_info(pred_blk)->avail_out, pred);
427       in[i] = translate(leader ? leader : pred, block, pos, env);
428       need_new |= (in[i] != pred);
429       --i;
430     } while(i >= 0);
431     if (! need_new)
432       return node;
433
434     /* create a copy */
435     nn = new_ir_node(
436           get_irn_dbg_info(node),
437           current_ir_graph,
438           get_Block_cfgpred_block(block, pos),
439           get_irn_op(node),
440           get_irn_mode(node),
441           arity,
442           in);
443     /* We need the attribute copy here, because the Hash value of a
444        node might depend on that. */
445     copy_node_attr(node, nn);
446     res = node_add(env->trans_set, nn);
447     if (nn != res)
448       obstack_free(env->obst, nn);
449     else
450       DB((dbg, LEVEL_2, "--> Translate %+F in <%+F,%d> into %+F\n", node, block, pos, res));
451     return res;
452   }
453   return node;
454 }
455
456 #if 0
457 /**
458  * Implements phi_translate.
459  */
460 static ir_node *deep_phi_translate(ir_node *node, ir_node *block, int pos, pre_env *env)
461 {
462   struct obstack *old;
463   ir_node *res;
464
465   if (! need_copy(node, block))
466     return node;
467
468   /* Create a copy of the node in the pos'th predecessor block.
469      Use our environmental obstack, as these nodes are always
470      temporary. */
471   old = current_ir_graph->obst;
472   current_ir_graph->obst = env->obst;
473   res = translate(node, block, pos, env);
474   current_ir_graph->obst = old;
475
476   return res;
477 }  /* phi_translate */
478 #endif
479
480 /**
481  * Implements phi_translate.
482  */
483 static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, pre_env *env)
484 {
485   ir_node *nn, *res;
486   int i, arity;
487   struct obstack *old;
488
489   if (is_Phi(node)) {
490     if (get_irn_intra_n(node, -1) == block)
491       return get_Phi_pred(node, pos);
492     return node;
493   }
494
495   arity = get_irn_intra_arity(node);
496
497   /* check if the node has at least one Phi predecessor */
498   for (i = 0; i < arity; ++i) {
499     ir_node *pred    = get_irn_intra_n(node, i);
500     ir_node *pred_bl = get_irn_intra_n(pred, -1);
501     ir_node *leader  = value_lookup(get_block_info(pred_bl)->avail_out, pred);
502
503     leader = leader != NULL ? leader : pred;
504     if (is_Phi(leader) && get_irn_intra_n(pred, -1) == block)
505       break;
506   }
507   if (i >= arity) {
508     /* no Phi in the predecessors */
509     return node;
510   }
511
512   /* Create a copy of the node in the pos'th predecessor block.
513      Use our environmental obstack, as these nodes are always
514      temporary. */
515   old = current_ir_graph->obst;
516   current_ir_graph->obst = env->obst;
517   nn = new_ir_node(
518           get_irn_dbg_info(node),
519           current_ir_graph,
520           NULL,
521           get_irn_op(node),
522           get_irn_mode(node),
523           arity,
524           get_irn_in(node));
525   /* We need the attribute copy here, because the Hash value of a
526      node might depend on that. */
527   copy_node_attr(node, nn);
528
529   set_irn_n(nn, -1, get_irn_intra_n(node, -1));
530   for (i = 0; i < arity; ++i) {
531     ir_node *pred    = get_irn_intra_n(node, i);
532     ir_node *pred_bl = get_irn_intra_n(pred, -1);
533     ir_node *leader  = value_lookup(get_block_info(pred_bl)->avail_out, pred);
534
535     leader = leader != NULL ? leader : pred;
536     if (is_Phi(leader) && get_irn_intra_n(pred, -1) == block)
537       set_irn_n(nn, i, get_Phi_pred(leader, pos));
538     else
539       set_irn_n(nn, i, leader);
540   }
541   res = node_add(env->trans_set, nn);
542   current_ir_graph->obst = old;
543
544   if (nn != res)
545     obstack_free(env->obst, nn);
546   else {
547     DB((dbg, LEVEL_2, "--> Translate %+F in <%+F,%d> into %+F\n", node, block, pos, res));
548   }
549   return res;
550 }  /* phi_translate */
551
552 /**
553  * check if a node n is clean in block block.
554  */
555 static int _is_clean(ir_node *n, ir_node *block)
556 {
557   int i;
558
559   if (get_nodes_block(n) != block)
560     return 1;
561   if (is_Phi(n))
562     return 1;
563
564   if (irn_visited(n))
565     return 0;
566
567   if (! is_nice_value(n))
568     goto bad;
569   for (i = get_irn_arity(n) - 1; i >= 0; --i) {
570     ir_node *pred = get_irn_n(n, i);
571     if (! _is_clean(pred, block))
572       goto bad;
573   }
574   return 1;
575 bad:
576   mark_irn_visited(n);
577   return 0;
578 }
579
580 /**
581  * check if a node n is clean.
582  */
583 static int is_clean(ir_node *n)
584 {
585   int res = _is_clean(n, get_nodes_block(n));
586   return res;
587 }
588
589 /**
590  * Clean a node set.
591  * This function is called for node sets with is_clean
592  * nodes only, so we must just remove nodes that don't
593  * have available inputs
594  */
595 static void clean_node_set(node_set *set, ir_node *blk)
596 {
597   ir_node *n, *pred, *pred_blk;
598   int i;
599
600 restart:
601   for (n = node_set_first(set); n; n = node_set_next(set)) {
602     for (i = get_irn_intra_arity(n) - 1; i >= 0; --i) {
603       pred = get_irn_intra_n(n, i);
604
605       pred_blk = get_irn_intra_n(pred, -1);
606       if (block_dominates(pred_blk, blk))
607         continue;
608       /* pred do not dominate it, but may be in the set */
609       if (node_lookup(set, pred) != NULL)
610         continue;
611       /* we found a node that must be removed */
612       node_set_break(set);
613       node_set_remove(set, n);
614       DB((dbg, LEVEL_2, "<-- Cleaning %+F\n", n));
615       goto restart;
616     }
617   }
618 }
619
620 /**
621  * computes Antic_in(block):
622  */
623 static void compute_antic(ir_node *block, void *ctx)
624 {
625   pre_env *env = ctx;
626   block_info *succ_info;
627   block_info *info = get_block_info(block);
628   ir_node *succ;
629   int size;
630
631   /* no need for computations in start block */
632   if (block == env->start_block)
633     return;
634
635   size = node_set_count(info->antic_in);
636
637   /* the end block has no successor */
638   if (block != env->end_block) {
639     int n_succ = get_Block_n_cfg_outs(block);
640
641     if (n_succ == 1) {
642       ir_node *node, *list;
643       int i, pos = -1;
644
645       /* find blocks position in succ's block predecessors */
646       succ = get_Block_cfg_out(block, 0);
647       for (i = get_Block_n_cfgpreds(succ) - 1; i >= 0; --i) {
648         if (get_Block_cfgpred_block(succ, i) == block) {
649           pos = i;
650           break;
651         }
652       }
653       assert(pos >= 0);
654
655       succ_info = get_block_info(succ);
656       /* translate into list: we cannot insert into a set we iterate
657        * and succ might be equal to block for endless loops */
658       list = NULL;
659       node_set_foreach(node, succ_info->antic_in) {
660         set_irn_link(node, list);
661         list = node;
662       }
663       for (node = list; node; node = get_irn_link(node)) {
664         ir_node *trans = phi_translate(node, succ, pos, env);
665
666         if (is_clean(trans))
667           node_add(info->antic_in, trans);
668       }
669     }
670     else {
671       ir_node *n, *succ0;
672       block_info *succ0_info;
673       int i;
674
675       assert(n_succ > 1);
676
677       /* Select a successor to compute the disjoint of all Nodes
678          sets, it might be useful to select the block with the
679          smallest number of nodes.  For simplicity we choose the
680          first one. */
681       succ0 = get_Block_cfg_out(block, 0);
682       succ0_info = get_block_info(succ0);
683       node_set_foreach(n, succ0_info->antic_in) {
684         /* we need the disjoint */
685         for (i = 1; i < n_succ; ++i) {
686           ir_node *succ = get_Block_cfg_out(block, i);
687           block_info *succ_info = get_block_info(succ);
688           if (node_lookup(succ_info->antic_in, n) == NULL)
689             break;
690         }
691         if (i >= n_succ) {
692           /* we found a node that is common in all Antic_in(succ(b)),
693              put it in Antic_in(b) */
694           node_add(info->antic_in, n);
695         }
696       }
697     }
698
699     /*
700      * This step calculates Antic_in(b) = Antic_out(b) \/ Nodes(b).
701      * It is enough to do this in the first iteration, because
702      * the set info->nodes is not changed anymore.
703      */
704     if (env->first_iter) {
705       ir_node *n;
706       node_set_foreach(n, info->nodes) {
707         if (is_clean(n))
708           node_add(info->antic_in, n);
709       }
710     }
711   }
712
713 //  clean_node_set(info->antic_in, block);
714   (void) clean_node_set;
715
716   dump_node_set(info->antic_in, "Antic_in", block);
717   if (size != node_set_count(info->antic_in)) {
718     /* the Antic_in set has changed */
719     env->changes |= 1;
720   }
721 }  /* compute_antic */
722
723 /**
724  * allocate a block info
725  */
726 static void alloc_blk_info(ir_node *block, void *ctx)
727 {
728   int i;
729   pre_env *env = ctx;
730   block_info *info = obstack_alloc(env->obst, sizeof(*info));
731
732   set_irn_link(block, info);
733   info->nodes     = new_node_set();
734   info->antic_in  = new_node_set();
735   info->avail_out = new_value_set();
736   info->avail     = NULL;
737   info->not_found = 0;
738   info->new_set   = NULL;
739   info->next      = env->list;
740   env->list       = info;
741
742   /* fill the nodes set, we will need it later */
743   for (i = get_irn_n_outs(block) - 1; i >= 0; --i) {
744     ir_node *n = get_irn_out(block, i);
745
746     set_irn_link(n, NULL);
747
748     /* we cannot optimize pinned nodes, so do not remember them */
749     if (is_nice_value(n))
750       node_add(info->nodes, n);
751   }
752 }
753
754 /**
755  * Perform insertion of partially redundant values.
756  * For every Block node, do the following:
757  * 1.  Propagate the NEW_SETS of the dominator into the current block.
758  * If the block has multiple predecessors,
759  *     2a. Iterate over the ANTIC expressions for the block to see if
760  *         any of them are partially redundant.
761  *     2b. If so, insert them into the necessary predecessors to make
762  *         the expression fully redundant.
763  *     2c. Insert a new Phi merging the values of the predecessors.
764  *     2d. Insert the new Phi, and the new expressions, into the
765  *         NEW_SETS set.
766  */
767 static void insert_nodes(ir_node *block, void *ctx)
768 {
769   pre_env *env = ctx;
770   value_entry *entry;
771   ir_node *e, *idom, *first_s, *worklist;
772   block_info *curr_info, *idom_info;
773   int pos, arity = get_irn_intra_arity(block);
774   int all_same, by_some, updated;
775
776   /* ensure that even the start block has a new_set */
777   curr_info = get_block_info(block);
778   if (curr_info->new_set)
779     del_value_set(curr_info->new_set);
780   curr_info->new_set = new_value_set();
781
782   if (block == env->start_block)
783     return;
784
785   idom = get_Block_idom(block);
786   idom_info = get_block_info(idom);
787
788   /* update the new_sets */
789   updated = 0;
790   dump_value_set(idom_info->new_set, "[New Set]", idom);
791   value_set_foreach(entry, idom_info->new_set) {
792     updated |= value_add_or_replace(curr_info->avail_out, entry->node, entry->value);
793   }
794   if (updated)
795     dump_value_set(curr_info->avail_out, "Updated [Avail_out]", block);
796
797   if (arity <= 1)
798     return;
799
800   /* convert the set into a list. This allows the removal of
801    * elements from the set */
802   worklist = NULL;
803   node_set_foreach(e, curr_info->antic_in) {
804     set_irn_link(e, worklist);
805     worklist = e;
806   }
807
808   for (e = worklist; e != NULL; e = get_irn_link(e)) {
809     ir_mode *mode;
810
811     /* If the value was already computed in the dominator, then
812        it is totally redundant.  Hence we have nothing to insert. */
813     if (value_lookup(idom_info->avail_out, e)) {
814 //      DB((dbg, LEVEL_2, "Found %+F from block %+F avail in dom %+F\n", v, block, idom));
815       continue;
816     }
817
818     by_some  = 0;
819     all_same = 1;
820     first_s  = NULL;
821     mode     = NULL;
822
823     /* for all predecessor blocks */
824     for (pos = 0; pos < arity; ++pos) {
825       block_info *pred_info;
826       ir_node *pred_blk = get_Block_cfgpred_block(block, pos);
827       ir_node *e_prime, *v_prime, *e_dprime;
828
829       /* ignore bad blocks. */
830       if (is_Bad(pred_blk))
831         continue;
832
833       e_prime = phi_translate(e, block, pos, env);
834       v_prime = e_prime;
835
836       pred_info = get_block_info(pred_blk);
837       e_dprime = value_lookup(pred_info->avail_out, v_prime);
838
839       if (e_dprime == NULL) {
840         all_same = 0;
841         pred_info->avail = e_prime;
842         pred_info->not_found = 1;
843       }
844       else {
845         mode     = get_irn_mode(e_dprime);
846         e_dprime = e_dprime;
847         pred_info->avail = e_dprime;
848         pred_info->not_found = 0;
849         by_some = 1;
850         if (first_s == NULL)
851           first_s = e_dprime;
852         else if (first_s != e_dprime)
853           all_same = 0;
854
855         DB((dbg, LEVEL_2, "Found %+F from block %+F as %+F in pred %+F\n", e, block, e_dprime, pred_blk));
856       }  /* if */
857     }  /* for */
858
859     /* If it's not the same value already existing along every predecessor, and
860        it's defined by some predecessor, it is partially redundant. */
861     if (! all_same && by_some) {
862       ir_node *phi, **in;
863
864       DB((dbg, LEVEL_1, "Partial redundant %+F from block %+F found\n", e, block));
865
866       in = xmalloc(arity * sizeof(*in));
867       /* for all predecessor blocks */
868       for (pos = 0; pos < arity; ++pos) {
869         ir_node *pred_blk = get_Block_cfgpred_block(block, pos);
870         block_info *pred_info = get_block_info(pred_blk);
871
872         /* ignore bad blocks. */
873         if (is_Bad(pred_blk)) {
874           in[pos] = new_Bad();
875           continue;
876         }
877
878         /* ignore blocks that already have the expression */
879         if (pred_info->not_found) {
880           ir_node *e_prime = pred_info->avail;
881           ir_node *nn;
882           if (!is_Phi(e_prime)) {
883             mode = get_irn_mode(e_prime);
884             nn = new_ir_node(
885               get_irn_dbg_info(e_prime),
886               current_ir_graph, pred_blk,
887               get_irn_op(e_prime),
888               mode,
889               get_irn_arity(e_prime),
890               get_irn_in(e_prime) + 1);
891             copy_node_attr(e_prime, nn);
892
893             DB((dbg, LEVEL_2, "New node %+F in block %+F created\n", nn, pred_blk));
894             pred_info->avail = value_add(pred_info->avail_out, nn, e_prime)->node;
895           }
896         }
897         in[pos] = pred_info->avail;
898       }  /* for */
899       phi = new_r_Phi(current_ir_graph, block, arity, in, mode);
900       free(in);
901       value_add_or_replace(curr_info->avail_out, phi, e);
902       value_add(curr_info->new_set, phi, e);
903       DB((dbg, LEVEL_2, "New %+F for redundant %+F created\n", phi, e));
904
905       /* the good case: we really replace an instruction */
906       node_set_remove(curr_info->antic_in, e);
907
908       env->changes |= 1;
909     }  /* if */
910   }  /* node_set_foreach */
911 }  /* insert_nodes */
912
913 /**
914  * Do the elimination step: collect all changes
915  * We cannot do the changes right here, as this would change
916  * the hash values of the nodes in the avail_out set!
917  */
918 static void collect_elim_pairs(ir_node *block, void *ctx)
919 {
920   pre_env *env = ctx;
921   block_info *curr_info = get_block_info(block);
922   ir_node *v;
923
924   dump_node_set(curr_info->nodes, "Updating nodes", block);
925   node_set_foreach(v, curr_info->nodes) {
926     ir_node *l = value_lookup(curr_info->avail_out, v);
927
928     assert(l);
929     if (l != v) {
930       elim_pair *p = obstack_alloc(env->obst, sizeof(*p));
931
932       p->old_node = v;
933       p->new_node = l;
934       p->next     = env->pairs;
935       env->pairs  = p;
936     }
937   }
938 }
939
940 /**
941  * Do all the recorded changes and optimize
942  * newly created Phi's.
943  */
944 static void eliminate_nodes(elim_pair *pairs)
945 {
946   elim_pair *p;
947
948   for (p = pairs; p != NULL; p = p->next) {
949     DB((dbg, LEVEL_2, "Replacing %+F by %+F\n", p->old_node, p->new_node));
950     /*
951      * PRE tends to create Phi(self, self, ... , x, self, self, ...)
952      * which we can optimize here
953      */
954     if (is_Phi(p->new_node)) {
955       int i;
956       ir_node *res = NULL;
957
958       for (i = get_irn_intra_arity(p->new_node) - 1; i >= 0; --i) {
959         ir_node *pred = get_irn_n(p->new_node, i);
960
961         if (pred != p->old_node) {
962           if (res) {
963             res = NULL;
964             break;
965           }
966           res = pred;
967         }
968       }
969       if (res)
970         p->new_node = res;
971     }
972     exchange(p->old_node, p->new_node);
973   }
974 }
975
976 /*
977  * Argh: Endless loops cause problems, because the
978  * insert algorithm did not terminate. We get translated nodes that
979  * references the origin. These nodes are translated again and again...
980  *
981  * The current fix is to use post-dominance. This simple ignores
982  * endless loops, ie we cannot optimize them.
983  */
984 void do_gvn_pre(ir_graph *irg)
985 {
986   struct obstack obst;
987   pre_env a_env;
988   optimization_state_t state;
989   block_info *p;
990   unsigned antic_iter, insert_iter;
991
992   assert(!"COMPLETELY BROKEN YET, DO NOT USE");
993
994   /* register a debug mask */
995   FIRM_DBG_REGISTER(dbg, "firm.opt.gvn_pre");
996   firm_dbg_set_mask(dbg, SET_LEVEL_2);
997
998   obstack_init(&obst);
999   a_env.obst        = &obst;
1000   a_env.trans_set   = new_node_set();
1001   a_env.list        = NULL;
1002   a_env.start_block = get_irg_start_block(irg);
1003   a_env.end_block   = get_irg_end_block(irg);
1004   a_env.pairs       = NULL;
1005
1006   /* Move Proj's into the same block as their args,
1007      else we would assign the result to wrong blocks */
1008   normalize_proj_nodes(irg);
1009
1010   /* critical edges MUST be removed */
1011   remove_critical_cf_edges(irg);
1012
1013   /* we need dominator for Antic_out calculation */
1014   if (get_irg_dom_state(irg) != dom_consistent)
1015     compute_doms(irg);
1016   if (get_irg_postdom_state(irg) != dom_consistent)
1017     compute_postdoms(irg);
1018   /* we get all nodes of a block by following outs */
1019   if (get_irg_outs_state(irg) != outs_consistent)
1020     compute_irg_outs(irg);
1021
1022   /*
1023    * Switch on GCSE. We need it to correctly compute
1024    * the leader of a node by hashing.
1025    */
1026   save_optimization_state(&state);
1027   set_opt_global_cse(1);
1028
1029   DB((dbg, LEVEL_1, "Doing GVN-PRE for %e\n", get_irg_entity(irg)));
1030   printf("Doing GVN-PRE for %s\n", get_entity_name(get_irg_entity(irg)));
1031
1032   /* allocate block info for all blocks */
1033   irg_block_walk_graph(irg, NULL, alloc_blk_info, &a_env);
1034
1035   /* compute the available value sets for all blocks */
1036   dom_tree_walk_irg(irg, compute_avail_top_down, NULL, &a_env);
1037
1038   /* compute the anticipated value sets for all blocks */
1039   inc_irg_visited(irg);
1040   antic_iter = 0;
1041   a_env.first_iter = 1;
1042   do {
1043     DB((dbg, LEVEL_1, "Antic_in Iteration %d starts ...\n", ++antic_iter));
1044     a_env.changes = 0;
1045     irg_block_walk_graph(irg, compute_antic, NULL, &a_env);
1046 //    postdom_tree_walk_irg(irg, compute_antic, NULL, &a_env);
1047     a_env.first_iter = 0;
1048     DB((dbg, LEVEL_1, "------------------------\n"));
1049   } while (a_env.changes != 0);
1050
1051   /* compute redundant expressions */
1052   insert_iter = 0;
1053   do {
1054     DB((dbg, LEVEL_1, "Insert Iteration %d starts ...\n", ++insert_iter));
1055     a_env.changes = 0;
1056     dom_tree_walk_irg(irg, insert_nodes, NULL, &a_env);
1057     DB((dbg, LEVEL_1, "------------------------\n"));
1058   } while (a_env.changes != 0);
1059
1060   /* last step: eliminate nodes */
1061   dom_tree_walk_irg(irg, collect_elim_pairs, NULL, &a_env);
1062   eliminate_nodes(a_env.pairs);
1063
1064   restore_optimization_state(&state);
1065
1066   /* clean up: delete all sets */
1067   for (p = a_env.list; p != NULL; p = p->next) {
1068     if (p->antic_in)
1069       del_node_set(p->antic_in);
1070     if (p->avail_out)
1071       del_value_set(p->avail_out);
1072     if (p->nodes)
1073       del_node_set(p->nodes);
1074     if (p->new_set)
1075       del_value_set(p->new_set);
1076   }
1077   del_node_set(a_env.trans_set);
1078   obstack_free(&obst, NULL);
1079   set_irg_pinned(irg, op_pin_state_pinned);
1080
1081   if (a_env.pairs) {
1082     set_irg_outs_inconsistent(irg);
1083     set_irg_loopinfo_inconsistent(irg);
1084   }
1085 }  /* do_gvn_pre */