From: Jim Wilson Date: Tue, 27 Mar 2001 22:48:03 +0000 (+0000) Subject: Fix ia64-linux ICE on bash. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=685af3af8a54997d1d9e9aa2293b06eca703ec5f;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ff97291e32..07107a411ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-03-27 Jim Wilson + + * 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 * cppmacro.c (stringify_arg): Null terminate strings. diff --git a/gcc/flow.c b/gcc/flow.c index 5b9b31bfb96..6625a6936f5 100644 --- a/gcc/flow.c +++ b/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 the register is now unconditionally dead, - remove the entry in the splay_tree. */ - if (ncond == const1_rtx) + 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. 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); } }