OSDN Git Service

* tree-ssa-ccp.c (get_default_value): Use SSA_NAME_VALUE rather
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
1 /* SSA-PRE for trees.
2    Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3    Contributed by Daniel Berlin <dan@dberlin.org> and Steven Bosscher
4    <stevenb@suse.de> 
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "errors.h"
28 #include "ggc.h"
29 #include "tree.h"
30 #include "basic-block.h"
31 #include "diagnostic.h"
32 #include "tree-inline.h"
33 #include "tree-flow.h"
34 #include "tree-gimple.h"
35 #include "tree-dump.h"
36 #include "timevar.h"
37 #include "fibheap.h"
38 #include "hashtab.h"
39 #include "tree-iterator.h"
40 #include "real.h"
41 #include "alloc-pool.h"
42 #include "tree-pass.h"
43 #include "flags.h"
44 #include "splay-tree.h"
45 #include "bitmap.h"
46 #include "langhooks.h"
47
48 /* TODO:
49    
50    1. Avail sets can be shared by making an avail_find_leader that
51       walks up the dominator tree and looks in those avail sets.
52       This might affect code optimality, it's unclear right now.
53    2. Load motion can be performed by value numbering the loads the
54       same as we do other expressions.  This requires iterative
55       hashing the vuses into the values.  Right now we simply assign
56       a new value every time we see a statement with a vuse.
57    3. Strength reduction can be performed by anticipating expressions
58       we can repair later on.
59    4. Our canonicalization of expressions during lookups don't take
60       constants into account very well.  In particular, we don't fold
61       anywhere, so we can get situations where we stupidly think
62       something is a new value (a + 1 + 1 vs a + 2).  This is somewhat
63       expensive to fix, but it does expose a lot more eliminations.
64       It may or not be worth it, depending on how critical you
65       consider PRE vs just plain GRE.
66 */   
67
68 /* For ease of terminology, "expression node" in the below refers to
69    every expression node but MODIFY_EXPR, because MODIFY_EXPR's represent
70    the actual statement containing the expressions we care about, and
71    we cache the value number by putting it in the expression.  */
72
73 /* Basic algorithm
74    
75    First we walk the statements to generate the AVAIL sets, the
76    EXP_GEN sets, and the tmp_gen sets.  EXP_GEN sets represent the
77    generation of values/expressions by a given block.  We use them
78    when computing the ANTIC sets.  The AVAIL sets consist of
79    SSA_NAME's that represent values, so we know what values are
80    available in what blocks.  AVAIL is a forward dataflow problem.  In
81    SSA, values are never killed, so we don't need a kill set, or a
82    fixpoint iteration, in order to calculate the AVAIL sets.  In
83    traditional parlance, AVAIL sets tell us the downsafety of the
84    expressions/values.
85    
86    Next, we generate the ANTIC sets.  These sets represent the
87    anticipatable expressions.  ANTIC is a backwards dataflow
88    problem.An expression is anticipatable in a given block if it could
89    be generated in that block.  This means that if we had to perform
90    an insertion in that block, of the value of that expression, we
91    could.  Calculating the ANTIC sets requires phi translation of
92    expressions, because the flow goes backwards through phis.  We must
93    iterate to a fixpoint of the ANTIC sets, because we have a kill
94    set.  Even in SSA form, values are not live over the entire
95    function, only from their definition point onwards.  So we have to
96    remove values from the ANTIC set once we go past the definition
97    point of the leaders that make them up.
98    compute_antic/compute_antic_aux performs this computation.
99
100    Third, we perform insertions to make partially redundant
101    expressions fully redundant.
102
103    An expression is partially redundant (excluding partial
104    anticipation) if:
105
106    1. It is AVAIL in some, but not all, of the predecessors of a
107       given block.
108    2. It is ANTIC in all the predecessors.
109
110    In order to make it fully redundant, we insert the expression into
111    the predecessors where it is not available, but is ANTIC.
112    insert/insert_aux performs this insertion.
113
114    Fourth, we eliminate fully redundant expressions.
115    This is a simple statement walk that replaces redundant
116    calculations  with the now available values.  */
117
118 /* Representations of value numbers:
119
120    Value numbers are represented using the "value handle" approach.
121    This means that each SSA_NAME (and for other reasons to be
122    disclosed in a moment, expression nodes) has a value handle that
123    can be retrieved through get_value_handle.  This value handle, *is*
124    the value number of the SSA_NAME.  You can pointer compare the
125    value handles for equivalence purposes.
126
127    For debugging reasons, the value handle is internally more than
128    just a number, it is a VAR_DECL named "value.x", where x is a
129    unique number for each value number in use.  This allows
130    expressions with SSA_NAMES replaced by value handles to still be
131    pretty printed in a sane way.  They simply print as "value.3 *
132    value.5", etc.  
133
134    Expression nodes have value handles associated with them as a
135    cache.  Otherwise, we'd have to look them up again in the hash
136    table This makes significant difference (factor of two or more) on
137    some test cases.  They can be thrown away after the pass is
138    finished.  */
139
140 /* Representation of expressions on value numbers: 
141
142    In some portions of this code, you will notice we allocate "fake"
143    analogues to the expression we are value numbering, and replace the
144    operands with the values of the expression.  Since we work on
145    values, and not just names, we canonicalize expressions to value
146    expressions for use in the ANTIC sets, the EXP_GEN set, etc.  
147
148    This is theoretically unnecessary, it just saves a bunch of
149    repeated get_value_handle and find_leader calls in the remainder of
150    the code, trading off temporary memory usage for speed.  The tree
151    nodes aren't actually creating more garbage, since they are
152    allocated in a special pools which are thrown away at the end of
153    this pass.  
154
155    All of this also means that if you print the EXP_GEN or ANTIC sets,
156    you will see "value.5 + value.7" in the set, instead of "a_55 +
157    b_66" or something.  The only thing that actually cares about
158    seeing the value leaders is phi translation, and it needs to be
159    able to find the leader for a value in an arbitrary block, so this
160    "value expression" form is perfect for it (otherwise you'd do
161    get_value_handle->find_leader->translate->get_value_handle->find_leader).*/
162
163
164 /* Representation of sets:
165
166    There are currently two types of sets used, hopefully to be unified soon.
167    The AVAIL sets do not need to be sorted in any particular order,
168    and thus, are simply represented as two bitmaps, one that keeps
169    track of values present in the set, and one that keeps track of
170    expressions present in the set.
171    
172    The other sets are represented as doubly linked lists kept in topological
173    order, with an optional supporting bitmap of values present in the
174    set.  The sets represent values, and the elements can be values or
175    expressions.  The elements can appear in different sets, but each
176    element can only appear once in each set.
177
178    Since each node in the set represents a value, we also want to be
179    able to map expression, set pairs to something that tells us
180    whether the value is present is a set.  We use a per-set bitmap for
181    that.  The value handles also point to a linked list of the
182    expressions they represent via a tree annotation.  This is mainly
183    useful only for debugging, since we don't do identity lookups.  */
184
185
186 /* A value set element.  Basically a single linked list of
187    expressions/values.  */
188 typedef struct value_set_node
189 {
190   /* An expression.  */
191   tree expr;
192
193   /* A pointer to the next element of the value set.  */
194   struct value_set_node *next;
195 } *value_set_node_t;
196
197
198 /* A value set.  This is a singly linked list of value_set_node
199    elements with a possible bitmap that tells us what values exist in
200    the set.  This set must be kept in topologically sorted order.  */
201 typedef struct value_set
202 {
203   /* The head of the list.  Used for iterating over the list in
204      order.  */
205   value_set_node_t head;
206
207   /* The tail of the list.  Used for tail insertions, which are
208      necessary to keep the set in topologically sorted order because
209      of how the set is built.  */
210   value_set_node_t tail;
211   
212   /* The length of the list.  */
213   size_t length;
214   
215   /* True if the set is indexed, which means it contains a backing
216      bitmap for quick determination of whether certain values exist in the
217      set.  */
218   bool indexed;
219   
220   /* The bitmap of values that exist in the set.  May be NULL in an
221      empty or non-indexed set.  */
222   bitmap values;
223   
224 } *value_set_t;
225
226
227 /* An unordered bitmap set.  One bitmap tracks values, the other,
228    expressions.  */
229 typedef struct bitmap_set
230 {
231   bitmap expressions;
232   bitmap values;
233 } *bitmap_set_t;
234
235 /* Sets that we need to keep track of.  */
236 typedef struct bb_value_sets
237 {
238   /* The EXP_GEN set, which represents expressions/values generated in
239      a basic block.  */
240   value_set_t exp_gen;
241
242   /* The PHI_GEN set, which represents PHI results generated in a
243      basic block.  */
244   bitmap_set_t phi_gen;
245
246   /* The TMP_GEN set, which represents results/temporaries generated
247      in a basic block. IE the LHS of an expression.  */
248   bitmap_set_t tmp_gen;
249
250   /* The AVAIL_OUT set, which represents which values are available in
251      a given basic block.  */
252   bitmap_set_t avail_out;
253
254   /* The ANTIC_IN set, which represents which values are anticiptable
255      in a given basic block.  */
256   value_set_t antic_in;
257
258   /* The NEW_SETS set, which is used during insertion to augment the
259      AVAIL_OUT set of blocks with the new insertions performed during
260      the current iteration.  */
261   bitmap_set_t new_sets;
262 } *bb_value_sets_t;
263
264 #define EXP_GEN(BB)     ((bb_value_sets_t) ((BB)->aux))->exp_gen
265 #define PHI_GEN(BB)     ((bb_value_sets_t) ((BB)->aux))->phi_gen
266 #define TMP_GEN(BB)     ((bb_value_sets_t) ((BB)->aux))->tmp_gen
267 #define AVAIL_OUT(BB)   ((bb_value_sets_t) ((BB)->aux))->avail_out
268 #define ANTIC_IN(BB)    ((bb_value_sets_t) ((BB)->aux))->antic_in
269 #define NEW_SETS(BB)    ((bb_value_sets_t) ((BB)->aux))->new_sets
270
271 /* This structure is used to keep track of statistics on what
272    optimization PRE was able to perform.  */
273 static struct
274 {
275   /* The number of RHS computations eliminated by PRE.  */
276   int eliminations;
277
278   /* The number of new expressions/temporaries generated by PRE.  */
279   int insertions;
280
281   /* The number of new PHI nodes added by PRE.  */
282   int phis;
283 } pre_stats;
284
285
286 static tree bitmap_find_leader (bitmap_set_t, tree);
287 static tree find_leader (value_set_t, tree);
288 static void value_insert_into_set (value_set_t, tree);
289 static void bitmap_value_insert_into_set (bitmap_set_t, tree);
290 static void bitmap_value_replace_in_set (bitmap_set_t, tree);
291 static void insert_into_set (value_set_t, tree);
292 static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
293 static bool bitmap_set_contains_value (bitmap_set_t, tree);
294 static bitmap_set_t bitmap_set_new (void);
295 static value_set_t set_new  (bool);
296 static bool is_undefined_value (tree);
297 static tree create_expression_by_pieces (basic_block, tree, tree);
298
299
300 /* We can add and remove elements and entries to and from sets
301    and hash tables, so we use alloc pools for them.  */
302
303 static alloc_pool value_set_pool;
304 static alloc_pool bitmap_set_pool;
305 static alloc_pool value_set_node_pool;
306 static alloc_pool binary_node_pool;
307 static alloc_pool unary_node_pool;
308 static alloc_pool reference_node_pool;
309 static struct obstack grand_bitmap_obstack;
310
311 /* Set of blocks with statements that have had its EH information
312    cleaned up.  */
313 static bitmap need_eh_cleanup;
314
315 /* The phi_translate_table caches phi translations for a given
316    expression and predecessor.  */
317
318 static htab_t phi_translate_table;
319
320 /* A three tuple {e, pred, v} used to cache phi translations in the
321    phi_translate_table.  */
322
323 typedef struct expr_pred_trans_d
324 {
325   /* The expression.  */
326   tree e;
327
328   /* The predecessor block along which we translated the expression.  */
329   basic_block pred;
330
331   /* The value that resulted from the translation.  */
332   tree v;
333
334   /* The hashcode for the expression, pred pair. This is cached for
335      speed reasons.  */
336   hashval_t hashcode;
337 } *expr_pred_trans_t;
338
339 /* Return the hash value for a phi translation table entry.  */
340
341 static hashval_t
342 expr_pred_trans_hash (const void *p)
343 {
344   const expr_pred_trans_t ve = (expr_pred_trans_t) p;
345   return ve->hashcode;
346 }
347
348 /* Return true if two phi translation table entries are the same.
349    P1 and P2 should point to the expr_pred_trans_t's to be compared.*/
350
351 static int
352 expr_pred_trans_eq (const void *p1, const void *p2)
353 {
354   const expr_pred_trans_t ve1 = (expr_pred_trans_t) p1;
355   const expr_pred_trans_t ve2 = (expr_pred_trans_t) p2;
356   basic_block b1 = ve1->pred;
357   basic_block b2 = ve2->pred;
358
359   
360   /* If they are not translations for the same basic block, they can't
361      be equal.  */
362   if (b1 != b2)
363     return false;
364
365   /* If they are for the same basic block, determine if the
366      expressions are equal.   */  
367   if (expressions_equal_p (ve1->e, ve2->e))
368     return true;
369   
370   return false;
371 }
372
373 /* Search in the phi translation table for the translation of
374    expression E in basic block PRED. Return the translated value, if
375    found, NULL otherwise.  */ 
376
377 static inline tree
378 phi_trans_lookup (tree e, basic_block pred)
379 {
380   void **slot;
381   struct expr_pred_trans_d ept;
382   ept.e = e;
383   ept.pred = pred;
384   ept.hashcode = vn_compute (e, (unsigned long) pred, NULL);
385   slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
386                                    NO_INSERT);
387   if (!slot)
388     return NULL;
389   else
390     return ((expr_pred_trans_t) *slot)->v;
391 }
392
393
394 /* Add the tuple mapping from {expression E, basic block PRED} to
395    value V, to the phi translation table.  */
396
397 static inline void
398 phi_trans_add (tree e, tree v, basic_block pred)
399 {
400   void **slot;
401   expr_pred_trans_t new_pair = xmalloc (sizeof (*new_pair));
402   new_pair->e = e;
403   new_pair->pred = pred;
404   new_pair->v = v;
405   new_pair->hashcode = vn_compute (e, (unsigned long) pred, NULL);
406   slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
407                                    new_pair->hashcode, INSERT);
408   if (*slot)
409     free (*slot);
410   *slot = (void *) new_pair;
411 }
412
413
414 /* Add expression E to the expression set of value V.  */
415
416 void
417 add_to_value (tree v, tree e)
418 {
419   /* Constants have no expression sets.  */
420   if (is_gimple_min_invariant (v))
421     return;
422
423   if (VALUE_HANDLE_EXPR_SET (v) == NULL)
424     VALUE_HANDLE_EXPR_SET (v) = set_new (false);
425
426   insert_into_set (VALUE_HANDLE_EXPR_SET (v), e);
427 }
428
429
430 /* Return true if value V exists in the bitmap for SET.  */
431
432 static inline bool
433 value_exists_in_set_bitmap (value_set_t set, tree v)
434 {
435   if (!set->values)
436     return false;
437
438   return bitmap_bit_p (set->values, VALUE_HANDLE_ID (v));
439 }
440
441
442 /* Remove value V from the bitmap for SET.  */
443
444 static void
445 value_remove_from_set_bitmap (value_set_t set, tree v)
446 {
447   gcc_assert (set->indexed);
448
449   if (!set->values)
450     return;
451
452   bitmap_clear_bit (set->values, VALUE_HANDLE_ID (v));
453 }
454
455
456 /* Insert the value number V into the bitmap of values existing in
457    SET.  */
458
459 static inline void
460 value_insert_into_set_bitmap (value_set_t set, tree v)
461 {
462   gcc_assert (set->indexed);
463
464   if (set->values == NULL)
465     {
466       set->values = BITMAP_OBSTACK_ALLOC (&grand_bitmap_obstack);
467       bitmap_clear (set->values);
468     }
469
470   bitmap_set_bit (set->values, VALUE_HANDLE_ID (v));
471 }
472
473
474 /* Create a new bitmap set and return it.  */
475
476 static bitmap_set_t 
477 bitmap_set_new (void)
478 {
479   bitmap_set_t ret = pool_alloc (bitmap_set_pool);
480   ret->expressions = BITMAP_OBSTACK_ALLOC (&grand_bitmap_obstack);
481   ret->values = BITMAP_OBSTACK_ALLOC (&grand_bitmap_obstack);
482   bitmap_clear (ret->expressions);
483   bitmap_clear (ret->values);
484   return ret;
485 }
486
487 /* Create a new set.  */
488
489 static value_set_t
490 set_new  (bool indexed)
491 {
492   value_set_t ret;
493   ret = pool_alloc (value_set_pool);
494   ret->head = ret->tail = NULL;
495   ret->length = 0;
496   ret->indexed = indexed;
497   ret->values = NULL;
498   return ret;
499 }
500
501 /* Insert an expression EXPR into a bitmapped set.  */
502
503 static void
504 bitmap_insert_into_set (bitmap_set_t set, tree expr)
505 {
506   tree val;
507   /* XXX: For now, we only let SSA_NAMES into the bitmap sets.  */
508   gcc_assert (TREE_CODE (expr) == SSA_NAME);
509   val = get_value_handle (expr);
510   
511   gcc_assert (val);
512   if (!is_gimple_min_invariant (val))
513   {
514     bitmap_set_bit (set->values, VALUE_HANDLE_ID (val));
515     bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
516   }
517 }
518
519 /* Insert EXPR into SET.  */
520
521 static void
522 insert_into_set (value_set_t set, tree expr)
523 {
524   value_set_node_t newnode = pool_alloc (value_set_node_pool);
525   tree val = get_value_handle (expr);
526   gcc_assert (val);
527   
528   if (is_gimple_min_invariant (val))
529     return;
530
531   /* For indexed sets, insert the value into the set value bitmap.
532      For all sets, add it to the linked list and increment the list
533      length.  */
534   if (set->indexed)
535     value_insert_into_set_bitmap (set, val);
536
537   newnode->next = NULL;
538   newnode->expr = expr;
539   set->length ++;
540   if (set->head == NULL)
541     {
542       set->head = set->tail = newnode;
543     }
544   else
545     {
546       set->tail->next = newnode;
547       set->tail = newnode;
548     }
549 }
550
551 /* Copy a bitmapped set ORIG, into bitmapped set DEST.  */
552
553 static void
554 bitmap_set_copy (bitmap_set_t dest, bitmap_set_t orig)
555 {
556   bitmap_copy (dest->expressions, orig->expressions);
557   bitmap_copy (dest->values, orig->values);
558 }
559
560 /* Copy the set ORIG to the set DEST.  */
561
562 static void
563 set_copy (value_set_t dest, value_set_t orig)
564 {
565   value_set_node_t node;
566  
567   if (!orig || !orig->head)
568     return;
569
570   for (node = orig->head;
571        node;
572        node = node->next)
573     {
574       insert_into_set (dest, node->expr);
575     }
576 }
577
578 /* Remove EXPR from SET.  */
579
580 static void
581 set_remove (value_set_t set, tree expr)
582 {
583   value_set_node_t node, prev;
584
585   /* Remove the value of EXPR from the bitmap, decrement the set
586      length, and remove it from the actual double linked list.  */ 
587   value_remove_from_set_bitmap (set, get_value_handle (expr));
588   set->length--;
589   prev = NULL;
590   for (node = set->head; 
591        node != NULL; 
592        prev = node, node = node->next)
593     {
594       if (node->expr == expr)
595         {
596           if (prev == NULL)
597             set->head = node->next;
598           else
599             prev->next= node->next;
600  
601           if (node == set->tail)
602             set->tail = prev;
603           pool_free (value_set_node_pool, node);
604           return;
605         }
606     }
607 }
608
609 /* Return true if SET contains the value VAL.  */
610
611 static bool
612 set_contains_value (value_set_t set, tree val)
613 {
614   /* All constants are in every set.  */
615   if (is_gimple_min_invariant (val))
616     return true;
617   
618   if (set->length == 0)
619     return false;
620   
621   return value_exists_in_set_bitmap (set, val);
622 }
623
624 /* Return true if bitmapped set SET contains the expression EXPR.  */
625 static bool
626 bitmap_set_contains (bitmap_set_t set, tree expr)
627 {
628   /* All constants are in every set.  */
629   if (is_gimple_min_invariant (get_value_handle (expr)))
630     return true;
631
632   /* XXX: Bitmapped sets only contain SSA_NAME's for now.  */
633   if (TREE_CODE (expr) != SSA_NAME)
634     return false;
635   return bitmap_bit_p (set->expressions, SSA_NAME_VERSION (expr));
636 }
637
638   
639 /* Return true if bitmapped set SET contains the value VAL.  */
640
641 static bool
642 bitmap_set_contains_value (bitmap_set_t set, tree val)
643 {
644   if (is_gimple_min_invariant (val))
645     return true;
646   return bitmap_bit_p (set->values, VALUE_HANDLE_ID (val));
647 }
648
649 /* Replace an instance of value LOOKFOR with expression EXPR in SET.  */
650
651 static void
652 bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr)
653 {
654   value_set_t exprset;
655   value_set_node_t node;
656   if (is_gimple_min_invariant (lookfor))
657     return;
658   if (!bitmap_set_contains_value (set, lookfor))
659     return;
660   /* The number of expressions having a given value is usually
661      significantly less than the total number of expressions in SET.
662      Thus, rather than check, for each expression in SET, whether it
663      has the value LOOKFOR, we walk the reverse mapping that tells us
664      what expressions have a given value, and see if any of those
665      expressions are in our set.  For large testcases, this is about
666      5-10x faster than walking the bitmap.  If this is somehow a
667      significant lose for some cases, we can choose which set to walk
668      based on the set size.  */
669   exprset = VALUE_HANDLE_EXPR_SET (lookfor);
670   for (node = exprset->head; node; node = node->next)
671     {
672       if (TREE_CODE (node->expr) == SSA_NAME)
673         {
674           if (bitmap_bit_p (set->expressions, SSA_NAME_VERSION (node->expr)))
675             {
676               bitmap_clear_bit (set->expressions, SSA_NAME_VERSION (node->expr));
677               bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
678               return;
679             }
680         }
681     }
682 }
683
684 /* Subtract bitmapped set B from value set A, and return the new set.  */
685
686 static value_set_t
687 bitmap_set_subtract_from_value_set (value_set_t a, bitmap_set_t b,
688                                     bool indexed)
689 {
690   value_set_t ret = set_new (indexed);
691   value_set_node_t node;
692   for (node = a->head;
693        node;
694        node = node->next)
695     {
696       if (!bitmap_set_contains (b, node->expr))
697         insert_into_set (ret, node->expr);
698     }
699   return ret;
700 }
701
702 /* Return true if two sets are equal.  */
703
704 static bool
705 set_equal (value_set_t a, value_set_t b)
706 {
707   value_set_node_t node;
708
709   if (a->length != b->length)
710     return false;
711   for (node = a->head;
712        node;
713        node = node->next)
714     {
715       if (!set_contains_value (b, get_value_handle (node->expr)))
716         return false;
717     }
718   return true;
719 }
720
721 /* Replace an instance of EXPR's VALUE with EXPR in SET.  */
722
723 static void
724 bitmap_value_replace_in_set (bitmap_set_t set, tree expr)
725 {
726   tree val = get_value_handle (expr);
727   bitmap_set_replace_value (set, val, expr);
728 }
729
730 /* Insert EXPR into SET if EXPR's value is not already present in
731    SET.  */
732
733 static void
734 bitmap_value_insert_into_set (bitmap_set_t set, tree expr)
735 {
736   tree val = get_value_handle (expr);
737
738   if (is_gimple_min_invariant (val))
739     return;
740   
741   if (!bitmap_set_contains_value (set, val))
742     bitmap_insert_into_set (set, expr);
743 }
744
745 /* Insert the value for EXPR into SET, if it doesn't exist already.  */
746
747 static void
748 value_insert_into_set (value_set_t set, tree expr)
749 {
750   tree val = get_value_handle (expr);
751
752   /* Constant and invariant values exist everywhere, and thus,
753      actually keeping them in the sets is pointless.  */
754   if (is_gimple_min_invariant (val))
755     return;
756
757   if (!set_contains_value (set, val))
758     insert_into_set (set, expr);
759 }
760
761
762 /* Print out SET to OUTFILE.  */
763
764 static void
765 bitmap_print_value_set (FILE *outfile, bitmap_set_t set,
766                         const char *setname, int blockindex)
767 {
768   fprintf (outfile, "%s[%d] := { ", setname, blockindex);
769   if (set)
770     {
771       int i;
772       EXECUTE_IF_SET_IN_BITMAP (set->expressions, 0, i,
773       {
774         print_generic_expr (outfile, ssa_name (i), 0);
775         
776         fprintf (outfile, " (");
777         print_generic_expr (outfile, get_value_handle (ssa_name (i)), 0);
778         fprintf (outfile, ") ");
779         if (bitmap_last_set_bit (set->expressions) != i)
780           fprintf (outfile, ", ");
781       });
782     }
783   fprintf (outfile, " }\n");
784 }
785 /* Print out the value_set SET to OUTFILE.  */
786
787 static void
788 print_value_set (FILE *outfile, value_set_t set,
789                  const char *setname, int blockindex)
790 {
791   value_set_node_t node;
792   fprintf (outfile, "%s[%d] := { ", setname, blockindex);
793   if (set)
794     {
795       for (node = set->head;
796            node;
797            node = node->next)
798         {
799           print_generic_expr (outfile, node->expr, 0);
800           
801           fprintf (outfile, " (");
802           print_generic_expr (outfile, get_value_handle (node->expr), 0);
803           fprintf (outfile, ") ");
804                      
805           if (node->next)
806             fprintf (outfile, ", ");
807         }
808     }
809
810   fprintf (outfile, " }\n");
811 }
812
813 /* Print out the expressions that have VAL to OUTFILE.  */
814
815 void
816 print_value_expressions (FILE *outfile, tree val)
817 {
818   if (VALUE_HANDLE_EXPR_SET (val))
819     {
820       char s[10];
821       sprintf (s, "VH.%04d", VALUE_HANDLE_ID (val));
822       print_value_set (outfile, VALUE_HANDLE_EXPR_SET (val), s, 0);
823     }
824 }
825
826
827 void
828 debug_value_expressions (tree val)
829 {
830   print_value_expressions (stderr, val);
831 }
832
833   
834 void debug_value_set (value_set_t, const char *, int);
835
836 void
837 debug_value_set (value_set_t set, const char *setname, int blockindex)
838 {
839   print_value_set (stderr, set, setname, blockindex);
840 }
841
842 /* Translate EXPR using phis in PHIBLOCK, so that it has the values of
843    the phis in PRED.  Return NULL if we can't find a leader for each
844    part of the translated expression.  */
845
846 static tree
847 phi_translate (tree expr, value_set_t set, basic_block pred,
848                basic_block phiblock)
849 {
850   tree phitrans = NULL;
851   tree oldexpr = expr;
852   
853   if (expr == NULL)
854     return NULL;
855
856   if (is_gimple_min_invariant (expr))
857     return expr;
858
859   /* Phi translations of a given expression don't change,  */
860   phitrans = phi_trans_lookup (expr, pred);
861   if (phitrans)
862     return phitrans;
863   
864   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
865     {
866     case tcc_reference:
867       /* XXX: Until we have PRE of loads working, none will be ANTIC. */
868       return NULL;
869
870     case tcc_binary:
871       {
872         tree oldop1 = TREE_OPERAND (expr, 0);
873         tree oldop2 = TREE_OPERAND (expr, 1);
874         tree newop1;
875         tree newop2;
876         tree newexpr;
877         
878         newop1 = phi_translate (find_leader (set, oldop1),
879                                 set, pred, phiblock);
880         if (newop1 == NULL)
881           return NULL;
882         newop2 = phi_translate (find_leader (set, oldop2),
883                                 set, pred, phiblock);
884         if (newop2 == NULL)
885           return NULL;
886         if (newop1 != oldop1 || newop2 != oldop2)
887           {
888             newexpr = pool_alloc (binary_node_pool);
889             memcpy (newexpr, expr, tree_size (expr));
890             create_tree_ann (newexpr);
891             TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldop1 : get_value_handle (newop1);
892             TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
893             vn_lookup_or_add (newexpr, NULL);
894             expr = newexpr;
895             phi_trans_add (oldexpr, newexpr, pred);         
896           }
897       }
898       return expr;
899
900     case tcc_unary:
901       {
902         tree oldop1 = TREE_OPERAND (expr, 0);
903         tree newop1;
904         tree newexpr;
905
906         newop1 = phi_translate (find_leader (set, oldop1),
907                                 set, pred, phiblock);
908         if (newop1 == NULL)
909           return NULL;
910         if (newop1 != oldop1)
911           {
912             newexpr = pool_alloc (unary_node_pool);
913             memcpy (newexpr, expr, tree_size (expr));
914             create_tree_ann (newexpr);   
915             TREE_OPERAND (newexpr, 0) = get_value_handle (newop1);
916             vn_lookup_or_add (newexpr, NULL);
917             expr = newexpr;
918             phi_trans_add (oldexpr, newexpr, pred);
919           }
920       }
921       return expr;
922
923     case tcc_exceptional:
924       {
925         tree phi = NULL;
926         int i;
927         gcc_assert (TREE_CODE (expr) == SSA_NAME);
928         if (TREE_CODE (SSA_NAME_DEF_STMT (expr)) == PHI_NODE)
929           phi = SSA_NAME_DEF_STMT (expr);
930         else
931           return expr;
932         
933         for (i = 0; i < PHI_NUM_ARGS (phi); i++)
934           if (PHI_ARG_EDGE (phi, i)->src == pred)
935             {
936               tree val;
937               if (is_undefined_value (PHI_ARG_DEF (phi, i)))
938                 return NULL;
939               val = vn_lookup_or_add (PHI_ARG_DEF (phi, i), NULL);
940               return PHI_ARG_DEF (phi, i);
941             }
942       }
943       return expr;
944
945     default:
946       gcc_unreachable ();
947     }
948 }
949
950 static void
951 phi_translate_set (value_set_t dest, value_set_t set, basic_block pred,
952                    basic_block phiblock)
953 {
954   value_set_node_t node;
955   for (node = set->head;
956        node;
957        node = node->next)
958     {
959       tree translated;
960       translated = phi_translate (node->expr, set, pred, phiblock);
961       phi_trans_add (node->expr, translated, pred);
962       
963       if (translated != NULL)
964         value_insert_into_set (dest, translated);
965     } 
966 }
967
968 /* Find the leader for a value (i.e., the name representing that
969    value) in a given set, and return it.  Return NULL if no leader is
970    found.  */
971
972 static tree
973 bitmap_find_leader (bitmap_set_t set, tree val)
974 {
975   if (val == NULL)
976     return NULL;
977   
978   if (is_gimple_min_invariant (val))
979     return val;
980   if (bitmap_set_contains_value (set, val))
981     {
982       /* Rather than walk the entire bitmap of expressions, and see
983          whether any of them has the value we are looking for, we look
984          at the reverse mapping, which tells us the set of expressions
985          that have a given value (IE value->expressions with that
986          value) and see if any of those expressions are in our set.
987          The number of expressions per value is usually significantly
988          less than the number of expressions in the set.  In fact, for
989          large testcases, doing it this way is roughly 5-10x faster
990          than walking the bitmap.
991          If this is somehow a significant lose for some cases, we can
992          choose which set to walk based on which set is smaller.  */     
993       value_set_t exprset;
994       value_set_node_t node;
995       exprset = VALUE_HANDLE_EXPR_SET (val);
996       for (node = exprset->head; node; node = node->next)
997         {
998           if (TREE_CODE (node->expr) == SSA_NAME)
999             {
1000               if (bitmap_bit_p (set->expressions, 
1001                                 SSA_NAME_VERSION (node->expr)))
1002                 return node->expr;
1003             }
1004         }
1005     }
1006   return NULL;
1007 }
1008
1009         
1010 /* Find the leader for a value (i.e., the name representing that
1011    value) in a given set, and return it.  Return NULL if no leader is
1012    found.  */
1013
1014 static tree
1015 find_leader (value_set_t set, tree val)
1016 {
1017   value_set_node_t node;
1018
1019   if (val == NULL)
1020     return NULL;
1021
1022   /* Constants represent themselves.  */
1023   if (is_gimple_min_invariant (val))
1024     return val;
1025
1026   if (set->length == 0)
1027     return NULL;
1028   
1029   if (value_exists_in_set_bitmap (set, val))
1030     {
1031       for (node = set->head;
1032            node;
1033            node = node->next)
1034         {
1035           if (get_value_handle (node->expr) == val)
1036             return node->expr;
1037         }
1038     }
1039
1040   return NULL;
1041 }
1042
1043 /* Determine if the expression EXPR is valid in SET.  This means that
1044    we have a leader for each part of the expression (if it consists of
1045    values), or the expression is an SSA_NAME.  
1046
1047    NB:  We never should run into a case where we have SSA_NAME +
1048    SSA_NAME or SSA_NAME + value.  The sets valid_in_set is called on,
1049    the ANTIC sets, will only ever have SSA_NAME's or binary value
1050    expression (IE VALUE1 + VALUE2)  */
1051
1052 static bool
1053 valid_in_set (value_set_t set, tree expr)
1054 {
1055   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
1056     {
1057     case tcc_binary:
1058       {
1059         tree op1 = TREE_OPERAND (expr, 0);
1060         tree op2 = TREE_OPERAND (expr, 1);
1061         return set_contains_value (set, op1) && set_contains_value (set, op2);
1062       }
1063
1064     case tcc_unary:
1065       {
1066         tree op1 = TREE_OPERAND (expr, 0);
1067         return set_contains_value (set, op1);
1068       }
1069
1070     case tcc_reference:
1071       /* XXX: Until PRE of loads works, no reference nodes are ANTIC.  */
1072       return false;
1073
1074     case tcc_exceptional:
1075       gcc_assert (TREE_CODE (expr) == SSA_NAME);
1076       return true;
1077
1078     default:
1079       /* No other cases should be encountered.  */
1080       gcc_unreachable (); 
1081    }
1082 }
1083
1084 /* Clean the set of expressions that are no longer valid in SET.  This
1085    means expressions that are made up of values we have no leaders for
1086    in SET.  */
1087
1088 static void
1089 clean (value_set_t set)
1090 {
1091   value_set_node_t node;
1092   value_set_node_t next;
1093   node = set->head;
1094   while (node)
1095     {
1096       next = node->next;
1097       if (!valid_in_set (set, node->expr))      
1098         set_remove (set, node->expr);
1099       node = next;
1100     }
1101 }
1102
1103 DEF_VEC_MALLOC_P (basic_block);
1104
1105 /* Compute the ANTIC set for BLOCK.
1106
1107 ANTIC_OUT[BLOCK] = intersection of ANTIC_IN[b] for all succ(BLOCK), if
1108 succs(BLOCK) > 1
1109 ANTIC_OUT[BLOCK] = phi_translate (ANTIC_IN[succ(BLOCK)]) if
1110 succs(BLOCK) == 1
1111
1112 ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] -
1113 TMP_GEN[BLOCK])
1114
1115 Iterate until fixpointed.
1116
1117 XXX: It would be nice to either write a set_clear, and use it for
1118 antic_out, or to mark the antic_out set as deleted at the end
1119 of this routine, so that the pool can hand the same memory back out
1120 again for the next antic_out.  */
1121
1122
1123 static bool
1124 compute_antic_aux (basic_block block)
1125 {
1126   basic_block son;
1127   edge e;
1128   bool changed = false;
1129   value_set_t S, old, ANTIC_OUT;
1130   value_set_node_t node;
1131   
1132   ANTIC_OUT = S = NULL;
1133   /* If any edges from predecessors are abnormal, antic_in is empty, so
1134      punt.  Remember that the block has an incoming abnormal edge by
1135      setting the BB_VISITED flag.  */
1136   if (! (block->flags & BB_VISITED))
1137     {
1138       for (e = block->pred; e; e = e->pred_next)
1139         if (e->flags & EDGE_ABNORMAL)
1140           {
1141             block->flags |= BB_VISITED;
1142             break;
1143           }
1144     }
1145   if (block->flags & BB_VISITED)
1146     {
1147       S = NULL;
1148       goto visit_sons;
1149     }
1150   
1151
1152   old = set_new (false);
1153   set_copy (old, ANTIC_IN (block));
1154   ANTIC_OUT = set_new (true);
1155
1156   /* If the block has no successors, ANTIC_OUT is empty, because it is
1157      the exit block.  */
1158   if (block->succ == NULL);
1159
1160   /* If we have one successor, we could have some phi nodes to
1161      translate through.  */
1162   else if (block->succ->succ_next == NULL)
1163     {
1164       phi_translate_set (ANTIC_OUT, ANTIC_IN(block->succ->dest),
1165                          block, block->succ->dest);
1166     }
1167   /* If we have multiple successors, we take the intersection of all of
1168      them.  */
1169   else
1170     {
1171       VEC (basic_block) * worklist;
1172       edge e;
1173       size_t i;
1174       basic_block bprime, first;
1175
1176       worklist = VEC_alloc (basic_block, 2);
1177       e = block->succ;
1178       while (e)
1179         {
1180           VEC_safe_push (basic_block, worklist, e->dest);
1181           e = e->succ_next;
1182         }
1183       first = VEC_index (basic_block, worklist, 0);
1184       set_copy (ANTIC_OUT, ANTIC_IN (first));
1185
1186       for (i = 1; VEC_iterate (basic_block, worklist, i, bprime); i++)
1187         {
1188           node = ANTIC_OUT->head;
1189           while (node)
1190             {
1191               tree val;
1192               value_set_node_t next = node->next;
1193               val = get_value_handle (node->expr);
1194               if (!set_contains_value (ANTIC_IN (bprime), val))
1195                 set_remove (ANTIC_OUT, node->expr);
1196               node = next;
1197             }
1198         }
1199       VEC_free (basic_block, worklist);
1200     }
1201
1202   /* Generate ANTIC_OUT - TMP_GEN */
1203   S = bitmap_set_subtract_from_value_set (ANTIC_OUT, TMP_GEN (block), false);
1204
1205   /* Start ANTIC_IN with EXP_GEN - TMP_GEN */
1206   ANTIC_IN (block) = bitmap_set_subtract_from_value_set (EXP_GEN (block), 
1207                                                          TMP_GEN (block),
1208                                                          true);
1209   
1210   /* Then union in the ANTIC_OUT - TMP_GEN values, to get ANTIC_OUT U
1211      EXP_GEN - TMP_GEN */
1212   for (node = S->head;
1213        node;
1214        node = node->next)
1215     {
1216       value_insert_into_set (ANTIC_IN (block), node->expr);
1217     }
1218   clean (ANTIC_IN (block));
1219   
1220
1221   if (!set_equal (old, ANTIC_IN (block)))
1222     changed = true;
1223
1224  visit_sons:
1225   if (dump_file && (dump_flags & TDF_DETAILS))
1226     {
1227       if (ANTIC_OUT)
1228         print_value_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);
1229       print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index);
1230       if (S)
1231         print_value_set (dump_file, S, "S", block->index);
1232
1233     }
1234
1235   for (son = first_dom_son (CDI_POST_DOMINATORS, block);
1236        son;
1237        son = next_dom_son (CDI_POST_DOMINATORS, son))
1238     {
1239       changed |= compute_antic_aux (son);
1240     }
1241   return changed;
1242 }
1243
1244 /* Compute ANTIC sets.  */
1245
1246 static void
1247 compute_antic (void)
1248 {
1249   bool changed = true;
1250   basic_block bb;
1251   int num_iterations = 0;
1252   FOR_ALL_BB (bb)
1253     {
1254       ANTIC_IN (bb) = set_new (true);
1255       gcc_assert (!(bb->flags & BB_VISITED));
1256     }
1257
1258   while (changed)
1259     {
1260       num_iterations++;
1261       changed = false;
1262       changed = compute_antic_aux (EXIT_BLOCK_PTR);
1263     }
1264   FOR_ALL_BB (bb)
1265     {
1266       bb->flags &= ~BB_VISITED;
1267     }
1268   if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
1269     fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
1270 }
1271
1272
1273 /* Find a leader for an expression, or generate one using
1274    create_expression_by_pieces if it's ANTIC but
1275    complex.  
1276    BLOCK is the basic_block we are looking for leaders in.
1277    EXPR is the expression to find a leader or generate for. 
1278    STMTS is the statement list to put the inserted expressions on.
1279    Returns the SSA_NAME of the LHS of the generated expression or the
1280    leader.  */
1281
1282 static tree
1283 find_or_generate_expression (basic_block block, tree expr, tree stmts)
1284 {
1285   tree genop;
1286   genop = bitmap_find_leader (AVAIL_OUT (block), expr);
1287   /* Depending on the order we process DOM branches in, the value
1288      may not have propagated to all the dom children yet during
1289      this iteration.  In this case, the value will always be in
1290      the NEW_SETS for us already, having been propagated from our
1291      dominator.  */
1292   if (genop == NULL)
1293     genop = bitmap_find_leader (NEW_SETS (block), expr);
1294   /* If it's still NULL, see if it is a complex expression, and if
1295      so, generate it recursively, otherwise, abort, because it's
1296      not really .  */
1297   if (genop == NULL)
1298     {
1299       genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
1300       gcc_assert (UNARY_CLASS_P (genop)
1301                   || BINARY_CLASS_P (genop)
1302                   || REFERENCE_CLASS_P (genop));
1303       genop = create_expression_by_pieces (block, genop, stmts);
1304     }
1305   return genop;
1306 }
1307
1308   
1309 /* Create an expression in pieces, so that we can handle very complex
1310    expressions that may be ANTIC, but not necessary GIMPLE.  
1311    BLOCK is the basic block the expression will be inserted into,
1312    EXPR is the expression to insert (in value form)
1313    STMTS is a statement list to append the necessary insertions into.
1314
1315    This function will abort if we hit some value that shouldn't be
1316    ANTIC but is (IE there is no leader for it, or its components).
1317    This function may also generate expressions that are themselves
1318    partially or fully redundant.  Those that are will be either made
1319    fully redundant during the next iteration of insert (for partially
1320    redundant ones), or eliminated by eliminate (for fully redundant
1321    ones).  */
1322
1323 static tree
1324 create_expression_by_pieces (basic_block block, tree expr, tree stmts)
1325 {
1326   tree name = NULL_TREE;
1327   tree newexpr = NULL_TREE;
1328   tree v;
1329   
1330   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
1331     {
1332     case tcc_binary:
1333       {
1334         tree_stmt_iterator tsi;
1335         tree genop1, genop2;
1336         tree temp;
1337         tree op1 = TREE_OPERAND (expr, 0);
1338         tree op2 = TREE_OPERAND (expr, 1);
1339         genop1 = find_or_generate_expression (block, op1, stmts);
1340         genop2 = find_or_generate_expression (block, op2, stmts);
1341         temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
1342         add_referenced_tmp_var (temp);
1343         newexpr = build (TREE_CODE (expr), TREE_TYPE (expr), 
1344                          genop1, genop2);
1345         newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
1346                          temp, newexpr);
1347         name = make_ssa_name (temp, newexpr);
1348         TREE_OPERAND (newexpr, 0) = name;
1349         tsi = tsi_last (stmts);
1350         tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
1351         pre_stats.insertions++;
1352         break;
1353       }
1354     case tcc_unary:
1355       {
1356         tree_stmt_iterator tsi;
1357         tree genop1;
1358         tree temp;
1359         tree op1 = TREE_OPERAND (expr, 0);
1360         genop1 = find_or_generate_expression (block, op1, stmts);
1361         temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
1362         add_referenced_tmp_var (temp);
1363         newexpr = build (TREE_CODE (expr), TREE_TYPE (expr), 
1364                          genop1);
1365         newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
1366                          temp, newexpr);
1367         name = make_ssa_name (temp, newexpr);
1368         TREE_OPERAND (newexpr, 0) = name;
1369         tsi = tsi_last (stmts);
1370         tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
1371         pre_stats.insertions++;
1372
1373         break;
1374       }
1375     default:
1376       gcc_unreachable ();
1377       
1378     }
1379   v = get_value_handle (expr);
1380   vn_add (name, v, NULL);
1381   bitmap_insert_into_set (NEW_SETS (block), name);
1382   bitmap_value_insert_into_set (AVAIL_OUT (block), name);
1383   if (dump_file && (dump_flags & TDF_DETAILS))
1384     {                               
1385       fprintf (dump_file, "Inserted ");
1386       print_generic_expr (dump_file, newexpr, 0);
1387       fprintf (dump_file, " in predecessor %d\n", block->index);
1388     }
1389   return name;
1390 }
1391       
1392 /* Perform insertion of partially redundant values.
1393    For BLOCK, do the following:
1394    1.  Propagate the NEW_SETS of the dominator into the current block.
1395    If the block has multiple predecessors, 
1396        2a. Iterate over the ANTIC expressions for the block to see if
1397            any of them are partially redundant.
1398        2b. If so, insert them into the necessary predecessors to make
1399            the expression fully redundant.
1400        2c. Insert a new PHI merging the values of the predecessors.
1401        2d. Insert the new PHI, and the new expressions, into the
1402            NEW_SETS set.  
1403    3. Recursively call ourselves on the dominator children of BLOCK.
1404
1405 */
1406 static bool
1407 insert_aux (basic_block block)
1408 {
1409   basic_block son;
1410   bool new_stuff = false;
1411
1412   if (block)
1413     {
1414       basic_block dom;
1415       dom = get_immediate_dominator (CDI_DOMINATORS, block);
1416       if (dom)
1417         {
1418           int i;
1419           bitmap_set_t newset = NEW_SETS (dom);
1420           EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i,
1421           {
1422             bitmap_insert_into_set (NEW_SETS (block), ssa_name (i));
1423             bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i));
1424           });
1425           if (block->pred->pred_next)
1426             {
1427               value_set_node_t node;
1428               for (node = ANTIC_IN (block)->head;
1429                    node;
1430                    node = node->next)
1431                 {
1432                   if (BINARY_CLASS_P (node->expr)
1433                       || UNARY_CLASS_P (node->expr))
1434                     {
1435                       tree *avail;
1436                       tree val;
1437                       bool by_some = false;
1438                       bool cant_insert = false;
1439                       bool all_same = true;
1440                       tree first_s = NULL;
1441                       edge pred;
1442                       basic_block bprime;
1443                       tree eprime;
1444
1445                       val = get_value_handle (node->expr);
1446                       if (bitmap_set_contains_value (PHI_GEN (block), val))
1447                         continue; 
1448                       if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
1449                         {
1450                           if (dump_file && (dump_flags & TDF_DETAILS))
1451                             fprintf (dump_file, "Found fully redundant value\n");
1452                           continue;
1453                         }
1454                                     
1455                       avail = xcalloc (last_basic_block, sizeof (tree));
1456                       for (pred = block->pred;
1457                            pred;
1458                            pred = pred->pred_next)
1459                         {
1460                           tree vprime;
1461                           tree edoubleprime;
1462
1463                           /* This can happen in the very weird case
1464                              that our fake infinite loop edges have caused a
1465                              critical edge to appear.  */
1466                           if (EDGE_CRITICAL_P (pred))
1467                             {
1468                               cant_insert = true;
1469                               break;
1470                             }
1471                           bprime = pred->src;
1472                           eprime = phi_translate (node->expr,
1473                                                   ANTIC_IN (block),
1474                                                   bprime, block);
1475
1476                           /* eprime will generally only be NULL if the
1477                              value of the expression, translated
1478                              through the PHI for this predecessor, is
1479                              undefined.  If that is the case, we can't
1480                              make the expression fully redundant,
1481                              because its value is undefined along a
1482                              predecessor path.  We can thus break out
1483                              early because it doesn't matter what the
1484                              rest of the results are.  */
1485                           if (eprime == NULL)
1486                             {
1487                               cant_insert = true;
1488                               break;
1489                             }
1490
1491                           vprime = get_value_handle (eprime);
1492                           gcc_assert (vprime);
1493                           edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
1494                                                              vprime);
1495                           if (edoubleprime == NULL)
1496                             {
1497                               avail[bprime->index] = eprime;
1498                               all_same = false;
1499                             }
1500                           else
1501                             {
1502                               avail[bprime->index] = edoubleprime;
1503                               by_some = true; 
1504                               if (first_s == NULL)
1505                                 first_s = edoubleprime;
1506                               else if (first_s != edoubleprime)
1507                                 all_same = false;
1508                               gcc_assert (first_s == edoubleprime 
1509                                           || !operand_equal_p
1510                                               (first_s, edoubleprime, 0));
1511                             }
1512                         }
1513                       /* If we can insert it, it's not the same value
1514                          already existing along every predecessor, and
1515                          it's defined by some predecessor, it is
1516                          partially redundant.  */
1517                       if (!cant_insert && !all_same && by_some)
1518                         {
1519                           tree type = TREE_TYPE (avail[block->pred->src->index]);
1520                           tree temp;
1521                           if (dump_file && (dump_flags & TDF_DETAILS))
1522                             {
1523                               fprintf (dump_file, "Found partial redundancy for expression ");
1524                               print_generic_expr (dump_file, node->expr, 0);
1525                               fprintf (dump_file, "\n");
1526                             }
1527
1528                           /* Make the necessary insertions.  */
1529                           for (pred = block->pred;
1530                                pred;
1531                                pred = pred->pred_next)
1532                             {
1533                               tree stmts = alloc_stmt_list ();
1534                               tree builtexpr;
1535                               bprime = pred->src;
1536                               eprime = avail[bprime->index];
1537                               if (BINARY_CLASS_P (eprime)
1538                                   || UNARY_CLASS_P (eprime))
1539                                 {
1540                                   builtexpr = create_expression_by_pieces (bprime,
1541                                                                            eprime,
1542                                                                            stmts);
1543                                   bsi_insert_on_edge (pred, stmts);
1544                                   avail[bprime->index] = builtexpr;
1545                                 }                             
1546                             } 
1547                           /* Now build a phi for the new variable.  */
1548                           temp = create_tmp_var (type, "prephitmp");
1549                           add_referenced_tmp_var (temp);
1550                           temp = create_phi_node (temp, block);
1551                           vn_add (PHI_RESULT (temp), val, NULL);
1552
1553 #if 0
1554                           if (!set_contains_value (AVAIL_OUT (block), val))
1555                             insert_into_set (AVAIL_OUT (block), 
1556                                              PHI_RESULT (temp));
1557                           else
1558 #endif
1559                             bitmap_value_replace_in_set (AVAIL_OUT (block), 
1560                                                          PHI_RESULT (temp));
1561                           for (pred = block->pred;
1562                                pred;
1563                                pred = pred->pred_next)
1564                             {
1565                               add_phi_arg (&temp, avail[pred->src->index],
1566                                            pred);
1567                             }
1568                           if (dump_file && (dump_flags & TDF_DETAILS))
1569                             {
1570                               fprintf (dump_file, "Created phi ");
1571                               print_generic_expr (dump_file, temp, 0);
1572                               fprintf (dump_file, " in block %d\n", block->index);
1573                             }
1574                           pre_stats.phis++;
1575                           new_stuff = true;
1576                           bitmap_insert_into_set (NEW_SETS (block),
1577                                                   PHI_RESULT (temp));
1578                           bitmap_insert_into_set (PHI_GEN (block),
1579                                                   PHI_RESULT (temp));
1580                         }
1581
1582                       free (avail);
1583                     }
1584                 }
1585             }
1586         }
1587     }
1588   for (son = first_dom_son (CDI_DOMINATORS, block);
1589        son;
1590        son = next_dom_son (CDI_DOMINATORS, son))
1591     {
1592       new_stuff |= insert_aux (son);
1593     }
1594
1595   return new_stuff;
1596 }
1597
1598 /* Perform insertion of partially redundant values.  */
1599
1600 static void
1601 insert (void)
1602 {
1603   bool new_stuff = true;
1604   basic_block bb;
1605   int num_iterations = 0;
1606   
1607   FOR_ALL_BB (bb)
1608     NEW_SETS (bb) = bitmap_set_new ();
1609   
1610   while (new_stuff)
1611     {
1612       num_iterations++;
1613       new_stuff = false;
1614       new_stuff = insert_aux (ENTRY_BLOCK_PTR);
1615     }
1616   if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
1617     fprintf (dump_file, "insert required %d iterations\n", num_iterations);
1618 }
1619
1620
1621 /* Return true if VAR is an SSA variable with no defining statement in
1622    this procedure, *AND* isn't a live-on-entry parameter.  */
1623
1624 static bool
1625 is_undefined_value (tree expr)
1626 {
1627   return (TREE_CODE (expr) == SSA_NAME
1628           && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
1629           /* PARM_DECLs and hard registers are always defined.  */
1630           && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL
1631           && !DECL_HARD_REGISTER (SSA_NAME_VAR (expr)));
1632 }
1633
1634
1635 /* Given an SSA variable VAR and an expression EXPR, compute the value
1636    number for EXPR and create a value handle (VAL) for it.  If VAR and
1637    EXPR are not the same, associate VAL with VAR.  Finally, add VAR to
1638    S1 and its value handle to S2.
1639
1640    VUSES represent the virtual use operands associated with EXPR (if
1641    any). They are used when computing the hash value for EXPR.  */
1642
1643 static inline void
1644 add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1,
1645              bitmap_set_t s2)
1646 {
1647   tree val = vn_lookup_or_add (expr, vuses);
1648
1649   /* VAR and EXPR may be the same when processing statements for which
1650      we are not computing value numbers (e.g., non-assignments, or
1651      statements that make aliased stores).  In those cases, we are
1652      only interested in making VAR available as its own value.  */
1653   if (var != expr)
1654     vn_add (var, val, NULL);
1655
1656   bitmap_insert_into_set (s1, var);
1657   bitmap_value_insert_into_set (s2, var);
1658 }
1659
1660
1661 /* Given a unary or binary expression EXPR, create and return a new
1662    expression with the same structure as EXPR but with its operands
1663    replaced with the value handles of each of the operands of EXPR.
1664    Insert EXPR's operands into the EXP_GEN set for BLOCK.
1665
1666    VUSES represent the virtual use operands associated with EXPR (if
1667    any). They are used when computing the hash value for EXPR.  */
1668
1669 static inline tree
1670 create_value_expr_from (tree expr, basic_block block, vuse_optype vuses)
1671 {
1672   int i;
1673   enum tree_code code = TREE_CODE (expr);
1674   tree vexpr;
1675
1676   gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
1677               || TREE_CODE_CLASS (code) == tcc_binary
1678               || TREE_CODE_CLASS (code) == tcc_reference);
1679
1680   if (TREE_CODE_CLASS (code) == tcc_unary)
1681     vexpr = pool_alloc (unary_node_pool);
1682   else if (TREE_CODE_CLASS (code) == tcc_reference)
1683     vexpr = pool_alloc (reference_node_pool);
1684   else
1685     vexpr = pool_alloc (binary_node_pool);
1686
1687   memcpy (vexpr, expr, tree_size (expr));
1688
1689   for (i = 0; i < TREE_CODE_LENGTH (code); i++)
1690     {
1691       tree op = TREE_OPERAND (expr, i);
1692       if (op != NULL)
1693         {
1694           tree val = vn_lookup_or_add (op, vuses);
1695           if (!is_undefined_value (op))
1696             value_insert_into_set (EXP_GEN (block), op);
1697           if (TREE_CODE (val) == VALUE_HANDLE)
1698             TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
1699           TREE_OPERAND (vexpr, i) = val;
1700         }
1701     }
1702
1703   return vexpr;
1704 }
1705
1706
1707 /* Compute the AVAIL set for BLOCK.
1708    This function performs value numbering of the statements in BLOCK. 
1709    The AVAIL sets are built from information we glean while doing this
1710    value numbering, since the AVAIL sets contain only one entry per
1711    value.
1712    
1713    AVAIL_IN[BLOCK] = AVAIL_OUT[dom(BLOCK)].
1714    AVAIL_OUT[BLOCK] = AVAIL_IN[BLOCK] U PHI_GEN[BLOCK] U TMP_GEN[BLOCK].  */
1715
1716 static void
1717 compute_avail (basic_block block)
1718 {
1719   basic_block son;
1720   
1721   /* For arguments with default definitions, we pretend they are
1722      defined in the entry block.  */
1723   if (block == ENTRY_BLOCK_PTR)
1724     {
1725       tree param;
1726       for (param = DECL_ARGUMENTS (current_function_decl);
1727            param;
1728            param = TREE_CHAIN (param))
1729         {
1730           if (default_def (param) != NULL)
1731             {
1732               tree val;
1733               tree def = default_def (param);
1734               val = vn_lookup_or_add (def, NULL);
1735               bitmap_insert_into_set (TMP_GEN (block), def);
1736               bitmap_value_insert_into_set (AVAIL_OUT (block), def);
1737             }
1738         }
1739     }
1740   else if (block)
1741     {
1742       block_stmt_iterator bsi;
1743       tree stmt, phi;
1744       basic_block dom;
1745
1746       /* Initially, the set of available values in BLOCK is that of
1747          its immediate dominator.  */
1748       dom = get_immediate_dominator (CDI_DOMINATORS, block);
1749       if (dom)
1750         bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
1751
1752       /* Generate values for PHI nodes.  */
1753       for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
1754         /* We have no need for virtual phis, as they don't represent
1755            actual computations.  */
1756         if (is_gimple_reg (PHI_RESULT (phi)))
1757           add_to_sets (PHI_RESULT (phi), PHI_RESULT (phi), NULL,
1758                        PHI_GEN (block), AVAIL_OUT (block));
1759
1760       /* Now compute value numbers and populate value sets with all
1761          the expressions computed in BLOCK.  */
1762       for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
1763         {
1764           stmt_ann_t ann;
1765           size_t j;
1766
1767           stmt = bsi_stmt (bsi);
1768           ann = stmt_ann (stmt);
1769           get_stmt_operands (stmt);
1770
1771           /* We are only interested in assignments of the form
1772              X_i = EXPR, where EXPR represents an "interesting"
1773              computation, it has no volatile operands and X_i
1774              doesn't flow through an abnormal edge.  */
1775           if (TREE_CODE (stmt) == MODIFY_EXPR
1776               && !ann->has_volatile_ops
1777               && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
1778               && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (stmt, 0)))
1779             {
1780               tree lhs = TREE_OPERAND (stmt, 0);
1781               tree rhs = TREE_OPERAND (stmt, 1);
1782               vuse_optype vuses = STMT_VUSE_OPS (stmt);
1783
1784               STRIP_USELESS_TYPE_CONVERSION (rhs);
1785               if (TREE_CODE (rhs) == SSA_NAME
1786                   || is_gimple_min_invariant (rhs))
1787                 {
1788                   /* Compute a value number for the RHS of the statement
1789                      and add its value to the AVAIL_OUT set for the block.
1790                      Add the LHS to TMP_GEN.  */
1791                   add_to_sets (lhs, rhs, vuses, TMP_GEN (block), 
1792                                AVAIL_OUT (block));
1793                   
1794                   if (TREE_CODE (rhs) == SSA_NAME
1795                       && !is_undefined_value (rhs))
1796                     value_insert_into_set (EXP_GEN (block), rhs);
1797                   continue;
1798                 }          
1799               else if (UNARY_CLASS_P (rhs) || BINARY_CLASS_P (rhs)
1800                        || TREE_CODE (rhs) == INDIRECT_REF)
1801                 {
1802                   /* For binary, unary, and reference expressions,
1803                      create a duplicate expression with the operands
1804                      replaced with the value handles of the original
1805                      RHS.  */
1806                   tree newt = create_value_expr_from (rhs, block, vuses);
1807                   add_to_sets (lhs, newt, vuses, TMP_GEN (block),
1808                                AVAIL_OUT (block));
1809                   value_insert_into_set (EXP_GEN (block), newt);
1810                   continue;
1811                 }
1812             }
1813
1814           /* For any other statement that we don't recognize, simply
1815              make the names generated by the statement available in
1816              AVAIL_OUT and TMP_GEN.  */
1817           for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
1818             {
1819               tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
1820               add_to_sets (def, def, NULL, TMP_GEN (block),
1821                             AVAIL_OUT (block));
1822             }
1823
1824           for (j = 0; j < NUM_USES (STMT_USE_OPS (stmt)); j++)
1825             {
1826               tree use = USE_OP (STMT_USE_OPS (stmt), j);
1827               add_to_sets (use, use, NULL, TMP_GEN (block),
1828                             AVAIL_OUT (block));
1829             }
1830         }
1831     }
1832
1833   /* Compute available sets for the dominator children of BLOCK.  */
1834   for (son = first_dom_son (CDI_DOMINATORS, block);
1835        son;
1836        son = next_dom_son (CDI_DOMINATORS, son))
1837     compute_avail (son);
1838 }
1839
1840
1841 /* Eliminate fully redundant computations.  */
1842
1843 static void
1844 eliminate (void)
1845 {
1846   basic_block b;
1847
1848   FOR_EACH_BB (b)
1849     {
1850       block_stmt_iterator i;
1851       
1852       for (i = bsi_start (b); !bsi_end_p (i); bsi_next (&i))
1853         {
1854           tree stmt = bsi_stmt (i);
1855
1856           /* Lookup the RHS of the expression, see if we have an
1857              available computation for it.  If so, replace the RHS with
1858              the available computation.  */
1859           if (TREE_CODE (stmt) == MODIFY_EXPR
1860               && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
1861               && TREE_CODE (TREE_OPERAND (stmt ,1)) != SSA_NAME
1862               && !is_gimple_min_invariant (TREE_OPERAND (stmt, 1))
1863               && !stmt_ann (stmt)->has_volatile_ops)
1864             {
1865               tree lhs = TREE_OPERAND (stmt, 0);
1866               tree *rhs_p = &TREE_OPERAND (stmt, 1);
1867               tree sprime;
1868
1869               sprime = bitmap_find_leader (AVAIL_OUT (b),
1870                                            vn_lookup (lhs, NULL));
1871               if (sprime 
1872                   && sprime != lhs
1873                   && (TREE_CODE (*rhs_p) != SSA_NAME
1874                       || may_propagate_copy (*rhs_p, sprime)))
1875                 {
1876                   gcc_assert (sprime != *rhs_p);
1877
1878                   if (dump_file && (dump_flags & TDF_DETAILS))
1879                     {
1880                       fprintf (dump_file, "Replaced ");
1881                       print_generic_expr (dump_file, *rhs_p, 0);
1882                       fprintf (dump_file, " with ");
1883                       print_generic_expr (dump_file, sprime, 0);
1884                       fprintf (dump_file, " in ");
1885                       print_generic_stmt (dump_file, stmt, 0);
1886                     }
1887                   pre_stats.eliminations++;
1888                   propagate_tree_value (rhs_p, sprime);
1889                   modify_stmt (stmt);
1890
1891                   /* If we removed EH side effects from the statement, clean
1892                      its EH information.  */
1893                   if (maybe_clean_eh_stmt (stmt))
1894                     {
1895                       bitmap_set_bit (need_eh_cleanup,
1896                                       bb_for_stmt (stmt)->index);
1897                       if (dump_file && (dump_flags & TDF_DETAILS))
1898                         fprintf (dump_file, "  Removed EH side effects.\n");
1899                     }
1900                 }
1901             }
1902         }
1903     }
1904 }
1905
1906
1907 /* Initialize data structures used by PRE.  */
1908
1909 static void
1910 init_pre (void)
1911 {
1912   basic_block bb;
1913
1914   connect_infinite_loops_to_exit ();
1915   vn_init ();
1916   memset (&pre_stats, 0, sizeof (pre_stats));
1917
1918   /* If block 0 has more than one predecessor, it means that its PHI
1919      nodes will have arguments coming from block -1.  This creates
1920      problems for several places in PRE that keep local arrays indexed
1921      by block number.  To prevent this, we split the edge coming from
1922      ENTRY_BLOCK_PTR (FIXME, if ENTRY_BLOCK_PTR had an index number
1923      different than -1 we wouldn't have to hack this.  tree-ssa-dce.c
1924      needs a similar change).  */
1925   if (ENTRY_BLOCK_PTR->succ->dest->pred->pred_next)
1926     if (!(ENTRY_BLOCK_PTR->succ->flags & EDGE_ABNORMAL))
1927       split_edge (ENTRY_BLOCK_PTR->succ);
1928
1929   FOR_ALL_BB (bb)
1930     bb->aux = xcalloc (1, sizeof (struct bb_value_sets));
1931
1932   gcc_obstack_init (&grand_bitmap_obstack);
1933   phi_translate_table = htab_create (511, expr_pred_trans_hash,
1934                                      expr_pred_trans_eq, free);
1935   value_set_pool = create_alloc_pool ("Value sets",
1936                                       sizeof (struct value_set), 30);
1937   bitmap_set_pool = create_alloc_pool ("Bitmap sets",
1938                                        sizeof (struct bitmap_set), 30);
1939   value_set_node_pool = create_alloc_pool ("Value set nodes",
1940                                            sizeof (struct value_set_node), 30);
1941   calculate_dominance_info (CDI_POST_DOMINATORS);
1942   calculate_dominance_info (CDI_DOMINATORS);
1943   binary_node_pool = create_alloc_pool ("Binary tree nodes",
1944                                         tree_code_size (PLUS_EXPR), 30);
1945   unary_node_pool = create_alloc_pool ("Unary tree nodes",
1946                                        tree_code_size (NEGATE_EXPR), 30);
1947   reference_node_pool = create_alloc_pool ("Reference tree nodes",
1948                                            tree_code_size (COMPONENT_REF), 30);
1949   FOR_ALL_BB (bb)
1950     {
1951       EXP_GEN (bb) = set_new (true);
1952       PHI_GEN (bb) = bitmap_set_new ();
1953       TMP_GEN (bb) = bitmap_set_new ();
1954       AVAIL_OUT (bb) = bitmap_set_new ();
1955     }
1956
1957   need_eh_cleanup = BITMAP_XMALLOC ();
1958 }
1959
1960
1961 /* Deallocate data structures used by PRE.  */
1962
1963 static void
1964 fini_pre (void)
1965 {
1966   basic_block bb;
1967   unsigned int i;
1968
1969   bsi_commit_edge_inserts (NULL);
1970
1971   obstack_free (&grand_bitmap_obstack, NULL);
1972   free_alloc_pool (value_set_pool);
1973   free_alloc_pool (bitmap_set_pool);
1974   free_alloc_pool (value_set_node_pool);
1975   free_alloc_pool (binary_node_pool);
1976   free_alloc_pool (reference_node_pool);
1977   free_alloc_pool (unary_node_pool);
1978   htab_delete (phi_translate_table);
1979   remove_fake_exit_edges ();
1980
1981   FOR_ALL_BB (bb)
1982     {
1983       free (bb->aux);
1984       bb->aux = NULL;
1985     }
1986
1987   free_dominance_info (CDI_POST_DOMINATORS);
1988   vn_delete ();
1989
1990   if (bitmap_first_set_bit (need_eh_cleanup) >= 0)
1991     {
1992       tree_purge_all_dead_eh_edges (need_eh_cleanup);
1993       cleanup_tree_cfg ();
1994     }
1995
1996   BITMAP_XFREE (need_eh_cleanup);
1997
1998   /* Wipe out pointers to VALUE_HANDLEs.  In the not terribly distant
1999      future we will want them to be persistent though.  */
2000   for (i = 0; i < num_ssa_names; i++)
2001     {
2002       tree name = ssa_name (i);
2003
2004       if (!name)
2005         continue;
2006
2007       if (SSA_NAME_VALUE (name)
2008           && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
2009         SSA_NAME_VALUE (name) = NULL;
2010     }
2011 }
2012
2013
2014 /* Main entry point to the SSA-PRE pass.  DO_FRE is true if the caller
2015    only wants to do full redundancy elimination.  */
2016
2017 static void
2018 execute_pre (bool do_fre)
2019 {
2020   init_pre ();
2021
2022   /* Collect and value number expressions computed in each basic
2023      block.  */
2024   compute_avail (ENTRY_BLOCK_PTR);
2025
2026   if (dump_file && (dump_flags & TDF_DETAILS))
2027     {
2028       basic_block bb;
2029
2030       FOR_ALL_BB (bb)
2031         {
2032           print_value_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
2033           bitmap_print_value_set (dump_file, TMP_GEN (bb), "tmp_gen", 
2034                                   bb->index);
2035           bitmap_print_value_set (dump_file, AVAIL_OUT (bb), "avail_out", 
2036                                   bb->index);
2037         }
2038     }
2039
2040   /* Insert can get quite slow on an incredibly large number of basic
2041      blocks due to some quadratic behavior.  Until this behavior is
2042      fixed, don't run it when he have an incredibly large number of
2043      bb's.  If we aren't going to run insert, there is no point in
2044      computing ANTIC, either, even though it's plenty fast.  */
2045   if (!do_fre && n_basic_blocks < 4000)
2046     {
2047       compute_antic ();
2048       insert ();
2049     }
2050
2051   /* Remove all the redundant expressions.  */
2052   eliminate ();
2053   
2054   if (dump_file && (dump_flags & TDF_STATS))
2055     {
2056       fprintf (dump_file, "Insertions:%d\n", pre_stats.insertions);
2057       fprintf (dump_file, "New PHIs:%d\n", pre_stats.phis);
2058       fprintf (dump_file, "Eliminated:%d\n", pre_stats.eliminations);
2059     }
2060
2061   fini_pre ();
2062 }
2063
2064
2065 /* Gate and execute functions for PRE.  */
2066
2067 static void
2068 do_pre (void)
2069 {
2070   execute_pre (false);
2071 }
2072
2073 static bool
2074 gate_pre (void)
2075 {
2076   return flag_tree_pre != 0;
2077 }
2078
2079 struct tree_opt_pass pass_pre =
2080 {
2081   "pre",                                /* name */
2082   gate_pre,                             /* gate */
2083   do_pre,                               /* execute */
2084   NULL,                                 /* sub */
2085   NULL,                                 /* next */
2086   0,                                    /* static_pass_number */
2087   TV_TREE_PRE,                          /* tv_id */
2088   PROP_no_crit_edges | PROP_cfg
2089     | PROP_ssa | PROP_alias,            /* properties_required */
2090   0,                                    /* properties_provided */
2091   0,                                    /* properties_destroyed */
2092   0,                                    /* todo_flags_start */
2093   TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
2094   0                                     /* letter */
2095 };
2096
2097
2098 /* Gate and execute functions for FRE.  */
2099
2100 static void
2101 do_fre (void)
2102 {
2103   execute_pre (true);
2104 }
2105
2106 static bool
2107 gate_fre (void)
2108 {
2109   return flag_tree_fre != 0;
2110 }
2111
2112 struct tree_opt_pass pass_fre =
2113 {
2114   "fre",                                /* name */
2115   gate_fre,                             /* gate */
2116   do_fre,                               /* execute */
2117   NULL,                                 /* sub */
2118   NULL,                                 /* next */
2119   0,                                    /* static_pass_number */
2120   TV_TREE_FRE,                          /* tv_id */
2121   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
2122   0,                                    /* properties_provided */
2123   0,                                    /* properties_destroyed */
2124   0,                                    /* todo_flags_start */
2125   TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
2126   0                                     /* letter */
2127 };