Mercurial > hg > CbC > CbC_gcc
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)) |