Fix ia64-linux ICE on bash.

* flow.c (struct reg_cond_life_info): New fields orig_condition
	and stores.
	(init_propagate_block_info): Set new fields.
	(mark_regno_cond_dead): Set and use new fields.
	(flush_reg_cond_reg_1): Likewise.
	(and_reg_cond, case AND): Check for redundant AND conditions.
	(mark_used_reg): Delete unnecessary clears before freeing splay trees.
	Set new fields.

From-SVN: r40881
This commit is contained in:
Jim Wilson 2001-03-27 22:48:03 +00:00 committed by Jim Wilson
parent b044e9d5e9
commit 685af3af8a
2 changed files with 52 additions and 11 deletions

View file

@ -1,3 +1,14 @@
2001-03-27 Jim Wilson <wilson@redhat.com>
* flow.c (struct reg_cond_life_info): New fields orig_condition
and stores.
(init_propagate_block_info): Set new fields.
(mark_regno_cond_dead): Set and use new fields.
(flush_reg_cond_reg_1): Likewise.
(and_reg_cond, case AND): Check for redundant AND conditions.
(mark_used_reg): Delete unnecessary clears before freeing splay trees.
Set new fields.
2001-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
* cppmacro.c (stringify_arg): Null terminate strings.

View file

@ -275,8 +275,14 @@ static rtx tail_recursion_label_list;
/* Holds information for tracking conditional register life information. */
struct reg_cond_life_info
{
/* An EXPR_LIST of conditions under which a register is dead. */
/* A boolean expression of conditions under which a register is dead. */
rtx condition;
/* Conditions under which a register is dead at the basic block end. */
rtx orig_condition;
/* A boolean expression of conditions under which a register has been
stored into. */
rtx stores;
/* ??? Could store mask of bytes that are dead, so that we could finally
track lifetimes of multi-word registers accessed via subregs. */
@ -4202,6 +4208,8 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
else
cond = cond_true;
rcli->condition = cond;
rcli->stores = const0_rtx;
rcli->orig_condition = cond;
splay_tree_insert (pbi->reg_cond_dead, i,
(splay_tree_value) rcli);
@ -5146,6 +5154,8 @@ mark_regno_cond_dead (pbi, regno, cond)
which it is dead. */
rcli = (struct reg_cond_life_info *) xmalloc (sizeof (*rcli));
rcli->condition = cond;
rcli->stores = cond;
rcli->orig_condition = const0_rtx;
splay_tree_insert (pbi->reg_cond_dead, regno,
(splay_tree_value) rcli);
@ -5161,10 +5171,21 @@ mark_regno_cond_dead (pbi, regno, cond)
rcli = (struct reg_cond_life_info *) node->value;
ncond = rcli->condition;
ncond = ior_reg_cond (ncond, cond, 1);
if (rcli->stores == const0_rtx)
rcli->stores = cond;
else if (rcli->stores != const1_rtx)
rcli->stores = ior_reg_cond (rcli->stores, cond, 1);
/* If the register is now unconditionally dead,
remove the entry in the splay_tree. */
if (ncond == const1_rtx)
/* If the register is now unconditionally dead, remove the entry
in the splay_tree. A register is unconditionally dead if the
dead condition ncond is true. A register is also unconditionally
dead if the sum of all conditional stores is an unconditional
store (stores is true), and the dead condition is identically the
same as the original dead condition initialized at the end of
the block. This is a pointer compare, not an rtx_equal_p
compare. */
if (ncond == const1_rtx
|| (ncond == rcli->orig_condition && rcli->stores == const1_rtx))
splay_tree_remove (pbi->reg_cond_dead, regno);
else
{
@ -5210,6 +5231,8 @@ flush_reg_cond_reg_1 (node, data)
/* Splice out portions of the expression that refer to regno. */
rcli = (struct reg_cond_life_info *) node->value;
rcli->condition = elim_reg_cond (rcli->condition, regno);
if (rcli->stores != const0_rtx && rcli->stores != const1_rtx)
rcli->stores = elim_reg_cond (rcli->stores, regno);
/* If the entire condition is now false, signal the node to be removed. */
if (rcli->condition == const0_rtx)
@ -5416,6 +5439,17 @@ and_reg_cond (old, x, add)
}
if (! add)
return old;
/* If X is identical to one of the existing terms of the AND,
then just return what we already have. */
/* ??? There really should be some sort of recursive check here in
case there are nested ANDs. */
if ((GET_CODE (XEXP (old, 0)) == GET_CODE (x)
&& REGNO (XEXP (XEXP (old, 0), 0)) == REGNO (XEXP (x, 0)))
|| (GET_CODE (XEXP (old, 1)) == GET_CODE (x)
&& REGNO (XEXP (XEXP (old, 1), 0)) == REGNO (XEXP (x, 0))))
return old;
return gen_rtx_AND (0, old, x);
case NOT:
@ -5899,10 +5933,7 @@ mark_used_reg (pbi, reg, cond, insn)
/* If the register is now unconditionally live, remove the
entry in the splay_tree. */
if (ncond == const0_rtx)
{
rcli->condition = NULL_RTX;
splay_tree_remove (pbi->reg_cond_dead, regno);
}
splay_tree_remove (pbi->reg_cond_dead, regno);
else
{
rcli->condition = ncond;
@ -5916,6 +5947,8 @@ mark_used_reg (pbi, reg, cond, insn)
the condition under which it is still dead. */
rcli = (struct reg_cond_life_info *) xmalloc (sizeof (*rcli));
rcli->condition = not_reg_cond (cond);
rcli->stores = const0_rtx;
rcli->orig_condition = const0_rtx;
splay_tree_insert (pbi->reg_cond_dead, regno,
(splay_tree_value) rcli);
@ -5925,7 +5958,6 @@ mark_used_reg (pbi, reg, cond, insn)
else if (some_was_live)
{
splay_tree_node node;
struct reg_cond_life_info *rcli;
node = splay_tree_lookup (pbi->reg_cond_dead, regno);
if (node != NULL)
@ -5934,8 +5966,6 @@ mark_used_reg (pbi, reg, cond, insn)
unconditionally so. Remove it from the conditionally dead
list, so that a conditional set won't cause us to think
it dead. */
rcli = (struct reg_cond_life_info *) node->value;
rcli->condition = NULL_RTX;
splay_tree_remove (pbi->reg_cond_dead, regno);
}
}