comparison gcc/dce.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* RTL dead code elimination. 1 /* RTL dead code elimination.
2 Copyright (C) 2005-2017 Free Software Foundation, Inc. 2 Copyright (C) 2005-2018 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
129 /* Initialization of pseudo PIC register should never be removed. */ 129 /* Initialization of pseudo PIC register should never be removed. */
130 else if (DF_REF_REG (def) == pic_offset_table_rtx 130 else if (DF_REF_REG (def) == pic_offset_table_rtx
131 && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) 131 && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
132 return false; 132 return false;
133 133
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
134 body = PATTERN (insn); 140 body = PATTERN (insn);
135 switch (GET_CODE (body)) 141 switch (GET_CODE (body))
136 { 142 {
137 case USE: 143 case USE:
138 case VAR_LOCATION: 144 case VAR_LOCATION:
139 return false; 145 return false;
140 146
141 case CLOBBER: 147 case CLOBBER:
148 case CLOBBER_HIGH:
142 if (fast) 149 if (fast)
143 { 150 {
144 /* A CLOBBER of a dead pseudo register serves no purpose. 151 /* A CLOBBER of a dead pseudo register serves no purpose.
145 That is not necessarily true for hard registers until 152 That is not necessarily true for hard registers until
146 after reload. */ 153 after reload. */
205 212
206 static void 213 static void
207 mark_nonreg_stores_1 (rtx dest, const_rtx pattern, void *data) 214 mark_nonreg_stores_1 (rtx dest, const_rtx pattern, void *data)
208 { 215 {
209 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest)) 216 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest))
210 mark_insn ((rtx_insn *) data, true); 217 {
218 gcc_checking_assert (GET_CODE (pattern) != CLOBBER_HIGH);
219 mark_insn ((rtx_insn *) data, true);
220 }
211 } 221 }
212 222
213 223
214 /* A note_stores callback used by mark_nonreg_stores. DATA is the 224 /* A note_stores callback used by mark_nonreg_stores. DATA is the
215 instruction containing DEST. */ 225 instruction containing DEST. */
216 226
217 static void 227 static void
218 mark_nonreg_stores_2 (rtx dest, const_rtx pattern, void *data) 228 mark_nonreg_stores_2 (rtx dest, const_rtx pattern, void *data)
219 { 229 {
220 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest)) 230 if (GET_CODE (pattern) != CLOBBER && !REG_P (dest))
221 mark_insn ((rtx_insn *) data, false); 231 {
232 gcc_checking_assert (GET_CODE (pattern) != CLOBBER_HIGH);
233 mark_insn ((rtx_insn *) data, false);
234 }
222 } 235 }
223 236
224 237
225 /* Mark INSN if BODY stores to a non-register destination. */ 238 /* Mark INSN if BODY stores to a non-register destination. */
226 239
291 if (GET_CODE (XEXP (p, 0)) == USE 304 if (GET_CODE (XEXP (p, 0)) == USE
292 && MEM_P (XEXP (XEXP (p, 0), 0))) 305 && MEM_P (XEXP (XEXP (p, 0), 0)))
293 { 306 {
294 rtx mem = XEXP (XEXP (p, 0), 0), addr; 307 rtx mem = XEXP (XEXP (p, 0), 0), addr;
295 HOST_WIDE_INT off = 0, size; 308 HOST_WIDE_INT off = 0, size;
296 if (!MEM_SIZE_KNOWN_P (mem)) 309 if (!MEM_SIZE_KNOWN_P (mem) || !MEM_SIZE (mem).is_constant (&size))
297 return false; 310 return false;
298 size = MEM_SIZE (mem);
299 addr = XEXP (mem, 0); 311 addr = XEXP (mem, 0);
300 if (GET_CODE (addr) == PLUS 312 if (GET_CODE (addr) == PLUS
301 && REG_P (XEXP (addr, 0)) 313 && REG_P (XEXP (addr, 0))
302 && CONST_INT_P (XEXP (addr, 1))) 314 && CONST_INT_P (XEXP (addr, 1)))
303 { 315 {
358 for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1)) 370 for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
359 if (GET_CODE (XEXP (p, 0)) == USE 371 if (GET_CODE (XEXP (p, 0)) == USE
360 && MEM_P (XEXP (XEXP (p, 0), 0))) 372 && MEM_P (XEXP (XEXP (p, 0), 0)))
361 { 373 {
362 rtx mem = XEXP (XEXP (p, 0), 0), addr; 374 rtx mem = XEXP (XEXP (p, 0), 0), addr;
363 HOST_WIDE_INT off = 0, byte; 375 HOST_WIDE_INT off = 0, byte, size;
376 /* Checked in the previous iteration. */
377 size = MEM_SIZE (mem).to_constant ();
364 addr = XEXP (mem, 0); 378 addr = XEXP (mem, 0);
365 if (GET_CODE (addr) == PLUS 379 if (GET_CODE (addr) == PLUS
366 && REG_P (XEXP (addr, 0)) 380 && REG_P (XEXP (addr, 0))
367 && CONST_INT_P (XEXP (addr, 1))) 381 && CONST_INT_P (XEXP (addr, 1)))
368 { 382 {
384 break; 398 break;
385 399
386 set = single_set (DF_REF_INSN (defs->ref)); 400 set = single_set (DF_REF_INSN (defs->ref));
387 off += INTVAL (XEXP (SET_SRC (set), 1)); 401 off += INTVAL (XEXP (SET_SRC (set), 1));
388 } 402 }
389 for (byte = off; byte < off + MEM_SIZE (mem); byte++) 403 for (byte = off; byte < off + size; byte++)
390 { 404 {
391 if (!bitmap_set_bit (sp_bytes, byte - min_sp_off)) 405 if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
392 gcc_unreachable (); 406 gcc_unreachable ();
393 } 407 }
394 } 408 }
467 } 481 }
468 else 482 else
469 break; 483 break;
470 } 484 }
471 485
486 HOST_WIDE_INT size;
472 if (!MEM_SIZE_KNOWN_P (mem) 487 if (!MEM_SIZE_KNOWN_P (mem)
473 || !check_argument_store (MEM_SIZE (mem), off, min_sp_off, 488 || !MEM_SIZE (mem).is_constant (&size)
489 || !check_argument_store (size, off, min_sp_off,
474 max_sp_off, sp_bytes)) 490 max_sp_off, sp_bytes))
475 break; 491 break;
476 492
477 if (!deletable_insn_p (insn, fast, NULL)) 493 if (!deletable_insn_p (insn, fast, NULL))
478 break; 494 break;
558 574
559 FOR_EACH_BB_REVERSE_FN (bb, cfun) 575 FOR_EACH_BB_REVERSE_FN (bb, cfun)
560 FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next) 576 FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next)
561 if (NONDEBUG_INSN_P (insn)) 577 if (NONDEBUG_INSN_P (insn))
562 { 578 {
579 rtx turn_into_use = NULL_RTX;
580
563 /* Always delete no-op moves. */ 581 /* Always delete no-op moves. */
564 if (noop_move_p (insn)) 582 if (noop_move_p (insn))
565 ; 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 }
566 592
567 /* Otherwise rely only on the DCE algorithm. */ 593 /* Otherwise rely only on the DCE algorithm. */
568 else if (marked_insn_p (insn)) 594 else if (marked_insn_p (insn))
569 continue; 595 continue;
570 596
587 to the stack pointer, this will almost always lead to a 613 to the stack pointer, this will almost always lead to a
588 miscompile. */ 614 miscompile. */
589 if (!dbg_cnt (dce)) 615 if (!dbg_cnt (dce))
590 continue; 616 continue;
591 617
592 if (crtl->shrink_wrapped_separate
593 && find_reg_note (insn, REG_CFA_RESTORE, NULL))
594 {
595 if (dump_file)
596 fprintf (dump_file, "DCE: NOT deleting insn %d, it's a "
597 "callee-save restore\n", INSN_UID (insn));
598 continue;
599 }
600
601 if (dump_file) 618 if (dump_file)
602 fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn)); 619 fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
603 620
604 /* Before we delete the insn we have to remove the REG_EQUAL notes 621 /* Before we delete the insn we have to remove the REG_EQUAL notes
605 for the destination regs in order to avoid dangling notes. */ 622 for the destination regs in order to avoid dangling notes. */
609 have unreachable blocks. We rememeber this and call 626 have unreachable blocks. We rememeber this and call
610 delete_unreachable_blocks at the end. */ 627 delete_unreachable_blocks at the end. */
611 if (CALL_P (insn)) 628 if (CALL_P (insn))
612 must_clean = true; 629 must_clean = true;
613 630
614 /* Now delete the insn. */ 631 if (turn_into_use)
615 delete_insn_and_edges (insn); 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);
616 } 644 }
617 645
618 /* Deleted a pure or const call. */ 646 /* Deleted a pure or const call. */
619 if (must_clean) 647 if (must_clean)
620 delete_unreachable_blocks (); 648 delete_unreachable_blocks ();
775 insn = worklist.pop (); 803 insn = worklist.pop ();
776 mark_reg_dependencies (insn); 804 mark_reg_dependencies (insn);
777 } 805 }
778 worklist.release (); 806 worklist.release ();
779 807
780 if (MAY_HAVE_DEBUG_INSNS) 808 if (MAY_HAVE_DEBUG_BIND_INSNS)
781 reset_unmarked_insns_debug_uses (); 809 reset_unmarked_insns_debug_uses ();
782 810
783 /* Before any insns are deleted, we must remove the chains since 811 /* Before any insns are deleted, we must remove the chains since
784 they are not bidirectional. */ 812 they are not bidirectional. */
785 df_remove_problem (df_chain); 813 df_remove_problem (df_chain);
879 if (DEBUG_INSN_P (insn)) 907 if (DEBUG_INSN_P (insn))
880 { 908 {
881 df_ref use; 909 df_ref use;
882 FOR_EACH_INSN_USE (use, insn) 910 FOR_EACH_INSN_USE (use, insn)
883 if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER 911 if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER
884 && (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (use))) 912 && known_eq (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (use))),
885 == 2 * UNITS_PER_WORD) 913 2 * UNITS_PER_WORD)
886 && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use)) 914 && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use))
887 && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use) + 1)) 915 && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use) + 1))
888 dead_debug_add (&debug, use, DF_REF_REGNO (use)); 916 dead_debug_add (&debug, use, DF_REF_REGNO (use));
889 } 917 }
890 else if (INSN_P (insn)) 918 else if (INSN_P (insn))