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