Commit 80c29cc4 by Roman Zippel Committed by Richard Henderson

gcse.c (reg_first_set, [...]): Replace with ...

        * gcse.c (reg_first_set, reg_last_set): Replace with ...
        (reg_avail_info, current_bb): ... these.
        (oprs_unchanged_p, record_last_reg_set_info): Use them.
        (compute_hash_table): Likewise.

Co-Authored-By: Richard Henderson <rth@redhat.com>

From-SVN: r45213
parent bce7bfe8
2001-08-27 Roman Zippel <zippel@linux-m68k.org> 2001-08-27 Roman Zippel <zippel@linux-m68k.org>
Richard Henderson <rth@redhat.com>
* gcse.c (reg_first_set, reg_last_set): Replace with ...
(reg_avail_info, current_bb): ... these.
(oprs_unchanged_p, record_last_reg_set_info): Use them.
(compute_hash_table): Likewise.
2001-08-27 Roman Zippel <zippel@linux-m68k.org>
* flow.c (verify_flow_info): Use checksums to verify edges. * flow.c (verify_flow_info): Use checksums to verify edges.
......
...@@ -1298,11 +1298,19 @@ compute_sets (f) ...@@ -1298,11 +1298,19 @@ compute_sets (f)
/* Hash table support. */ /* Hash table support. */
/* For each register, the cuid of the first/last insn in the block to set it, /* For each register, the cuid of the first/last insn in the block
or -1 if not set. */ that set it, or -1 if not set. */
#define NEVER_SET -1 #define NEVER_SET -1
static int *reg_first_set;
static int *reg_last_set; struct reg_avail_info
{
int last_bb;
int first_set;
int last_set;
};
static struct reg_avail_info *reg_avail_info;
static int current_bb;
/* See whether X, the source of a set, is something we want to consider for /* See whether X, the source of a set, is something we want to consider for
...@@ -1376,15 +1384,19 @@ oprs_unchanged_p (x, insn, avail_p) ...@@ -1376,15 +1384,19 @@ oprs_unchanged_p (x, insn, avail_p)
switch (code) switch (code)
{ {
case REG: case REG:
if (avail_p) {
return (reg_last_set[REGNO (x)] == NEVER_SET struct reg_avail_info *info = &reg_avail_info[REGNO (x)];
|| reg_last_set[REGNO (x)] < INSN_CUID (insn));
else if (info->last_bb != current_bb)
return (reg_first_set[REGNO (x)] == NEVER_SET return 1;
|| reg_first_set[REGNO (x)] >= INSN_CUID (insn)); if (avail_p)
return info->last_set < INSN_CUID (insn);
else
return info->first_set >= INSN_CUID (insn);
}
case MEM: case MEM:
if (load_killed_in_block_p (BLOCK_FOR_INSN (insn), INSN_CUID (insn), if (load_killed_in_block_p (BASIC_BLOCK (current_bb), INSN_CUID (insn),
x, avail_p)) x, avail_p))
return 0; return 0;
else else
...@@ -2328,12 +2340,15 @@ dump_hash_table (file, name, table, table_size, total_size) ...@@ -2328,12 +2340,15 @@ dump_hash_table (file, name, table, table_size, total_size)
/* Record register first/last/block set information for REGNO in INSN. /* Record register first/last/block set information for REGNO in INSN.
reg_first_set records the first place in the block where the register first_set records the first place in the block where the register
is set and is used to compute "anticipatability". is set and is used to compute "anticipatability".
reg_last_set records the last place in the block where the register last_set records the last place in the block where the register
is set and is used to compute "availability". is set and is used to compute "availability".
last_bb records the block for which first_set and last_set are
valid, as a quick test to invalidate them.
reg_set_in_block records whether the register is set in the block reg_set_in_block records whether the register is set in the block
and is used to compute "transparency". */ and is used to compute "transparency". */
...@@ -2342,11 +2357,16 @@ record_last_reg_set_info (insn, regno) ...@@ -2342,11 +2357,16 @@ record_last_reg_set_info (insn, regno)
rtx insn; rtx insn;
int regno; int regno;
{ {
if (reg_first_set[regno] == NEVER_SET) struct reg_avail_info *info = &reg_avail_info[regno];
reg_first_set[regno] = INSN_CUID (insn); int cuid = INSN_CUID (insn);
reg_last_set[regno] = INSN_CUID (insn); info->last_set = cuid;
SET_BIT (reg_set_in_block[BLOCK_NUM (insn)], regno); if (info->last_bb != current_bb)
{
info->last_bb = current_bb;
info->first_set = cuid;
SET_BIT (reg_set_in_block[current_bb], regno);
}
} }
...@@ -2453,7 +2473,7 @@ static void ...@@ -2453,7 +2473,7 @@ static void
compute_hash_table (set_p) compute_hash_table (set_p)
int set_p; int set_p;
{ {
int bb; unsigned int i;
/* While we compute the hash table we also compute a bit array of which /* While we compute the hash table we also compute a bit array of which
registers are set in which blocks. registers are set in which blocks.
...@@ -2473,29 +2493,25 @@ compute_hash_table (set_p) ...@@ -2473,29 +2493,25 @@ compute_hash_table (set_p)
} }
} }
/* Some working arrays used to track first and last set in each block. */ /* Some working arrays used to track first and last set in each block. */
/* ??? One could use alloca here, but at some size a threshold is crossed reg_avail_info = (struct reg_avail_info*)
beyond which one should use malloc. Are we at that threshold here? */ gmalloc (max_gcse_regno * sizeof (struct reg_avail_info));
reg_first_set = (int *) gmalloc (max_gcse_regno * sizeof (int));
reg_last_set = (int *) gmalloc (max_gcse_regno * sizeof (int));
for (bb = 0; bb < n_basic_blocks; bb++) for (i = 0; i < max_gcse_regno; ++i)
reg_avail_info[i].last_bb = NEVER_SET;
for (current_bb = 0; current_bb < n_basic_blocks; current_bb++)
{ {
rtx insn; rtx insn;
unsigned int regno; unsigned int regno;
int in_libcall_block; int in_libcall_block;
unsigned int i;
/* First pass over the instructions records information used to /* First pass over the instructions records information used to
determine when registers and memory are first and last set. determine when registers and memory are first and last set.
??? hard-reg reg_set_in_block computation ??? hard-reg reg_set_in_block computation
could be moved to compute_sets since they currently don't change. */ could be moved to compute_sets since they currently don't change. */
for (i = 0; i < max_gcse_regno; i++) for (insn = BLOCK_HEAD (current_bb);
reg_first_set[i] = reg_last_set[i] = NEVER_SET; insn && insn != NEXT_INSN (BLOCK_END (current_bb));
for (insn = BLOCK_HEAD (bb);
insn && insn != NEXT_INSN (BLOCK_END (bb));
insn = NEXT_INSN (insn)) insn = NEXT_INSN (insn))
{ {
if (! INSN_P (insn)) if (! INSN_P (insn))
...@@ -2523,8 +2539,8 @@ compute_hash_table (set_p) ...@@ -2523,8 +2539,8 @@ compute_hash_table (set_p)
/* The next pass builds the hash table. */ /* The next pass builds the hash table. */
for (insn = BLOCK_HEAD (bb), in_libcall_block = 0; for (insn = BLOCK_HEAD (current_bb), in_libcall_block = 0;
insn && insn != NEXT_INSN (BLOCK_END (bb)); insn && insn != NEXT_INSN (BLOCK_END (current_bb));
insn = NEXT_INSN (insn)) insn = NEXT_INSN (insn))
if (INSN_P (insn)) if (INSN_P (insn))
{ {
...@@ -2536,11 +2552,8 @@ compute_hash_table (set_p) ...@@ -2536,11 +2552,8 @@ compute_hash_table (set_p)
} }
} }
free (reg_first_set); free (reg_avail_info);
free (reg_last_set); reg_avail_info = NULL;
/* Catch bugs early. */
reg_first_set = reg_last_set = 0;
} }
/* Allocate space for the set hash table. /* Allocate space for the set hash table.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment