Commit 7eb136d6 by Michael Meissner

Fix urgent bug

From-SVN: r14150
parent cb100943
...@@ -251,8 +251,8 @@ do { \ ...@@ -251,8 +251,8 @@ do { \
} while (0) } while (0)
/* Allocate a register set with oballoc. */ /* Allocate a register set with oballoc. */
#define OBALLOC_REG_SET() \ #define OBSTACK_ALLOC_REG_SET(OBSTACK) \
((regset) obstack_alloc (&flow_obstack, regset_bytes)) ((regset) obstack_alloc (OBSTACK, regset_bytes))
/* Allocate a register set with alloca. */ /* Allocate a register set with alloca. */
#define ALLOCA_REG_SET() ((regset) alloca (regset_bytes)) #define ALLOCA_REG_SET() ((regset) alloca (regset_bytes))
......
...@@ -123,6 +123,13 @@ Boston, MA 02111-1307, USA. */ ...@@ -123,6 +123,13 @@ Boston, MA 02111-1307, USA. */
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free
/* The contents of the current function definition are allocated
in this obstack, and all are freed at the end of the function.
For top-level functions, this is temporary_obstack.
Separate obstacks are made for nested functions. */
extern struct obstack *function_obstack;
/* List of labels that must never be deleted. */ /* List of labels that must never be deleted. */
extern rtx forced_labels; extern rtx forced_labels;
...@@ -246,7 +253,7 @@ static int jmp_uses_reg_or_mem PROTO((rtx)); ...@@ -246,7 +253,7 @@ static int jmp_uses_reg_or_mem PROTO((rtx));
static void mark_label_ref PROTO((rtx, rtx, int)); static void mark_label_ref PROTO((rtx, rtx, int));
static void life_analysis PROTO((rtx, int)); static void life_analysis PROTO((rtx, int));
void allocate_for_life_analysis PROTO((void)); void allocate_for_life_analysis PROTO((void));
static void init_regset_vector PROTO((regset *, regset, int, int)); static void init_regset_vector PROTO((regset *, int, int, struct obstack *));
static void propagate_block PROTO((regset, rtx, rtx, int, static void propagate_block PROTO((regset, rtx, rtx, int,
regset, int)); regset, int));
static rtx flow_delete_insn PROTO((rtx)); static rtx flow_delete_insn PROTO((rtx));
...@@ -260,7 +267,8 @@ static void find_auto_inc PROTO((regset, rtx, rtx)); ...@@ -260,7 +267,8 @@ static void find_auto_inc PROTO((regset, rtx, rtx));
static void mark_used_regs PROTO((regset, regset, rtx, int, rtx)); static void mark_used_regs PROTO((regset, regset, rtx, int, rtx));
static int try_pre_increment_1 PROTO((rtx)); static int try_pre_increment_1 PROTO((rtx));
static int try_pre_increment PROTO((rtx, rtx, HOST_WIDE_INT)); static int try_pre_increment PROTO((rtx, rtx, HOST_WIDE_INT));
static rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT)); /* CYGNUS LOCAL: regmove/amylaar */ /* find_use_as_address non-static */
rtx find_use_as_address PROTO((rtx, rtx, HOST_WIDE_INT));
void dump_flow_info PROTO((FILE *)); void dump_flow_info PROTO((FILE *));
/* Find basic blocks of the current function and perform data flow analysis. /* Find basic blocks of the current function and perform data flow analysis.
...@@ -860,7 +868,6 @@ life_analysis (f, nregs) ...@@ -860,7 +868,6 @@ life_analysis (f, nregs)
rtx f; rtx f;
int nregs; int nregs;
{ {
register regset tem;
int first_pass; int first_pass;
int changed; int changed;
/* For each basic block, a bitmask of regs /* For each basic block, a bitmask of regs
...@@ -906,24 +913,18 @@ life_analysis (f, nregs) ...@@ -906,24 +913,18 @@ life_analysis (f, nregs)
if there isn't enough space. if there isn't enough space.
Don't use oballoc since we may need to allocate other things during Don't use oballoc since we may need to allocate other things during
this function on the temporary obstack. */ this function on the temporary obstack. */
tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * regset_bytes); init_regset_vector (basic_block_live_at_end, n_basic_blocks, regset_bytes,
bzero ((char *) tem, n_basic_blocks * regset_bytes); &flow_obstack);
init_regset_vector (basic_block_live_at_end, tem,
n_basic_blocks, regset_bytes);
basic_block_new_live_at_end basic_block_new_live_at_end
= (regset *) alloca (n_basic_blocks * sizeof (regset)); = (regset *) alloca (n_basic_blocks * sizeof (regset));
tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * regset_bytes); init_regset_vector (basic_block_new_live_at_end, n_basic_blocks, regset_bytes,
bzero ((char *) tem, n_basic_blocks * regset_bytes); &flow_obstack);
init_regset_vector (basic_block_new_live_at_end, tem,
n_basic_blocks, regset_bytes);
basic_block_significant basic_block_significant
= (regset *) alloca (n_basic_blocks * sizeof (regset)); = (regset *) alloca (n_basic_blocks * sizeof (regset));
tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * regset_bytes); init_regset_vector (basic_block_significant, n_basic_blocks, regset_bytes,
bzero ((char *) tem, n_basic_blocks * regset_bytes); &flow_obstack);
init_regset_vector (basic_block_significant, tem,
n_basic_blocks, regset_bytes);
/* Record which insns refer to any volatile memory /* Record which insns refer to any volatile memory
or for any reason can't be deleted just because they are dead stores. or for any reason can't be deleted just because they are dead stores.
...@@ -1259,7 +1260,6 @@ void ...@@ -1259,7 +1260,6 @@ void
allocate_for_life_analysis () allocate_for_life_analysis ()
{ {
register int i; register int i;
register regset tem;
regset_size = ((max_regno + REGSET_ELT_BITS - 1) / REGSET_ELT_BITS); regset_size = ((max_regno + REGSET_ELT_BITS - 1) / REGSET_ELT_BITS);
regset_bytes = regset_size * sizeof (*(regset) 0); regset_bytes = regset_size * sizeof (*(regset) 0);
...@@ -1275,13 +1275,11 @@ allocate_for_life_analysis () ...@@ -1275,13 +1275,11 @@ allocate_for_life_analysis ()
basic_block_live_at_start basic_block_live_at_start
= (regset *) oballoc (n_basic_blocks * sizeof (regset)); = (regset *) oballoc (n_basic_blocks * sizeof (regset));
tem = (regset) oballoc (n_basic_blocks * regset_bytes); init_regset_vector (basic_block_live_at_start, n_basic_blocks, regset_bytes,
bzero ((char *) tem, n_basic_blocks * regset_bytes); function_obstack);
init_regset_vector (basic_block_live_at_start, tem,
n_basic_blocks, regset_bytes);
regs_live_at_setjmp = (regset) oballoc (regset_bytes); regs_live_at_setjmp = OBSTACK_ALLOC_REG_SET (function_obstack);
bzero ((char *) regs_live_at_setjmp, regset_bytes); CLEAR_REG_SET (regs_live_at_setjmp);
} }
/* Make each element of VECTOR point at a regset, /* Make each element of VECTOR point at a regset,
...@@ -1290,19 +1288,18 @@ allocate_for_life_analysis () ...@@ -1290,19 +1288,18 @@ allocate_for_life_analysis ()
BYTES_PER_ELT is the number of bytes in one regset. */ BYTES_PER_ELT is the number of bytes in one regset. */
static void static void
init_regset_vector (vector, space, nelts, bytes_per_elt) init_regset_vector (vector, nelts, bytes_per_elt, alloc_obstack)
regset *vector; regset *vector;
regset space;
int nelts; int nelts;
int bytes_per_elt; int bytes_per_elt;
struct obstack *alloc_obstack;
{ {
register int i; register int i;
register regset p = space;
for (i = 0; i < nelts; i++) for (i = 0; i < nelts; i++)
{ {
vector[i] = p; vector[i] = OBSTACK_ALLOC_REG_SET (alloc_obstack);
p += bytes_per_elt / sizeof (*p); CLEAR_REG_SET (vector[i]);
} }
} }
...@@ -1354,8 +1351,8 @@ propagate_block (old, first, last, final, significant, bnum) ...@@ -1354,8 +1351,8 @@ propagate_block (old, first, last, final, significant, bnum)
current basic block, and adjust as we pass ends and starts of loops. */ current basic block, and adjust as we pass ends and starts of loops. */
loop_depth = basic_block_loop_depth[bnum]; loop_depth = basic_block_loop_depth[bnum];
dead = (regset) alloca (regset_bytes); dead = ALLOCA_REG_SET ();
live = (regset) alloca (regset_bytes); live = ALLOCA_REG_SET ();
cc0_live = 0; cc0_live = 0;
last_mem_set = 0; last_mem_set = 0;
...@@ -1378,7 +1375,7 @@ propagate_block (old, first, last, final, significant, bnum) ...@@ -1378,7 +1375,7 @@ propagate_block (old, first, last, final, significant, bnum)
register int i; register int i;
num_scratch = 0; num_scratch = 0;
maxlive = (regset) alloca (regset_bytes); maxlive = ALLOCA_REG_SET ();
COPY_REG_SET (maxlive, old); COPY_REG_SET (maxlive, old);
regs_sometimes_live = (int *) alloca (max_regno * sizeof (int)); regs_sometimes_live = (int *) alloca (max_regno * sizeof (int));
...@@ -2300,9 +2297,15 @@ mark_used_regs (needed, live, x, final, insn) ...@@ -2300,9 +2297,15 @@ mark_used_regs (needed, live, x, final, insn)
return; return;
case MEM: case MEM:
/* Invalidate the data for the last MEM stored. We could do this only /* CYGNUS LOCAL dje/8176 */
if the addresses conflict, but this doesn't seem worthwhile. */ /* Invalidate the data for the last MEM stored, but only if MEM is
something that can be stored into. */
if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
; /* needn't clear last_mem_set */
else
last_mem_set = 0; last_mem_set = 0;
/* END CYGNUS LOCAL */
#ifdef AUTO_INC_DEC #ifdef AUTO_INC_DEC
if (final) if (final)
...@@ -2732,7 +2735,7 @@ try_pre_increment (insn, reg, amount) ...@@ -2732,7 +2735,7 @@ try_pre_increment (insn, reg, amount)
If REG appears more than once, or is used other than in such an address, If REG appears more than once, or is used other than in such an address,
return (rtx)1. */ return (rtx)1. */
static rtx rtx /* CYGNUS LOCAL: regmove/amylaar */ /* find_use_as_address non-static */
find_use_as_address (x, reg, plusconst) find_use_as_address (x, reg, plusconst)
register rtx x; register rtx x;
rtx reg; rtx reg;
......
...@@ -1350,6 +1350,15 @@ mostly_true_jump (jump_insn, condition) ...@@ -1350,6 +1350,15 @@ mostly_true_jump (jump_insn, condition)
int rare_dest = rare_destination (target_label); int rare_dest = rare_destination (target_label);
int rare_fallthrough = rare_destination (NEXT_INSN (jump_insn)); int rare_fallthrough = rare_destination (NEXT_INSN (jump_insn));
/* CYGNUS LOCAL -- branch prediction */
int expected = condjump_expect_p (jump_insn);
if (expected > 0)
return 2;
else if (expected < 0)
return -1;
/* END CYGNUS LOCAL -- branch prediction */
/* If branch probabilities are available, then use that number since it /* If branch probabilities are available, then use that number since it
always gives a correct answer. */ always gives a correct answer. */
if (flag_branch_probabilities) if (flag_branch_probabilities)
......
...@@ -3857,12 +3857,13 @@ schedule_block (b, file) ...@@ -3857,12 +3857,13 @@ schedule_block (b, file)
attach_deaths_insn (insn); attach_deaths_insn (insn);
/* Find registers now made live by that instruction. */ /* Find registers now made live by that instruction. */
EXECUTE_IF_SET_IN_REG_SET (bb_live_regs, 0, i, EXECUTE_IF_AND_COMPL_IN_REG_SET (bb_live_regs, old_live_regs, 0, i,
{ {
sometimes_max sometimes_max
= new_sometimes_live (regs_sometimes_live, = new_sometimes_live (regs_sometimes_live,
i, sometimes_max); i, sometimes_max);
}); });
IOR_REG_SET (old_live_regs, bb_live_regs);
/* Count lengths of all regs we are worrying about now, /* Count lengths of all regs we are worrying about now,
and handle registers no longer live. */ and handle registers no longer live. */
...@@ -3874,7 +3875,7 @@ schedule_block (b, file) ...@@ -3874,7 +3875,7 @@ schedule_block (b, file)
p->live_length += 1; p->live_length += 1;
if (REGNO_REG_SET_P (bb_live_regs, p->regno)) if (!REGNO_REG_SET_P (bb_live_regs, p->regno))
{ {
/* This is the end of one of this register's lifetime /* This is the end of one of this register's lifetime
segments. Save the lifetime info collected so far, segments. Save the lifetime info collected so far,
......
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