]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/dce.c
Daily bump.
[thirdparty/gcc.git] / gcc / dce.c
CommitLineData
6fb5fa3c 1/* RTL dead code elimination.
cc806ac1 2 Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
6fb5fa3c
DB
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
6fb5fa3c
DB
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
6fb5fa3c
DB
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "hashtab.h"
24#include "tm.h"
25#include "rtl.h"
26#include "tree.h"
27#include "regs.h"
28#include "hard-reg-set.h"
29#include "flags.h"
30#include "df.h"
31#include "cselib.h"
32#include "dce.h"
33#include "timevar.h"
34#include "tree-pass.h"
35#include "dbgcnt.h"
36
37DEF_VEC_I(int);
38DEF_VEC_ALLOC_I(int,heap);
39
40
41/* -------------------------------------------------------------------------
42 Core mark/delete routines
43 ------------------------------------------------------------------------- */
44
2e6be65e
EB
45/* True if we are invoked while the df engine is running; in this case,
46 we don't want to reenter it. */
6fb5fa3c
DB
47static bool df_in_progress = false;
48
6fb5fa3c
DB
49/* Instructions that have been marked but whose dependencies have not
50 yet been processed. */
51static VEC(rtx,heap) *worklist;
52
2e6be65e
EB
53/* Bitmap of instructions marked as needed indexed by INSN_UID. */
54static sbitmap marked;
55
56/* Bitmap obstacks used for block processing by the fast algorithm. */
6fb5fa3c
DB
57static bitmap_obstack dce_blocks_bitmap_obstack;
58static bitmap_obstack dce_tmp_bitmap_obstack;
59
6fb5fa3c 60
d4d7f1d1
RS
61/* A subroutine for which BODY is part of the instruction being tested;
62 either the top-level pattern, or an element of a PARALLEL. The
63 instruction is known not to be a bare USE or CLOBBER. */
6fb5fa3c
DB
64
65static bool
d4d7f1d1 66deletable_insn_p_1 (rtx body)
6fb5fa3c 67{
6cad9859 68 switch (GET_CODE (body))
6fb5fa3c 69 {
6fb5fa3c
DB
70 case PREFETCH:
71 case TRAP_IF:
72 /* The UNSPEC case was added here because the ia-64 claims that
73 USEs do not work after reload and generates UNSPECS rather
74 than USEs. Since dce is run after reload we need to avoid
75 deleting these even if they are dead. If it turns out that
76 USEs really do work after reload, the ia-64 should be
77 changed, and the UNSPEC case can be removed. */
78 case UNSPEC:
79 return false;
80
d4d7f1d1 81 default:
0a64eeca 82 if (volatile_refs_p (body))
d4d7f1d1
RS
83 return false;
84
85 if (flag_non_call_exceptions && may_trap_p (body))
86 return false;
87
88 return true;
89 }
90}
91
2e6be65e 92
d4d7f1d1
RS
93/* Return true if INSN is a normal instruction that can be deleted by
94 the DCE pass. */
95
96static bool
97deletable_insn_p (rtx insn, bool fast)
98{
99 rtx body, x;
100 int i;
101
5ba5ab9b
KZ
102 if (CALL_P (insn)
103 /* We cannot delete calls inside of the recursive dce because
104 this may cause basic blocks to be deleted and this messes up
105 the rest of the stack of optimization passes. */
106 && (!df_in_progress)
107 /* We cannot delete pure or const sibling calls because it is
108 hard to see the result. */
becfd6e5 109 && (!SIBLING_CALL_P (insn))
5ba5ab9b
KZ
110 /* We can delete dead const or pure calls as long as they do not
111 infinite loop. */
becfd6e5
KZ
112 && (RTL_CONST_OR_PURE_CALL_P (insn)
113 && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
114 return true;
115
d4d7f1d1
RS
116 if (!NONJUMP_INSN_P (insn))
117 return false;
118
119 body = PATTERN (insn);
120 switch (GET_CODE (body))
121 {
122 case USE:
123 return false;
124
6fb5fa3c
DB
125 case CLOBBER:
126 if (fast)
127 {
128 /* A CLOBBER of a dead pseudo register serves no purpose.
129 That is not necessarily true for hard registers until
130 after reload. */
6cad9859 131 x = XEXP (body, 0);
6fb5fa3c
DB
132 return REG_P (x) && (!HARD_REGISTER_P (x) || reload_completed);
133 }
d4d7f1d1 134 else
6fb5fa3c
DB
135 /* Because of the way that use-def chains are built, it is not
136 possible to tell if the clobber is dead because it can
137 never be the target of a use-def chain. */
138 return false;
139
6cad9859 140 case PARALLEL:
d4d7f1d1
RS
141 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
142 if (!deletable_insn_p_1 (XVECEXP (body, 0, i)))
143 return false;
144 return true;
6cad9859 145
6fb5fa3c 146 default:
d4d7f1d1 147 return deletable_insn_p_1 (body);
6fb5fa3c
DB
148 }
149}
150
151
2e6be65e 152/* Return true if INSN has been marked as needed. */
6fb5fa3c
DB
153
154static inline int
155marked_insn_p (rtx insn)
156{
157 if (insn)
158 return TEST_BIT (marked, INSN_UID (insn));
159 else
160 /* Artificial defs are always needed and they do not have an
161 insn. */
162 return true;
163}
164
165
166/* If INSN has not yet been marked as needed, mark it now, and add it to
167 the worklist. */
168
169static void
170mark_insn (rtx insn, bool fast)
171{
172 if (!marked_insn_p (insn))
173 {
174 if (!fast)
175 VEC_safe_push (rtx, heap, worklist, insn);
176 SET_BIT (marked, INSN_UID (insn));
177 if (dump_file)
178 fprintf (dump_file, " Adding insn %d to worklist\n", INSN_UID (insn));
179 }
180}
181
182
183/* A note_stores callback used by mark_nonreg_stores. DATA is the
184 instruction containing DEST. */
185
186static void
7bc980e1 187mark_nonreg_stores_1 (rtx dest, const_rtx pattern, void *data)
6fb5fa3c
DB
188{
189 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest))
190 mark_insn ((rtx) data, true);
191}
192
193
194/* A note_stores callback used by mark_nonreg_stores. DATA is the
195 instruction containing DEST. */
196
197static void
7bc980e1 198mark_nonreg_stores_2 (rtx dest, const_rtx pattern, void *data)
6fb5fa3c
DB
199{
200 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest))
201 mark_insn ((rtx) data, false);
202}
203
204
205/* Mark INSN if BODY stores to a non-register destination. */
206
207static void
208mark_nonreg_stores (rtx body, rtx insn, bool fast)
209{
210 if (fast)
211 note_stores (body, mark_nonreg_stores_1, insn);
212 else
213 note_stores (body, mark_nonreg_stores_2, insn);
214}
215
216
6fb5fa3c
DB
217/* Delete all REG_EQUAL notes of the registers INSN writes, to prevent
218 bad dangling REG_EQUAL notes. */
219
220static void
221delete_corresponding_reg_eq_notes (rtx insn)
222{
223 struct df_ref **def_rec;
224 for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
225 {
226 struct df_ref *def = *def_rec;
227 unsigned int regno = DF_REF_REGNO (def);
228 /* This loop is a little tricky. We cannot just go down the
229 chain because it is being modified by the actions in the
230 loop. So we just get the head. We plan to drain the list
231 anyway. */
232 while (DF_REG_EQ_USE_CHAIN (regno))
233 {
234 struct df_ref *eq_use = DF_REG_EQ_USE_CHAIN (regno);
235 rtx noted_insn = DF_REF_INSN (eq_use);
236 rtx note = find_reg_note (noted_insn, REG_EQUAL, NULL_RTX);
237 if (!note)
238 note = find_reg_note (noted_insn, REG_EQUIV, NULL_RTX);
239
240 /* This assert is generally triggered when someone deletes a
241 REG_EQUAL or REG_EQUIV note by hacking the list manually
242 rather than calling remove_note. */
243 gcc_assert (note);
244 remove_note (noted_insn, note);
245 }
246 }
247}
248
249
9ed7b221 250/* Delete every instruction that hasn't been marked. */
6fb5fa3c
DB
251
252static void
253delete_unmarked_insns (void)
254{
255 basic_block bb;
256 rtx insn, next;
5ba5ab9b 257 bool must_clean = false;
6fb5fa3c 258
6fb5fa3c
DB
259 FOR_EACH_BB (bb)
260 FOR_BB_INSNS_SAFE (bb, insn, next)
261 if (INSN_P (insn))
262 {
9ed7b221 263 /* Always delete no-op moves. */
6fb5fa3c 264 if (noop_move_p (insn))
9ed7b221
EB
265 ;
266
9ed7b221 267 /* Otherwise rely only on the DCE algorithm. */
6fb5fa3c
DB
268 else if (marked_insn_p (insn))
269 continue;
270
6fb5fa3c
DB
271 if (!dbg_cnt (dce))
272 continue;
273
274 if (dump_file)
275 fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
276
9ed7b221
EB
277 /* Before we delete the insn we have to delete REG_EQUAL notes
278 for the destination regs in order to avoid dangling notes. */
279 delete_corresponding_reg_eq_notes (insn);
6fb5fa3c 280
5ba5ab9b
KZ
281 /* If a pure or const call is deleted, this may make the cfg
282 have unreachable blocks. We rememeber this and call
283 delete_unreachable_blocks at the end. */
284 if (CALL_P (insn))
285 must_clean = true;
286
9ed7b221 287 /* Now delete the insn. */
6fb5fa3c 288 delete_insn_and_edges (insn);
6fb5fa3c 289 }
5ba5ab9b
KZ
290
291 /* Deleted a pure or const call. */
292 if (must_clean)
293 delete_unreachable_blocks ();
6fb5fa3c
DB
294}
295
296
6fb5fa3c
DB
297/* Go through the instructions and mark those whose necessity is not
298 dependent on inter-instruction information. Make sure all other
299 instructions are not marked. */
300
301static void
302prescan_insns_for_dce (bool fast)
303{
304 basic_block bb;
9ed7b221 305 rtx insn, next;
6fb5fa3c
DB
306
307 if (dump_file)
308 fprintf (dump_file, "Finding needed instructions:\n");
309
310 FOR_EACH_BB (bb)
9ed7b221
EB
311 FOR_BB_INSNS_SAFE (bb, insn, next)
312 if (INSN_P (insn))
313 {
4a8cae83 314 if (deletable_insn_p (insn, fast))
9ed7b221
EB
315 mark_nonreg_stores (PATTERN (insn), insn, fast);
316 else
317 mark_insn (insn, fast);
318 }
6fb5fa3c
DB
319
320 if (dump_file)
321 fprintf (dump_file, "Finished finding needed instructions:\n");
322}
323
324
325/* UD-based DSE routines. */
326
6ed3da00 327/* Mark instructions that define artificially-used registers, such as
6fb5fa3c
DB
328 the frame pointer and the stack pointer. */
329
330static void
331mark_artificial_uses (void)
332{
333 basic_block bb;
334 struct df_link *defs;
335 struct df_ref **use_rec;
336
337 FOR_ALL_BB (bb)
338 {
339 for (use_rec = df_get_artificial_uses (bb->index);
340 *use_rec; use_rec++)
341 for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next)
342 mark_insn (DF_REF_INSN (defs->ref), false);
343 }
344}
345
2e6be65e 346
6fb5fa3c
DB
347/* Mark every instruction that defines a register value that INSN uses. */
348
349static void
350mark_reg_dependencies (rtx insn)
351{
352 struct df_link *defs;
353 struct df_ref **use_rec;
354
6fb5fa3c
DB
355 for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
356 {
357 struct df_ref *use = *use_rec;
358 if (dump_file)
359 {
360 fprintf (dump_file, "Processing use of ");
361 print_simple_rtl (dump_file, DF_REF_REG (use));
362 fprintf (dump_file, " in insn %d:\n", INSN_UID (insn));
363 }
364 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
365 mark_insn (DF_REF_INSN (defs->ref), false);
366 }
367}
368
369
2e6be65e
EB
370/* Initialize global variables for a new DCE pass. */
371
6fb5fa3c 372static void
2e6be65e
EB
373init_dce (bool fast)
374{
375 if (!df_in_progress)
376 {
377 if (!fast)
378 df_chain_add_problem (DF_UD_CHAIN);
379 df_analyze ();
380 }
381
382 if (dump_file)
383 df_dump (dump_file);
384
385 if (fast)
386 {
387 bitmap_obstack_initialize (&dce_blocks_bitmap_obstack);
388 bitmap_obstack_initialize (&dce_tmp_bitmap_obstack);
389 }
390
391 marked = sbitmap_alloc (get_max_uid () + 1);
392 sbitmap_zero (marked);
393}
394
395
396/* Free the data allocated by init_dce. */
397
398static void
399fini_dce (bool fast)
6fb5fa3c
DB
400{
401 sbitmap_free (marked);
2e6be65e
EB
402
403 if (fast)
404 {
405 bitmap_obstack_release (&dce_blocks_bitmap_obstack);
406 bitmap_obstack_release (&dce_tmp_bitmap_obstack);
407 }
6fb5fa3c
DB
408}
409
410
411/* UD-chain based DCE. */
412
413static unsigned int
414rest_of_handle_ud_dce (void)
415{
416 rtx insn;
417
6fb5fa3c
DB
418 init_dce (false);
419
420 prescan_insns_for_dce (false);
421 mark_artificial_uses ();
422 while (VEC_length (rtx, worklist) > 0)
423 {
424 insn = VEC_pop (rtx, worklist);
425 mark_reg_dependencies (insn);
426 }
2e6be65e 427
6fb5fa3c
DB
428 /* Before any insns are deleted, we must remove the chains since
429 they are not bidirectional. */
430 df_remove_problem (df_chain);
431 delete_unmarked_insns ();
432
2e6be65e 433 fini_dce (false);
6fb5fa3c
DB
434 return 0;
435}
436
437
438static bool
439gate_ud_dce (void)
440{
7d817ebc
DE
441 return optimize > 1 && flag_dce
442 && dbg_cnt (dce_ud);
6fb5fa3c
DB
443}
444
8ddbbcae 445struct rtl_opt_pass pass_ud_rtl_dce =
6fb5fa3c 446{
8ddbbcae
JH
447 {
448 RTL_PASS,
6fb5fa3c
DB
449 "dce", /* name */
450 gate_ud_dce, /* gate */
451 rest_of_handle_ud_dce, /* execute */
452 NULL, /* sub */
453 NULL, /* next */
454 0, /* static_pass_number */
455 TV_DCE, /* tv_id */
456 0, /* properties_required */
457 0, /* properties_provided */
458 0, /* properties_destroyed */
459 0, /* todo_flags_start */
460 TODO_dump_func |
a36b8a1e 461 TODO_df_finish | TODO_verify_rtl_sharing |
8ddbbcae
JH
462 TODO_ggc_collect /* todo_flags_finish */
463 }
6fb5fa3c
DB
464};
465
2e6be65e 466
6fb5fa3c
DB
467/* -------------------------------------------------------------------------
468 Fast DCE functions
469 ------------------------------------------------------------------------- */
470
cc806ac1
RS
471/* Process basic block BB. Return true if the live_in set has
472 changed. REDO_OUT is true if the info at the bottom of the block
473 needs to be recalculated before starting. AU is the proper set of
474 artificial uses. */
6fb5fa3c
DB
475
476static bool
cc806ac1 477byte_dce_process_block (basic_block bb, bool redo_out, bitmap au)
6fb5fa3c
DB
478{
479 bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
480 rtx insn;
481 bool block_changed;
cc806ac1 482 struct df_ref **def_rec;
6fb5fa3c
DB
483
484 if (redo_out)
485 {
486 /* Need to redo the live_out set of this block if when one of
487 the succs of this block has had a change in it live in
488 set. */
489 edge e;
490 edge_iterator ei;
cc806ac1
RS
491 df_confluence_function_n con_fun_n = df_byte_lr->problem->con_fun_n;
492 bitmap_clear (DF_BYTE_LR_OUT (bb));
6fb5fa3c
DB
493 FOR_EACH_EDGE (e, ei, bb->succs)
494 (*con_fun_n) (e);
495 }
496
497 if (dump_file)
498 {
499 fprintf (dump_file, "processing block %d live out = ", bb->index);
cc806ac1 500 df_print_byte_regset (dump_file, DF_BYTE_LR_OUT (bb));
6fb5fa3c
DB
501 }
502
cc806ac1
RS
503 bitmap_copy (local_live, DF_BYTE_LR_OUT (bb));
504
505 df_byte_lr_simulate_artificial_refs_at_end (bb, local_live);
506
507 FOR_BB_INSNS_REVERSE (bb, insn)
508 if (INSN_P (insn))
509 {
510 /* The insn is needed if there is someone who uses the output. */
511 for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
512 {
513 struct df_ref *def = *def_rec;
514 unsigned int last;
515 unsigned int dregno = DF_REF_REGNO (def);
516 unsigned int start = df_byte_lr_get_regno_start (dregno);
517 unsigned int len = df_byte_lr_get_regno_len (dregno);
518
519 unsigned int sb;
520 unsigned int lb;
521 /* This is one of the only places where DF_MM_MAY should
522 be used for defs. Need to make sure that we are
523 checking for all of the bits that may be used. */
524
525 if (!df_compute_accessed_bytes (def, DF_MM_MAY, &sb, &lb))
526 {
527 start += sb;
528 len = lb - sb;
529 }
530
531 if (bitmap_bit_p (au, dregno))
532 {
533 mark_insn (insn, true);
534 goto quickexit;
535 }
536
537 last = start + len;
538 while (start < last)
539 if (bitmap_bit_p (local_live, start++))
540 {
541 mark_insn (insn, true);
542 goto quickexit;
543 }
544 }
545
546 quickexit:
547
548 /* No matter if the instruction is needed or not, we remove
549 any regno in the defs from the live set. */
550 df_byte_lr_simulate_defs (insn, local_live);
551
552 /* On the other hand, we do not allow the dead uses to set
553 anything in local_live. */
554 if (marked_insn_p (insn))
555 df_byte_lr_simulate_uses (insn, local_live);
556
557 if (dump_file)
558 {
559 fprintf (dump_file, "finished processing insn %d live out = ",
560 INSN_UID (insn));
561 df_print_byte_regset (dump_file, local_live);
562 }
563 }
564
565 df_byte_lr_simulate_artificial_refs_at_top (bb, local_live);
566
567 block_changed = !bitmap_equal_p (local_live, DF_BYTE_LR_IN (bb));
568 if (block_changed)
569 bitmap_copy (DF_BYTE_LR_IN (bb), local_live);
570 BITMAP_FREE (local_live);
571 return block_changed;
572}
573
574
575/* Process basic block BB. Return true if the live_in set has
576 changed. REDO_OUT is true if the info at the bottom of the block
577 needs to be recalculated before starting. AU is the proper set of
578 artificial uses. */
579
580static bool
581dce_process_block (basic_block bb, bool redo_out, bitmap au)
582{
583 bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
584 rtx insn;
585 bool block_changed;
586 struct df_ref **def_rec;
6fb5fa3c 587
cc806ac1 588 if (redo_out)
6fb5fa3c 589 {
cc806ac1
RS
590 /* Need to redo the live_out set of this block if when one of
591 the succs of this block has had a change in it live in
592 set. */
593 edge e;
594 edge_iterator ei;
595 df_confluence_function_n con_fun_n = df_lr->problem->con_fun_n;
596 bitmap_clear (DF_LR_OUT (bb));
597 FOR_EACH_EDGE (e, ei, bb->succs)
598 (*con_fun_n) (e);
6fb5fa3c
DB
599 }
600
cc806ac1 601 if (dump_file)
6fb5fa3c 602 {
cc806ac1
RS
603 fprintf (dump_file, "processing block %d live out = ", bb->index);
604 df_print_regset (dump_file, DF_LR_OUT (bb));
6fb5fa3c
DB
605 }
606
cc806ac1
RS
607 bitmap_copy (local_live, DF_LR_OUT (bb));
608
609 df_simulate_artificial_refs_at_end (bb, local_live);
541d3103 610
6fb5fa3c
DB
611 FOR_BB_INSNS_REVERSE (bb, insn)
612 if (INSN_P (insn))
613 {
9ed7b221
EB
614 bool needed = false;
615
616 /* The insn is needed if there is someone who uses the output. */
617 for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
618 if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
619 || bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))
620 {
621 needed = true;
622 break;
623 }
6fb5fa3c 624
9ed7b221
EB
625 if (needed)
626 mark_insn (insn, true);
6fb5fa3c
DB
627
628 /* No matter if the instruction is needed or not, we remove
629 any regno in the defs from the live set. */
630 df_simulate_defs (insn, local_live);
631
632 /* On the other hand, we do not allow the dead uses to set
633 anything in local_live. */
634 if (marked_insn_p (insn))
635 df_simulate_uses (insn, local_live);
636 }
637
cc806ac1 638 df_simulate_artificial_refs_at_top (bb, local_live);
6fb5fa3c
DB
639
640 block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb));
641 if (block_changed)
642 bitmap_copy (DF_LR_IN (bb), local_live);
643
644 BITMAP_FREE (local_live);
645 return block_changed;
646}
647
2e6be65e 648
cc806ac1
RS
649/* Perform fast DCE once initialization is done. If BYTE_LEVEL is
650 true, use the byte level dce, otherwise do it at the pseudo
651 level. */
2e6be65e 652
6fb5fa3c 653static void
cc806ac1 654fast_dce (bool byte_level)
6fb5fa3c
DB
655{
656 int *postorder = df_get_postorder (DF_BACKWARD);
657 int n_blocks = df_get_n_blocks (DF_BACKWARD);
6fb5fa3c
DB
658 /* The set of blocks that have been seen on this iteration. */
659 bitmap processed = BITMAP_ALLOC (&dce_blocks_bitmap_obstack);
660 /* The set of blocks that need to have the out vectors reset because
661 the in of one of their successors has changed. */
662 bitmap redo_out = BITMAP_ALLOC (&dce_blocks_bitmap_obstack);
663 bitmap all_blocks = BITMAP_ALLOC (&dce_blocks_bitmap_obstack);
664 bool global_changed = true;
cc806ac1
RS
665
666 /* These regs are considered always live so if they end up dying
667 because of some def, we need to bring the back again. Calling
668 df_simulate_fixup_sets has the disadvantage of calling
669 bb_has_eh_pred once per insn, so we cache the information
670 here. */
671 bitmap au = df->regular_block_artificial_uses;
672 bitmap au_eh = df->eh_block_artificial_uses;
9ed7b221 673 int i;
6fb5fa3c
DB
674
675 prescan_insns_for_dce (true);
676
677 for (i = 0; i < n_blocks; i++)
678 bitmap_set_bit (all_blocks, postorder[i]);
679
680 while (global_changed)
681 {
682 global_changed = false;
9ed7b221 683
6fb5fa3c
DB
684 for (i = 0; i < n_blocks; i++)
685 {
686 int index = postorder[i];
687 basic_block bb = BASIC_BLOCK (index);
688 bool local_changed;
689
690 if (index < NUM_FIXED_BLOCKS)
691 {
692 bitmap_set_bit (processed, index);
693 continue;
694 }
695
cc806ac1
RS
696 if (byte_level)
697 local_changed
698 = byte_dce_process_block (bb, bitmap_bit_p (redo_out, index),
699 bb_has_eh_pred (bb) ? au_eh : au);
700 else
701 local_changed
702 = dce_process_block (bb, bitmap_bit_p (redo_out, index),
703 bb_has_eh_pred (bb) ? au_eh : au);
6fb5fa3c
DB
704 bitmap_set_bit (processed, index);
705
706 if (local_changed)
707 {
708 edge e;
709 edge_iterator ei;
710 FOR_EACH_EDGE (e, ei, bb->preds)
711 if (bitmap_bit_p (processed, e->src->index))
712 /* Be tricky about when we need to iterate the
713 analysis. We only have redo the analysis if the
714 bitmaps change at the top of a block that is the
715 entry to a loop. */
716 global_changed = true;
717 else
718 bitmap_set_bit (redo_out, e->src->index);
719 }
720 }
721
722 if (global_changed)
723 {
724 /* Turn off the RUN_DCE flag to prevent recursive calls to
725 dce. */
726 int old_flag = df_clear_flags (DF_LR_RUN_DCE);
727
728 /* So something was deleted that requires a redo. Do it on
729 the cheap. */
730 delete_unmarked_insns ();
731 sbitmap_zero (marked);
732 bitmap_clear (processed);
733 bitmap_clear (redo_out);
734
735 /* We do not need to rescan any instructions. We only need
736 to redo the dataflow equations for the blocks that had a
737 change at the top of the block. Then we need to redo the
738 iteration. */
cc806ac1
RS
739 if (byte_level)
740 df_analyze_problem (df_byte_lr, all_blocks, postorder, n_blocks);
741 else
742 df_analyze_problem (df_lr, all_blocks, postorder, n_blocks);
6fb5fa3c
DB
743
744 if (old_flag & DF_LR_RUN_DCE)
745 df_set_flags (DF_LR_RUN_DCE);
9ed7b221 746
6fb5fa3c
DB
747 prescan_insns_for_dce (true);
748 }
6fb5fa3c
DB
749 }
750
751 delete_unmarked_insns ();
752
753 BITMAP_FREE (processed);
754 BITMAP_FREE (redo_out);
755 BITMAP_FREE (all_blocks);
756}
757
758
cc806ac1 759/* Fast register level DCE. */
6fb5fa3c
DB
760
761static unsigned int
762rest_of_handle_fast_dce (void)
763{
764 init_dce (true);
cc806ac1
RS
765 fast_dce (false);
766 fini_dce (true);
767 return 0;
768}
769
770
771/* Fast byte level DCE. */
772
773static unsigned int
774rest_of_handle_fast_byte_dce (void)
775{
776 df_byte_lr_add_problem ();
777 init_dce (true);
778 fast_dce (true);
2e6be65e 779 fini_dce (true);
6fb5fa3c
DB
780 return 0;
781}
782
783
784/* This is an internal call that is used by the df live register
785 problem to run fast dce as a side effect of creating the live
786 information. The stack is organized so that the lr problem is run,
787 this pass is run, which updates the live info and the df scanning
788 info, and then returns to allow the rest of the problems to be run.
789
790 This can be called by elsewhere but it will not update the bit
2e6be65e 791 vectors for any other problems than LR. */
6fb5fa3c
DB
792
793void
794run_fast_df_dce (void)
795{
796 if (flag_dce)
797 {
798 /* If dce is able to delete something, it has to happen
799 immediately. Otherwise there will be problems handling the
800 eq_notes. */
801 enum df_changeable_flags old_flags
802 = df_clear_flags (DF_DEFER_INSN_RESCAN + DF_NO_INSN_RESCAN);
803
804 df_in_progress = true;
805 rest_of_handle_fast_dce ();
2e6be65e
EB
806 df_in_progress = false;
807
6fb5fa3c
DB
808 df_set_flags (old_flags);
809 }
810}
811
2e6be65e 812
9ed7b221
EB
813/* Run a fast DCE pass. */
814
815void
816run_fast_dce (void)
6fb5fa3c 817{
9ed7b221
EB
818 if (flag_dce)
819 rest_of_handle_fast_dce ();
6fb5fa3c
DB
820}
821
822
9ed7b221
EB
823static bool
824gate_fast_dce (void)
6fb5fa3c 825{
7d817ebc
DE
826 return optimize > 0 && flag_dce
827 && dbg_cnt (dce_fast);
6fb5fa3c
DB
828}
829
8ddbbcae 830struct rtl_opt_pass pass_fast_rtl_dce =
6fb5fa3c 831{
8ddbbcae
JH
832 {
833 RTL_PASS,
6fb5fa3c
DB
834 "dce", /* name */
835 gate_fast_dce, /* gate */
836 rest_of_handle_fast_dce, /* execute */
837 NULL, /* sub */
838 NULL, /* next */
839 0, /* static_pass_number */
840 TV_DCE, /* tv_id */
841 0, /* properties_required */
842 0, /* properties_provided */
843 0, /* properties_destroyed */
844 0, /* todo_flags_start */
845 TODO_dump_func |
a36b8a1e 846 TODO_df_finish | TODO_verify_rtl_sharing |
8ddbbcae
JH
847 TODO_ggc_collect /* todo_flags_finish */
848 }
6fb5fa3c 849};
cc806ac1
RS
850
851struct rtl_opt_pass pass_fast_rtl_byte_dce =
852{
853 {
854 RTL_PASS,
855 "byte-dce", /* name */
856 gate_fast_dce, /* gate */
857 rest_of_handle_fast_byte_dce, /* execute */
858 NULL, /* sub */
859 NULL, /* next */
860 0, /* static_pass_number */
861 TV_DCE, /* tv_id */
862 0, /* properties_required */
863 0, /* properties_provided */
864 0, /* properties_destroyed */
865 0, /* todo_flags_start */
866 TODO_dump_func |
867 TODO_df_finish | TODO_verify_rtl_sharing |
868 TODO_ggc_collect /* todo_flags_finish */
869 }
870};