aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Matz <matzmich@cs.tu-berlin.de>2000-11-30 21:40:33 +0000
committerRichard Henderson <rth@gcc.gnu.org>2000-11-30 13:40:33 -0800
commit25e4379fe54884cd49f653bc97ddf98f89d8c796 (patch)
tree85bc1efd0f69f6554f716ba134eaafceffa2538b
parent41c395330242369ea5d33c544ad41f8833df782c (diff)
downloadgcc-25e4379fe54884cd49f653bc97ddf98f89d8c796.zip
gcc-25e4379fe54884cd49f653bc97ddf98f89d8c796.tar.gz
gcc-25e4379fe54884cd49f653bc97ddf98f89d8c796.tar.bz2
flow.c (make_edge): Early out, if no flags to set.
* flow.c (make_edge): Early out, if no flags to set. (calculate_global_regs_live): Clear out garbage only when necessary. * simplify-rtx.c (varray_type used_regs): New. (clear_table): Use it to only clear necessary items. (cselib_lookup, cselib_record_set): Remember newly set items. (cselib_update_varray_sizes, cselib_init): Initialize and grow used_regs. * local-alloc.c (update_equiv_regs): New local `cleared_regs'. Move clearing of dead regs out of insn-loop. From-SVN: r37899
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/flow.c36
-rw-r--r--gcc/local-alloc.c43
-rw-r--r--gcc/simplify-rtx.c35
4 files changed, 99 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3b38448..dbb46a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2000-11-30 Michael Matz <matzmich@cs.tu-berlin.de>
+
+ * flow.c (make_edge): Early out, if no flags to set.
+ (calculate_global_regs_live): Clear out garbage only when necessary.
+
+ * simplify-rtx.c (varray_type used_regs): New.
+ (clear_table): Use it to only clear necessary items.
+ (cselib_lookup, cselib_record_set): Remember newly set items.
+ (cselib_update_varray_sizes, cselib_init): Initialize and grow
+ used_regs.
+
+ * local-alloc.c (update_equiv_regs): New local `cleared_regs'.
+ Move clearing of dead regs out of insn-loop.
+
2000-11-30 Richard Henderson <rth@redhat.com>
* calls.c (expand_call): Emit queued insns before creating
diff --git a/gcc/flow.c b/gcc/flow.c
index 1e37082..4aacbf8 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -1262,13 +1262,27 @@ make_edge (edge_cache, src, dst, flags)
&& dst != EXIT_BLOCK_PTR);
/* Make sure we don't add duplicate edges. */
- if (! use_edge_cache || TEST_BIT (edge_cache[src->index], dst->index))
- for (e = src->succ; e; e = e->succ_next)
- if (e->dest == dst)
- {
- e->flags |= flags;
- return;
- }
+ switch (use_edge_cache)
+ {
+ default:
+ /* Quick test for non-existance of the edge. */
+ if (! TEST_BIT (edge_cache[src->index], dst->index))
+ break;
+
+ /* The edge exists; early exit if no work to do. */
+ if (flags == 0)
+ return;
+
+ /* FALLTHRU */
+ case 0:
+ for (e = src->succ; e; e = e->succ_next)
+ if (e->dest == dst)
+ {
+ e->flags |= flags;
+ return;
+ }
+ break;
+ }
e = (edge) xcalloc (1, sizeof (*e));
n_edges++;
@@ -3306,15 +3320,15 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
qtail = queue;
qhead = qend = queue + n_basic_blocks + 2;
- /* Clear out the garbage that might be hanging out in bb->aux. */
- for (i = n_basic_blocks - 1; i >= 0; --i)
- BASIC_BLOCK (i)->aux = NULL;
-
/* Queue the blocks set in the initial mask. Do this in reverse block
number order so that we are more likely for the first round to do
useful work. We use AUX non-null to flag that the block is queued. */
if (blocks_in)
{
+ /* Clear out the garbage that might be hanging out in bb->aux. */
+ for (i = n_basic_blocks - 1; i >= 0; --i)
+ BASIC_BLOCK (i)->aux = NULL;
+
EXECUTE_IF_SET_IN_SBITMAP (blocks_in, 0, i,
{
basic_block bb = BASIC_BLOCK (i);
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index ac2183e..62142f0 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -804,8 +804,11 @@ update_equiv_regs ()
rtx insn;
int block;
int loop_depth;
+ regset_head cleared_regs;
+ int clear_regnos = 0;
reg_equiv = (struct equivalence *) xcalloc (max_regno, sizeof *reg_equiv);
+ INIT_REG_SET (&cleared_regs);
init_alias_analysis ();
@@ -1135,7 +1138,6 @@ update_equiv_regs ()
INSN. Update the flow information. */
else if (PREV_INSN (insn) != equiv_insn)
{
- int l;
rtx new_insn;
new_insn = emit_insn_before (copy_rtx (PATTERN (equiv_insn)),
@@ -1156,22 +1158,43 @@ update_equiv_regs ()
if (block >= 0 && insn == BLOCK_HEAD (block))
BLOCK_HEAD (block) = PREV_INSN (insn);
- for (l = 0; l < n_basic_blocks; l++)
- {
- CLEAR_REGNO_REG_SET (
- BASIC_BLOCK (l)->global_live_at_start,
- regno);
- CLEAR_REGNO_REG_SET (
- BASIC_BLOCK (l)->global_live_at_end,
- regno);
- }
+ /* Remember to clear REGNO from all basic block's live
+ info. */
+ SET_REGNO_REG_SET (&cleared_regs, regno);
+ clear_regnos++;
}
}
}
}
+ /* Clear all dead REGNOs from all basic block's live info. */
+ if (clear_regnos)
+ {
+ int j, l;
+ if (clear_regnos > 8)
+ {
+ for (l = 0; l < n_basic_blocks; l++)
+ {
+ AND_COMPL_REG_SET (BASIC_BLOCK (l)->global_live_at_start,
+ &cleared_regs);
+ AND_COMPL_REG_SET (BASIC_BLOCK (l)->global_live_at_end,
+ &cleared_regs);
+ }
+ }
+ else
+ EXECUTE_IF_SET_IN_REG_SET (&cleared_regs, 0, j,
+ {
+ for (l = 0; l < n_basic_blocks; l++)
+ {
+ CLEAR_REGNO_REG_SET (BASIC_BLOCK (l)->global_live_at_start, j);
+ CLEAR_REGNO_REG_SET (BASIC_BLOCK (l)->global_live_at_end, j);
+ }
+ });
+ }
+
/* Clean up. */
end_alias_analysis ();
+ CLEAR_REG_SET (&cleared_regs);
free (reg_equiv);
}
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 08ceaf7..ae15b08 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -111,7 +111,7 @@ static struct elt_loc_list *new_elt_loc_list PARAMS ((struct elt_loc_list *,
static void unchain_one_value PARAMS ((cselib_val *));
static void unchain_one_elt_list PARAMS ((struct elt_list **));
static void unchain_one_elt_loc_list PARAMS ((struct elt_loc_list **));
-static void clear_table PARAMS ((void));
+static void clear_table PARAMS ((int));
static int discard_useless_locs PARAMS ((void **, void *));
static int discard_useless_values PARAMS ((void **, void *));
static void remove_useless_values PARAMS ((void));
@@ -168,6 +168,10 @@ static int n_useless_values;
static varray_type reg_values;
#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
+/* Here the set of indices I with REG_VALUES(I) != 0 is saved. This is used
+ in clear_table() for fast emptying. */
+static varray_type used_regs;
+
/* We pass this to cselib_invalidate_mem to invalidate all of
memory for a non-const call instruction. */
static rtx callmem;
@@ -2200,15 +2204,23 @@ unchain_one_value (v)
}
/* Remove all entries from the hash table. Also used during
- initialization. */
+ initialization. If CLEAR_ALL isn't set, then only clear the entries
+ which are known to have been used. */
static void
-clear_table ()
+clear_table (clear_all)
+ int clear_all;
{
unsigned int i;
- for (i = 0; i < cselib_nregs; i++)
- REG_VALUES (i) = 0;
+ if (clear_all)
+ for (i = 0; i < cselib_nregs; i++)
+ REG_VALUES (i) = 0;
+ else
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (used_regs); i++)
+ REG_VALUES (VARRAY_UINT (used_regs, i)) = 0;
+
+ VARRAY_POP_ALL (used_regs);
htab_empty (hash_table);
obstack_free (&cselib_obstack, cselib_startobj);
@@ -2867,6 +2879,8 @@ cselib_lookup (x, mode, create)
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
+ if (REG_VALUES (i) == 0)
+ VARRAY_PUSH_UINT (used_regs, i);
REG_VALUES (i) = new_elt_list (REG_VALUES (i), e);
slot = htab_find_slot_with_hash (hash_table, x, e->value, INSERT);
*slot = e;
@@ -3133,6 +3147,9 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
if (dreg >= 0)
{
+ if (REG_VALUES (dreg) == 0)
+ VARRAY_PUSH_UINT (used_regs, dreg);
+
REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
if (src_elt->locs == 0)
n_useless_values--;
@@ -3249,7 +3266,7 @@ cselib_process_insn (insn)
&& GET_CODE (PATTERN (insn)) == ASM_OPERANDS
&& MEM_VOLATILE_P (PATTERN (insn))))
{
- clear_table ();
+ clear_table (0);
return;
}
@@ -3309,6 +3326,7 @@ cselib_update_varray_sizes ()
cselib_nregs = nregs;
VARRAY_GROW (reg_values, nregs);
+ VARRAY_GROW (used_regs, nregs);
}
/* Initialize cselib for one pass. The caller must also call
@@ -3329,8 +3347,9 @@ cselib_init ()
cselib_nregs = max_reg_num ();
VARRAY_ELT_LIST_INIT (reg_values, cselib_nregs, "reg_values");
+ VARRAY_UINT_INIT (used_regs, cselib_nregs, "used_regs");
hash_table = htab_create (31, get_value_hash, entry_and_rtx_equal_p, NULL);
- clear_table ();
+ clear_table (1);
}
/* Called when the current user is done with cselib. */
@@ -3338,6 +3357,6 @@ cselib_init ()
void
cselib_finish ()
{
- clear_table ();
+ clear_table (0);
htab_delete (hash_table);
}