mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-30 23:35:00 +08:00
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
This commit is contained in:
parent
41c3953302
commit
25e4379fe5
@ -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
|
||||
|
36
gcc/flow.c
36
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user