From 81dda3d57580cae84901187cf6375c26bde09963 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 14 Jan 2008 12:19:58 +0000 Subject: [PATCH] re PR rtl-optimization/31944 (Endless loop while building a 64-bit 2.6.20 kernel) PR rtl-optimization/31944 * cse.c (remove_pseudo_from_table): New function. (merge_equiv_classes): Use above function to remove pseudo-registers. (invalidate): Likewise. From-SVN: r131524 --- gcc/ChangeLog | 7 +++++ gcc/cse.c | 30 ++++++++++++------- gcc/testsuite/ChangeLog | 4 +++ .../gcc.c-torture/compile/20080114-1.c | 14 +++++++++ 4 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20080114-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8ae029b6c10e..42b678c3e092 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-01-14 Eric Botcazou + + PR rtl-optimization/31944 + * cse.c (remove_pseudo_from_table): New function. + (merge_equiv_classes): Use above function to remove pseudo-registers. + (invalidate): Likewise. + 2007-12-31 John David Anglin PR driver/33772 diff --git a/gcc/cse.c b/gcc/cse.c index 70fec9eec638..a35c41c8a0d1 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -583,7 +583,8 @@ static void delete_reg_equiv (unsigned int); static int mention_regs (rtx); static int insert_regs (rtx, struct table_elt *, int); static void remove_from_table (struct table_elt *, unsigned); -static struct table_elt *lookup (rtx, unsigned, enum machine_mode); +static void remove_pseudo_from_table (rtx, unsigned); +static struct table_elt *lookup (rtx, unsigned, enum machine_mode); static struct table_elt *lookup_for_remove (rtx, unsigned, enum machine_mode); static rtx lookup_as_function (rtx, enum rtx_code); static struct table_elt *insert (rtx, struct table_elt *, unsigned, @@ -1382,6 +1383,19 @@ remove_from_table (struct table_elt *elt, unsigned int hash) table_size--; } +/* Same as above, but X is a pseudo-register. */ + +static void +remove_pseudo_from_table (rtx x, unsigned int hash) +{ + struct table_elt *elt; + + /* Because a pseudo-register can be referenced in more than one + mode, we might have to remove more than one table entry. */ + while ((elt = lookup_for_remove (x, hash, VOIDmode))) + remove_from_table (elt, hash); +} + /* Look up X in the hash table and return its table element, or 0 if X is not in the table. @@ -1708,7 +1722,10 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2) delete_reg_equiv (REGNO (exp)); } - remove_from_table (elt, hash); + if (REG_P (exp) && REGNO (exp) >= FIRST_PSEUDO_REGISTER) + remove_pseudo_from_table (exp, hash); + else + remove_from_table (elt, hash); if (insert_regs (exp, class1, 0) || need_rehash) { @@ -1804,14 +1821,7 @@ invalidate (rtx x, enum machine_mode full_mode) SUBREG_TICKED (regno) = -1; if (regno >= FIRST_PSEUDO_REGISTER) - { - /* Because a register can be referenced in more than one mode, - we might have to remove more than one table entry. */ - struct table_elt *elt; - - while ((elt = lookup_for_remove (x, hash, GET_MODE (x)))) - remove_from_table (elt, hash); - } + remove_pseudo_from_table (x, hash); else { HOST_WIDE_INT in_table diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e041686832bb..99e21bf25bf0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-01-14 Eric Botcazou + + * gcc.c-torture/compile/20080114-1.c: New test. + 2008-01-09 Kaveh R. Ghazi * gcc.c-torture/execute/builtins/chk.h: Don't check !__PIE__. diff --git a/gcc/testsuite/gcc.c-torture/compile/20080114-1.c b/gcc/testsuite/gcc.c-torture/compile/20080114-1.c new file mode 100644 index 000000000000..51affb7bddc9 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20080114-1.c @@ -0,0 +1,14 @@ +/* PR rtl-optimization/31944 */ +/* Origin: Aurelien Jarno */ + +int type; + +void stuck(int res) +{ + if (type == 1) { + if (res == 0) asm volatile("nop"); + } + else if (type == 0) { + if (res == 0) asm volatile("nop" : : "i" (0)); + } +} -- 2.47.2