OSDN Git Service

PR java/8473:
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-phiopt.c
1 /* Optimization of PHI nodes by converting them into straightline code.
2    Copyright (C) 2004 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5    
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10    
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15    
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "errors.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "flags.h"
30 #include "tm_p.h"
31 #include "basic-block.h"
32 #include "timevar.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "tree-pass.h"
36 #include "tree-dump.h"
37 #include "langhooks.h"
38
39 static void tree_ssa_phiopt (void);
40 static bool conditional_replacement (basic_block, tree, tree, tree);
41 static bool value_replacement (basic_block, tree, tree, tree);
42 static bool abs_replacement (basic_block, tree, tree, tree);
43 static void replace_phi_with_stmt (block_stmt_iterator, basic_block,
44                                    basic_block, tree, tree);
45 static bool candidate_bb_for_phi_optimization (basic_block,
46                                                basic_block *,
47                                                basic_block *);
48 static bool empty_block_p (basic_block);
49
50 /* This pass eliminates PHI nodes which can be trivially implemented as
51    an assignment from a conditional expression.  ie if we have something
52    like:
53
54      bb0:
55       if (cond) goto bb2; else goto bb1;
56      bb1:
57      bb2:
58       x = PHI (0 (bb1), 1 (bb0)
59
60    We can rewrite that as:
61     
62      bb0:
63      bb1:
64      bb2:
65       x = cond;
66
67    bb1 will become unreachable and bb0 and bb2 will almost always
68    be merged into a single block.  This occurs often due to gimplification
69     of conditionals. 
70    
71    Also done is the following optimization:
72
73      bb0:
74       if (a != b) goto bb2; else goto bb1;
75      bb1:
76      bb2:
77       x = PHI (a (bb1), b (bb0))
78
79    We can rewrite that as:
80
81      bb0:
82      bb1:
83      bb2:
84       x = b;
85
86    This can sometimes occur as a result of other optimizations.  A
87    similar transformation is done by the ifcvt RTL optimizer. 
88
89    This pass also eliminates PHI nodes which are really absolute 
90    values.  i.e. if we have something like:
91
92      bb0:
93       if (a >= 0) goto bb2; else goto bb1;
94      bb1:
95       x = -a;
96      bb2:
97       x = PHI (x (bb1), a (bb0));
98
99    We can rewrite that as:
100
101      bb0:
102      bb1:
103      bb2:
104       x = ABS_EXPR< a >;
105
106    bb1 will become unreachable and bb0 and bb2 will almost always be merged
107    into a single block.  Similar transformations are done by the ifcvt
108    RTL optimizer.  */ 
109
110 static void
111 tree_ssa_phiopt (void)
112 {
113   basic_block bb;
114   bool removed_phis = false;
115
116   /* Search every basic block for PHI nodes we may be able to optimize.  */
117   FOR_EACH_BB (bb)
118     {
119       tree arg0, arg1, phi;
120
121       /* We're searching for blocks with one PHI node which has two
122          arguments.  */
123       phi = phi_nodes (bb);
124       if (phi && PHI_CHAIN (phi) == NULL
125           && PHI_NUM_ARGS (phi) == 2)
126         {
127           arg0 = PHI_ARG_DEF (phi, 0);
128           arg1 = PHI_ARG_DEF (phi, 1);
129             
130           /* Do the replacement of conditional if it can be done.  */
131             if (conditional_replacement (bb, phi, arg0, arg1)
132                 || value_replacement (bb, phi, arg0, arg1)
133                 || abs_replacement (bb, phi, arg0, arg1))
134               {
135                 /* We have done the replacement so we need to rebuild the
136                    cfg when this pass is complete.  */
137                 removed_phis = true;
138               }
139         }
140     }
141
142   /* If we removed any PHIs, then we have unreachable blocks and blocks
143      which need to be merged in the CFG.  */
144   if (removed_phis)
145     cleanup_tree_cfg ();
146 }
147
148 /* Return TRUE if block BB has no executable statements, otherwise return
149    FALSE.  */
150 static bool
151 empty_block_p (basic_block bb)
152 {
153   block_stmt_iterator bsi;
154
155   /* BB must have no executable statements.  */
156   bsi = bsi_start (bb);
157   while (!bsi_end_p (bsi)
158           && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
159               || IS_EMPTY_STMT (bsi_stmt (bsi))))
160     bsi_next (&bsi);
161   
162   if (!bsi_end_p (bsi))
163     return false;
164
165   return true;
166 }
167
168 /* BB is a basic block which has only one PHI node with precisely two
169    arguments.
170
171    Examine both of BB's predecessors to see if one ends with a 
172    COND_EXPR and the other is a successor of the COND_EXPR.  If so, then
173    we may be able to optimize PHI nodes at the start of BB. 
174
175    If so, mark store the block with the COND_EXPR into COND_BLOCK_P
176    and the other block into OTHER_BLOCK_P and return true, otherwise
177    return false.  */
178
179 static bool
180 candidate_bb_for_phi_optimization (basic_block bb,
181                                    basic_block *cond_block_p,
182                                    basic_block *other_block_p)
183 {
184   tree last0, last1;
185   basic_block cond_block, other_block;
186
187   /* One of the alternatives must come from a block ending with
188      a COND_EXPR.  */
189   last0 = last_stmt (bb->pred->src);
190   last1 = last_stmt (bb->pred->pred_next->src);
191   if (last0 && TREE_CODE (last0) == COND_EXPR)
192     {
193       cond_block = bb->pred->src;
194       other_block = bb->pred->pred_next->src;
195     }
196   else if (last1 && TREE_CODE (last1) == COND_EXPR)
197     {
198       other_block = bb->pred->src;
199       cond_block = bb->pred->pred_next->src;
200     }
201   else
202     return false;
203   
204   /* COND_BLOCK must have precisely two successors.  We indirectly
205      verify that those successors are BB and OTHER_BLOCK.  */
206   if (!cond_block->succ
207       || !cond_block->succ->succ_next
208       || cond_block->succ->succ_next->succ_next
209       || (cond_block->succ->flags & EDGE_ABNORMAL) != 0
210       || (cond_block->succ->succ_next->flags & EDGE_ABNORMAL) != 0)
211     return false;
212   
213   /* OTHER_BLOCK must have a single predecessor which is COND_BLOCK,
214      OTHER_BLOCK must have a single successor which is BB and
215      OTHER_BLOCK must have no PHI nodes.  */
216   if (!other_block->pred
217       || other_block->pred->src != cond_block
218       || other_block->pred->pred_next
219       || !other_block->succ
220       || other_block->succ->dest != bb
221       || other_block->succ->succ_next
222       || phi_nodes (other_block))
223     return false;
224   
225   *cond_block_p = cond_block;
226   *other_block_p = other_block;
227   /* Everything looks OK.  */
228   return true;
229 }
230
231 /* Replace PHI in block BB with statement NEW.  NEW is inserted after
232    BSI.  Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
233    is known to have two edges, one of which must reach BB).  */
234
235 static void
236 replace_phi_with_stmt (block_stmt_iterator bsi, basic_block bb,
237                        basic_block cond_block, tree phi, tree new)
238 {
239   basic_block block_to_remove;
240
241   /* Insert our new statement at the head of our block.  */
242   bsi_insert_after (&bsi, new, BSI_NEW_STMT);
243   
244   /* Register our new statement as the defining statement for
245      the result.  */
246   SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new;
247   
248   /* Remove the now useless PHI node. 
249   
250      We do not want to use remove_phi_node since that releases the
251      SSA_NAME as well and the SSA_NAME is still being used.  */
252   release_phi_node (phi);
253   bb_ann (bb)->phi_nodes = NULL;
254   
255   /* Remove the empty basic block.  */
256   if (cond_block->succ->dest == bb)
257     {
258       cond_block->succ->flags |= EDGE_FALLTHRU;
259       cond_block->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
260
261       block_to_remove = cond_block->succ->succ_next->dest;
262     }
263   else
264     {
265       cond_block->succ->succ_next->flags |= EDGE_FALLTHRU;
266       cond_block->succ->succ_next->flags
267         &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
268
269       block_to_remove = cond_block->succ->dest;
270     }
271   delete_basic_block (block_to_remove);
272   
273   /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
274   bsi = bsi_last (cond_block);
275   bsi_remove (&bsi);
276   
277   if (dump_file && (dump_flags & TDF_DETAILS))
278     fprintf (dump_file,
279               "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
280               cond_block->index,
281               bb->index);
282 }
283
284 /*  The function conditional_replacement does the main work of doing the
285     conditional replacement.  Return true if the replacement is done.
286     Otherwise return false.
287     BB is the basic block where the replacement is going to be done on.  ARG0
288     is argument 0 from PHI.  Likewise for ARG1.   */
289
290 static bool
291 conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
292 {
293   tree result;
294   tree old_result = NULL;
295   basic_block other_block = NULL;
296   basic_block cond_block = NULL;
297   tree new, cond;
298   block_stmt_iterator bsi;
299   edge true_edge, false_edge;
300   tree new_var = NULL;
301
302   /* The PHI arguments have the constants 0 and 1, then convert
303      it to the conditional.  */
304   if ((integer_zerop (arg0) && integer_onep (arg1))
305       || (integer_zerop (arg1) && integer_onep (arg0)))
306     ;
307   else
308     return false;
309   
310   if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block)
311       || !empty_block_p (other_block))
312     return false;
313                                                                                 
314   /* If the condition is not a naked SSA_NAME and its type does not
315      match the type of the result, then we have to create a new
316      variable to optimize this case as it would likely create
317      non-gimple code when the condition was converted to the
318      result's type.  */
319   cond = COND_EXPR_COND (last_stmt (cond_block));
320   result = PHI_RESULT (phi);
321   if (TREE_CODE (cond) != SSA_NAME
322       && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
323     {
324       new_var = make_rename_temp (TREE_TYPE (cond), NULL);
325       old_result = cond;
326       cond = new_var;
327     }
328   
329   /* If the condition was a naked SSA_NAME and the type is not the
330      same as the type of the result, then convert the type of the
331      condition.  */
332   if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
333     cond = fold_convert (TREE_TYPE (result), cond);
334   
335   /* We need to know which is the true edge and which is the false
336      edge so that we know when to invert the condition below.  */
337   extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
338       
339   /* Insert our new statement at the head of our block.  */
340   bsi = bsi_start (bb);
341   
342   if (old_result)
343     {
344       tree new1;
345       if (TREE_CODE_CLASS (TREE_CODE (old_result)) != '<')
346         return false;
347       
348       new1 = build (TREE_CODE (old_result), TREE_TYPE (result),
349                     TREE_OPERAND (old_result, 0),
350                     TREE_OPERAND (old_result, 1));
351       
352       new1 = build (MODIFY_EXPR, TREE_TYPE (result), new_var, new1);
353       bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
354     }
355   
356   /* At this point we know we have a COND_EXPR with two successors.
357      One successor is BB, the other successor is an empty block which
358      falls through into BB.
359   
360      There is a single PHI node at the join point (BB) and its arguments
361      are constants (0, 1).
362   
363      So, given the condition COND, and the two PHI arguments, we can
364      rewrite this PHI into non-branching code: 
365   
366        dest = (COND) or dest = COND'
367   
368      We use the condition as-is if the argument associated with the
369      true edge has the value one or the argument associated with the
370      false edge as the value zero.  Note that those conditions are not
371      the same since only one of the outgoing edges from the COND_EXPR
372      will directly reach BB and thus be associated with an argument.  */
373   if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0))
374       || (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0))
375       || (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1))
376       || (PHI_ARG_EDGE (phi, 1) == false_edge && integer_zerop (arg1)))
377     {
378       new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
379                     PHI_RESULT (phi), cond);
380     }
381   else
382     {
383       tree cond1 = invert_truthvalue (cond);
384       
385       cond = cond1;
386       /* If what we get back is a conditional expression, there is no
387           way that it can be gimple.  */
388       if (TREE_CODE (cond) == COND_EXPR)
389         return false; 
390
391       /* If what we get back is not gimple try to create it as gimple by
392          using a temporary variable.   */
393       if (is_gimple_cast (cond)
394           && !is_gimple_val (TREE_OPERAND (cond, 0)))
395         {
396           tree temp = TREE_OPERAND (cond, 0);
397           tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
398           new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
399           bsi_insert_after (&bsi, new, BSI_NEW_STMT);
400           cond = fold_convert (TREE_TYPE (result), new_var_1);
401         }
402       
403       if (TREE_CODE (cond) == TRUTH_NOT_EXPR
404           &&  !is_gimple_val (TREE_OPERAND (cond, 0)))
405         return false;
406
407       new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
408                     PHI_RESULT (phi), cond);
409     }
410   
411   replace_phi_with_stmt (bsi, bb, cond_block, phi, new);
412
413   /* Note that we optimized this PHI.  */
414   return true;
415 }
416
417 /*  The function value_replacement does the main work of doing the value
418     replacement.  Return true if the replacement is done.  Otherwise return
419     false.
420     BB is the basic block where the replacement is going to be done on.  ARG0
421     is argument 0 from the PHI.  Likewise for ARG1.   */
422
423 static bool
424 value_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
425 {
426   tree result;
427   basic_block other_block = NULL;
428   basic_block cond_block = NULL;
429   tree new, cond;
430   edge true_edge, false_edge;
431
432   /* If the type says honor signed zeros we cannot do this
433      optimization.   */
434   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
435     return false;
436
437   if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block)
438       || !empty_block_p (other_block))
439     return false;
440
441   cond = COND_EXPR_COND (last_stmt (cond_block));
442   result = PHI_RESULT (phi);
443
444   /* This transformation is only valid for equality comparisons.  */
445   if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
446     return false;
447
448   /* We need to know which is the true edge and which is the false
449       edge so that we know if have abs or negative abs.  */
450   extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
451
452   /* At this point we know we have a COND_EXPR with two successors.
453      One successor is BB, the other successor is an empty block which
454      falls through into BB.
455
456      The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
457
458      There is a single PHI node at the join point (BB) with two arguments.
459
460      We now need to verify that the two arguments in the PHI node match
461      the two arguments to the equality comparison.  */
462   
463   if ((operand_equal_p (arg0, TREE_OPERAND (cond, 0), 0)
464        && operand_equal_p (arg1, TREE_OPERAND (cond, 1), 0))
465       || (operand_equal_p (arg1, TREE_OPERAND (cond, 0), 0)
466           && operand_equal_p (arg0, TREE_OPERAND (cond, 1), 0)))
467     {
468       edge e;
469       tree arg;
470
471       /* For NE_EXPR, we want to build an assignment result = arg where
472          arg is the PHI argument associated with the true edge.  For
473          EQ_EXPR we want the PHI argument associated with the false edge.  */
474       e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
475
476       /* Unfortunately, E may not reach BB (it may instead have gone to
477          OTHER_BLOCK).  If that is the case, then we want the single outgoing
478          edge from OTHER_BLOCK which reaches BB and represents the desired
479          path from COND_BLOCK.  */
480       if (e->dest == other_block)
481         e = e->dest->succ;
482
483       /* Now we know the incoming edge to BB that has the argument for the
484          RHS of our new assignment statement.  */
485       if (PHI_ARG_EDGE (phi, 0) == e)
486         arg = arg0;
487       else
488         arg = arg1;
489
490       /* Build the new assignment.  */
491       new = build (MODIFY_EXPR, TREE_TYPE (result), result, arg);
492
493       replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new);
494
495       /* Note that we optimized this PHI.  */
496       return true;
497     }
498   return false;
499 }
500
501 /*  The function absolute_replacement does the main work of doing the absolute
502     replacement.  Return true if the replacement is done.  Otherwise return
503     false.
504     bb is the basic block where the replacement is going to be done on.  arg0
505     is argument 0 from the phi.  Likewise for arg1.   */
506 static bool
507 abs_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
508 {
509   tree result;
510   basic_block other_block = NULL;
511   basic_block cond_block = NULL;
512   tree new, cond;
513   block_stmt_iterator bsi;
514   edge true_edge, false_edge;
515   tree assign = NULL;
516   edge e;
517   tree rhs = NULL, lhs = NULL;
518   bool negate;
519   enum tree_code cond_code;
520
521   /* If the type says honor signed zeros we cannot do this
522      optimization.   */
523   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
524     return false;
525
526   if (!candidate_bb_for_phi_optimization (bb, &cond_block, &other_block))
527     return false;
528
529   /* OTHER_BLOCK must have only one executable statement which must have the
530      form arg0 = -arg1 or arg1 = -arg0.  */
531   bsi = bsi_start (other_block);
532   while (!bsi_end_p (bsi))
533     {
534       tree stmt = bsi_stmt (bsi);
535
536       /* Empty statements and labels are uninteresting.  */
537       if (TREE_CODE (stmt) == LABEL_EXPR
538           || IS_EMPTY_STMT (stmt))
539         {
540           bsi_next (&bsi);
541           continue;
542         }
543
544       /* If we found the assignment, but it was not the only executable
545          statement in OTHER_BLOCK, then we can not optimize.  */
546       if (assign)
547         return false;
548
549       /* If we got here, then we have found the first executable statement
550          in OTHER_BLOCK.  If it is anything other than arg = -arg1 or
551          arg1 = -arg0, then we can not optimize.  */
552       if (TREE_CODE (stmt) == MODIFY_EXPR)
553         {
554           lhs = TREE_OPERAND (stmt, 0);
555           rhs = TREE_OPERAND (stmt, 1);
556
557           if (TREE_CODE (rhs) == NEGATE_EXPR)
558             {
559               rhs = TREE_OPERAND (rhs, 0);
560
561               /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
562               if ((lhs == arg0 && rhs == arg1)
563                   || (lhs == arg1 && rhs == arg0))
564                 {
565                   assign = stmt;
566                   bsi_next (&bsi);
567                 }
568               else
569                 return false;
570             }
571           else
572             return false;
573         }
574       else
575         return false;
576     }
577
578   /* If we did not find the proper negation assignment, then we can not
579      optimize.  */
580   if (assign == NULL)
581     return false;
582
583   cond = COND_EXPR_COND (last_stmt (cond_block));
584   result = PHI_RESULT (phi);
585
586   /* Only relationals comparing arg[01] against zero are interesting.  */
587   cond_code = TREE_CODE (cond);
588   if (cond_code != GT_EXPR && cond_code != GE_EXPR
589       && cond_code != LT_EXPR && cond_code != LE_EXPR)
590     return false;
591
592   /* Make sure the conditional is arg[01] OP y.   */
593   if (TREE_OPERAND (cond, 0) != rhs)
594     return false;
595
596   if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
597                ? real_zerop (TREE_OPERAND (cond, 1))
598                : integer_zerop (TREE_OPERAND (cond, 1)))
599     ;
600   else
601     return false;
602
603   /* We need to know which is the true edge and which is the false
604      edge so that we know if have abs or negative abs.  */
605   extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
606
607   /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
608      will need to negate the result.  Similarly for LT_EXPR/LE_EXPR if
609      the false edge goes to OTHER_BLOCK.  */
610   if (cond_code == GT_EXPR || cond_code == GE_EXPR)
611     e = true_edge;
612   else
613     e = false_edge;
614   
615   if (e->dest == other_block)
616     negate = true;
617   else
618     negate = false;
619   
620   if (negate)
621     lhs = make_rename_temp (TREE_TYPE (result), NULL);
622   else
623     lhs = result;
624
625   /*  Build the modify expression with abs expression.   */
626   new = build (MODIFY_EXPR, TREE_TYPE (lhs),
627                lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
628
629   replace_phi_with_stmt (bsi_start (bb), bb, cond_block, phi, new);
630
631   if (negate)
632     {
633
634       /* Get the right BSI.  We want to insert after the recently 
635          added ABS_EXPR statement (which we know is the first statement
636          in the block.  */
637       bsi = bsi_start (bb);
638       bsi_next (&bsi);
639       new = build (MODIFY_EXPR, TREE_TYPE (result),
640                    result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
641
642       bsi_insert_after (&bsi, new, BSI_NEW_STMT);
643
644       /* Register the new statement as defining the temporary -- this is
645          normally done by replace_phi_with_stmt, but the link will be wrong
646          if we had to negate the resulting value.  */
647       SSA_NAME_DEF_STMT (result) = new;
648     }
649
650   /* Note that we optimized this PHI.  */
651   return true;
652 }
653
654
655 /* Always do these optimizations if we have SSA
656    trees to work on.  */                                                
657 static bool
658 gate_phiopt (void)
659 {
660   return 1;
661 }
662                                                                                                 
663 struct tree_opt_pass pass_phiopt =
664 {
665   "phiopt",                             /* name */
666   gate_phiopt,                          /* gate */
667   tree_ssa_phiopt,                      /* execute */
668   NULL,                                 /* sub */
669   NULL,                                 /* next */
670   0,                                    /* static_pass_number */
671   TV_TREE_PHIOPT,                       /* tv_id */
672   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
673   0,                                    /* properties_provided */
674   0,                                    /* properties_destroyed */
675   0,                                    /* todo_flags_start */
676   TODO_dump_func | TODO_ggc_collect     /* todo_flags_finish */
677     | TODO_verify_ssa | TODO_rename_vars
678     | TODO_verify_flow
679 };
680                                                                                                 
681