summaryrefslogtreecommitdiff
path: root/gcc/lra.c
diff options
context:
space:
mode:
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-13 03:02:49 +0000
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-13 03:02:49 +0000
commit497ba60f76c13da878a9932dc38eda8e7333c0b6 (patch)
tree6e275a0a0d4c96a79407def2c6bc8fc0ee919f34 /gcc/lra.c
parent2bef00f6c5beb4563d4e8f5834a5a1e0955f07d9 (diff)
downloadgcc-497ba60f76c13da878a9932dc38eda8e7333c0b6.tar.gz
2014-11-12 Vladimir Makarov <vmakarov@redhat.com>
* common.opt (flra-remat): New. * opts.c (default_options_table): Add entry for flra_remat. * timevar_def (TV_LRA_REMAT): New. * doc/invoke.texi (-flra-remat): Add description of the new option. * doc/passes.texi (-flra-remat): Remove lra-equivs.c and lra-saves.c. Add lra-remat.c. * Makefile.in (OBJS): Add lra-remat.o. * lra-remat.c: New file. * lra.c: Add info about the rematerialization pass in the top comment. (collect_non_operand_hard_regs, add_regs_to_insn_regno_info): Process unallocatable regs too. (lra_constraint_new_insn_uid_start): Remove. (lra): Add code for calling rematerialization sub-pass. * lra-int.h (lra_constraint_new_insn_uid_start): Remove. (lra_constrain_insn, lra_remat): New prototypes. (lra_eliminate_regs_1): Add parameter. * lra-lives.c (make_hard_regno_born, make_hard_regno_dead): Process unallocatable hard regs too. (process_bb_lives): Ditto. * lra-spills.c (remove_pseudos): Add argument to lra_eliminate_regs_1 call. * lra-eliminations.c (lra_eliminate_regs_1): Add parameter. Use it for sp offset calculation. (lra_eliminate_regs): Add argument for lra_eliminate_regs_1 call. (eliminate_regs_in_insn): Add parameter. Use it for sp offset calculation. (process_insn_for_elimination): Add argument for eliminate_regs_in_insn call. * lra-constraints.c (get_equiv_with_elimination): Add argument for lra_eliminate_regs_1 call. (process_addr_reg): Add parameter. Use it. (process_address_1): Ditto. Add argument for process_addr_reg call. (process_address): Ditto. (curr_insn_transform): Add parameter. Use it. Add argument for process_address calls. (lra_constrain_insn): New function. (lra_constraints): Add argument for curr_insn_transform call. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217458 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra.c')
-rw-r--r--gcc/lra.c107
1 files changed, 59 insertions, 48 deletions
diff --git a/gcc/lra.c b/gcc/lra.c
index 3ae47e86ba6..a140f2ab89a 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
generated;
o Some pseudos might be spilled to assign hard registers to
new reload pseudos;
+ o Recalculating spilled pseudo values (rematerialization);
o Changing spilled pseudos to stack memory or their equivalences;
o Allocation stack memory changes the address displacement and
new iteration is needed.
@@ -57,19 +58,26 @@ along with GCC; see the file COPYING3. If not see
----------- | ---------------- |
| | |
| V New |
- ---------------- No ------------ pseudos -------------------
- | Spilled pseudo | change |Constraints:| or insns | Inheritance/split |
- | to memory |<-------| RTL |--------->| transformations |
- | substitution | | transfor- | | in EBB scope |
- ---------------- | mations | -------------------
- | ------------
- V
- -------------------------
- | Hard regs substitution, |
- | devirtalization, and |------> Finish
- | restoring scratches got |
- | memory |
- -------------------------
+ | ------------ pseudos -------------------
+ | |Constraints:| or insns | Inheritance/split |
+ | | RTL |--------->| transformations |
+ | | transfor- | | in EBB scope |
+ | substi- | mations | -------------------
+ | tutions ------------
+ | | No change
+ ---------------- V
+ | Spilled pseudo | -------------------
+ | to memory |<----| Rematerialization |
+ | substitution | -------------------
+ ----------------
+ | No susbtitions
+ V
+ -------------------------
+ | Hard regs substitution, |
+ | devirtalization, and |------> Finish
+ | restoring scratches got |
+ | memory |
+ -------------------------
To speed up the process:
o We process only insns affected by changes on previous
@@ -849,38 +857,38 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
{
if ((regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER)
return list;
+ /* Process all regs even unallocatable ones as we need info
+ about all regs for rematerialization pass. */
for (last = regno + hard_regno_nregs[regno][mode];
regno < last;
regno++)
- if (! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)
- || TEST_HARD_REG_BIT (eliminable_regset, regno))
- {
- for (curr = list; curr != NULL; curr = curr->next)
- if (curr->regno == regno && curr->subreg_p == subreg_p
- && curr->biggest_mode == mode)
- {
- if (curr->type != type)
- curr->type = OP_INOUT;
- if (curr->early_clobber != early_clobber)
- curr->early_clobber = true;
- break;
- }
- if (curr == NULL)
+ {
+ for (curr = list; curr != NULL; curr = curr->next)
+ if (curr->regno == regno && curr->subreg_p == subreg_p
+ && curr->biggest_mode == mode)
{
- /* This is a new hard regno or the info can not be
- integrated into the found structure. */
+ if (curr->type != type)
+ curr->type = OP_INOUT;
+ if (curr->early_clobber != early_clobber)
+ curr->early_clobber = true;
+ break;
+ }
+ if (curr == NULL)
+ {
+ /* This is a new hard regno or the info can not be
+ integrated into the found structure. */
#ifdef STACK_REGS
- early_clobber
- = (early_clobber
- /* This clobber is to inform popping floating
- point stack only. */
- && ! (FIRST_STACK_REG <= regno
- && regno <= LAST_STACK_REG));
+ early_clobber
+ = (early_clobber
+ /* This clobber is to inform popping floating
+ point stack only. */
+ && ! (FIRST_STACK_REG <= regno
+ && regno <= LAST_STACK_REG));
#endif
- list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
- early_clobber, list);
- }
- }
+ list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
+ early_clobber, list);
+ }
+ }
return list;
}
switch (code)
@@ -1456,10 +1464,8 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
if (REG_P (x))
{
regno = REGNO (x);
- if (regno < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)
- && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
- return;
+ /* Process all regs even unallocatable ones as we need info about
+ all regs for rematerialization pass. */
expand_reg_info ();
if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
{
@@ -2152,9 +2158,6 @@ bitmap_head lra_optional_reload_pseudos;
pass. */
bitmap_head lra_subreg_reload_pseudos;
-/* First UID of insns generated before a new spill pass. */
-int lra_constraint_new_insn_uid_start;
-
/* File used for output of LRA debug information. */
FILE *lra_dump_file;
@@ -2252,7 +2255,6 @@ lra (FILE *f)
lra_curr_reload_num = 0;
push_insns (get_last_insn (), NULL);
/* It is needed for the 1st coalescing. */
- lra_constraint_new_insn_uid_start = get_max_uid ();
bitmap_initialize (&lra_inheritance_pseudos, &reg_obstack);
bitmap_initialize (&lra_split_regs, &reg_obstack);
bitmap_initialize (&lra_optional_reload_pseudos, &reg_obstack);
@@ -2345,12 +2347,21 @@ lra (FILE *f)
lra_create_live_ranges (lra_reg_spill_p);
live_p = true;
}
+ /* Now we know what pseudos should be spilled. Try to
+ rematerialize them first. */
+ if (lra_remat ())
+ {
+ /* We need full live info -- see the comment above. */
+ lra_create_live_ranges (lra_reg_spill_p);
+ live_p = true;
+ if (! lra_need_for_spills_p ())
+ break;
+ }
lra_spill ();
/* Assignment of stack slots changes elimination offsets for
some eliminations. So update the offsets here. */
lra_eliminate (false, false);
lra_constraint_new_regno_start = max_reg_num ();
- lra_constraint_new_insn_uid_start = get_max_uid ();
lra_assignment_iter_after_spill = 0;
}
restore_scratches ();