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