]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/dce.c
Update copyright years.
[thirdparty/gcc.git] / gcc / dce.c
CommitLineData
6fb5fa3c 1/* RTL dead code elimination.
a5544970 2 Copyright (C) 2005-2019 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"
c7131fb2 23#include "backend.h"
6fb5fa3c 24#include "rtl.h"
957060b5
AM
25#include "tree.h"
26#include "predict.h"
c7131fb2 27#include "df.h"
4d0cdd0c 28#include "memmodel.h"
957060b5 29#include "tm_p.h"
957060b5 30#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
60393bbc
AM
31#include "cfgrtl.h"
32#include "cfgbuild.h"
33#include "cfgcleanup.h"
6fb5fa3c 34#include "dce.h"
08df6c0d 35#include "valtrack.h"
6fb5fa3c
DB
36#include "tree-pass.h"
37#include "dbgcnt.h"
38
6fb5fa3c
DB
39
40/* -------------------------------------------------------------------------
41 Core mark/delete routines
42 ------------------------------------------------------------------------- */
43
2e6be65e
EB
44/* True if we are invoked while the df engine is running; in this case,
45 we don't want to reenter it. */
6fb5fa3c
DB
46static bool df_in_progress = false;
47
2da02156
EB
48/* True if we are allowed to alter the CFG in this pass. */
49static bool can_alter_cfg = false;
50
6fb5fa3c
DB
51/* Instructions that have been marked but whose dependencies have not
52 yet been processed. */
0ece9321 53static vec<rtx_insn *> worklist;
6fb5fa3c 54
2e6be65e
EB
55/* Bitmap of instructions marked as needed indexed by INSN_UID. */
56static sbitmap marked;
57
58/* Bitmap obstacks used for block processing by the fast algorithm. */
6fb5fa3c
DB
59static bitmap_obstack dce_blocks_bitmap_obstack;
60static bitmap_obstack dce_tmp_bitmap_obstack;
61
0ece9321 62static bool find_call_stack_args (rtx_call_insn *, bool, bool, bitmap);
6fb5fa3c 63
d4d7f1d1
RS
64/* A subroutine for which BODY is part of the instruction being tested;
65 either the top-level pattern, or an element of a PARALLEL. The
66 instruction is known not to be a bare USE or CLOBBER. */
6fb5fa3c
DB
67
68static bool
d4d7f1d1 69deletable_insn_p_1 (rtx body)
6fb5fa3c 70{
6cad9859 71 switch (GET_CODE (body))
6fb5fa3c 72 {
6fb5fa3c
DB
73 case PREFETCH:
74 case TRAP_IF:
75 /* The UNSPEC case was added here because the ia-64 claims that
76 USEs do not work after reload and generates UNSPECS rather
77 than USEs. Since dce is run after reload we need to avoid
78 deleting these even if they are dead. If it turns out that
79 USEs really do work after reload, the ia-64 should be
80 changed, and the UNSPEC case can be removed. */
81 case UNSPEC:
82 return false;
83
d4d7f1d1 84 default:
1d65f45c 85 return !volatile_refs_p (body);
d4d7f1d1
RS
86 }
87}
88
2e6be65e 89
d4d7f1d1
RS
90/* Return true if INSN is a normal instruction that can be deleted by
91 the DCE pass. */
92
93static bool
0ece9321 94deletable_insn_p (rtx_insn *insn, bool fast, bitmap arg_stores)
d4d7f1d1
RS
95{
96 rtx body, x;
97 int i;
bfac633a 98 df_ref def;
d4d7f1d1 99
5ba5ab9b
KZ
100 if (CALL_P (insn)
101 /* We cannot delete calls inside of the recursive dce because
102 this may cause basic blocks to be deleted and this messes up
103 the rest of the stack of optimization passes. */
104 && (!df_in_progress)
105 /* We cannot delete pure or const sibling calls because it is
106 hard to see the result. */
becfd6e5 107 && (!SIBLING_CALL_P (insn))
5ba5ab9b
KZ
108 /* We can delete dead const or pure calls as long as they do not
109 infinite loop. */
becfd6e5
KZ
110 && (RTL_CONST_OR_PURE_CALL_P (insn)
111 && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
0ece9321
DM
112 return find_call_stack_args (as_a <rtx_call_insn *> (insn), false,
113 fast, arg_stores);
becfd6e5 114
642d55de
EB
115 /* Don't delete jumps, notes and the like. */
116 if (!NONJUMP_INSN_P (insn))
117 return false;
118
2da02156
EB
119 /* Don't delete insns that may throw if we cannot do so. */
120 if (!(cfun->can_delete_dead_exceptions && can_alter_cfg)
121 && !insn_nothrow_p (insn))
642d55de
EB
122 return false;
123
211d71a7 124 /* If INSN sets a global_reg, leave it untouched. */
bfac633a
RS
125 FOR_EACH_INSN_DEF (def, insn)
126 if (HARD_REGISTER_NUM_P (DF_REF_REGNO (def))
127 && global_regs[DF_REF_REGNO (def)])
211d71a7 128 return false;
56873e13
ES
129 /* Initialization of pseudo PIC register should never be removed. */
130 else if (DF_REF_REG (def) == pic_offset_table_rtx
131 && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
132 return false;
211d71a7 133
45399fdc
JJ
134 /* Callee-save restores are needed. */
135 if (RTX_FRAME_RELATED_P (insn)
136 && crtl->shrink_wrapped_separate
137 && find_reg_note (insn, REG_CFA_RESTORE, NULL))
138 return false;
139
d4d7f1d1
RS
140 body = PATTERN (insn);
141 switch (GET_CODE (body))
142 {
143 case USE:
b5b8b0ac 144 case VAR_LOCATION:
d4d7f1d1
RS
145 return false;
146
6fb5fa3c 147 case CLOBBER:
8df47bdf 148 case CLOBBER_HIGH:
6fb5fa3c
DB
149 if (fast)
150 {
151 /* A CLOBBER of a dead pseudo register serves no purpose.
152 That is not necessarily true for hard registers until
153 after reload. */
6cad9859 154 x = XEXP (body, 0);
6fb5fa3c
DB
155 return REG_P (x) && (!HARD_REGISTER_P (x) || reload_completed);
156 }
d4d7f1d1 157 else
6fb5fa3c
DB
158 /* Because of the way that use-def chains are built, it is not
159 possible to tell if the clobber is dead because it can
160 never be the target of a use-def chain. */
161 return false;
162
6cad9859 163 case PARALLEL:
d4d7f1d1
RS
164 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
165 if (!deletable_insn_p_1 (XVECEXP (body, 0, i)))
166 return false;
167 return true;
6cad9859 168
6fb5fa3c 169 default:
d4d7f1d1 170 return deletable_insn_p_1 (body);
6fb5fa3c
DB
171 }
172}
173
174
2e6be65e 175/* Return true if INSN has been marked as needed. */
6fb5fa3c
DB
176
177static inline int
0ece9321 178marked_insn_p (rtx_insn *insn)
6fb5fa3c 179{
50e94c7e
SB
180 /* Artificial defs are always needed and they do not have an insn.
181 We should never see them here. */
182 gcc_assert (insn);
d7c028c0 183 return bitmap_bit_p (marked, INSN_UID (insn));
6fb5fa3c
DB
184}
185
186
187/* If INSN has not yet been marked as needed, mark it now, and add it to
188 the worklist. */
189
190static void
0ece9321 191mark_insn (rtx_insn *insn, bool fast)
6fb5fa3c
DB
192{
193 if (!marked_insn_p (insn))
194 {
195 if (!fast)
9771b263 196 worklist.safe_push (insn);
d7c028c0 197 bitmap_set_bit (marked, INSN_UID (insn));
6fb5fa3c
DB
198 if (dump_file)
199 fprintf (dump_file, " Adding insn %d to worklist\n", INSN_UID (insn));
0196c95e
JJ
200 if (CALL_P (insn)
201 && !df_in_progress
202 && !SIBLING_CALL_P (insn)
203 && (RTL_CONST_OR_PURE_CALL_P (insn)
204 && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
0ece9321 205 find_call_stack_args (as_a <rtx_call_insn *> (insn), true, fast, NULL);
6fb5fa3c
DB
206 }
207}
208
209
210/* A note_stores callback used by mark_nonreg_stores. DATA is the
211 instruction containing DEST. */
212
213static void
7bc980e1 214mark_nonreg_stores_1 (rtx dest, const_rtx pattern, void *data)
6fb5fa3c
DB
215{
216 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest))
8df47bdf
AH
217 {
218 gcc_checking_assert (GET_CODE (pattern) != CLOBBER_HIGH);
219 mark_insn ((rtx_insn *) data, true);
220 }
6fb5fa3c
DB
221}
222
223
224/* A note_stores callback used by mark_nonreg_stores. DATA is the
225 instruction containing DEST. */
226
227static void
7bc980e1 228mark_nonreg_stores_2 (rtx dest, const_rtx pattern, void *data)
6fb5fa3c
DB
229{
230 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest))
8df47bdf
AH
231 {
232 gcc_checking_assert (GET_CODE (pattern) != CLOBBER_HIGH);
233 mark_insn ((rtx_insn *) data, false);
234 }
6fb5fa3c
DB
235}
236
237
238/* Mark INSN if BODY stores to a non-register destination. */
239
240static void
0ece9321 241mark_nonreg_stores (rtx body, rtx_insn *insn, bool fast)
6fb5fa3c
DB
242{
243 if (fast)
244 note_stores (body, mark_nonreg_stores_1, insn);
245 else
246 note_stores (body, mark_nonreg_stores_2, insn);
247}
248
249
7eb87420 250/* Return true if a store to SIZE bytes, starting OFF bytes from stack pointer,
2e0642cd
JJ
251 is a call argument store, and clear corresponding bits from SP_BYTES
252 bitmap if it is. */
253
254static bool
7eb87420
RS
255check_argument_store (HOST_WIDE_INT size, HOST_WIDE_INT off,
256 HOST_WIDE_INT min_sp_off, HOST_WIDE_INT max_sp_off,
257 bitmap sp_bytes)
2e0642cd
JJ
258{
259 HOST_WIDE_INT byte;
7eb87420 260 for (byte = off; byte < off + size; byte++)
2e0642cd
JJ
261 {
262 if (byte < min_sp_off
263 || byte >= max_sp_off
264 || !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
265 return false;
266 }
267 return true;
268}
269
270
0196c95e
JJ
271/* Try to find all stack stores of CALL_INSN arguments if
272 ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found
273 and it is therefore safe to eliminate the call, return true,
274 otherwise return false. This function should be first called
275 with DO_MARK false, and only when the CALL_INSN is actually
276 going to be marked called again with DO_MARK true. */
277
278static bool
0ece9321 279find_call_stack_args (rtx_call_insn *call_insn, bool do_mark, bool fast,
0196c95e
JJ
280 bitmap arg_stores)
281{
0ece9321
DM
282 rtx p;
283 rtx_insn *insn, *prev_insn;
0196c95e
JJ
284 bool ret;
285 HOST_WIDE_INT min_sp_off, max_sp_off;
286 bitmap sp_bytes;
287
288 gcc_assert (CALL_P (call_insn));
289 if (!ACCUMULATE_OUTGOING_ARGS)
290 return true;
291
292 if (!do_mark)
293 {
294 gcc_assert (arg_stores);
295 bitmap_clear (arg_stores);
296 }
297
298 min_sp_off = INTTYPE_MAXIMUM (HOST_WIDE_INT);
299 max_sp_off = 0;
300
301 /* First determine the minimum and maximum offset from sp for
302 stored arguments. */
303 for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
304 if (GET_CODE (XEXP (p, 0)) == USE
305 && MEM_P (XEXP (XEXP (p, 0), 0)))
306 {
f5541398
RS
307 rtx mem = XEXP (XEXP (p, 0), 0), addr;
308 HOST_WIDE_INT off = 0, size;
d05d7551 309 if (!MEM_SIZE_KNOWN_P (mem) || !MEM_SIZE (mem).is_constant (&size))
0196c95e
JJ
310 return false;
311 addr = XEXP (mem, 0);
312 if (GET_CODE (addr) == PLUS
313 && REG_P (XEXP (addr, 0))
314 && CONST_INT_P (XEXP (addr, 1)))
315 {
316 off = INTVAL (XEXP (addr, 1));
317 addr = XEXP (addr, 0);
318 }
319 if (addr != stack_pointer_rtx)
320 {
321 if (!REG_P (addr))
322 return false;
323 /* If not fast, use chains to see if addr wasn't set to
324 sp + offset. */
325 if (!fast)
326 {
bfac633a 327 df_ref use;
0196c95e
JJ
328 struct df_link *defs;
329 rtx set;
330
bfac633a
RS
331 FOR_EACH_INSN_USE (use, call_insn)
332 if (rtx_equal_p (addr, DF_REF_REG (use)))
0196c95e
JJ
333 break;
334
bfac633a 335 if (use == NULL)
0196c95e
JJ
336 return false;
337
bfac633a 338 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
0196c95e
JJ
339 if (! DF_REF_IS_ARTIFICIAL (defs->ref))
340 break;
341
342 if (defs == NULL)
343 return false;
344
345 set = single_set (DF_REF_INSN (defs->ref));
346 if (!set)
347 return false;
348
349 if (GET_CODE (SET_SRC (set)) != PLUS
350 || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
351 || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
352 return false;
353
354 off += INTVAL (XEXP (SET_SRC (set), 1));
355 }
356 else
357 return false;
358 }
359 min_sp_off = MIN (min_sp_off, off);
f5541398 360 max_sp_off = MAX (max_sp_off, off + size);
0196c95e
JJ
361 }
362
363 if (min_sp_off >= max_sp_off)
364 return true;
365 sp_bytes = BITMAP_ALLOC (NULL);
366
367 /* Set bits in SP_BYTES bitmap for bytes relative to sp + min_sp_off
368 which contain arguments. Checking has been done in the previous
369 loop. */
370 for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
371 if (GET_CODE (XEXP (p, 0)) == USE
372 && MEM_P (XEXP (XEXP (p, 0), 0)))
373 {
374 rtx mem = XEXP (XEXP (p, 0), 0), addr;
d05d7551
RS
375 HOST_WIDE_INT off = 0, byte, size;
376 /* Checked in the previous iteration. */
377 size = MEM_SIZE (mem).to_constant ();
0196c95e
JJ
378 addr = XEXP (mem, 0);
379 if (GET_CODE (addr) == PLUS
380 && REG_P (XEXP (addr, 0))
381 && CONST_INT_P (XEXP (addr, 1)))
382 {
383 off = INTVAL (XEXP (addr, 1));
384 addr = XEXP (addr, 0);
385 }
386 if (addr != stack_pointer_rtx)
387 {
bfac633a 388 df_ref use;
0196c95e
JJ
389 struct df_link *defs;
390 rtx set;
391
bfac633a
RS
392 FOR_EACH_INSN_USE (use, call_insn)
393 if (rtx_equal_p (addr, DF_REF_REG (use)))
0196c95e
JJ
394 break;
395
bfac633a 396 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
0196c95e
JJ
397 if (! DF_REF_IS_ARTIFICIAL (defs->ref))
398 break;
399
400 set = single_set (DF_REF_INSN (defs->ref));
401 off += INTVAL (XEXP (SET_SRC (set), 1));
402 }
d05d7551 403 for (byte = off; byte < off + size; byte++)
0196c95e 404 {
821bb7f8
RG
405 if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
406 gcc_unreachable ();
0196c95e
JJ
407 }
408 }
409
410 /* Walk backwards, looking for argument stores. The search stops
750900db 411 when seeing another call, sp adjustment or memory store other than
0196c95e
JJ
412 argument store. */
413 ret = false;
414 for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
415 {
416 rtx set, mem, addr;
2e0642cd 417 HOST_WIDE_INT off;
0196c95e
JJ
418
419 if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn)))
0ece9321 420 prev_insn = NULL;
0196c95e
JJ
421 else
422 prev_insn = PREV_INSN (insn);
423
424 if (CALL_P (insn))
425 break;
426
2e0642cd 427 if (!NONDEBUG_INSN_P (insn))
0196c95e
JJ
428 continue;
429
430 set = single_set (insn);
431 if (!set || SET_DEST (set) == stack_pointer_rtx)
432 break;
433
434 if (!MEM_P (SET_DEST (set)))
435 continue;
436
437 mem = SET_DEST (set);
438 addr = XEXP (mem, 0);
439 off = 0;
440 if (GET_CODE (addr) == PLUS
441 && REG_P (XEXP (addr, 0))
442 && CONST_INT_P (XEXP (addr, 1)))
443 {
444 off = INTVAL (XEXP (addr, 1));
445 addr = XEXP (addr, 0);
446 }
447 if (addr != stack_pointer_rtx)
448 {
449 if (!REG_P (addr))
450 break;
451 if (!fast)
452 {
bfac633a 453 df_ref use;
0196c95e
JJ
454 struct df_link *defs;
455 rtx set;
456
bfac633a
RS
457 FOR_EACH_INSN_USE (use, insn)
458 if (rtx_equal_p (addr, DF_REF_REG (use)))
0196c95e
JJ
459 break;
460
bfac633a 461 if (use == NULL)
0196c95e
JJ
462 break;
463
bfac633a 464 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
0196c95e
JJ
465 if (! DF_REF_IS_ARTIFICIAL (defs->ref))
466 break;
467
468 if (defs == NULL)
469 break;
470
471 set = single_set (DF_REF_INSN (defs->ref));
472 if (!set)
473 break;
474
475 if (GET_CODE (SET_SRC (set)) != PLUS
476 || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
477 || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
478 break;
479
480 off += INTVAL (XEXP (SET_SRC (set), 1));
481 }
482 else
483 break;
484 }
485
d05d7551 486 HOST_WIDE_INT size;
7eb87420 487 if (!MEM_SIZE_KNOWN_P (mem)
d05d7551
RS
488 || !MEM_SIZE (mem).is_constant (&size)
489 || !check_argument_store (size, off, min_sp_off,
2e0642cd 490 max_sp_off, sp_bytes))
0196c95e
JJ
491 break;
492
0196c95e
JJ
493 if (!deletable_insn_p (insn, fast, NULL))
494 break;
495
496 if (do_mark)
497 mark_insn (insn, fast);
498 else
499 bitmap_set_bit (arg_stores, INSN_UID (insn));
500
501 if (bitmap_empty_p (sp_bytes))
502 {
503 ret = true;
504 break;
505 }
506 }
507
508 BITMAP_FREE (sp_bytes);
509 if (!ret && arg_stores)
510 bitmap_clear (arg_stores);
511
512 return ret;
513}
514
515
885c9b5d
EB
516/* Remove all REG_EQUAL and REG_EQUIV notes referring to the registers INSN
517 writes to. */
6fb5fa3c
DB
518
519static void
0ece9321 520remove_reg_equal_equiv_notes_for_defs (rtx_insn *insn)
6fb5fa3c 521{
bfac633a 522 df_ref def;
885c9b5d 523
bfac633a
RS
524 FOR_EACH_INSN_DEF (def, insn)
525 remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (def));
6fb5fa3c
DB
526}
527
a7a110bb
AO
528/* Scan all BBs for debug insns and reset those that reference values
529 defined in unmarked insns. */
530
531static void
532reset_unmarked_insns_debug_uses (void)
533{
534 basic_block bb;
0ece9321 535 rtx_insn *insn, *next;
a7a110bb 536
4f42035e 537 FOR_EACH_BB_REVERSE_FN (bb, cfun)
a7a110bb
AO
538 FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next)
539 if (DEBUG_INSN_P (insn))
540 {
bfac633a 541 df_ref use;
a7a110bb 542
bfac633a 543 FOR_EACH_INSN_USE (use, insn)
a7a110bb 544 {
a7a110bb
AO
545 struct df_link *defs;
546 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
547 {
0ece9321 548 rtx_insn *ref_insn;
a7a110bb
AO
549 if (DF_REF_IS_ARTIFICIAL (defs->ref))
550 continue;
8ced31fe
JJ
551 ref_insn = DF_REF_INSN (defs->ref);
552 if (!marked_insn_p (ref_insn))
a7a110bb
AO
553 break;
554 }
555 if (!defs)
556 continue;
557 /* ??? FIXME could we propagate the values assigned to
558 each of the DEFs? */
559 INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
560 df_insn_rescan_debug_internal (insn);
8ced31fe 561 break;
a7a110bb
AO
562 }
563 }
564}
6fb5fa3c 565
9ed7b221 566/* Delete every instruction that hasn't been marked. */
6fb5fa3c
DB
567
568static void
569delete_unmarked_insns (void)
570{
571 basic_block bb;
0ece9321 572 rtx_insn *insn, *next;
5ba5ab9b 573 bool must_clean = false;
6fb5fa3c 574
4f42035e 575 FOR_EACH_BB_REVERSE_FN (bb, cfun)
cd3f1729 576 FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next)
a7a110bb 577 if (NONDEBUG_INSN_P (insn))
6fb5fa3c 578 {
6f21dc3c
JJ
579 rtx turn_into_use = NULL_RTX;
580
9ed7b221 581 /* Always delete no-op moves. */
6fb5fa3c 582 if (noop_move_p (insn))
6f21dc3c
JJ
583 {
584 if (RTX_FRAME_RELATED_P (insn))
585 turn_into_use
586 = find_reg_note (insn, REG_CFA_RESTORE, NULL);
587 if (turn_into_use && REG_P (XEXP (turn_into_use, 0)))
588 turn_into_use = XEXP (turn_into_use, 0);
589 else
590 turn_into_use = NULL_RTX;
591 }
9ed7b221 592
9ed7b221 593 /* Otherwise rely only on the DCE algorithm. */
6fb5fa3c
DB
594 else if (marked_insn_p (insn))
595 continue;
596
cd3f1729
KZ
597 /* Beware that reaching a dbg counter limit here can result
598 in miscompiled file. This occurs when a group of insns
599 must be deleted together, typically because the kept insn
600 depends on the output from the deleted insn. Deleting
601 this insns in reverse order (both at the bb level and
602 when looking at the blocks) minimizes this, but does not
603 eliminate it, since it is possible for the using insn to
604 be top of a block and the producer to be at the bottom of
605 the block. However, in most cases this will only result
606 in an uninitialized use of an insn that is dead anyway.
607
608 However, there is one rare case that will cause a
609 miscompile: deletion of non-looping pure and constant
610 calls on a machine where ACCUMULATE_OUTGOING_ARGS is true.
611 In this case it is possible to remove the call, but leave
612 the argument pushes to the stack. Because of the changes
613 to the stack pointer, this will almost always lead to a
614 miscompile. */
6fb5fa3c
DB
615 if (!dbg_cnt (dce))
616 continue;
617
618 if (dump_file)
619 fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
620
885c9b5d 621 /* Before we delete the insn we have to remove the REG_EQUAL notes
9ed7b221 622 for the destination regs in order to avoid dangling notes. */
885c9b5d 623 remove_reg_equal_equiv_notes_for_defs (insn);
6fb5fa3c 624
5ba5ab9b
KZ
625 /* If a pure or const call is deleted, this may make the cfg
626 have unreachable blocks. We rememeber this and call
627 delete_unreachable_blocks at the end. */
628 if (CALL_P (insn))
629 must_clean = true;
630
6f21dc3c
JJ
631 if (turn_into_use)
632 {
633 /* Don't remove frame related noop moves if they cary
634 REG_CFA_RESTORE note, while we don't need to emit any code,
635 we need it to emit the CFI restore note. */
636 PATTERN (insn)
637 = gen_rtx_USE (GET_MODE (turn_into_use), turn_into_use);
638 INSN_CODE (insn) = -1;
639 df_insn_rescan (insn);
640 }
641 else
642 /* Now delete the insn. */
643 delete_insn_and_edges (insn);
6fb5fa3c 644 }
5ba5ab9b
KZ
645
646 /* Deleted a pure or const call. */
647 if (must_clean)
648 delete_unreachable_blocks ();
6fb5fa3c
DB
649}
650
651
6fb5fa3c
DB
652/* Go through the instructions and mark those whose necessity is not
653 dependent on inter-instruction information. Make sure all other
654 instructions are not marked. */
655
656static void
657prescan_insns_for_dce (bool fast)
658{
659 basic_block bb;
0ece9321 660 rtx_insn *insn, *prev;
0196c95e
JJ
661 bitmap arg_stores = NULL;
662
6fb5fa3c
DB
663 if (dump_file)
664 fprintf (dump_file, "Finding needed instructions:\n");
0196c95e
JJ
665
666 if (!df_in_progress && ACCUMULATE_OUTGOING_ARGS)
667 arg_stores = BITMAP_ALLOC (NULL);
668
11cd3bed 669 FOR_EACH_BB_FN (bb, cfun)
0196c95e
JJ
670 {
671 FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev)
a7a110bb 672 if (NONDEBUG_INSN_P (insn))
0196c95e
JJ
673 {
674 /* Don't mark argument stores now. They will be marked
675 if needed when the associated CALL is marked. */
676 if (arg_stores && bitmap_bit_p (arg_stores, INSN_UID (insn)))
677 continue;
678 if (deletable_insn_p (insn, fast, arg_stores))
679 mark_nonreg_stores (PATTERN (insn), insn, fast);
680 else
681 mark_insn (insn, fast);
682 }
683 /* find_call_stack_args only looks at argument stores in the
684 same bb. */
685 if (arg_stores)
686 bitmap_clear (arg_stores);
687 }
688
689 if (arg_stores)
690 BITMAP_FREE (arg_stores);
6fb5fa3c
DB
691
692 if (dump_file)
693 fprintf (dump_file, "Finished finding needed instructions:\n");
694}
695
696
697/* UD-based DSE routines. */
698
6ed3da00 699/* Mark instructions that define artificially-used registers, such as
6fb5fa3c
DB
700 the frame pointer and the stack pointer. */
701
702static void
703mark_artificial_uses (void)
704{
705 basic_block bb;
706 struct df_link *defs;
292321a5 707 df_ref use;
6fb5fa3c 708
04a90bec 709 FOR_ALL_BB_FN (bb, cfun)
292321a5
RS
710 FOR_EACH_ARTIFICIAL_USE (use, bb->index)
711 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
712 if (!DF_REF_IS_ARTIFICIAL (defs->ref))
713 mark_insn (DF_REF_INSN (defs->ref), false);
6fb5fa3c
DB
714}
715
2e6be65e 716
6fb5fa3c
DB
717/* Mark every instruction that defines a register value that INSN uses. */
718
719static void
0ece9321 720mark_reg_dependencies (rtx_insn *insn)
6fb5fa3c
DB
721{
722 struct df_link *defs;
bfac633a 723 df_ref use;
6fb5fa3c 724
b5b8b0ac
AO
725 if (DEBUG_INSN_P (insn))
726 return;
727
bfac633a 728 FOR_EACH_INSN_USE (use, insn)
6fb5fa3c 729 {
6fb5fa3c
DB
730 if (dump_file)
731 {
732 fprintf (dump_file, "Processing use of ");
733 print_simple_rtl (dump_file, DF_REF_REG (use));
734 fprintf (dump_file, " in insn %d:\n", INSN_UID (insn));
735 }
736 for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
50e94c7e
SB
737 if (! DF_REF_IS_ARTIFICIAL (defs->ref))
738 mark_insn (DF_REF_INSN (defs->ref), false);
6fb5fa3c
DB
739 }
740}
741
742
2e6be65e
EB
743/* Initialize global variables for a new DCE pass. */
744
6fb5fa3c 745static void
2e6be65e
EB
746init_dce (bool fast)
747{
748 if (!df_in_progress)
749 {
750 if (!fast)
7b19209f
SB
751 {
752 df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
753 df_chain_add_problem (DF_UD_CHAIN);
754 }
2e6be65e
EB
755 df_analyze ();
756 }
757
758 if (dump_file)
759 df_dump (dump_file);
760
761 if (fast)
762 {
763 bitmap_obstack_initialize (&dce_blocks_bitmap_obstack);
764 bitmap_obstack_initialize (&dce_tmp_bitmap_obstack);
2da02156 765 can_alter_cfg = false;
2e6be65e 766 }
2da02156
EB
767 else
768 can_alter_cfg = true;
2e6be65e
EB
769
770 marked = sbitmap_alloc (get_max_uid () + 1);
f61e445a 771 bitmap_clear (marked);
2e6be65e
EB
772}
773
774
775/* Free the data allocated by init_dce. */
776
777static void
778fini_dce (bool fast)
6fb5fa3c
DB
779{
780 sbitmap_free (marked);
2e6be65e
EB
781
782 if (fast)
783 {
784 bitmap_obstack_release (&dce_blocks_bitmap_obstack);
785 bitmap_obstack_release (&dce_tmp_bitmap_obstack);
786 }
6fb5fa3c
DB
787}
788
789
790/* UD-chain based DCE. */
791
792static unsigned int
793rest_of_handle_ud_dce (void)
794{
0ece9321 795 rtx_insn *insn;
6fb5fa3c 796
6fb5fa3c
DB
797 init_dce (false);
798
799 prescan_insns_for_dce (false);
800 mark_artificial_uses ();
9771b263 801 while (worklist.length () > 0)
6fb5fa3c 802 {
9771b263 803 insn = worklist.pop ();
6fb5fa3c
DB
804 mark_reg_dependencies (insn);
805 }
9771b263 806 worklist.release ();
2e6be65e 807
36f52e8f 808 if (MAY_HAVE_DEBUG_BIND_INSNS)
a7a110bb
AO
809 reset_unmarked_insns_debug_uses ();
810
6fb5fa3c
DB
811 /* Before any insns are deleted, we must remove the chains since
812 they are not bidirectional. */
813 df_remove_problem (df_chain);
814 delete_unmarked_insns ();
815
2e6be65e 816 fini_dce (false);
6fb5fa3c
DB
817 return 0;
818}
819
820
17795822
TS
821namespace {
822
823const pass_data pass_data_ud_rtl_dce =
6fb5fa3c 824{
27a4cd48
DM
825 RTL_PASS, /* type */
826 "ud_dce", /* name */
827 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
828 TV_DCE, /* tv_id */
829 0, /* properties_required */
830 0, /* properties_provided */
831 0, /* properties_destroyed */
832 0, /* todo_flags_start */
3bea341f 833 TODO_df_finish, /* todo_flags_finish */
6fb5fa3c
DB
834};
835
17795822 836class pass_ud_rtl_dce : public rtl_opt_pass
27a4cd48
DM
837{
838public:
c3284718
RS
839 pass_ud_rtl_dce (gcc::context *ctxt)
840 : rtl_opt_pass (pass_data_ud_rtl_dce, ctxt)
27a4cd48
DM
841 {}
842
843 /* opt_pass methods: */
1a3d085c
TS
844 virtual bool gate (function *)
845 {
846 return optimize > 1 && flag_dce && dbg_cnt (dce_ud);
847 }
848
be55bfe6
TS
849 virtual unsigned int execute (function *)
850 {
851 return rest_of_handle_ud_dce ();
852 }
27a4cd48
DM
853
854}; // class pass_ud_rtl_dce
855
17795822
TS
856} // anon namespace
857
27a4cd48
DM
858rtl_opt_pass *
859make_pass_ud_rtl_dce (gcc::context *ctxt)
860{
861 return new pass_ud_rtl_dce (ctxt);
862}
863
2e6be65e 864
6fb5fa3c
DB
865/* -------------------------------------------------------------------------
866 Fast DCE functions
867 ------------------------------------------------------------------------- */
868
cc806ac1
RS
869/* Process basic block BB. Return true if the live_in set has
870 changed. REDO_OUT is true if the info at the bottom of the block
871 needs to be recalculated before starting. AU is the proper set of
e9f950ba
AO
872 artificial uses. Track global substitution of uses of dead pseudos
873 in debug insns using GLOBAL_DEBUG. */
6fb5fa3c
DB
874
875static bool
e9f950ba
AO
876word_dce_process_block (basic_block bb, bool redo_out,
877 struct dead_debug_global *global_debug)
6fb5fa3c
DB
878{
879 bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
0ece9321 880 rtx_insn *insn;
6fb5fa3c 881 bool block_changed;
e9f950ba 882 struct dead_debug_local debug;
6fb5fa3c
DB
883
884 if (redo_out)
885 {
886 /* Need to redo the live_out set of this block if when one of
887 the succs of this block has had a change in it live in
888 set. */
889 edge e;
890 edge_iterator ei;
8d074192
BS
891 df_confluence_function_n con_fun_n = df_word_lr->problem->con_fun_n;
892 bitmap_clear (DF_WORD_LR_OUT (bb));
6fb5fa3c
DB
893 FOR_EACH_EDGE (e, ei, bb->succs)
894 (*con_fun_n) (e);
895 }
896
897 if (dump_file)
898 {
899 fprintf (dump_file, "processing block %d live out = ", bb->index);
8d074192 900 df_print_word_regset (dump_file, DF_WORD_LR_OUT (bb));
6fb5fa3c
DB
901 }
902
8d074192 903 bitmap_copy (local_live, DF_WORD_LR_OUT (bb));
e9f950ba 904 dead_debug_local_init (&debug, NULL, global_debug);
cc806ac1
RS
905
906 FOR_BB_INSNS_REVERSE (bb, insn)
1adbb361
AO
907 if (DEBUG_INSN_P (insn))
908 {
bfac633a
RS
909 df_ref use;
910 FOR_EACH_INSN_USE (use, insn)
911 if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER
cf098191
RS
912 && known_eq (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (use))),
913 2 * UNITS_PER_WORD)
bfac633a
RS
914 && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use))
915 && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use) + 1))
916 dead_debug_add (&debug, use, DF_REF_REGNO (use));
1adbb361
AO
917 }
918 else if (INSN_P (insn))
cc806ac1 919 {
8d074192 920 bool any_changed;
1adbb361 921
cc806ac1
RS
922 /* No matter if the instruction is needed or not, we remove
923 any regno in the defs from the live set. */
8d074192
BS
924 any_changed = df_word_lr_simulate_defs (insn, local_live);
925 if (any_changed)
926 mark_insn (insn, true);
cc806ac1
RS
927
928 /* On the other hand, we do not allow the dead uses to set
929 anything in local_live. */
930 if (marked_insn_p (insn))
8d074192 931 df_word_lr_simulate_uses (insn, local_live);
6f9e260c 932
39bc0f01 933 /* Insert debug temps for dead REGs used in subsequent debug
6f9e260c
AO
934 insns. We may have to emit a debug temp even if the insn
935 was marked, in case the debug use was after the point of
936 death. */
937 if (debug.used && !bitmap_empty_p (debug.used))
1adbb361 938 {
bfac633a 939 df_ref def;
1adbb361 940
bfac633a
RS
941 FOR_EACH_INSN_DEF (def, insn)
942 dead_debug_insert_temp (&debug, DF_REF_REGNO (def), insn,
85d87497
JJ
943 marked_insn_p (insn)
944 && !control_flow_insn_p (insn)
945 ? DEBUG_TEMP_AFTER_WITH_REG_FORCE
946 : DEBUG_TEMP_BEFORE_WITH_VALUE);
1adbb361
AO
947 }
948
cc806ac1
RS
949 if (dump_file)
950 {
b8698a0f 951 fprintf (dump_file, "finished processing insn %d live out = ",
cc806ac1 952 INSN_UID (insn));
8d074192 953 df_print_word_regset (dump_file, local_live);
cc806ac1
RS
954 }
955 }
b8698a0f 956
8d074192 957 block_changed = !bitmap_equal_p (local_live, DF_WORD_LR_IN (bb));
cc806ac1 958 if (block_changed)
8d074192
BS
959 bitmap_copy (DF_WORD_LR_IN (bb), local_live);
960
e9f950ba 961 dead_debug_local_finish (&debug, NULL);
cc806ac1
RS
962 BITMAP_FREE (local_live);
963 return block_changed;
964}
965
966
967/* Process basic block BB. Return true if the live_in set has
968 changed. REDO_OUT is true if the info at the bottom of the block
969 needs to be recalculated before starting. AU is the proper set of
e9f950ba
AO
970 artificial uses. Track global substitution of uses of dead pseudos
971 in debug insns using GLOBAL_DEBUG. */
cc806ac1
RS
972
973static bool
e9f950ba
AO
974dce_process_block (basic_block bb, bool redo_out, bitmap au,
975 struct dead_debug_global *global_debug)
cc806ac1
RS
976{
977 bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
0ece9321 978 rtx_insn *insn;
cc806ac1 979 bool block_changed;
bfac633a 980 df_ref def;
e9f950ba 981 struct dead_debug_local debug;
6fb5fa3c 982
cc806ac1 983 if (redo_out)
6fb5fa3c 984 {
cc806ac1
RS
985 /* Need to redo the live_out set of this block if when one of
986 the succs of this block has had a change in it live in
987 set. */
988 edge e;
989 edge_iterator ei;
990 df_confluence_function_n con_fun_n = df_lr->problem->con_fun_n;
991 bitmap_clear (DF_LR_OUT (bb));
992 FOR_EACH_EDGE (e, ei, bb->succs)
993 (*con_fun_n) (e);
6fb5fa3c
DB
994 }
995
cc806ac1 996 if (dump_file)
6fb5fa3c 997 {
fafe34f9 998 fprintf (dump_file, "processing block %d lr out = ", bb->index);
cc806ac1 999 df_print_regset (dump_file, DF_LR_OUT (bb));
6fb5fa3c
DB
1000 }
1001
cc806ac1
RS
1002 bitmap_copy (local_live, DF_LR_OUT (bb));
1003
02b47899 1004 df_simulate_initialize_backwards (bb, local_live);
e9f950ba 1005 dead_debug_local_init (&debug, NULL, global_debug);
541d3103 1006
6fb5fa3c 1007 FOR_BB_INSNS_REVERSE (bb, insn)
1adbb361
AO
1008 if (DEBUG_INSN_P (insn))
1009 {
bfac633a
RS
1010 df_ref use;
1011 FOR_EACH_INSN_USE (use, insn)
1012 if (!bitmap_bit_p (local_live, DF_REF_REGNO (use))
1013 && !bitmap_bit_p (au, DF_REF_REGNO (use)))
1014 dead_debug_add (&debug, use, DF_REF_REGNO (use));
1adbb361
AO
1015 }
1016 else if (INSN_P (insn))
6fb5fa3c 1017 {
f251709a 1018 bool needed = marked_insn_p (insn);
9ed7b221
EB
1019
1020 /* The insn is needed if there is someone who uses the output. */
f251709a 1021 if (!needed)
bfac633a
RS
1022 FOR_EACH_INSN_DEF (def, insn)
1023 if (bitmap_bit_p (local_live, DF_REF_REGNO (def))
1024 || bitmap_bit_p (au, DF_REF_REGNO (def)))
39bc0f01
AO
1025 {
1026 needed = true;
1027 mark_insn (insn, true);
1028 break;
1029 }
b8698a0f 1030
6fb5fa3c
DB
1031 /* No matter if the instruction is needed or not, we remove
1032 any regno in the defs from the live set. */
1033 df_simulate_defs (insn, local_live);
1034
1035 /* On the other hand, we do not allow the dead uses to set
1036 anything in local_live. */
f251709a 1037 if (needed)
6fb5fa3c 1038 df_simulate_uses (insn, local_live);
6f9e260c 1039
39bc0f01 1040 /* Insert debug temps for dead REGs used in subsequent debug
6f9e260c
AO
1041 insns. We may have to emit a debug temp even if the insn
1042 was marked, in case the debug use was after the point of
1043 death. */
1044 if (debug.used && !bitmap_empty_p (debug.used))
bfac633a
RS
1045 FOR_EACH_INSN_DEF (def, insn)
1046 dead_debug_insert_temp (&debug, DF_REF_REGNO (def), insn,
85d87497
JJ
1047 needed && !control_flow_insn_p (insn)
1048 ? DEBUG_TEMP_AFTER_WITH_REG_FORCE
1049 : DEBUG_TEMP_BEFORE_WITH_VALUE);
6fb5fa3c 1050 }
b8698a0f 1051
e9f950ba 1052 dead_debug_local_finish (&debug, NULL);
02b47899 1053 df_simulate_finalize_backwards (bb, local_live);
6fb5fa3c
DB
1054
1055 block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb));
1056 if (block_changed)
1057 bitmap_copy (DF_LR_IN (bb), local_live);
1058
1059 BITMAP_FREE (local_live);
1060 return block_changed;
1061}
1062
2e6be65e 1063
8d074192
BS
1064/* Perform fast DCE once initialization is done. If WORD_LEVEL is
1065 true, use the word level dce, otherwise do it at the pseudo
cc806ac1 1066 level. */
2e6be65e 1067
6fb5fa3c 1068static void
8d074192 1069fast_dce (bool word_level)
6fb5fa3c
DB
1070{
1071 int *postorder = df_get_postorder (DF_BACKWARD);
1072 int n_blocks = df_get_n_blocks (DF_BACKWARD);
6fb5fa3c
DB
1073 /* The set of blocks that have been seen on this iteration. */
1074 bitmap processed = BITMAP_ALLOC (&dce_blocks_bitmap_obstack);
1075 /* The set of blocks that need to have the out vectors reset because
1076 the in of one of their successors has changed. */
1077 bitmap redo_out = BITMAP_ALLOC (&dce_blocks_bitmap_obstack);
1078 bitmap all_blocks = BITMAP_ALLOC (&dce_blocks_bitmap_obstack);
1079 bool global_changed = true;
cc806ac1
RS
1080
1081 /* These regs are considered always live so if they end up dying
1082 because of some def, we need to bring the back again. Calling
1083 df_simulate_fixup_sets has the disadvantage of calling
1084 bb_has_eh_pred once per insn, so we cache the information
1085 here. */
a7e3698d
JH
1086 bitmap au = &df->regular_block_artificial_uses;
1087 bitmap au_eh = &df->eh_block_artificial_uses;
9ed7b221 1088 int i;
e9f950ba 1089 struct dead_debug_global global_debug;
6fb5fa3c
DB
1090
1091 prescan_insns_for_dce (true);
1092
1093 for (i = 0; i < n_blocks; i++)
1094 bitmap_set_bit (all_blocks, postorder[i]);
1095
e9f950ba
AO
1096 dead_debug_global_init (&global_debug, NULL);
1097
6fb5fa3c
DB
1098 while (global_changed)
1099 {
1100 global_changed = false;
9ed7b221 1101
6fb5fa3c
DB
1102 for (i = 0; i < n_blocks; i++)
1103 {
1104 int index = postorder[i];
06e28de2 1105 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, index);
6fb5fa3c
DB
1106 bool local_changed;
1107
1108 if (index < NUM_FIXED_BLOCKS)
1109 {
1110 bitmap_set_bit (processed, index);
1111 continue;
1112 }
1113
8d074192 1114 if (word_level)
b8698a0f 1115 local_changed
e9f950ba
AO
1116 = word_dce_process_block (bb, bitmap_bit_p (redo_out, index),
1117 &global_debug);
cc806ac1 1118 else
b8698a0f 1119 local_changed
cc806ac1 1120 = dce_process_block (bb, bitmap_bit_p (redo_out, index),
e9f950ba
AO
1121 bb_has_eh_pred (bb) ? au_eh : au,
1122 &global_debug);
6fb5fa3c 1123 bitmap_set_bit (processed, index);
b8698a0f 1124
6fb5fa3c
DB
1125 if (local_changed)
1126 {
1127 edge e;
1128 edge_iterator ei;
1129 FOR_EACH_EDGE (e, ei, bb->preds)
1130 if (bitmap_bit_p (processed, e->src->index))
1131 /* Be tricky about when we need to iterate the
1132 analysis. We only have redo the analysis if the
1133 bitmaps change at the top of a block that is the
1134 entry to a loop. */
1135 global_changed = true;
1136 else
1137 bitmap_set_bit (redo_out, e->src->index);
1138 }
1139 }
b8698a0f 1140
6fb5fa3c
DB
1141 if (global_changed)
1142 {
1143 /* Turn off the RUN_DCE flag to prevent recursive calls to
1144 dce. */
1145 int old_flag = df_clear_flags (DF_LR_RUN_DCE);
1146
1147 /* So something was deleted that requires a redo. Do it on
1148 the cheap. */
1149 delete_unmarked_insns ();
f61e445a 1150 bitmap_clear (marked);
6fb5fa3c
DB
1151 bitmap_clear (processed);
1152 bitmap_clear (redo_out);
b8698a0f 1153
6fb5fa3c
DB
1154 /* We do not need to rescan any instructions. We only need
1155 to redo the dataflow equations for the blocks that had a
1156 change at the top of the block. Then we need to redo the
b8698a0f 1157 iteration. */
8d074192
BS
1158 if (word_level)
1159 df_analyze_problem (df_word_lr, all_blocks, postorder, n_blocks);
cc806ac1
RS
1160 else
1161 df_analyze_problem (df_lr, all_blocks, postorder, n_blocks);
6fb5fa3c
DB
1162
1163 if (old_flag & DF_LR_RUN_DCE)
1164 df_set_flags (DF_LR_RUN_DCE);
9ed7b221 1165
6fb5fa3c
DB
1166 prescan_insns_for_dce (true);
1167 }
6fb5fa3c
DB
1168 }
1169
e9f950ba
AO
1170 dead_debug_global_finish (&global_debug, NULL);
1171
6fb5fa3c
DB
1172 delete_unmarked_insns ();
1173
1174 BITMAP_FREE (processed);
1175 BITMAP_FREE (redo_out);
1176 BITMAP_FREE (all_blocks);
1177}
1178
1179
cc806ac1 1180/* Fast register level DCE. */
6fb5fa3c
DB
1181
1182static unsigned int
1183rest_of_handle_fast_dce (void)
1184{
1185 init_dce (true);
cc806ac1
RS
1186 fast_dce (false);
1187 fini_dce (true);
1188 return 0;
1189}
1190
1191
1192/* Fast byte level DCE. */
1193
8d074192
BS
1194void
1195run_word_dce (void)
cc806ac1 1196{
25aef556
BS
1197 int old_flags;
1198
1199 if (!flag_dce)
1200 return;
1201
8d074192 1202 timevar_push (TV_DCE);
25aef556 1203 old_flags = df_clear_flags (DF_DEFER_INSN_RESCAN + DF_NO_INSN_RESCAN);
8d074192 1204 df_word_lr_add_problem ();
cc806ac1
RS
1205 init_dce (true);
1206 fast_dce (true);
2e6be65e 1207 fini_dce (true);
25aef556 1208 df_set_flags (old_flags);
8d074192 1209 timevar_pop (TV_DCE);
6fb5fa3c
DB
1210}
1211
1212
1213/* This is an internal call that is used by the df live register
1214 problem to run fast dce as a side effect of creating the live
1215 information. The stack is organized so that the lr problem is run,
1216 this pass is run, which updates the live info and the df scanning
1217 info, and then returns to allow the rest of the problems to be run.
1218
1219 This can be called by elsewhere but it will not update the bit
2e6be65e 1220 vectors for any other problems than LR. */
6fb5fa3c
DB
1221
1222void
1223run_fast_df_dce (void)
1224{
1225 if (flag_dce)
1226 {
1227 /* If dce is able to delete something, it has to happen
1228 immediately. Otherwise there will be problems handling the
1229 eq_notes. */
81f40b79
ILT
1230 int old_flags =
1231 df_clear_flags (DF_DEFER_INSN_RESCAN + DF_NO_INSN_RESCAN);
1232
6fb5fa3c
DB
1233 df_in_progress = true;
1234 rest_of_handle_fast_dce ();
2e6be65e
EB
1235 df_in_progress = false;
1236
6fb5fa3c
DB
1237 df_set_flags (old_flags);
1238 }
1239}
1240
2e6be65e 1241
9ed7b221
EB
1242/* Run a fast DCE pass. */
1243
1244void
1245run_fast_dce (void)
6fb5fa3c 1246{
9ed7b221
EB
1247 if (flag_dce)
1248 rest_of_handle_fast_dce ();
6fb5fa3c
DB
1249}
1250
1251
17795822
TS
1252namespace {
1253
1254const pass_data pass_data_fast_rtl_dce =
6fb5fa3c 1255{
27a4cd48
DM
1256 RTL_PASS, /* type */
1257 "rtl_dce", /* name */
1258 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
1259 TV_DCE, /* tv_id */
1260 0, /* properties_required */
1261 0, /* properties_provided */
1262 0, /* properties_destroyed */
1263 0, /* todo_flags_start */
3bea341f 1264 TODO_df_finish, /* todo_flags_finish */
6fb5fa3c 1265};
27a4cd48 1266
17795822 1267class pass_fast_rtl_dce : public rtl_opt_pass
27a4cd48
DM
1268{
1269public:
c3284718
RS
1270 pass_fast_rtl_dce (gcc::context *ctxt)
1271 : rtl_opt_pass (pass_data_fast_rtl_dce, ctxt)
27a4cd48
DM
1272 {}
1273
1274 /* opt_pass methods: */
1a3d085c
TS
1275 virtual bool gate (function *)
1276 {
1277 return optimize > 0 && flag_dce && dbg_cnt (dce_fast);
1278 }
1279
be55bfe6
TS
1280 virtual unsigned int execute (function *)
1281 {
1282 return rest_of_handle_fast_dce ();
1283 }
27a4cd48
DM
1284
1285}; // class pass_fast_rtl_dce
1286
17795822
TS
1287} // anon namespace
1288
27a4cd48
DM
1289rtl_opt_pass *
1290make_pass_fast_rtl_dce (gcc::context *ctxt)
1291{
1292 return new pass_fast_rtl_dce (ctxt);
1293}