OSDN Git Service

2008-07-28 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-ifcombine.c
1 /* Combining of if-expressions on trees.
2    Copyright (C) 2007 Free Software Foundation, Inc.
3    Contributed by Richard Guenther <rguenther@suse.de>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "basic-block.h"
27 #include "timevar.h"
28 #include "diagnostic.h"
29 #include "tree-flow.h"
30 #include "tree-pass.h"
31 #include "tree-dump.h"
32
33 /* This pass combines COND_EXPRs to simplify control flow.  It
34    currently recognizes bit tests and comparisons in chains that
35    represent logical and or logical or of two COND_EXPRs.
36
37    It does so by walking basic blocks in a approximate reverse
38    post-dominator order and trying to match CFG patterns that
39    represent logical and or logical or of two COND_EXPRs.
40    Transformations are done if the COND_EXPR conditions match
41    either
42
43      1. two single bit tests X & (1 << Yn) (for logical and)
44
45      2. two bit tests X & Yn (for logical or)
46
47      3. two comparisons X OPn Y (for logical or)
48
49    To simplify this pass, removing basic blocks and dead code
50    is left to CFG cleanup and DCE.  */
51
52
53 /* Recognize a if-then-else CFG pattern starting to match with the
54    COND_BB basic-block containing the COND_EXPR.  The recognized
55    then end else blocks are stored to *THEN_BB and *ELSE_BB.  If
56    *THEN_BB and/or *ELSE_BB are already set, they are required to
57    match the then and else basic-blocks to make the pattern match.
58    Returns true if the pattern matched, false otherwise.  */
59
60 static bool
61 recognize_if_then_else (basic_block cond_bb,
62                         basic_block *then_bb, basic_block *else_bb)
63 {
64   edge t, e;
65
66   if (EDGE_COUNT (cond_bb->succs) != 2)
67     return false;
68
69   /* Find the then/else edges.  */
70   t = EDGE_SUCC (cond_bb, 0);
71   e = EDGE_SUCC (cond_bb, 1);
72   if (!(t->flags & EDGE_TRUE_VALUE))
73     {
74       edge tmp = t;
75       t = e;
76       e = tmp;
77     }
78   if (!(t->flags & EDGE_TRUE_VALUE)
79       || !(e->flags & EDGE_FALSE_VALUE))
80     return false;
81
82   /* Check if the edge destinations point to the required block.  */
83   if (*then_bb
84       && t->dest != *then_bb)
85     return false;
86   if (*else_bb
87       && e->dest != *else_bb)
88     return false;
89
90   if (!*then_bb)
91     *then_bb = t->dest;
92   if (!*else_bb)
93     *else_bb = e->dest;
94
95   return true;
96 }
97
98 /* Verify if the basic block BB does not have side-effects.  Return
99    true in this case, else false.  */
100
101 static bool
102 bb_no_side_effects_p (basic_block bb)
103 {
104   gimple_stmt_iterator gsi;
105
106   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
107     {
108       gimple stmt = gsi_stmt (gsi);
109
110       if (gimple_has_volatile_ops (stmt)
111           || !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
112         return false;
113     }
114
115   return true;
116 }
117
118 /* Verify if all PHI node arguments in DEST for edges from BB1 or
119    BB2 to DEST are the same.  This makes the CFG merge point
120    free from side-effects.  Return true in this case, else false.  */
121
122 static bool
123 same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
124 {
125   edge e1 = find_edge (bb1, dest);
126   edge e2 = find_edge (bb2, dest);
127   gimple_stmt_iterator gsi;
128   gimple phi;
129
130   for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
131     {
132       phi = gsi_stmt (gsi);
133       if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
134                             PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
135         return false;
136     }
137
138   return true;
139 }
140
141 /* Return the best representative SSA name for CANDIDATE which is used
142    in a bit test.  */
143
144 static tree
145 get_name_for_bit_test (tree candidate)
146 {
147   /* Skip single-use names in favor of using the name from a
148      non-widening conversion definition.  */
149   if (TREE_CODE (candidate) == SSA_NAME
150       && has_single_use (candidate))
151     {
152       gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
153       if (is_gimple_assign (def_stmt)
154           && gimple_assign_cast_p (def_stmt))
155         {
156           if (TYPE_PRECISION (TREE_TYPE (candidate))
157               <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
158             return gimple_assign_rhs1 (def_stmt);
159         }
160     }
161
162   return candidate;
163 }
164
165 /* Helpers for recognize_single_bit_test defined mainly for source code
166    formating.  */
167
168 static int
169 operand_precision (tree t)
170 {
171   return TYPE_PRECISION (TREE_TYPE (t));
172 }
173
174 static bool
175 integral_operand_p (tree t)
176 {
177   return INTEGRAL_TYPE_P (TREE_TYPE (t));
178 }
179
180 /* Recognize a single bit test pattern in GIMPLE_COND and its defining
181    statements.  Store the name being tested in *NAME and the bit
182    in *BIT.  The GIMPLE_COND computes *NAME & (1 << *BIT).
183    Returns true if the pattern matched, false otherwise.  */
184
185 static bool
186 recognize_single_bit_test (gimple cond, tree *name, tree *bit)
187 {
188   gimple stmt;
189
190   /* Get at the definition of the result of the bit test.  */
191   if (gimple_cond_code (cond) != NE_EXPR
192       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
193       || !integer_zerop (gimple_cond_rhs (cond)))
194     return false;
195   stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
196   if (!is_gimple_assign (stmt))
197     return false;
198
199   /* Look at which bit is tested.  One form to recognize is
200      D.1985_5 = state_3(D) >> control1_4(D);
201      D.1986_6 = (int) D.1985_5;
202      D.1987_7 = op0 & 1;
203      if (D.1987_7 != 0)  */
204   if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
205       && integer_onep (gimple_assign_rhs2 (stmt))
206       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
207     {
208       tree orig_name = gimple_assign_rhs1 (stmt);
209
210       /* Look through copies and conversions to eventually
211          find the stmt that computes the shift.  */
212       stmt = SSA_NAME_DEF_STMT (orig_name);
213
214       while (is_gimple_assign (stmt)
215              && (gimple_assign_copy_p (stmt)
216                  || (gimple_assign_cast_p (stmt)
217                      && integral_operand_p (gimple_assign_lhs (stmt))
218                      && integral_operand_p (gimple_assign_rhs1 (stmt))
219                      && (operand_precision (gimple_assign_lhs (stmt))
220                          <= operand_precision (gimple_assign_rhs1 (stmt))))))
221         {
222           stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
223         }
224
225       /* If we found such, decompose it.  */
226       if (is_gimple_assign (stmt)
227           && gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
228         {
229           /* op0 & (1 << op1) */
230           *bit = gimple_assign_rhs2 (stmt);
231           *name = gimple_assign_rhs1 (stmt);
232         }
233       else
234         {
235           /* t & 1 */
236           *bit = integer_zero_node;
237           *name = get_name_for_bit_test (orig_name);
238         }
239
240       return true;
241     }
242
243   /* Another form is
244      D.1987_7 = op0 & (1 << CST)
245      if (D.1987_7 != 0)  */
246   if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
247       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
248       && integer_pow2p (gimple_assign_rhs2 (stmt)))
249     {
250       *name = gimple_assign_rhs1 (stmt);
251       *bit = build_int_cst (integer_type_node,
252                             tree_log2 (gimple_assign_rhs2 (stmt)));
253       return true;
254     }
255
256   /* Another form is
257      D.1986_6 = 1 << control1_4(D)
258      D.1987_7 = op0 & D.1986_6
259      if (D.1987_7 != 0)  */
260   if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
261       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
262       && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
263     {
264       gimple tmp;
265
266       /* Both arguments of the BIT_AND_EXPR can be the single-bit
267          specifying expression.  */
268       tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
269       if (is_gimple_assign (tmp)
270           && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
271           && integer_onep (gimple_assign_rhs1 (tmp)))
272         {
273           *name = gimple_assign_rhs2 (stmt);
274           *bit = gimple_assign_rhs2 (tmp);
275           return true;
276         }
277
278       tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
279       if (is_gimple_assign (tmp)
280           && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
281           && integer_onep (gimple_assign_rhs1 (tmp)))
282         {
283           *name = gimple_assign_rhs1 (stmt);
284           *bit = gimple_assign_rhs2 (tmp);
285           return true;
286         }
287     }
288
289   return false;
290 }
291
292 /* Recognize a bit test pattern in a GIMPLE_COND and its defining
293    statements.  Store the name being tested in *NAME and the bits
294    in *BITS.  The COND_EXPR computes *NAME & *BITS.
295    Returns true if the pattern matched, false otherwise.  */
296
297 static bool
298 recognize_bits_test (gimple cond, tree *name, tree *bits)
299 {
300   gimple stmt;
301
302   /* Get at the definition of the result of the bit test.  */
303   if (gimple_cond_code (cond) != NE_EXPR
304       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
305       || !integer_zerop (gimple_cond_rhs (cond)))
306     return false;
307   stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
308   if (!is_gimple_assign (stmt)
309       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
310     return false;
311
312   *name = get_name_for_bit_test (gimple_assign_rhs1 (stmt));
313   *bits = gimple_assign_rhs2 (stmt);
314
315   return true;
316 }
317
318 /* If-convert on a and pattern with a common else block.  The inner
319    if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
320    Returns true if the edges to the common else basic-block were merged.  */
321
322 static bool
323 ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
324 {
325   gimple_stmt_iterator gsi;
326   gimple inner_cond, outer_cond;
327   tree name1, name2, bit1, bit2;
328
329   inner_cond = last_stmt (inner_cond_bb);
330   if (!inner_cond
331       || gimple_code (inner_cond) != GIMPLE_COND)
332     return false;
333
334   outer_cond = last_stmt (outer_cond_bb);
335   if (!outer_cond
336       || gimple_code (outer_cond) != GIMPLE_COND)
337     return false;
338
339   /* See if we test a single bit of the same name in both tests.  In
340      that case remove the outer test, merging both else edges,
341      and change the inner one to test for
342      name & (bit1 | bit2) == (bit1 | bit2).  */
343   if (recognize_single_bit_test (inner_cond, &name1, &bit1)
344       && recognize_single_bit_test (outer_cond, &name2, &bit2)
345       && name1 == name2)
346     {
347       tree t, t2;
348
349       /* Do it.  */
350       gsi = gsi_for_stmt (inner_cond);
351       t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
352                        build_int_cst (TREE_TYPE (name1), 1), bit1);
353       t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
354                         build_int_cst (TREE_TYPE (name1), 1), bit2);
355       t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
356       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
357                                     true, GSI_SAME_STMT);
358       t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
359       t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
360                                      true, GSI_SAME_STMT);
361       t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
362       gimple_cond_set_condition_from_tree (inner_cond, t);
363       update_stmt (inner_cond);
364
365       /* Leave CFG optimization to cfg_cleanup.  */
366       gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
367       update_stmt (outer_cond);
368
369       if (dump_file)
370         {
371           fprintf (dump_file, "optimizing double bit test to ");
372           print_generic_expr (dump_file, name1, 0);
373           fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
374           print_generic_expr (dump_file, bit1, 0);
375           fprintf (dump_file, ") | (1 << ");
376           print_generic_expr (dump_file, bit2, 0);
377           fprintf (dump_file, ")\n");
378         }
379
380       return true;
381     }
382
383   return false;
384 }
385
386 /* If-convert on a or pattern with a common then block.  The inner
387    if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
388    Returns true, if the edges leading to the common then basic-block
389    were merged.  */
390
391 static bool
392 ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
393 {
394   gimple inner_cond, outer_cond;
395   tree name1, name2, bits1, bits2;
396
397   inner_cond = last_stmt (inner_cond_bb);
398   if (!inner_cond
399       || gimple_code (inner_cond) != GIMPLE_COND)
400     return false;
401
402   outer_cond = last_stmt (outer_cond_bb);
403   if (!outer_cond
404       || gimple_code (outer_cond) != GIMPLE_COND)
405     return false;
406
407   /* See if we have two bit tests of the same name in both tests.
408      In that case remove the outer test and change the inner one to
409      test for name & (bits1 | bits2) != 0.  */
410   if (recognize_bits_test (inner_cond, &name1, &bits1)
411       && recognize_bits_test (outer_cond, &name2, &bits2))
412     {
413       gimple_stmt_iterator gsi;
414       tree t;
415
416       /* Find the common name which is bit-tested.  */
417       if (name1 == name2)
418         ;
419       else if (bits1 == bits2)
420         {
421           t = name2;
422           name2 = bits2;
423           bits2 = t;
424           t = name1;
425           name1 = bits1;
426           bits1 = t;
427         }
428       else if (name1 == bits2)
429         {
430           t = name2;
431           name2 = bits2;
432           bits2 = t;
433         }
434       else if (bits1 == name2)
435         {
436           t = name1;
437           name1 = bits1;
438           bits1 = t;
439         }
440       else
441         return false;
442
443       /* Do it.  */
444       gsi = gsi_for_stmt (inner_cond);
445       t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
446       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
447                                     true, GSI_SAME_STMT);
448       t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
449       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
450                                     true, GSI_SAME_STMT);
451       t = fold_build2 (NE_EXPR, boolean_type_node, t,
452                        build_int_cst (TREE_TYPE (t), 0));
453       gimple_cond_set_condition_from_tree (inner_cond, t);
454       update_stmt (inner_cond);
455
456       /* Leave CFG optimization to cfg_cleanup.  */
457       gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
458       update_stmt (outer_cond);
459
460       if (dump_file)
461         {
462           fprintf (dump_file, "optimizing bits or bits test to ");
463           print_generic_expr (dump_file, name1, 0);
464           fprintf (dump_file, " & T != 0\nwith temporary T = ");
465           print_generic_expr (dump_file, bits1, 0);
466           fprintf (dump_file, " | ");
467           print_generic_expr (dump_file, bits2, 0);
468           fprintf (dump_file, "\n");
469         }
470
471       return true;
472     }
473
474   /* See if we have two comparisons that we can merge into one.
475      This happens for C++ operator overloading where for example
476      GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
477   else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
478            && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
479            && operand_equal_p (gimple_cond_lhs (inner_cond),
480                                gimple_cond_lhs (outer_cond), 0)
481            && operand_equal_p (gimple_cond_rhs (inner_cond),
482                                gimple_cond_rhs (outer_cond), 0))
483     {
484       enum tree_code code1 = gimple_cond_code (inner_cond);
485       enum tree_code code2 = gimple_cond_code (outer_cond);
486       enum tree_code code;
487       tree t;
488
489 #define CHK(a,b) ((code1 == a ## _EXPR && code2 == b ## _EXPR) \
490                   || (code2 == a ## _EXPR && code1 == b ## _EXPR))
491       /* Merge the two condition codes if possible.  */
492       if (code1 == code2)
493         code = code1;
494       else if (CHK (EQ, LT))
495         code = LE_EXPR;
496       else if (CHK (EQ, GT))
497         code = GE_EXPR;
498       else if (CHK (LT, LE))
499         code = LE_EXPR;
500       else if (CHK (GT, GE))
501         code = GE_EXPR;
502       else if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (inner_cond)))
503                || flag_unsafe_math_optimizations)
504         {
505           if (CHK (LT, GT))
506             code = NE_EXPR;
507           else if (CHK (LT, NE))
508             code = NE_EXPR;
509           else if (CHK (GT, NE))
510             code = NE_EXPR;
511           else
512             return false;
513         }
514       /* We could check for combinations leading to trivial true/false.  */
515       else
516         return false;
517 #undef CHK
518
519       /* Do it.  */
520       t = fold_build2 (code, boolean_type_node, gimple_cond_lhs (outer_cond),
521                        gimple_cond_rhs (outer_cond));
522       t = canonicalize_cond_expr_cond (t);
523       if (!t)
524         return false;
525       gimple_cond_set_condition_from_tree (inner_cond, t);
526       update_stmt (inner_cond);
527
528       /* Leave CFG optimization to cfg_cleanup.  */
529       gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
530       update_stmt (outer_cond);
531
532       if (dump_file)
533         {
534           fprintf (dump_file, "optimizing two comparisons to ");
535           print_generic_expr (dump_file, t, 0);
536           fprintf (dump_file, "\n");
537         }
538
539       return true;
540     }
541
542   return false;
543 }
544
545 /* Recognize a CFG pattern and dispatch to the appropriate
546    if-conversion helper.  We start with BB as the innermost
547    worker basic-block.  Returns true if a transformation was done.  */
548
549 static bool
550 tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
551 {
552   basic_block then_bb = NULL, else_bb = NULL;
553
554   if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
555     return false;
556
557   /* Recognize && and || of two conditions with a common
558      then/else block which entry edges we can merge.  That is:
559        if (a || b)
560          ;
561      and
562        if (a && b)
563          ;
564      This requires a single predecessor of the inner cond_bb.  */
565   if (single_pred_p (inner_cond_bb))
566     {
567       basic_block outer_cond_bb = single_pred (inner_cond_bb);
568
569       /* The && form is characterized by a common else_bb with
570          the two edges leading to it mergable.  The latter is
571          guaranteed by matching PHI arguments in the else_bb and
572          the inner cond_bb having no side-effects.  */
573       if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
574           && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
575           && bb_no_side_effects_p (inner_cond_bb))
576         {
577           /* We have
578                <outer_cond_bb>
579                  if (q) goto inner_cond_bb; else goto else_bb;
580                <inner_cond_bb>
581                  if (p) goto ...; else goto else_bb;
582                  ...
583                <else_bb>
584                  ...
585            */
586           return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
587         }
588
589       /* The || form is characterized by a common then_bb with the
590          two edges leading to it mergable.  The latter is guaranteed
591          by matching PHI arguments in the then_bb and the inner cond_bb
592          having no side-effects.  */
593       if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
594           && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
595           && bb_no_side_effects_p (inner_cond_bb))
596         {
597           /* We have
598                <outer_cond_bb>
599                  if (q) goto then_bb; else goto inner_cond_bb;
600                <inner_cond_bb>
601                  if (q) goto then_bb; else goto ...;
602                <then_bb>
603                  ...
604            */
605           return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
606         }
607     }
608
609   return false;
610 }
611
612 /* Main entry for the tree if-conversion pass.  */
613
614 static unsigned int
615 tree_ssa_ifcombine (void)
616 {
617   basic_block *bbs;
618   bool cfg_changed = false;
619   int i;
620
621   bbs = blocks_in_phiopt_order ();
622
623   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
624     {
625       basic_block bb = bbs[i];
626       gimple stmt = last_stmt (bb);
627
628       if (stmt
629           && gimple_code (stmt) == GIMPLE_COND)
630         cfg_changed |= tree_ssa_ifcombine_bb (bb);
631     }
632
633   free (bbs);
634
635   return cfg_changed ? TODO_cleanup_cfg : 0;
636 }
637
638 static bool
639 gate_ifcombine (void)
640 {
641   return 1;
642 }
643
644 struct gimple_opt_pass pass_tree_ifcombine = 
645 {
646  {
647   GIMPLE_PASS,
648   "ifcombine",                  /* name */
649   gate_ifcombine,               /* gate */
650   tree_ssa_ifcombine,           /* execute */
651   NULL,                         /* sub */
652   NULL,                         /* next */
653   0,                            /* static_pass_number */
654   TV_TREE_IFCOMBINE,            /* tv_id */
655   PROP_cfg | PROP_ssa,          /* properties_required */
656   0,                            /* properties_provided */
657   0,                            /* properties_destroyed */
658   0,                            /* todo_flags_start */
659   TODO_dump_func
660   | TODO_ggc_collect
661   | TODO_update_ssa
662   | TODO_verify_ssa             /* todo_flags_finish */
663  }
664 };