This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
2.95: Fix infinite recursion in combiner.
- To: <gcc-patches at gcc dot gnu dot org>
- Subject: 2.95: Fix infinite recursion in combiner.
- From: Bernd Schmidt <bernds at redhat dot com>
- Date: Tue, 3 Apr 2001 14:12:38 +0100 (BST)
See
http://gcc.gnu.org/ml/gcc-patches/1999-08/msg00743.html
for an explanation. This is a fairly nasty problem that can cause
infinite recursions.
Bernd
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ChangeLog,v
retrieving revision 1.3667.4.350
diff -u -p -r1.3667.4.350 ChangeLog
--- ChangeLog 2001/04/03 12:36:23 1.3667.4.350
+++ ChangeLog 2001/04/03 13:11:30
@@ -13,6 +13,14 @@
* arm/linux-elf.h (MAKE_DECL_ONE_ONLY, UNIQUE_SECTION_P): Define.
(UNIQUE_SECTION): Define.
+ Wed Aug 25 15:27:22 1999 Gavin Romig-Koch <gavin@cygnus.com>
+ * combine.c (nonzero_bits) : Allow single-ly set registers to be
+ anywere in the function only if they are pseudos and set before
+ being used (not live at the start of the function).
+ (num_sign_bit_copies) : Same.
+ (get_last_value_validate) : Same.
+ (get_last_value) : Same.
+
2001-03-30 Bernd Schmidt <bernds@redhat.com>
* jump.c (delete_barrier_successors): Fix error in last change.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.62.4.5
diff -u -p -r1.62.4.5 combine.c
--- combine.c 2001/01/25 14:03:01 1.62.4.5
+++ combine.c 2001/04/03 13:11:34
@@ -7580,8 +7580,11 @@ nonzero_bits (x, mode)
if (reg_last_set_value[REGNO (x)] != 0
&& reg_last_set_mode[REGNO (x)] == mode
- && (REG_N_SETS (REGNO (x)) == 1
- || reg_last_set_label[REGNO (x)] == label_tick)
+ && (reg_last_set_label[REGNO (x)] == label_tick
+ || (REGNO (x) >= FIRST_PSEUDO_REGISTER
+ && REG_N_SETS (REGNO (x)) == 1
+ && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
+ REGNO (x))))
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
return reg_last_set_nonzero_bits[REGNO (x)];
@@ -7970,8 +7973,11 @@ num_sign_bit_copies (x, mode)
if (reg_last_set_value[REGNO (x)] != 0
&& reg_last_set_mode[REGNO (x)] == mode
- && (REG_N_SETS (REGNO (x)) == 1
- || reg_last_set_label[REGNO (x)] == label_tick)
+ && (reg_last_set_label[REGNO (x)] == label_tick
+ || (REGNO (x) >= FIRST_PSEUDO_REGISTER
+ && REG_N_SETS (REGNO (x)) == 1
+ && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
+ REGNO (x))))
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
return reg_last_set_sign_bit_copies[REGNO (x)];
@@ -10819,9 +10825,11 @@ get_last_value_validate (loc, insn, tick
for (j = regno; j < endregno; j++)
if (reg_last_set_invalid[j]
- /* If this is a pseudo-register that was only set once, it is
- always valid. */
- || (! (regno >= FIRST_PSEUDO_REGISTER && REG_N_SETS (regno) == 1)
+ /* If this is a pseudo-register that was only set once and not
+ live at the beginning of the function, it is always valid. */
+ || (! (regno >= FIRST_PSEUDO_REGISTER
+ && REG_N_SETS (regno) == 1
+ && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))
&& reg_last_set_label[j] > tick))
{
if (replace)
@@ -10880,12 +10888,21 @@ get_last_value (x)
regno = REGNO (x);
value = reg_last_set_value[regno];
- /* If we don't have a value or if it isn't for this basic block,
- return 0. */
+ /* If we don't have a value, or if it isn't for this basic block and
+ it's either a hard register, set more than once, or it's a live
+ at the beginning of the function, return 0.
+
+ Because if it's not live at the beginnning of the function then the reg
+ is always set before being used (is never used without being set).
+ And, if it's set only once, and it's always set before use, then all
+ uses must have the same last value, even if it's not from this basic
+ block. */
if (value == 0
- || (REG_N_SETS (regno) != 1
- && reg_last_set_label[regno] != label_tick))
+ || (reg_last_set_label[regno] != label_tick
+ && (regno < FIRST_PSEUDO_REGISTER
+ || REG_N_SETS (regno) != 1
+ || REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))))
return 0;
/* If the value was set in a later insn than the ones we are processing,