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:
parent
b044e9d5e9
commit
685af3af8a
2 changed files with 52 additions and 11 deletions
|
@ -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.
|
||||
|
|
52
gcc/flow.c
52
gcc/flow.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue