1 /* Dead code elimination pass for the GNU compiler.
2 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Ben Elliston <bje@redhat.com>
4 and Andrew MacLeod <amacleod@redhat.com>
5 Adapted to use control dependence by Steven Bosscher, SUSE Labs.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 /* Dead code elimination.
28 Building an Optimizing Compiler,
29 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
31 Advanced Compiler Design and Implementation,
32 Steven Muchnick, Morgan Kaufmann, 1997, Section 18.10.
34 Dead-code elimination is the removal of statements which have no
35 impact on the program's output. "Dead statements" have no impact
36 on the program's output, while "necessary statements" may have
39 The algorithm consists of three phases:
40 1. Marking as necessary all statements known to be necessary,
41 e.g. most function calls, writing a value to memory, etc;
42 2. Propagating necessary statements, e.g., the statements
43 giving values to operands in necessary statements; and
44 3. Removing dead statements. */
48 #include "coretypes.h"
53 /* These RTL headers are needed for basic-block.h. */
56 #include "hard-reg-set.h"
57 #include "basic-block.h"
60 #include "diagnostic.h"
61 #include "tree-flow.h"
62 #include "tree-gimple.h"
63 #include "tree-dump.h"
64 #include "tree-pass.h"
68 static struct stmt_stats
76 static varray_type worklist
;
78 /* Vector indicating an SSA name has already been processed and marked
80 static sbitmap processed
;
82 /* Vector indicating that last_stmt if a basic block has already been
83 marked as necessary. */
84 static sbitmap last_stmt_necessary
;
86 /* Before we can determine whether a control branch is dead, we need to
87 compute which blocks are control dependent on which edges.
89 We expect each block to be control dependent on very few edges so we
90 use a bitmap for each block recording its edges. An array holds the
91 bitmap. The Ith bit in the bitmap is set if that block is dependent
93 bitmap
*control_dependence_map
;
95 /* Execute CODE for each edge (given number EDGE_NUMBER within the CODE)
96 for which the block with index N is control dependent. */
97 #define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE) \
98 EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[N], 0, EDGE_NUMBER, CODE)
100 /* Local function prototypes. */
101 static inline void set_control_dependence_map_bit (basic_block
, int);
102 static inline void clear_control_dependence_bitmap (basic_block
);
103 static void find_all_control_dependences (struct edge_list
*);
104 static void find_control_dependence (struct edge_list
*, int);
105 static inline basic_block
find_pdom (basic_block
);
107 static inline void mark_stmt_necessary (tree
, bool);
108 static inline void mark_operand_necessary (tree
);
110 static bool need_to_preserve_store (tree
);
111 static void mark_stmt_if_obviously_necessary (tree
, bool);
112 static void find_obviously_necessary_stmts (struct edge_list
*);
114 static void mark_control_dependent_edges_necessary (basic_block
, struct edge_list
*);
115 static void propagate_necessity (struct edge_list
*);
117 static void eliminate_unnecessary_stmts (void);
118 static void remove_dead_phis (basic_block
);
119 static void remove_dead_stmt (block_stmt_iterator
*, basic_block
);
121 static void print_stats (void);
122 static void tree_dce_init (bool);
123 static void tree_dce_done (bool);
125 /* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */
127 set_control_dependence_map_bit (basic_block bb
, int edge_index
)
129 if (bb
== ENTRY_BLOCK_PTR
)
131 if (bb
== EXIT_BLOCK_PTR
)
133 bitmap_set_bit (control_dependence_map
[bb
->index
], edge_index
);
136 /* Clear all control dependences for block BB. */
138 void clear_control_dependence_bitmap (basic_block bb
)
140 bitmap_clear (control_dependence_map
[bb
->index
]);
143 /* Record all blocks' control dependences on all edges in the edge
144 list EL, ala Morgan, Section 3.6. */
147 find_all_control_dependences (struct edge_list
*el
)
151 for (i
= 0; i
< NUM_EDGES (el
); ++i
)
152 find_control_dependence (el
, i
);
155 /* Determine all blocks' control dependences on the given edge with edge_list
156 EL index EDGE_INDEX, ala Morgan, Section 3.6. */
159 find_control_dependence (struct edge_list
*el
, int edge_index
)
161 basic_block current_block
;
162 basic_block ending_block
;
164 #ifdef ENABLE_CHECKING
165 if (INDEX_EDGE_PRED_BB (el
, edge_index
) == EXIT_BLOCK_PTR
)
169 if (INDEX_EDGE_PRED_BB (el
, edge_index
) == ENTRY_BLOCK_PTR
)
170 ending_block
= ENTRY_BLOCK_PTR
->next_bb
;
172 ending_block
= find_pdom (INDEX_EDGE_PRED_BB (el
, edge_index
));
174 for (current_block
= INDEX_EDGE_SUCC_BB (el
, edge_index
);
175 current_block
!= ending_block
&& current_block
!= EXIT_BLOCK_PTR
;
176 current_block
= find_pdom (current_block
))
178 edge e
= INDEX_EDGE (el
, edge_index
);
180 /* For abnormal edges, we don't make current_block control
181 dependent because instructions that throw are always necessary
183 if (e
->flags
& EDGE_ABNORMAL
)
186 set_control_dependence_map_bit (current_block
, edge_index
);
190 /* Find the immediate postdominator PDOM of the specified basic block BLOCK.
191 This function is necessary because some blocks have negative numbers. */
193 static inline basic_block
194 find_pdom (basic_block block
)
196 if (block
== ENTRY_BLOCK_PTR
)
198 else if (block
== EXIT_BLOCK_PTR
)
199 return EXIT_BLOCK_PTR
;
202 basic_block bb
= get_immediate_dominator (CDI_POST_DOMINATORS
, block
);
204 return EXIT_BLOCK_PTR
;
209 #define NECESSARY(stmt) stmt->common.asm_written_flag
211 /* If STMT is not already marked necessary, mark it, and add it to the
212 worklist if ADD_TO_WORKLIST is true. */
214 mark_stmt_necessary (tree stmt
, bool add_to_worklist
)
216 #ifdef ENABLE_CHECKING
218 || stmt
== error_mark_node
219 || (stmt
&& DECL_P (stmt
)))
223 if (NECESSARY (stmt
))
226 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
228 fprintf (dump_file
, "Marking useful stmt: ");
229 print_generic_stmt (dump_file
, stmt
, TDF_SLIM
);
230 fprintf (dump_file
, "\n");
233 NECESSARY (stmt
) = 1;
235 VARRAY_PUSH_TREE (worklist
, stmt
);
238 /* Mark the statement defining operand OP as necessary. */
241 mark_operand_necessary (tree op
)
246 #ifdef ENABLE_CHECKING
251 ver
= SSA_NAME_VERSION (op
);
252 if (TEST_BIT (processed
, ver
))
254 SET_BIT (processed
, ver
);
256 stmt
= SSA_NAME_DEF_STMT (op
);
257 #ifdef ENABLE_CHECKING
263 || IS_EMPTY_STMT (stmt
))
266 NECESSARY (stmt
) = 1;
267 VARRAY_PUSH_TREE (worklist
, stmt
);
270 /* Return true if a store to a variable needs to be preserved. */
273 need_to_preserve_store (tree ssa_name
)
275 return (needs_to_live_in_memory (SSA_NAME_VAR (ssa_name
)));
279 /* Mark STMT as necessary if it is obviously is. Add it to the worklist if
280 it can make other statements necessary.
282 If AGGRESSIVE is false, control statements are conservatively marked as
286 mark_stmt_if_obviously_necessary (tree stmt
, bool aggressive
)
289 v_may_def_optype v_may_defs
;
290 v_must_def_optype v_must_defs
;
295 /* Statements that are implicitly live. Most function calls, asm and return
296 statements are required. Labels and BIND_EXPR nodes are kept because
297 they are control flow, and we have no way of knowing whether they can be
298 removed. DCE can eliminate all the other statements in a block, and CFG
299 can then remove the block and labels. */
300 switch (TREE_CODE (stmt
))
304 case CASE_LABEL_EXPR
:
305 mark_stmt_necessary (stmt
, false);
311 mark_stmt_necessary (stmt
, true);
315 /* Most, but not all function calls are required. Function calls that
316 produce no result and have no side effects (i.e. const pure
317 functions) are unnecessary. */
318 if (TREE_SIDE_EFFECTS (stmt
))
319 mark_stmt_necessary (stmt
, true);
323 op
= get_call_expr_in (stmt
);
324 if (op
&& TREE_SIDE_EFFECTS (op
))
326 mark_stmt_necessary (stmt
, true);
330 /* These values are mildly magic bits of the EH runtime. We can't
331 see the entire lifetime of these values until landing pads are
333 if (TREE_CODE (TREE_OPERAND (stmt
, 0)) == EXC_PTR_EXPR
334 || TREE_CODE (TREE_OPERAND (stmt
, 0)) == FILTER_EXPR
)
336 mark_stmt_necessary (stmt
, true);
342 if (! simple_goto_p (stmt
))
343 mark_stmt_necessary (stmt
, true);
347 if (GOTO_DESTINATION (COND_EXPR_THEN (stmt
))
348 == GOTO_DESTINATION (COND_EXPR_ELSE (stmt
)))
350 /* A COND_EXPR is obviously dead if the target labels are the same.
351 We cannot kill the statement at this point, so to prevent the
352 statement from being marked necessary, we replace the condition
353 with a constant. The stmt is killed later on in cfg_cleanup. */
354 COND_EXPR_COND (stmt
) = integer_zero_node
;
362 mark_stmt_necessary (stmt
, true);
369 ann
= stmt_ann (stmt
);
370 /* If the statement has volatile operands, it needs to be preserved. Same
371 for statements that can alter control flow in unpredictable ways. */
372 if (ann
->has_volatile_ops
373 || is_ctrl_altering_stmt (stmt
))
375 mark_stmt_necessary (stmt
, true);
379 get_stmt_operands (stmt
);
381 defs
= DEF_OPS (ann
);
382 for (i
= 0; i
< NUM_DEFS (defs
); i
++)
384 tree def
= DEF_OP (defs
, i
);
385 if (need_to_preserve_store (def
))
387 mark_stmt_necessary (stmt
, true);
392 v_may_defs
= V_MAY_DEF_OPS (ann
);
393 for (i
= 0; i
< NUM_V_MAY_DEFS (v_may_defs
); i
++)
395 tree v_may_def
= V_MAY_DEF_RESULT (v_may_defs
, i
);
396 if (need_to_preserve_store (v_may_def
))
398 mark_stmt_necessary (stmt
, true);
403 v_must_defs
= V_MUST_DEF_OPS (ann
);
404 for (i
= 0; i
< NUM_V_MUST_DEFS (v_must_defs
); i
++)
406 tree v_must_def
= V_MUST_DEF_OP (v_must_defs
, i
);
407 if (need_to_preserve_store (v_must_def
))
409 mark_stmt_necessary (stmt
, true);
417 /* Find obviously necessary statements. These are things like most function
418 calls, and stores to file level variables.
420 If EL is NULL, control statements are conservatively marked as
421 necessary. Otherwise it contains the list of edges used by control
422 dependence analysis. */
425 find_obviously_necessary_stmts (struct edge_list
*el
)
428 block_stmt_iterator i
;
435 /* Check any PHI nodes in the block. */
436 for (phi
= phi_nodes (bb
); phi
; phi
= PHI_CHAIN (phi
))
440 /* PHIs for virtual variables do not directly affect code
441 generation and need not be considered inherently necessary
442 regardless of the bits set in their decl.
444 Thus, we only need to mark PHIs for real variables which
445 need their result preserved as being inherently necessary. */
446 if (is_gimple_reg (PHI_RESULT (phi
))
447 && need_to_preserve_store (PHI_RESULT (phi
)))
448 mark_stmt_necessary (phi
, true);
451 /* Check all statements in the block. */
452 for (i
= bsi_start (bb
); ! bsi_end_p (i
); bsi_next (&i
))
454 tree stmt
= bsi_stmt (i
);
455 NECESSARY (stmt
) = 0;
456 mark_stmt_if_obviously_necessary (stmt
, el
!= NULL
);
459 /* Mark this basic block as `not visited'. A block will be marked
460 visited when the edges that it is control dependent on have been
462 bb
->flags
&= ~BB_VISITED
;
467 /* Prevent the loops from being removed. We must keep the infinite loops,
468 and we currently do not have a means to recognize the finite ones. */
471 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
472 if (e
->flags
& EDGE_DFS_BACK
)
473 mark_control_dependent_edges_necessary (e
->dest
, el
);
478 /* Make corresponding control dependent edges necessary. We only
479 have to do this once for each basic block, so we clear the bitmap
482 mark_control_dependent_edges_necessary (basic_block bb
, struct edge_list
*el
)
486 #ifdef ENABLE_CHECKING
487 if (bb
== EXIT_BLOCK_PTR
)
491 if (bb
== ENTRY_BLOCK_PTR
)
494 EXECUTE_IF_CONTROL_DEPENDENT (bb
->index
, edge_number
,
497 basic_block cd_bb
= INDEX_EDGE_PRED_BB (el
, edge_number
);
499 if (TEST_BIT (last_stmt_necessary
, cd_bb
->index
))
501 SET_BIT (last_stmt_necessary
, cd_bb
->index
);
503 t
= last_stmt (cd_bb
);
504 if (t
&& is_ctrl_stmt (t
))
505 mark_stmt_necessary (t
, true);
509 /* Propagate necessity using the operands of necessary statements. Process
510 the uses on each statement in the worklist, and add all feeding statements
511 which contribute to the calculation of this value to the worklist.
513 In conservative mode, EL is NULL. */
516 propagate_necessity (struct edge_list
*el
)
519 bool aggressive
= (el
? true : false);
521 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
522 fprintf (dump_file
, "\nProcessing worklist:\n");
524 while (VARRAY_ACTIVE_SIZE (worklist
) > 0)
526 /* Take `i' from worklist. */
527 i
= VARRAY_TOP_TREE (worklist
);
528 VARRAY_POP (worklist
);
530 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
532 fprintf (dump_file
, "processing: ");
533 print_generic_stmt (dump_file
, i
, TDF_SLIM
);
534 fprintf (dump_file
, "\n");
539 /* Mark the last statements of the basic blocks that the block
540 containing `i' is control dependent on, but only if we haven't
542 basic_block bb
= bb_for_stmt (i
);
543 if (! (bb
->flags
& BB_VISITED
))
545 bb
->flags
|= BB_VISITED
;
546 mark_control_dependent_edges_necessary (bb
, el
);
550 if (TREE_CODE (i
) == PHI_NODE
)
552 /* PHI nodes are somewhat special in that each PHI alternative has
553 data and control dependencies. All the statements feeding the
554 PHI node's arguments are always necessary. In aggressive mode,
555 we also consider the control dependent edges leading to the
556 predecessor block associated with each PHI alternative as
559 for (k
= 0; k
< PHI_NUM_ARGS (i
); k
++)
561 tree arg
= PHI_ARG_DEF (i
, k
);
562 if (TREE_CODE (arg
) == SSA_NAME
)
563 mark_operand_necessary (arg
);
568 for (k
= 0; k
< PHI_NUM_ARGS (i
); k
++)
570 basic_block arg_bb
= PHI_ARG_EDGE (i
, k
)->src
;
571 if (! (arg_bb
->flags
& BB_VISITED
))
573 arg_bb
->flags
|= BB_VISITED
;
574 mark_control_dependent_edges_necessary (arg_bb
, el
);
581 /* Propagate through the operands. Examine all the USE, VUSE and
582 V_MAY_DEF operands in this statement. Mark all the statements
583 which feed this statement's uses as necessary. */
585 v_may_def_optype v_may_defs
;
590 get_stmt_operands (i
);
593 uses
= USE_OPS (ann
);
594 for (k
= 0; k
< NUM_USES (uses
); k
++)
595 mark_operand_necessary (USE_OP (uses
, k
));
597 vuses
= VUSE_OPS (ann
);
598 for (k
= 0; k
< NUM_VUSES (vuses
); k
++)
599 mark_operand_necessary (VUSE_OP (vuses
, k
));
601 /* The operands of V_MAY_DEF expressions are also needed as they
602 represent potential definitions that may reach this
603 statement (V_MAY_DEF operands allow us to follow def-def
605 v_may_defs
= V_MAY_DEF_OPS (ann
);
606 for (k
= 0; k
< NUM_V_MAY_DEFS (v_may_defs
); k
++)
607 mark_operand_necessary (V_MAY_DEF_OP (v_may_defs
, k
));
612 /* Eliminate unnecessary statements. Any instruction not marked as necessary
613 contributes nothing to the program, and can be deleted. */
616 eliminate_unnecessary_stmts (void)
619 block_stmt_iterator i
;
621 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
622 fprintf (dump_file
, "\nEliminating unnecessary statements:\n");
624 clear_special_calls ();
627 /* Remove dead PHI nodes. */
628 remove_dead_phis (bb
);
630 /* Remove dead statements. */
631 for (i
= bsi_start (bb
); ! bsi_end_p (i
) ; )
633 tree t
= bsi_stmt (i
);
637 /* If `i' is not necessary then remove it. */
639 remove_dead_stmt (&i
, bb
);
642 tree call
= get_call_expr_in (t
);
644 notice_special_calls (call
);
651 /* Remove dead PHI nodes from block BB. */
654 remove_dead_phis (basic_block bb
)
659 phi
= phi_nodes (bb
);
664 if (! NECESSARY (phi
))
666 tree next
= PHI_CHAIN (phi
);
668 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
670 fprintf (dump_file
, "Deleting : ");
671 print_generic_stmt (dump_file
, phi
, TDF_SLIM
);
672 fprintf (dump_file
, "\n");
675 remove_phi_node (phi
, prev
, bb
);
676 stats
.removed_phis
++;
682 phi
= PHI_CHAIN (phi
);
687 /* Remove dead statement pointed by iterator I. Receives the basic block BB
688 containing I so that we don't have to look it up. */
691 remove_dead_stmt (block_stmt_iterator
*i
, basic_block bb
)
693 tree t
= bsi_stmt (*i
);
695 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
697 fprintf (dump_file
, "Deleting : ");
698 print_generic_stmt (dump_file
, t
, TDF_SLIM
);
699 fprintf (dump_file
, "\n");
704 /* If we have determined that a conditional branch statement contributes
705 nothing to the program, then we not only remove it, but we also change
706 the flow graph so that the current block will simply fall-thru to its
707 immediate post-dominator. The blocks we are circumventing will be
708 removed by cleaup_cfg if this change in the flow graph makes them
710 if (is_ctrl_stmt (t
))
712 basic_block post_dom_bb
;
714 #ifdef ENABLE_CHECKING
715 /* The post dominance info has to be up-to-date. */
716 if (dom_computed
[CDI_POST_DOMINATORS
] != DOM_OK
)
719 /* Get the immediate post dominator of bb. */
720 post_dom_bb
= get_immediate_dominator (CDI_POST_DOMINATORS
, bb
);
721 /* Some blocks don't have an immediate post dominator. This can happen
722 for example with infinite loops. Removing an infinite loop is an
723 inappropriate transformation anyway... */
730 /* Redirect the first edge out of BB to reach POST_DOM_BB. */
731 redirect_edge_and_branch (bb
->succ
, post_dom_bb
);
732 PENDING_STMT (bb
->succ
) = NULL
;
734 /* The edge is no longer associated with a conditional, so it does
735 not have TRUE/FALSE flags. */
736 bb
->succ
->flags
&= ~(EDGE_TRUE_VALUE
| EDGE_FALSE_VALUE
);
738 /* If the edge reaches any block other than the exit, then it is a
739 fallthru edge; if it reaches the exit, then it is not a fallthru
741 if (post_dom_bb
!= EXIT_BLOCK_PTR
)
742 bb
->succ
->flags
|= EDGE_FALLTHRU
;
744 bb
->succ
->flags
&= ~EDGE_FALLTHRU
;
746 /* Remove the remaining the outgoing edges. */
747 for (e
= bb
->succ
->succ_next
; e
!= NULL
;)
758 /* Print out removed statement statistics. */
763 if (dump_file
&& (dump_flags
& (TDF_STATS
|TDF_DETAILS
)))
767 percg
= ((float) stats
.removed
/ (float) stats
.total
) * 100;
768 fprintf (dump_file
, "Removed %d of %d statements (%d%%)\n",
769 stats
.removed
, stats
.total
, (int) percg
);
771 if (stats
.total_phis
== 0)
774 percg
= ((float) stats
.removed_phis
/ (float) stats
.total_phis
) * 100;
776 fprintf (dump_file
, "Removed %d of %d PHI nodes (%d%%)\n",
777 stats
.removed_phis
, stats
.total_phis
, (int) percg
);
781 /* Initialization for this pass. Set up the used data structures. */
784 tree_dce_init (bool aggressive
)
786 memset ((void *) &stats
, 0, sizeof (stats
));
792 control_dependence_map
793 = xmalloc (last_basic_block
* sizeof (bitmap
));
794 for (i
= 0; i
< last_basic_block
; ++i
)
795 control_dependence_map
[i
] = BITMAP_XMALLOC ();
797 last_stmt_necessary
= sbitmap_alloc (last_basic_block
);
798 sbitmap_zero (last_stmt_necessary
);
801 processed
= sbitmap_alloc (num_ssa_names
+ 1);
802 sbitmap_zero (processed
);
804 VARRAY_TREE_INIT (worklist
, 64, "work list");
807 /* Cleanup after this pass. */
810 tree_dce_done (bool aggressive
)
816 for (i
= 0; i
< last_basic_block
; ++i
)
817 BITMAP_XFREE (control_dependence_map
[i
]);
818 free (control_dependence_map
);
820 sbitmap_free (last_stmt_necessary
);
823 sbitmap_free (processed
);
826 /* Main routine to eliminate dead code.
828 AGGRESSIVE controls the aggressiveness of the algorithm.
829 In conservative mode, we ignore control dependence and simply declare
830 all but the most trivially dead branches necessary. This mode is fast.
831 In aggressive mode, control dependences are taken into account, which
832 results in more dead code elimination, but at the cost of some time.
834 FIXME: Aggressive mode before PRE doesn't work currently because
835 the dominance info is not invalidated after DCE1. This is
836 not an issue right now because we only run aggressive DCE
837 as the last tree SSA pass, but keep this in mind when you
838 start experimenting with pass ordering. */
841 perform_tree_ssa_dce (bool aggressive
)
843 struct edge_list
*el
= NULL
;
845 tree_dce_init (aggressive
);
849 /* Compute control dependence. */
850 timevar_push (TV_CONTROL_DEPENDENCES
);
851 calculate_dominance_info (CDI_POST_DOMINATORS
);
852 el
= create_edge_list ();
853 find_all_control_dependences (el
);
854 timevar_pop (TV_CONTROL_DEPENDENCES
);
856 mark_dfs_back_edges ();
859 find_obviously_necessary_stmts (el
);
861 propagate_necessity (el
);
863 eliminate_unnecessary_stmts ();
866 free_dominance_info (CDI_POST_DOMINATORS
);
870 /* Debugging dumps. */
873 dump_function_to_file (current_function_decl
, dump_file
, dump_flags
);
877 tree_dce_done (aggressive
);
882 /* Pass entry points. */
886 perform_tree_ssa_dce (/*aggressive=*/false);
890 tree_ssa_cd_dce (void)
892 perform_tree_ssa_dce (/*aggressive=*/optimize
>= 2);
898 return flag_tree_dce
!= 0;
901 struct tree_opt_pass pass_dce
=
905 tree_ssa_dce
, /* execute */
908 0, /* static_pass_number */
909 TV_TREE_DCE
, /* tv_id */
910 PROP_cfg
| PROP_ssa
, /* properties_required */
911 0, /* properties_provided */
912 0, /* properties_destroyed */
913 0, /* todo_flags_start */
914 TODO_ggc_collect
| TODO_verify_ssa
/* todo_flags_finish */
917 struct tree_opt_pass pass_cd_dce
=
921 tree_ssa_cd_dce
, /* execute */
924 0, /* static_pass_number */
925 TV_TREE_CD_DCE
, /* tv_id */
926 PROP_cfg
| PROP_ssa
, /* properties_required */
927 0, /* properties_provided */
928 0, /* properties_destroyed */
929 0, /* todo_flags_start */
930 TODO_ggc_collect
| TODO_verify_ssa
| TODO_verify_flow
931 /* todo_flags_finish */