diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-13 03:02:49 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-13 03:02:49 +0000 |
commit | 497ba60f76c13da878a9932dc38eda8e7333c0b6 (patch) | |
tree | 6e275a0a0d4c96a79407def2c6bc8fc0ee919f34 /gcc/lra.c | |
parent | 2bef00f6c5beb4563d4e8f5834a5a1e0955f07d9 (diff) | |
download | gcc-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.c | 107 |
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, ®_obstack); bitmap_initialize (&lra_split_regs, ®_obstack); bitmap_initialize (&lra_optional_reload_pseudos, ®_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 (); |