]> gcc.gnu.org Git - gcc.git/blame - gcc/tree-ssa-dce.c
Daily bump.
[gcc.git] / gcc / tree-ssa-dce.c
CommitLineData
6de9cd9a
DN
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.
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it
10under the terms of the GNU General Public License as published by the
11Free Software Foundation; either version 2, or (at your option) any
12later version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT
15ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
20along with GCC; see the file COPYING. If not, write to the Free
21Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2202111-1307, USA. */
23
24/* Dead code elimination.
25
26 References:
27
28 Building an Optimizing Compiler,
29 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
30
31 Advanced Compiler Design and Implementation,
32 Steven Muchnick, Morgan Kaufmann, 1997, Section 18.10.
33
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
37 impact on the output.
38
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. */
45
46#include "config.h"
47#include "system.h"
48#include "coretypes.h"
49#include "tm.h"
50#include "errors.h"
51#include "ggc.h"
52
53/* These RTL headers are needed for basic-block.h. */
54#include "rtl.h"
55#include "tm_p.h"
56#include "hard-reg-set.h"
57#include "basic-block.h"
58
59#include "tree.h"
60#include "diagnostic.h"
61#include "tree-flow.h"
eadf906f 62#include "tree-gimple.h"
6de9cd9a
DN
63#include "tree-dump.h"
64#include "tree-pass.h"
65#include "timevar.h"
66#include "flags.h"
67\f
68static struct stmt_stats
69{
70 int total;
71 int total_phis;
72 int removed;
73 int removed_phis;
74} stats;
75
76static varray_type worklist;
77
78/* Vector indicating an SSA name has already been processed and marked
79 as necessary. */
80static sbitmap processed;
81
82/* Vector indicating that last_stmt if a basic block has already been
83 marked as necessary. */
84static sbitmap last_stmt_necessary;
85
86/* Before we can determine whether a control branch is dead, we need to
87 compute which blocks are control dependent on which edges.
88
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
92 on the Ith edge. */
93bitmap *control_dependence_map;
94
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)
99
100/* Local function prototypes. */
101static inline void set_control_dependence_map_bit (basic_block, int);
102static inline void clear_control_dependence_bitmap (basic_block);
103static void find_all_control_dependences (struct edge_list *);
104static void find_control_dependence (struct edge_list *, int);
105static inline basic_block find_pdom (basic_block);
106
107static inline void mark_stmt_necessary (tree, bool);
108static inline void mark_operand_necessary (tree);
109
110static bool need_to_preserve_store (tree);
111static void mark_stmt_if_obviously_necessary (tree, bool);
112static void find_obviously_necessary_stmts (struct edge_list *);
113
114static void mark_control_dependent_edges_necessary (basic_block, struct edge_list *);
115static void propagate_necessity (struct edge_list *);
116
117static void eliminate_unnecessary_stmts (void);
118static void remove_dead_phis (basic_block);
119static void remove_dead_stmt (block_stmt_iterator *, basic_block);
120
121static void print_stats (void);
122static void tree_dce_init (bool);
123static void tree_dce_done (bool);
124\f
125/* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */
126static inline void
127set_control_dependence_map_bit (basic_block bb, int edge_index)
128{
129 if (bb == ENTRY_BLOCK_PTR)
130 return;
131 if (bb == EXIT_BLOCK_PTR)
132 abort ();
133 bitmap_set_bit (control_dependence_map[bb->index], edge_index);
134}
135
136/* Clear all control dependences for block BB. */
137static inline
138void clear_control_dependence_bitmap (basic_block bb)
139{
140 bitmap_clear (control_dependence_map[bb->index]);
141}
142
143/* Record all blocks' control dependences on all edges in the edge
144 list EL, ala Morgan, Section 3.6. */
145
146static void
147find_all_control_dependences (struct edge_list *el)
148{
149 int i;
150
151 for (i = 0; i < NUM_EDGES (el); ++i)
152 find_control_dependence (el, i);
153}
154
155/* Determine all blocks' control dependences on the given edge with edge_list
156 EL index EDGE_INDEX, ala Morgan, Section 3.6. */
157
158static void
159find_control_dependence (struct edge_list *el, int edge_index)
160{
161 basic_block current_block;
162 basic_block ending_block;
163
164#ifdef ENABLE_CHECKING
165 if (INDEX_EDGE_PRED_BB (el, edge_index) == EXIT_BLOCK_PTR)
166 abort ();
167#endif
168
169 if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
170 ending_block = ENTRY_BLOCK_PTR->next_bb;
171 else
172 ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index));
173
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))
177 {
178 edge e = INDEX_EDGE (el, edge_index);
179
180 /* For abnormal edges, we don't make current_block control
181 dependent because instructions that throw are always necessary
182 anyway. */
183 if (e->flags & EDGE_ABNORMAL)
184 continue;
185
186 set_control_dependence_map_bit (current_block, edge_index);
187 }
188}
189
190/* Find the immediate postdominator PDOM of the specified basic block BLOCK.
191 This function is necessary because some blocks have negative numbers. */
192
193static inline basic_block
194find_pdom (basic_block block)
195{
196 if (block == ENTRY_BLOCK_PTR)
197 abort ();
198 else if (block == EXIT_BLOCK_PTR)
199 return EXIT_BLOCK_PTR;
200 else
201 {
202 basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
203 if (! bb)
204 return EXIT_BLOCK_PTR;
205 return bb;
206 }
207}
208\f
209#define NECESSARY(stmt) stmt->common.asm_written_flag
210
211/* If STMT is not already marked necessary, mark it, and add it to the
212 worklist if ADD_TO_WORKLIST is true. */
213static inline void
214mark_stmt_necessary (tree stmt, bool add_to_worklist)
215{
216#ifdef ENABLE_CHECKING
217 if (stmt == NULL
218 || stmt == error_mark_node
219 || (stmt && DECL_P (stmt)))
220 abort ();
221#endif
222
223 if (NECESSARY (stmt))
224 return;
225
226 if (dump_file && (dump_flags & TDF_DETAILS))
227 {
228 fprintf (dump_file, "Marking useful stmt: ");
229 print_generic_stmt (dump_file, stmt, TDF_SLIM);
230 fprintf (dump_file, "\n");
231 }
232
233 NECESSARY (stmt) = 1;
234 if (add_to_worklist)
235 VARRAY_PUSH_TREE (worklist, stmt);
236}
237
238/* Mark the statement defining operand OP as necessary. */
239
240static inline void
241mark_operand_necessary (tree op)
242{
243 tree stmt;
244 int ver;
245
246#ifdef ENABLE_CHECKING
247 if (op == NULL)
248 abort ();
249#endif
250
251 ver = SSA_NAME_VERSION (op);
252 if (TEST_BIT (processed, ver))
253 return;
254 SET_BIT (processed, ver);
255
256 stmt = SSA_NAME_DEF_STMT (op);
257#ifdef ENABLE_CHECKING
258 if (stmt == NULL)
259 abort ();
260#endif
261
262 if (NECESSARY (stmt)
263 || IS_EMPTY_STMT (stmt))
264 return;
265
266 NECESSARY (stmt) = 1;
267 VARRAY_PUSH_TREE (worklist, stmt);
268}
269\f
270/* Return true if a store to a variable needs to be preserved. */
271
272static inline bool
273need_to_preserve_store (tree ssa_name)
274{
275 return (needs_to_live_in_memory (SSA_NAME_VAR (ssa_name)));
276}
277\f
278
279/* Mark STMT as necessary if it is obviously is. Add it to the worklist if
280 it can make other statements necessary.
281
282 If AGGRESSIVE is false, control statements are conservatively marked as
283 necessary. */
284
285static void
286mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
287{
288 def_optype defs;
a32b97a2
BB
289 v_may_def_optype v_may_defs;
290 v_must_def_optype v_must_defs;
6de9cd9a
DN
291 stmt_ann_t ann;
292 size_t i;
293
294 /* Statements that are implicitly live. Most function calls, asm and return
295 statements are required. Labels and BIND_EXPR nodes are kept because
296 they are control flow, and we have no way of knowing whether they can be
297 removed. DCE can eliminate all the other statements in a block, and CFG
298 can then remove the block and labels. */
299 switch (TREE_CODE (stmt))
300 {
301 case BIND_EXPR:
302 case LABEL_EXPR:
303 case CASE_LABEL_EXPR:
304 mark_stmt_necessary (stmt, false);
305 return;
306
307 case ASM_EXPR:
308 case RESX_EXPR:
309 case RETURN_EXPR:
310 mark_stmt_necessary (stmt, true);
311 return;
312
313 case CALL_EXPR:
314 /* Most, but not all function calls are required. Function calls that
315 produce no result and have no side effects (i.e. const pure
316 functions) are unnecessary. */
317 if (TREE_SIDE_EFFECTS (stmt))
318 mark_stmt_necessary (stmt, true);
319 return;
320
321 case MODIFY_EXPR:
322 if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR
323 && TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
324 {
325 mark_stmt_necessary (stmt, true);
326 return;
327 }
328
329 /* These values are mildly magic bits of the EH runtime. We can't
330 see the entire lifetime of these values until landing pads are
331 generated. */
332 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == EXC_PTR_EXPR
333 || TREE_CODE (TREE_OPERAND (stmt, 0)) == FILTER_EXPR)
334 {
335 mark_stmt_necessary (stmt, true);
336 return;
337 }
338 break;
339
340 case GOTO_EXPR:
341 if (! simple_goto_p (stmt))
342 mark_stmt_necessary (stmt, true);
343 return;
344
345 case COND_EXPR:
346 if (GOTO_DESTINATION (COND_EXPR_THEN (stmt))
347 == GOTO_DESTINATION (COND_EXPR_ELSE (stmt)))
348 {
349 /* A COND_EXPR is obviously dead if the target labels are the same.
350 We cannot kill the statement at this point, so to prevent the
351 statement from being marked necessary, we replace the condition
352 with a constant. The stmt is killed later on in cfg_cleanup. */
353 COND_EXPR_COND (stmt) = integer_zero_node;
354 modify_stmt (stmt);
355 return;
356 }
357 /* Fall through. */
358
359 case SWITCH_EXPR:
360 if (! aggressive)
361 mark_stmt_necessary (stmt, true);
362 break;
363
364 default:
365 break;
366 }
367
368 ann = stmt_ann (stmt);
369 /* If the statement has volatile operands, it needs to be preserved. Same
370 for statements that can alter control flow in unpredictable ways. */
371 if (ann->has_volatile_ops
372 || is_ctrl_altering_stmt (stmt))
373 {
374 mark_stmt_necessary (stmt, true);
375 return;
376 }
377
378 get_stmt_operands (stmt);
379
380 defs = DEF_OPS (ann);
381 for (i = 0; i < NUM_DEFS (defs); i++)
382 {
383 tree def = DEF_OP (defs, i);
384 if (need_to_preserve_store (def))
385 {
386 mark_stmt_necessary (stmt, true);
387 return;
388 }
389 }
390
a32b97a2
BB
391 v_may_defs = V_MAY_DEF_OPS (ann);
392 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
6de9cd9a 393 {
a32b97a2
BB
394 tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i);
395 if (need_to_preserve_store (v_may_def))
396 {
397 mark_stmt_necessary (stmt, true);
398 return;
399 }
400 }
401
402 v_must_defs = V_MUST_DEF_OPS (ann);
403 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
404 {
405 tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
406 if (need_to_preserve_store (v_must_def))
6de9cd9a
DN
407 {
408 mark_stmt_necessary (stmt, true);
409 return;
410 }
411 }
412
413 return;
414}
415\f
416/* Find obviously necessary statements. These are things like most function
417 calls, and stores to file level variables.
418
419 If EL is NULL, control statements are conservatively marked as
420 necessary. Otherwise it contains the list of edges used by control
421 dependence analysis. */
422
423static void
424find_obviously_necessary_stmts (struct edge_list *el)
425{
426 basic_block bb;
427 block_stmt_iterator i;
428 edge e;
429
430 FOR_EACH_BB (bb)
431 {
432 tree phi;
433
434 /* Check any PHI nodes in the block. */
435 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
436 {
437 NECESSARY (phi) = 0;
438
439 /* PHIs for virtual variables do not directly affect code
440 generation and need not be considered inherently necessary
441 regardless of the bits set in their decl.
442
443 Thus, we only need to mark PHIs for real variables which
444 need their result preserved as being inherently necessary. */
445 if (is_gimple_reg (PHI_RESULT (phi))
446 && need_to_preserve_store (PHI_RESULT (phi)))
447 mark_stmt_necessary (phi, true);
448 }
449
450 /* Check all statements in the block. */
451 for (i = bsi_start (bb); ! bsi_end_p (i); bsi_next (&i))
452 {
453 tree stmt = bsi_stmt (i);
454 NECESSARY (stmt) = 0;
455 mark_stmt_if_obviously_necessary (stmt, el != NULL);
456 }
457
458 /* Mark this basic block as `not visited'. A block will be marked
459 visited when the edges that it is control dependent on have been
460 marked. */
461 bb->flags &= ~BB_VISITED;
462 }
463
464 if (el)
465 {
466 /* Prevent the loops from being removed. We must keep the infinite loops,
467 and we currently do not have a means to recognize the finite ones. */
468 FOR_EACH_BB (bb)
469 {
470 for (e = bb->succ; e; e = e->succ_next)
471 if (e->flags & EDGE_DFS_BACK)
472 mark_control_dependent_edges_necessary (e->dest, el);
473 }
474 }
475}
476\f
477/* Make corresponding control dependent edges necessary. We only
478 have to do this once for each basic block, so we clear the bitmap
479 after we're done. */
480static void
481mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
482{
483 int edge_number;
484
485 EXECUTE_IF_CONTROL_DEPENDENT (bb->index, edge_number,
486 {
487 tree t;
488 basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number);
489
490 if (TEST_BIT (last_stmt_necessary, cd_bb->index))
491 continue;
492 SET_BIT (last_stmt_necessary, cd_bb->index);
493
494 t = last_stmt (cd_bb);
495 if (is_ctrl_stmt (t))
496 mark_stmt_necessary (t, true);
497 });
498}
499\f
500/* Propagate necessity using the operands of necessary statements. Process
501 the uses on each statement in the worklist, and add all feeding statements
502 which contribute to the calculation of this value to the worklist.
503
504 In conservative mode, EL is NULL. */
505
506static void
507propagate_necessity (struct edge_list *el)
508{
509 tree i;
510 bool aggressive = (el ? true : false);
511
512 if (dump_file && (dump_flags & TDF_DETAILS))
513 fprintf (dump_file, "\nProcessing worklist:\n");
514
515 while (VARRAY_ACTIVE_SIZE (worklist) > 0)
516 {
517 /* Take `i' from worklist. */
518 i = VARRAY_TOP_TREE (worklist);
519 VARRAY_POP (worklist);
520
521 if (dump_file && (dump_flags & TDF_DETAILS))
522 {
523 fprintf (dump_file, "processing: ");
524 print_generic_stmt (dump_file, i, TDF_SLIM);
525 fprintf (dump_file, "\n");
526 }
527
528 if (aggressive)
529 {
530 /* Mark the last statements of the basic blocks that the block
531 containing `i' is control dependent on, but only if we haven't
532 already done so. */
533 basic_block bb = bb_for_stmt (i);
534 if (! (bb->flags & BB_VISITED))
535 {
536 bb->flags |= BB_VISITED;
537 mark_control_dependent_edges_necessary (bb, el);
538 }
539 }
540
541 if (TREE_CODE (i) == PHI_NODE)
542 {
543 /* PHI nodes are somewhat special in that each PHI alternative has
544 data and control dependencies. All the statements feeding the
545 PHI node's arguments are always necessary. In aggressive mode,
546 we also consider the control dependent edges leading to the
547 predecessor block associated with each PHI alternative as
548 necessary. */
549 int k;
550 for (k = 0; k < PHI_NUM_ARGS (i); k++)
551 {
552 tree arg = PHI_ARG_DEF (i, k);
553 if (TREE_CODE (arg) == SSA_NAME)
554 mark_operand_necessary (arg);
555 }
556
557 if (aggressive)
558 {
559 for (k = 0; k < PHI_NUM_ARGS (i); k++)
560 {
561 basic_block arg_bb = PHI_ARG_EDGE (i, k)->src;
562 if (! (arg_bb->flags & BB_VISITED))
563 {
564 arg_bb->flags |= BB_VISITED;
565 mark_control_dependent_edges_necessary (arg_bb, el);
566 }
567 }
568 }
569 }
570 else
571 {
572 /* Propagate through the operands. Examine all the USE, VUSE and
a32b97a2
BB
573 V_MAY_DEF operands in this statement. Mark all the statements
574 which feed this statement's uses as necessary. */
6de9cd9a 575 vuse_optype vuses;
a32b97a2 576 v_may_def_optype v_may_defs;
6de9cd9a
DN
577 use_optype uses;
578 stmt_ann_t ann;
579 size_t k;
580
581 get_stmt_operands (i);
582 ann = stmt_ann (i);
583
584 uses = USE_OPS (ann);
585 for (k = 0; k < NUM_USES (uses); k++)
586 mark_operand_necessary (USE_OP (uses, k));
587
588 vuses = VUSE_OPS (ann);
589 for (k = 0; k < NUM_VUSES (vuses); k++)
590 mark_operand_necessary (VUSE_OP (vuses, k));
591
a32b97a2 592 /* The operands of V_MAY_DEF expressions are also needed as they
6de9cd9a 593 represent potential definitions that may reach this
a32b97a2
BB
594 statement (V_MAY_DEF operands allow us to follow def-def
595 links). */
596 v_may_defs = V_MAY_DEF_OPS (ann);
597 for (k = 0; k < NUM_V_MAY_DEFS (v_may_defs); k++)
598 mark_operand_necessary (V_MAY_DEF_OP (v_may_defs, k));
6de9cd9a
DN
599 }
600 }
601}
602\f
603/* Eliminate unnecessary statements. Any instruction not marked as necessary
604 contributes nothing to the program, and can be deleted. */
605
606static void
607eliminate_unnecessary_stmts (void)
608{
609 basic_block bb;
610 block_stmt_iterator i;
611
612 if (dump_file && (dump_flags & TDF_DETAILS))
613 fprintf (dump_file, "\nEliminating unnecessary statements:\n");
614
615 clear_special_calls ();
616 FOR_EACH_BB (bb)
617 {
618 /* Remove dead PHI nodes. */
619 remove_dead_phis (bb);
620
621 /* Remove dead statements. */
622 for (i = bsi_start (bb); ! bsi_end_p (i) ; )
623 {
624 tree t = bsi_stmt (i);
625
626 stats.total++;
627
628 /* If `i' is not necessary then remove it. */
629 if (! NECESSARY (t))
630 remove_dead_stmt (&i, bb);
631 else
632 {
633 if (TREE_CODE (t) == CALL_EXPR)
634 notice_special_calls (t);
635 else if (TREE_CODE (t) == MODIFY_EXPR
636 && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
637 notice_special_calls (TREE_OPERAND (t, 1));
638 bsi_next (&i);
639 }
640 }
641 }
642}
643\f
644/* Remove dead PHI nodes from block BB. */
645
646static void
647remove_dead_phis (basic_block bb)
648{
649 tree prev, phi;
650
651 prev = NULL_TREE;
652 phi = phi_nodes (bb);
653 while (phi)
654 {
655 stats.total_phis++;
656
657 if (! NECESSARY (phi))
658 {
659 tree next = TREE_CHAIN (phi);
660
661 if (dump_file && (dump_flags & TDF_DETAILS))
662 {
663 fprintf (dump_file, "Deleting : ");
664 print_generic_stmt (dump_file, phi, TDF_SLIM);
665 fprintf (dump_file, "\n");
666 }
667
668 remove_phi_node (phi, prev, bb);
669 stats.removed_phis++;
670 phi = next;
671 }
672 else
673 {
674 prev = phi;
675 phi = TREE_CHAIN (phi);
676 }
677 }
678}
679\f
680/* Remove dead statement pointed by iterator I. Receives the basic block BB
681 containing I so that we don't have to look it up. */
682
683static void
684remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
685{
686 tree t = bsi_stmt (*i);
687
688 if (dump_file && (dump_flags & TDF_DETAILS))
689 {
690 fprintf (dump_file, "Deleting : ");
691 print_generic_stmt (dump_file, t, TDF_SLIM);
692 fprintf (dump_file, "\n");
693 }
694
695 stats.removed++;
696
697 /* If we have determined that a conditional branch statement contributes
698 nothing to the program, then we not only remove it, but we also change
699 the flow graph so that the current block will simply fall-thru to its
700 immediate post-dominator. The blocks we are circumventing will be
701 removed by cleaup_cfg if this change in the flow graph makes them
702 unreachable. */
703 if (is_ctrl_stmt (t))
704 {
705 basic_block post_dom_bb;
706 edge e;
707#ifdef ENABLE_CHECKING
708 /* The post dominance info has to be up-to-date. */
709 if (dom_computed[CDI_POST_DOMINATORS] != DOM_OK)
710 abort ();
711#endif
712 /* Get the immediate post dominator of bb. */
713 post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
714 /* Some blocks don't have an immediate post dominator. This can happen
715 for example with infinite loops. Removing an infinite loop is an
716 inappropriate transformation anyway... */
717 if (! post_dom_bb)
718 {
719 bsi_next (i);
720 return;
721 }
722
723 /* Redirect the first edge out of BB to reach POST_DOM_BB. */
724 redirect_edge_and_branch (bb->succ, post_dom_bb);
725 PENDING_STMT (bb->succ) = NULL;
726
727 /* The edge is no longer associated with a conditional, so it does
728 not have TRUE/FALSE flags. */
729 bb->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
730
731 /* If the edge reaches any block other than the exit, then it is a
732 fallthru edge; if it reaches the exit, then it is not a fallthru
733 edge. */
734 if (post_dom_bb != EXIT_BLOCK_PTR)
735 bb->succ->flags |= EDGE_FALLTHRU;
736 else
737 bb->succ->flags &= ~EDGE_FALLTHRU;
738
739 /* Remove the remaining the outgoing edges. */
740 for (e = bb->succ->succ_next; e != NULL;)
741 {
742 edge tmp = e;
743 e = e->succ_next;
744 remove_edge (tmp);
745 }
746 }
747
748 bsi_remove (i);
749}
750\f
751/* Print out removed statement statistics. */
752
753static void
754print_stats (void)
755{
756 if (dump_file && (dump_flags & (TDF_STATS|TDF_DETAILS)))
757 {
758 float percg;
759
760 percg = ((float) stats.removed / (float) stats.total) * 100;
761 fprintf (dump_file, "Removed %d of %d statements (%d%%)\n",
762 stats.removed, stats.total, (int) percg);
763
764 if (stats.total_phis == 0)
765 percg = 0;
766 else
767 percg = ((float) stats.removed_phis / (float) stats.total_phis) * 100;
768
769 fprintf (dump_file, "Removed %d of %d PHI nodes (%d%%)\n",
770 stats.removed_phis, stats.total_phis, (int) percg);
771 }
772}
773\f
774/* Initialization for this pass. Set up the used data structures. */
775
776static void
777tree_dce_init (bool aggressive)
778{
779 memset ((void *) &stats, 0, sizeof (stats));
780
781 if (aggressive)
782 {
783 int i;
784
785 control_dependence_map
786 = xmalloc (last_basic_block * sizeof (bitmap));
787 for (i = 0; i < last_basic_block; ++i)
788 control_dependence_map[i] = BITMAP_XMALLOC ();
789
790 last_stmt_necessary = sbitmap_alloc (last_basic_block);
791 sbitmap_zero (last_stmt_necessary);
792 }
793
95a3742c 794 processed = sbitmap_alloc (num_ssa_names + 1);
6de9cd9a
DN
795 sbitmap_zero (processed);
796
797 VARRAY_TREE_INIT (worklist, 64, "work list");
798}
799
800/* Cleanup after this pass. */
801
802static void
803tree_dce_done (bool aggressive)
804{
805 if (aggressive)
806 {
807 int i;
808
809 for (i = 0; i < last_basic_block; ++i)
810 BITMAP_XFREE (control_dependence_map[i]);
811 free (control_dependence_map);
812
813 sbitmap_free (last_stmt_necessary);
814 }
815
816 sbitmap_free (processed);
817}
818\f
819/* Main routine to eliminate dead code.
820
821 AGGRESSIVE controls the aggressiveness of the algorithm.
822 In conservative mode, we ignore control dependence and simply declare
823 all but the most trivially dead branches necessary. This mode is fast.
824 In aggressive mode, control dependences are taken into account, which
825 results in more dead code elimination, but at the cost of some time.
826
827 FIXME: Aggressive mode before PRE doesn't work currently because
828 the dominance info is not invalidated after DCE1. This is
829 not an issue right now because we only run aggressive DCE
830 as the last tree SSA pass, but keep this in mind when you
831 start experimenting with pass ordering. */
832
833static void
834perform_tree_ssa_dce (bool aggressive)
835{
836 struct edge_list *el = NULL;
837
838 tree_dce_init (aggressive);
839
840 if (aggressive)
841 {
842 /* Compute control dependence. */
843 timevar_push (TV_CONTROL_DEPENDENCES);
844 calculate_dominance_info (CDI_POST_DOMINATORS);
845 el = create_edge_list ();
846 find_all_control_dependences (el);
847 timevar_pop (TV_CONTROL_DEPENDENCES);
848
849 mark_dfs_back_edges ();
850 }
851
852 find_obviously_necessary_stmts (el);
853
854 propagate_necessity (el);
855
856 eliminate_unnecessary_stmts ();
857
858 if (aggressive)
859 free_dominance_info (CDI_POST_DOMINATORS);
860
861 cleanup_tree_cfg ();
862
863 /* Debugging dumps. */
864 if (dump_file)
865 {
866 dump_function_to_file (current_function_decl, dump_file, dump_flags);
867 print_stats ();
868 }
869
870 tree_dce_done (aggressive);
960076d9
AP
871
872 free_edge_list (el);
6de9cd9a
DN
873}
874
875/* Pass entry points. */
876static void
877tree_ssa_dce (void)
878{
879 perform_tree_ssa_dce (/*aggressive=*/false);
880}
881
882static void
883tree_ssa_cd_dce (void)
884{
885 perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
886}
887
888static bool
889gate_dce (void)
890{
891 return flag_tree_dce != 0;
892}
893
894struct tree_opt_pass pass_dce =
895{
896 "dce", /* name */
897 gate_dce, /* gate */
898 tree_ssa_dce, /* execute */
899 NULL, /* sub */
900 NULL, /* next */
901 0, /* static_pass_number */
902 TV_TREE_DCE, /* tv_id */
903 PROP_cfg | PROP_ssa, /* properties_required */
904 0, /* properties_provided */
905 0, /* properties_destroyed */
906 0, /* todo_flags_start */
907 TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
908};
909
910struct tree_opt_pass pass_cd_dce =
911{
912 "cddce", /* name */
913 gate_dce, /* gate */
914 tree_ssa_cd_dce, /* execute */
915 NULL, /* sub */
916 NULL, /* next */
917 0, /* static_pass_number */
918 TV_TREE_CD_DCE, /* tv_id */
919 PROP_cfg | PROP_ssa, /* properties_required */
920 0, /* properties_provided */
921 0, /* properties_destroyed */
922 0, /* todo_flags_start */
923 TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow
924 /* todo_flags_finish */
925};
926
This page took 0.164195 seconds and 5 git commands to generate.