OSDN Git Service

gcc/cp/
[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   block_stmt_iterator bsi;
105
106   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
107     {
108       tree stmt = bsi_stmt (bsi);
109       stmt_ann_t ann = stmt_ann (stmt);
110
111       if (ann->has_volatile_ops
112           || !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
113         return false;
114     }
115
116   return true;
117 }
118
119 /* Verify if all PHI node arguments in DEST for edges from BB1 or
120    BB2 to DEST are the same.  This makes the CFG merge point
121    free from side-effects.  Return true in this case, else false.  */
122
123 static bool
124 same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
125 {
126   edge e1 = find_edge (bb1, dest);
127   edge e2 = find_edge (bb2, dest);
128   tree phi;
129
130   for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
131     if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
132                           PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
133       return false;
134
135   return true;
136 }
137
138 /* Return the best representative SSA name for CANDIDATE which is used
139    in a bit test.  */
140
141 static tree
142 get_name_for_bit_test (tree candidate)
143 {
144   /* Skip single-use names in favor of using the name from a
145      non-widening conversion definition.  */
146   if (TREE_CODE (candidate) == SSA_NAME
147       && has_single_use (candidate))
148     {
149       tree def_stmt = SSA_NAME_DEF_STMT (candidate);
150       if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
151           && CONVERT_EXPR_P (GIMPLE_STMT_OPERAND (def_stmt, 1)))
152         {
153           tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
154           if (TYPE_PRECISION (TREE_TYPE (rhs))
155               <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
156             return TREE_OPERAND (rhs, 0);
157         }
158     }
159
160   return candidate;
161 }
162
163 /* Recognize a single bit test pattern in COND_EXPR and its defining
164    statements.  Store the name being tested in *NAME and the bit
165    in *BIT.  The COND_EXPR computes *NAME & (1 << *BIT).
166    Returns true if the pattern matched, false otherwise.  */
167
168 static bool
169 recognize_single_bit_test (tree cond_expr, tree *name, tree *bit)
170 {
171   tree t;
172
173   /* Get at the definition of the result of the bit test.  */
174   t = TREE_OPERAND (cond_expr, 0);
175   if (TREE_CODE (t) == NE_EXPR
176       && integer_zerop (TREE_OPERAND (t, 1)))
177     t = TREE_OPERAND (t, 0);
178   if (TREE_CODE (t) != SSA_NAME)
179     return false;
180   t = SSA_NAME_DEF_STMT (t);
181   if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
182     return false;
183   t = GIMPLE_STMT_OPERAND (t, 1);
184
185   /* Look at which bit is tested.  One form to recognize is
186      D.1985_5 = state_3(D) >> control1_4(D);
187      D.1986_6 = (int) D.1985_5;
188      D.1987_7 = op0 & 1;
189      if (D.1987_7 != 0)  */
190   if (TREE_CODE (t) == BIT_AND_EXPR
191       && integer_onep (TREE_OPERAND (t, 1))
192       && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
193     {
194       tree orig_name = TREE_OPERAND (t, 0);
195
196       /* Look through copies and conversions to eventually
197          find the stmt that computes the shift.  */
198       t = orig_name;
199       do {
200         t = SSA_NAME_DEF_STMT (t);
201         if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
202           break;
203         t = GIMPLE_STMT_OPERAND (t, 1);
204         if (CONVERT_EXPR_P (t))
205           t = TREE_OPERAND (t, 0);
206       } while (TREE_CODE (t) == SSA_NAME);
207
208       /* If we found such, decompose it.  */
209       if (TREE_CODE (t) == RSHIFT_EXPR)
210         {
211           /* op0 & (1 << op1) */
212           *bit = TREE_OPERAND (t, 1);
213           *name = TREE_OPERAND (t, 0);
214         }
215       else
216         {
217           /* t & 1 */
218           *bit = integer_zero_node;
219           *name = get_name_for_bit_test (orig_name);
220         }
221
222       return true;
223     }
224
225   /* Another form is
226      D.1987_7 = op0 & (1 << CST)
227      if (D.1987_7 != 0)  */
228   if (TREE_CODE (t) == BIT_AND_EXPR
229       && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
230       && integer_pow2p (TREE_OPERAND (t, 1)))
231     {
232       *name = TREE_OPERAND (t, 0);
233       *bit = build_int_cst (integer_type_node,
234                             tree_log2 (TREE_OPERAND (t, 1)));
235       return true;
236     }
237
238   /* Another form is
239      D.1986_6 = 1 << control1_4(D)
240      D.1987_7 = op0 & D.1986_6
241      if (D.1987_7 != 0)  */
242   if (TREE_CODE (t) == BIT_AND_EXPR
243       && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
244       && TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME)
245     {
246       tree tmp;
247
248       /* Both arguments of the BIT_AND_EXPR can be the single-bit
249          specifying expression.  */
250       tmp = SSA_NAME_DEF_STMT (TREE_OPERAND (t, 0));
251       if (TREE_CODE (tmp) == GIMPLE_MODIFY_STMT
252           && TREE_CODE (GIMPLE_STMT_OPERAND (tmp, 1)) == LSHIFT_EXPR
253           && integer_onep (TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 0)))
254         {
255           *name = TREE_OPERAND (t, 1);
256           *bit = TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 1);
257           return true;
258         }
259
260       tmp = SSA_NAME_DEF_STMT (TREE_OPERAND (t, 1));
261       if (TREE_CODE (tmp) == GIMPLE_MODIFY_STMT
262           && TREE_CODE (GIMPLE_STMT_OPERAND (tmp, 1)) == LSHIFT_EXPR
263           && integer_onep (TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 0)))
264         {
265           *name = TREE_OPERAND (t, 0);
266           *bit = TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 1);
267           return true;
268         }
269     }
270
271   return false;
272 }
273
274 /* Recognize a bit test pattern in COND_EXPR and its defining
275    statements.  Store the name being tested in *NAME and the bits
276    in *BITS.  The COND_EXPR computes *NAME & *BITS.
277    Returns true if the pattern matched, false otherwise.  */
278
279 static bool
280 recognize_bits_test (tree cond_expr, tree *name, tree *bits)
281 {
282   tree t;
283
284   /* Get at the definition of the result of the bit test.  */
285   t = TREE_OPERAND (cond_expr, 0);
286   if (TREE_CODE (t) == NE_EXPR
287       && integer_zerop (TREE_OPERAND (t, 1)))
288     t = TREE_OPERAND (t, 0);
289   if (TREE_CODE (t) != SSA_NAME)
290     return false;
291   t = SSA_NAME_DEF_STMT (t);
292   if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
293     return false;
294   t = GIMPLE_STMT_OPERAND (t, 1);
295
296   if (TREE_CODE (t) != BIT_AND_EXPR)
297     return false;
298
299   *name = get_name_for_bit_test (TREE_OPERAND (t, 0));
300   *bits = TREE_OPERAND (t, 1);
301
302   return true;
303 }
304
305 /* If-convert on a and pattern with a common else block.  The inner
306    if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
307    Returns true if the edges to the common else basic-block were merged.  */
308
309 static bool
310 ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
311 {
312   block_stmt_iterator bsi;
313   tree inner_cond, outer_cond;
314   tree name1, name2, bit1, bit2;
315
316   inner_cond = last_stmt (inner_cond_bb);
317   if (!inner_cond
318       || TREE_CODE (inner_cond) != COND_EXPR)
319     return false;
320
321   outer_cond = last_stmt (outer_cond_bb);
322   if (!outer_cond
323       || TREE_CODE (outer_cond) != COND_EXPR)
324     return false;
325
326   /* See if we test a single bit of the same name in both tests.  In
327      that case remove the outer test, merging both else edges,
328      and change the inner one to test for
329      name & (bit1 | bit2) == (bit1 | bit2).  */
330   if (recognize_single_bit_test (inner_cond, &name1, &bit1)
331       && recognize_single_bit_test (outer_cond, &name2, &bit2)
332       && name1 == name2)
333     {
334       tree t, t2;
335
336       /* Do it.  */
337       bsi = bsi_for_stmt (inner_cond);
338       t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
339                        build_int_cst (TREE_TYPE (name1), 1), bit1);
340       t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
341                         build_int_cst (TREE_TYPE (name1), 1), bit2);
342       t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
343       t = force_gimple_operand_bsi (&bsi, t, true, NULL_TREE,
344                                     true, BSI_SAME_STMT);
345       t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
346       t2 = force_gimple_operand_bsi (&bsi, t2, true, NULL_TREE,
347                                      true, BSI_SAME_STMT);
348       COND_EXPR_COND (inner_cond) = fold_build2 (EQ_EXPR, boolean_type_node,
349                                                  t2, t);
350       update_stmt (inner_cond);
351
352       /* Leave CFG optimization to cfg_cleanup.  */
353       COND_EXPR_COND (outer_cond) = boolean_true_node;
354       update_stmt (outer_cond);
355
356       if (dump_file)
357         {
358           fprintf (dump_file, "optimizing double bit test to ");
359           print_generic_expr (dump_file, name1, 0);
360           fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
361           print_generic_expr (dump_file, bit1, 0);
362           fprintf (dump_file, ") | (1 << ");
363           print_generic_expr (dump_file, bit2, 0);
364           fprintf (dump_file, ")\n");
365         }
366
367       return true;
368     }
369
370   return false;
371 }
372
373 /* If-convert on a or pattern with a common then block.  The inner
374    if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
375    Returns true, if the edges leading to the common then basic-block
376    were merged.  */
377
378 static bool
379 ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
380 {
381   tree inner_cond, outer_cond;
382   tree name1, name2, bits1, bits2;
383
384   inner_cond = last_stmt (inner_cond_bb);
385   if (!inner_cond
386       || TREE_CODE (inner_cond) != COND_EXPR)
387     return false;
388
389   outer_cond = last_stmt (outer_cond_bb);
390   if (!outer_cond
391       || TREE_CODE (outer_cond) != COND_EXPR)
392     return false;
393
394   /* See if we have two bit tests of the same name in both tests.
395      In that case remove the outer test and change the inner one to
396      test for name & (bits1 | bits2) != 0.  */
397   if (recognize_bits_test (inner_cond, &name1, &bits1)
398       && recognize_bits_test (outer_cond, &name2, &bits2))
399     {
400       block_stmt_iterator bsi;
401       tree t;
402
403       /* Find the common name which is bit-tested.  */
404       if (name1 == name2)
405         ;
406       else if (bits1 == bits2)
407         {
408           t = name2;
409           name2 = bits2;
410           bits2 = t;
411           t = name1;
412           name1 = bits1;
413           bits1 = t;
414         }
415       else if (name1 == bits2)
416         {
417           t = name2;
418           name2 = bits2;
419           bits2 = t;
420         }
421       else if (bits1 == name2)
422         {
423           t = name1;
424           name1 = bits1;
425           bits1 = t;
426         }
427       else
428         return false;
429
430       /* Do it.  */
431       bsi = bsi_for_stmt (inner_cond);
432       t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
433       t = force_gimple_operand_bsi (&bsi, t, true, NULL_TREE,
434                                     true, BSI_SAME_STMT);
435       t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
436       t = force_gimple_operand_bsi (&bsi, t, true, NULL_TREE,
437                                     true, BSI_SAME_STMT);
438       COND_EXPR_COND (inner_cond) = fold_build2 (NE_EXPR, boolean_type_node, t,
439                                                  build_int_cst (TREE_TYPE (t), 0));
440       update_stmt (inner_cond);
441
442       /* Leave CFG optimization to cfg_cleanup.  */
443       COND_EXPR_COND (outer_cond) = boolean_false_node;
444       update_stmt (outer_cond);
445
446       if (dump_file)
447         {
448           fprintf (dump_file, "optimizing bits or bits test to ");
449           print_generic_expr (dump_file, name1, 0);
450           fprintf (dump_file, " & T != 0\nwith temporary T = ");
451           print_generic_expr (dump_file, bits1, 0);
452           fprintf (dump_file, " | ");
453           print_generic_expr (dump_file, bits2, 0);
454           fprintf (dump_file, "\n");
455         }
456
457       return true;
458     }
459
460   /* See if we have two comparisons that we can merge into one.
461      This happens for C++ operator overloading where for example
462      GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
463   else if (COMPARISON_CLASS_P (COND_EXPR_COND (inner_cond))
464            && COMPARISON_CLASS_P (COND_EXPR_COND (outer_cond))
465            && operand_equal_p (TREE_OPERAND (COND_EXPR_COND (inner_cond), 0),
466                                TREE_OPERAND (COND_EXPR_COND (outer_cond), 0), 0)
467            && operand_equal_p (TREE_OPERAND (COND_EXPR_COND (inner_cond), 1),
468                                TREE_OPERAND (COND_EXPR_COND (outer_cond), 1), 0))
469     {
470       tree ccond1 = COND_EXPR_COND (inner_cond);
471       tree ccond2 = COND_EXPR_COND (outer_cond);
472       enum tree_code code1 = TREE_CODE (ccond1);
473       enum tree_code code2 = TREE_CODE (ccond2);
474       enum tree_code code;
475       tree t;
476
477 #define CHK(a,b) ((code1 == a ## _EXPR && code2 == b ## _EXPR) \
478                   || (code2 == a ## _EXPR && code1 == b ## _EXPR))
479       /* Merge the two condition codes if possible.  */
480       if (code1 == code2)
481         code = code1;
482       else if (CHK (EQ, LT))
483         code = LE_EXPR;
484       else if (CHK (EQ, GT))
485         code = GE_EXPR;
486       else if (CHK (LT, LE))
487         code = LE_EXPR;
488       else if (CHK (GT, GE))
489         code = GE_EXPR;
490       else if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (ccond1, 0)))
491                || flag_unsafe_math_optimizations)
492         {
493           if (CHK (LT, GT))
494             code = NE_EXPR;
495           else if (CHK (LT, NE))
496             code = NE_EXPR;
497           else if (CHK (GT, NE))
498             code = NE_EXPR;
499           else
500             return false;
501         }
502       /* We could check for combinations leading to trivial true/false.  */
503       else
504         return false;
505 #undef CHK
506
507       /* Do it.  */
508       t = fold_build2 (code, boolean_type_node,
509                        TREE_OPERAND (ccond2, 0), TREE_OPERAND (ccond2, 1));
510       t = canonicalize_cond_expr_cond (t);
511       if (!t)
512         return false;
513       COND_EXPR_COND (inner_cond) = t;
514       update_stmt (inner_cond);
515
516       /* Leave CFG optimization to cfg_cleanup.  */
517       COND_EXPR_COND (outer_cond) = boolean_false_node;
518       update_stmt (outer_cond);
519
520       if (dump_file)
521         {
522           fprintf (dump_file, "optimizing two comparisons to ");
523           print_generic_expr (dump_file, t, 0);
524           fprintf (dump_file, "\n");
525         }
526
527       return true;
528     }
529
530   return false;
531 }
532
533 /* Recognize a CFG pattern and dispatch to the appropriate
534    if-conversion helper.  We start with BB as the innermost
535    worker basic-block.  Returns true if a transformation was done.  */
536
537 static bool
538 tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
539 {
540   basic_block then_bb = NULL, else_bb = NULL;
541
542   if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
543     return false;
544
545   /* Recognize && and || of two conditions with a common
546      then/else block which entry edges we can merge.  That is:
547        if (a || b)
548          ;
549      and
550        if (a && b)
551          ;
552      This requires a single predecessor of the inner cond_bb.  */
553   if (single_pred_p (inner_cond_bb))
554     {
555       basic_block outer_cond_bb = single_pred (inner_cond_bb);
556
557       /* The && form is characterized by a common else_bb with
558          the two edges leading to it mergable.  The latter is
559          guaranteed by matching PHI arguments in the else_bb and
560          the inner cond_bb having no side-effects.  */
561       if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
562           && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
563           && bb_no_side_effects_p (inner_cond_bb))
564         {
565           /* We have
566                <outer_cond_bb>
567                  if (q) goto inner_cond_bb; else goto else_bb;
568                <inner_cond_bb>
569                  if (p) goto ...; else goto else_bb;
570                  ...
571                <else_bb>
572                  ...
573            */
574           return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
575         }
576
577       /* The || form is characterized by a common then_bb with the
578          two edges leading to it mergable.  The latter is guaranteed
579          by matching PHI arguments in the then_bb and the inner cond_bb
580          having no side-effects.  */
581       if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
582           && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
583           && bb_no_side_effects_p (inner_cond_bb))
584         {
585           /* We have
586                <outer_cond_bb>
587                  if (q) goto then_bb; else goto inner_cond_bb;
588                <inner_cond_bb>
589                  if (q) goto then_bb; else goto ...;
590                <then_bb>
591                  ...
592            */
593           return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
594         }
595     }
596
597   return false;
598 }
599
600 /* Main entry for the tree if-conversion pass.  */
601
602 static unsigned int
603 tree_ssa_ifcombine (void)
604 {
605   basic_block *bbs;
606   bool cfg_changed = false;
607   int i;
608
609   bbs = blocks_in_phiopt_order ();
610
611   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
612     {
613       basic_block bb = bbs[i];
614       tree stmt = last_stmt (bb);
615
616       if (stmt
617           && TREE_CODE (stmt) == COND_EXPR)
618         cfg_changed |= tree_ssa_ifcombine_bb (bb);
619     }
620
621   free (bbs);
622
623   return cfg_changed ? TODO_cleanup_cfg : 0;
624 }
625
626 static bool
627 gate_ifcombine (void)
628 {
629   return 1;
630 }
631
632 struct gimple_opt_pass pass_tree_ifcombine = 
633 {
634  {
635   GIMPLE_PASS,
636   "ifcombine",                  /* name */
637   gate_ifcombine,               /* gate */
638   tree_ssa_ifcombine,           /* execute */
639   NULL,                         /* sub */
640   NULL,                         /* next */
641   0,                            /* static_pass_number */
642   TV_TREE_IFCOMBINE,            /* tv_id */
643   PROP_cfg | PROP_ssa,          /* properties_required */
644   0,                            /* properties_provided */
645   0,                            /* properties_destroyed */
646   0,                            /* todo_flags_start */
647   TODO_dump_func
648   | TODO_ggc_collect
649   | TODO_update_ssa
650   | TODO_verify_ssa             /* todo_flags_finish */
651  }
652 };