Mercurial > hg > CbC > CbC_gcc
comparison gcc/shrink-wrap.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Shrink-wrapping related optimizations. | 1 /* Shrink-wrapping related optimizations. |
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. | 2 Copyright (C) 1987-2020 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 |
35 #include "emit-rtl.h" | 35 #include "emit-rtl.h" |
36 #include "output.h" | 36 #include "output.h" |
37 #include "tree-pass.h" | 37 #include "tree-pass.h" |
38 #include "cfgrtl.h" | 38 #include "cfgrtl.h" |
39 #include "cfgbuild.h" | 39 #include "cfgbuild.h" |
40 #include "params.h" | |
41 #include "bb-reorder.h" | 40 #include "bb-reorder.h" |
42 #include "shrink-wrap.h" | 41 #include "shrink-wrap.h" |
43 #include "regcprop.h" | 42 #include "regcprop.h" |
44 #include "rtl-iter.h" | 43 #include "rtl-iter.h" |
45 #include "valtrack.h" | 44 #include "valtrack.h" |
46 | 45 #include "function-abi.h" |
47 | 46 |
48 /* Return true if INSN requires the stack frame to be set up. | 47 /* Return true if INSN requires the stack frame to be set up. |
49 PROLOGUE_USED contains the hard registers used in the function | 48 PROLOGUE_USED contains the hard registers used in the function |
50 prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the | 49 prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the |
51 prologue to set up for the function. */ | 50 prologue to set up for the function. */ |
74 | 73 |
75 add_to_hard_reg_set (&hardregs, GET_MODE (dreg), REGNO (dreg)); | 74 add_to_hard_reg_set (&hardregs, GET_MODE (dreg), REGNO (dreg)); |
76 } | 75 } |
77 if (hard_reg_set_intersect_p (hardregs, prologue_used)) | 76 if (hard_reg_set_intersect_p (hardregs, prologue_used)) |
78 return true; | 77 return true; |
79 AND_COMPL_HARD_REG_SET (hardregs, call_used_reg_set); | 78 hardregs &= ~crtl->abi->full_reg_clobbers (); |
80 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 79 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
81 if (TEST_HARD_REG_BIT (hardregs, regno) | 80 if (TEST_HARD_REG_BIT (hardregs, regno) |
82 && df_regs_ever_live_p (regno)) | 81 && df_regs_ever_live_p (regno)) |
83 return true; | 82 return true; |
84 | 83 |
149 after INSN in BB. SPLIT_P indicates whether a live edge from BB | 148 after INSN in BB. SPLIT_P indicates whether a live edge from BB |
150 is splitted or not. */ | 149 is splitted or not. */ |
151 | 150 |
152 static bool | 151 static bool |
153 move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, | 152 move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, |
154 const HARD_REG_SET uses, | 153 const_hard_reg_set uses, |
155 const HARD_REG_SET defs, | 154 const_hard_reg_set defs, |
156 bool *split_p, | 155 bool *split_p, |
157 struct dead_debug_local *debug) | 156 struct dead_debug_local *debug) |
158 { | 157 { |
159 rtx set, src, dest; | 158 rtx set, src, dest; |
160 bitmap live_out, live_in, bb_uses = NULL, bb_defs = NULL; | 159 bitmap live_out, live_in, bb_uses = NULL, bb_defs = NULL; |
412 if (debug->used && !bitmap_empty_p (debug->used)) | 411 if (debug->used && !bitmap_empty_p (debug->used)) |
413 FOR_EACH_INSN_DEF (def, insn) | 412 FOR_EACH_INSN_DEF (def, insn) |
414 dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn, | 413 dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn, |
415 DEBUG_TEMP_BEFORE_WITH_VALUE); | 414 DEBUG_TEMP_BEFORE_WITH_VALUE); |
416 | 415 |
417 emit_insn_after (PATTERN (insn), bb_note (bb)); | 416 rtx_insn *insn_copy = emit_insn_after (PATTERN (insn), bb_note (bb)); |
417 /* Update the LABEL_NUSES count on any referenced labels. The ideal | |
418 solution here would be to actually move the instruction instead | |
419 of copying/deleting it as this loses some notations on the | |
420 insn. */ | |
421 mark_jump_label (PATTERN (insn), insn_copy, 0); | |
418 delete_insn (insn); | 422 delete_insn (insn); |
419 return true; | 423 return true; |
420 } | 424 } |
421 | 425 |
422 /* Look for register copies in the first block of the function, and move | 426 /* Look for register copies in the first block of the function, and move |
475 } | 479 } |
476 | 480 |
477 dead_debug_local_finish (&debug, NULL); | 481 dead_debug_local_finish (&debug, NULL); |
478 } | 482 } |
479 | 483 |
480 /* Return whether basic block PRO can get the prologue. It can not if it | 484 /* Return whether basic block PRO can get the prologue. It cannot if it |
481 has incoming complex edges that need a prologue inserted (we make a new | 485 has incoming complex edges that need a prologue inserted (we make a new |
482 block for the prologue, so those edges would need to be redirected, which | 486 block for the prologue, so those edges would need to be redirected, which |
483 does not work). It also can not if there exist registers live on entry | 487 does not work). It also cannot if there exist registers live on entry |
484 to PRO that are clobbered by the prologue. */ | 488 to PRO that are clobbered by the prologue. */ |
485 | 489 |
486 static bool | 490 static bool |
487 can_get_prologue (basic_block pro, HARD_REG_SET prologue_clobbered) | 491 can_get_prologue (basic_block pro, HARD_REG_SET prologue_clobbered) |
488 { | 492 { |
680 if (NONDEBUG_INSN_P (insn)) | 684 if (NONDEBUG_INSN_P (insn)) |
681 { | 685 { |
682 HARD_REG_SET this_used; | 686 HARD_REG_SET this_used; |
683 CLEAR_HARD_REG_SET (this_used); | 687 CLEAR_HARD_REG_SET (this_used); |
684 note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used); | 688 note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used); |
685 AND_COMPL_HARD_REG_SET (this_used, prologue_clobbered); | 689 this_used &= ~prologue_clobbered; |
686 IOR_HARD_REG_SET (prologue_used, this_used); | 690 prologue_used |= this_used; |
687 note_stores (PATTERN (insn), record_hard_reg_sets, &prologue_clobbered); | 691 note_stores (insn, record_hard_reg_sets, &prologue_clobbered); |
688 } | 692 } |
689 CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM); | 693 CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM); |
690 if (frame_pointer_needed) | 694 if (frame_pointer_needed) |
691 CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM); | 695 CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM); |
692 | 696 |
768 vec<basic_block> vec; | 772 vec<basic_block> vec; |
769 vec.create (n_basic_blocks_for_fn (cfun)); | 773 vec.create (n_basic_blocks_for_fn (cfun)); |
770 vec.quick_push (pro); | 774 vec.quick_push (pro); |
771 | 775 |
772 unsigned max_grow_size = get_uncond_jump_length (); | 776 unsigned max_grow_size = get_uncond_jump_length (); |
773 max_grow_size *= PARAM_VALUE (PARAM_MAX_GROW_COPY_BB_INSNS); | 777 max_grow_size *= param_max_grow_copy_bb_insns; |
774 | 778 |
775 while (!vec.is_empty () && pro != entry) | 779 while (!vec.is_empty () && pro != entry) |
776 { | 780 { |
777 while (pro != entry && !can_get_prologue (pro, prologue_clobbered)) | 781 while (pro != entry && !can_get_prologue (pro, prologue_clobbered)) |
778 { | 782 { |