summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-30 00:01:07 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-30 00:01:07 +0000
commitb662dace58b77000acf8f7997d1faacfde98c009 (patch)
treea016d44be068e81121dd50b88c7bb7e2b08e2c1e
parent0c4005bebc8f9989c289140633ece51c0589f9b9 (diff)
downloadgcc-b662dace58b77000acf8f7997d1faacfde98c009.tar.gz
Goodbye REG_LIVE_LENGTH
* regs.h (struct reg_info_t): Delete live_length. (REG_LIVE_LENGTH): Delete macro. * regstat.c (regstat_bb_compute_ri): Delete artificial_uses, local_live, local_processed and local_live_last_luid params. Replace bb_index param with bb. Don't set REG_LIVE_LENGTH. Formatting fixes. (regstat_compute_ri): Adjust for above. Don't set REG_LIVE_LENGTH. (dump_reg_info): Don't print live length. * ira.c (update_equiv_regs): Replace test of REG_LIVE_LENGTH with test of setjmp_crosses. Don't set REG_LIVE_LENGTH. Localize loop_depth var. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235663 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/ira.c11
-rw-r--r--gcc/regs.h15
-rw-r--r--gcc/regstat.c150
4 files changed, 38 insertions, 153 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9daedf3f918..8e93e915988 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
2016-04-30 Alan Modra <amodra@gmail.com>
+ * regs.h (struct reg_info_t): Delete live_length.
+ (REG_LIVE_LENGTH): Delete macro.
+ * regstat.c (regstat_bb_compute_ri): Delete artificial_uses,
+ local_live, local_processed and local_live_last_luid params.
+ Replace bb_index param with bb. Don't set REG_LIVE_LENGTH.
+ Formatting fixes.
+ (regstat_compute_ri): Adjust for above. Don't set
+ REG_LIVE_LENGTH.
+ (dump_reg_info): Don't print live length.
+ * ira.c (update_equiv_regs): Replace test of REG_LIVE_LENGTH
+ with test of setjmp_crosses. Don't set REG_LIVE_LENGTH.
+ Localize loop_depth var.
+
+2016-04-30 Alan Modra <amodra@gmail.com>
+
* ira.c (enum valid_equiv): New.
(validate_equiv_mem): Return enum.
(update_equiv_mem): Create replacement in more cases.
diff --git a/gcc/ira.c b/gcc/ira.c
index 7acf6806385..e597604b2ea 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3315,7 +3315,6 @@ update_equiv_regs (void)
{
rtx_insn *insn;
basic_block bb;
- int loop_depth;
/* Scan insns and set pdx_subregs if the reg is used in a
paradoxical subreg. Don't set such reg equivalent to a mem,
@@ -3329,9 +3328,10 @@ update_equiv_regs (void)
/* Scan the insns and find which registers have equivalences. Do this
in a separate scan of the insns because (due to -fcse-follow-jumps)
a register can be set below its use. */
+ bitmap setjmp_crosses = regstat_get_setjmp_crosses ();
FOR_EACH_BB_FN (bb, cfun)
{
- loop_depth = bb_loop_depth (bb);
+ int loop_depth = bb_loop_depth (bb);
for (insn = BB_HEAD (bb);
insn != NEXT_INSN (BB_END (bb));
@@ -3553,12 +3553,8 @@ update_equiv_regs (void)
reg_equiv[regno].loop_depth = (short) loop_depth;
/* Don't mess with things live during setjmp. */
- if (REG_LIVE_LENGTH (regno) >= 0 && optimize)
+ if (optimize && !bitmap_bit_p (setjmp_crosses, regno))
{
- /* Note that the statement below does not affect the priority
- in local-alloc! */
- REG_LIVE_LENGTH (regno) *= 2;
-
/* If the register is referenced exactly twice, meaning it is
set once and used once, indicate that the reference may be
replaced by the equivalence we computed above. Do this
@@ -3744,7 +3740,6 @@ combine_and_move_insns (void)
REG_N_CALLS_CROSSED (regno) = 0;
REG_FREQ_CALLS_CROSSED (regno) = 0;
REG_N_THROWING_CALLS_CROSSED (regno) = 0;
- REG_LIVE_LENGTH (regno) = 2;
if (use_insn == BB_HEAD (use_bb))
BB_HEAD (use_bb) = new_insn;
diff --git a/gcc/regs.h b/gcc/regs.h
index 6f992bd810b..244250d127c 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -105,7 +105,6 @@ struct reg_info_t
{
int freq; /* # estimated frequency (REG n) is used or set */
int deaths; /* # of times (REG n) dies */
- int live_length; /* # of instructions (REG n) is live */
int calls_crossed; /* # of calls (REG n) is live across */
int freq_calls_crossed; /* # estimated frequency (REG n) crosses call */
int throw_calls_crossed; /* # of calls that may throw (REG n) is live across */
@@ -170,20 +169,6 @@ extern size_t reg_info_p_size;
#define REG_N_THROWING_CALLS_CROSSED(N) (reg_info_p[N].throw_calls_crossed)
-/* Total number of instructions at which (REG n) is live.
-
- This is set in regstat.c whenever register info is requested and
- remains valid for the rest of the compilation of the function; it is
- used to control register allocation. The larger this is, the less
- priority (REG n) gets for allocation in a hard register (in IRA in
- priority-coloring mode).
-
- Negative values are special: -1 is used to mark a pseudo reg that
- should not be allocated to a hard register, because it crosses a
- setjmp call. */
-
-#define REG_LIVE_LENGTH(N) (reg_info_p[N].live_length)
-
/* Indexed by n, gives number of basic block that (REG n) is used in.
If the value is REG_BLOCK_GLOBAL (-1),
it means (REG n) is used in more than one basic block.
diff --git a/gcc/regstat.c b/gcc/regstat.c
index c05b69f6c1a..b25a63c8258 100644
--- a/gcc/regstat.c
+++ b/gcc/regstat.c
@@ -94,7 +94,7 @@ regstat_free_n_sets_and_refs (void)
/*----------------------------------------------------------------------------
REGISTER INFORMATION
- Process REG_N_DEATHS, REG_LIVE_LENGTH, REG_N_CALLS_CROSSED,
+ Process REG_N_DEATHS, REG_N_CALLS_CROSSED,
REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK.
----------------------------------------------------------------------------*/
@@ -106,24 +106,17 @@ struct reg_info_t *reg_info_p;
size_t reg_info_p_size;
/* Compute register info: lifetime, bb, and number of defs and uses
- for basic block BB. The three bitvectors are scratch regs used
- here. */
+ for basic block BB. LIVE is a scratch bitvector used here. */
static void
-regstat_bb_compute_ri (unsigned int bb_index,
- bitmap live, bitmap artificial_uses,
- bitmap local_live, bitmap local_processed,
- int *local_live_last_luid)
+regstat_bb_compute_ri (basic_block bb, bitmap live)
{
- basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
rtx_insn *insn;
df_ref def, use;
- int luid = 0;
bitmap_iterator bi;
unsigned int regno;
bitmap_copy (live, df_get_live_out (bb));
- bitmap_clear (artificial_uses);
/* Process the regs live at the end of the block. Mark them as
not local to any one basic block. */
@@ -132,30 +125,26 @@ regstat_bb_compute_ri (unsigned int bb_index,
/* Process the artificial defs and uses at the bottom of the block
to begin processing. */
- FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
+ FOR_EACH_ARTIFICIAL_DEF (def, bb->index)
if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
bitmap_clear_bit (live, DF_REF_REGNO (def));
- FOR_EACH_ARTIFICIAL_USE (use, bb_index)
+ FOR_EACH_ARTIFICIAL_USE (use, bb->index)
if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
{
regno = DF_REF_REGNO (use);
bitmap_set_bit (live, regno);
- bitmap_set_bit (artificial_uses, regno);
}
FOR_BB_INSNS_REVERSE (bb, insn)
{
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
bitmap_iterator bi;
- df_mw_hardreg *mw;
rtx link;
if (!NONDEBUG_INSN_P (insn))
continue;
- luid++;
-
link = REG_NOTES (insn);
while (link)
{
@@ -194,82 +183,24 @@ regstat_bb_compute_ri (unsigned int bb_index,
}
}
- /* We only care about real sets for calls. Clobbers cannot
- be depended on.
- Only do this if the value is totally dead. */
- FOR_EACH_INSN_INFO_MW (mw, insn_info)
- if (DF_MWS_REG_DEF_P (mw))
- {
- bool all_dead = true;
- unsigned int r;
-
- for (r = mw->start_regno; r <= mw->end_regno; r++)
- if (bitmap_bit_p (artificial_uses, r)
- || bitmap_bit_p (live, r))
- {
- all_dead = false;
- break;
- }
-
- if (all_dead)
- {
- regno = mw->start_regno;
- REG_LIVE_LENGTH (regno)++;
- }
- }
-
/* All of the defs except the return value are some sort of
clobber. This code is for the return. */
FOR_EACH_INSN_INFO_DEF (def, insn_info)
{
if ((!CALL_P (insn))
- || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
+ || (!(DF_REF_FLAGS (def)
+ & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
{
unsigned int dregno = DF_REF_REGNO (def);
- if (bitmap_bit_p (live, dregno))
- {
- /* If we have seen a use of DREGNO somewhere before (i.e.
- later in this basic block), and DEF is not a subreg
- store or conditional store, then kill the register
- here and add the proper length to its REG_LIVE_LENGTH.
-
- If we have not seen a use of DREGNO later in this basic
- block, then we need to add the length from here to the
- end of the block to the live length. */
- if (bitmap_bit_p (local_live, dregno))
- {
- /* Note that LOCAL_LIVE implies LOCAL_PROCESSED, so
- we don't have to set LOCAL_PROCESSED in this clause. */
- if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
- {
- REG_LIVE_LENGTH (dregno) +=
- (luid - local_live_last_luid[dregno]);
- local_live_last_luid[dregno] = luid;
- bitmap_clear_bit (local_live, dregno);
- }
- }
- else
- {
- bitmap_set_bit (local_processed, dregno);
- REG_LIVE_LENGTH (dregno) += luid;
- local_live_last_luid[dregno] = luid;
- }
-
- /* Kill this register if it is not a subreg store or
- conditional store.
- ??? This means that any partial store is live from
- the last use in a basic block to the start of this
- basic block. This results in poor calculations of
- REG_LIVE_LENGTH in large basic blocks. */
- if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
- bitmap_clear_bit (live, dregno);
- }
- else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG))
- && (!bitmap_bit_p (artificial_uses, dregno)))
- {
- REG_LIVE_LENGTH (dregno)++;
- }
+ /* Kill this register if it is not a subreg store or
+ conditional store.
+ ??? This means that any partial store is live from
+ the last use in a basic block to the start of this
+ basic block. */
+ if (!(DF_REF_FLAGS (def)
+ & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+ bitmap_clear_bit (live, dregno);
if (dregno >= FIRST_PSEUDO_REGISTER)
{
@@ -300,37 +231,8 @@ regstat_bb_compute_ri (unsigned int bb_index,
else if (REG_BASIC_BLOCK (uregno) != bb->index)
REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL;
}
-
- if (bitmap_set_bit (live, uregno))
- {
- /* This register is now live. Begin to process it locally.
-
- Note that we don't even get here if the variable was live
- at the end of the block since just a ref inside the block
- does not effect the calculations. */
- REG_LIVE_LENGTH (uregno) ++;
- local_live_last_luid[uregno] = luid;
- bitmap_set_bit (local_live, uregno);
- bitmap_set_bit (local_processed, uregno);
- }
}
}
-
- /* Add the liveness length to all registers that were used somewhere
- in this bock, but not between that use and the head of this block. */
- EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi)
- {
- REG_LIVE_LENGTH (regno) += (luid - local_live_last_luid[regno]);
- }
-
- /* Add the length of the block to all of the registers that were not
- referenced, but still live in this block. */
- bitmap_and_compl_into (live, local_processed);
- EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
- REG_LIVE_LENGTH (regno) += luid;
-
- bitmap_clear (local_processed);
- bitmap_clear (local_live);
}
@@ -340,12 +242,8 @@ regstat_compute_ri (void)
{
basic_block bb;
bitmap live = BITMAP_ALLOC (&df_bitmap_obstack);
- bitmap artificial_uses = BITMAP_ALLOC (&df_bitmap_obstack);
- bitmap local_live = BITMAP_ALLOC (&df_bitmap_obstack);
- bitmap local_processed = BITMAP_ALLOC (&df_bitmap_obstack);
unsigned int regno;
bitmap_iterator bi;
- int *local_live_last_luid;
/* Initialize everything. */
@@ -356,26 +254,18 @@ regstat_compute_ri (void)
max_regno = max_reg_num ();
reg_info_p_size = max_regno;
reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
- local_live_last_luid = XNEWVEC (int, max_regno);
FOR_EACH_BB_FN (bb, cfun)
{
- regstat_bb_compute_ri (bb->index, live, artificial_uses,
- local_live, local_processed,
- local_live_last_luid);
+ regstat_bb_compute_ri (bb, live);
}
BITMAP_FREE (live);
- BITMAP_FREE (artificial_uses);
- BITMAP_FREE (local_live);
- BITMAP_FREE (local_processed);
- free (local_live_last_luid);
/* See the setjmp comment in regstat_bb_compute_ri. */
EXECUTE_IF_SET_IN_BITMAP (setjmp_crosses, FIRST_PSEUDO_REGISTER, regno, bi)
{
REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
- REG_LIVE_LENGTH (regno) = -1;
}
timevar_pop (TV_REG_STATS);
@@ -533,11 +423,11 @@ dump_reg_info (FILE *file)
enum reg_class rclass, altclass;
if (regstat_n_sets_and_refs)
- fprintf (file, "\nRegister %d used %d times across %d insns",
- i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
+ fprintf (file, "\nRegister %d used %d times",
+ i, REG_N_REFS (i));
else if (df)
- fprintf (file, "\nRegister %d used %d times across %d insns",
- i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i), REG_LIVE_LENGTH (i));
+ fprintf (file, "\nRegister %d used %d times",
+ i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i));
if (REG_BASIC_BLOCK (i) >= NUM_FIXED_BLOCKS)
fprintf (file, " in block %d", REG_BASIC_BLOCK (i));