This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch RFC] Fix bogus RTL sharing error
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 28 Nov 2006 07:43:29 +0900 (JST)
- Subject: [patch RFC] Fix bogus RTL sharing error
Hi,
I've looked at the errors for invalid RTL sharing for Mips and
SH with the RTL sharing verifier.
A typical mips example of the insn causing the error is
(insn 68 24 31 (sequence [
(jump_insn 29 24 26 (set (pc)
(if_then_else (ne (reg:SI 4 $4 [199])
(const_int 0 [0x0]))
(label_ref:SI 19)
(pc))) 274 {*branch_equalitysi} (nil)
(expr_list:REG_BR_PRED (const_int 6 [0x6])
(expr_list:REG_DEAD (reg:SI 4 $4 [199])
(expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
(nil)))))
(insn 26 29 31 (set (reg/v:SI 16 $16 [orig:193 value ] [193])
(plus:SI (reg:SI 2 $2 [197])
(reg:SI 3 $3 [198]))) 6 {*addsi3} (nil)
(nil))
]) -1 (nil)
(nil))
and the verifier complains that the subexpression
(set (reg/v:SI 16 $16 [orig:193 value ] [193])
(plus:SI (reg:SI 2 $2 [197])
(reg:SI 3 $3 [198]))
is shared invalidly. But it seems that this error is bogus,
though I could be wrong about that.
During verification, verify_rtl_sharing clears the used flags
of all insn bodies and then checks them with marking the flag:
for (p = get_insns (); p; p = NEXT_INSN (p))
if (INSN_P (p))
{
reset_used_flags (PATTERN (p));
reset_used_flags (REG_NOTES (p));
reset_used_flags (LOG_LINKS (p));
}
for (p = get_insns (); p; p = NEXT_INSN (p))
if (INSN_P (p))
{
verify_rtx_sharing (PATTERN (p), p);
verify_rtx_sharing (REG_NOTES (p), p);
verify_rtx_sharing (LOG_LINKS (p), p);
}
In the above rtl which causes the error, verify_rtx_sharing
marked all used flags of the subexpressions of sequence.
However, since reset_used_flags doesn't go through the insn,
the used flag of the above set subexpression is never cleared.
Then if verify_rtl_sharing was invoked multiple times, that
subexpression causes a bogus error. The appended patch adds
a boolean argument to make reset_used_flags go through
the insns recursively.
Bootstrapped and regtested with the top level "make -k check"
on i686-pc-linux-gnu.
Regards,
kaz
--
2006-11-27 Kaz Kojima <kkojima@gcc.gnu.org>
* emit-rtl.c (reset_used_flags_1): New.
(verify_rtl_sharing): Use reset_used_flags_1 instead of
reset_used_flags for pattern of the insn.
(reset_used_flags): Use reset_used_flags_1.
--- ORIG/trunk/gcc/emit-rtl.c 2006-11-12 20:14:34.000000000 +0900
+++ LOCAL/trunk/gcc/emit-rtl.c 2006-11-25 22:50:16.000000000 +0900
@@ -185,6 +185,7 @@ static reg_attrs *get_reg_attrs (tree, i
static tree component_ref_for_mem_expr (tree);
static rtx gen_const_vector (enum machine_mode, int);
static void copy_rtx_if_shared_1 (rtx *orig);
+static void reset_used_flags_1 (rtx, bool);
/* Probability of the conditional branch currently proceeded by try_split.
Set to -1 otherwise. */
@@ -2289,7 +2290,7 @@ verify_rtl_sharing (void)
for (p = get_insns (); p; p = NEXT_INSN (p))
if (INSN_P (p))
{
- reset_used_flags (PATTERN (p));
+ reset_used_flags_1 (PATTERN (p), true);
reset_used_flags (REG_NOTES (p));
reset_used_flags (LOG_LINKS (p));
}
@@ -2494,6 +2495,12 @@ repeat:
void
reset_used_flags (rtx x)
{
+ reset_used_flags_1 (x, false);
+}
+
+static void
+reset_used_flags_1 (rtx x, bool handle_insn)
+{
int i, j;
enum rtx_code code;
const char *format_ptr;
@@ -2524,6 +2531,8 @@ repeat:
case INSN:
case JUMP_INSN:
case CALL_INSN:
+ if (handle_insn)
+ break;
case NOTE:
case LABEL_REF:
case BARRIER:
@@ -2549,12 +2558,12 @@ repeat:
x = XEXP (x, i);
goto repeat;
}
- reset_used_flags (XEXP (x, i));
+ reset_used_flags_1 (XEXP (x, i), handle_insn);
break;
case 'E':
for (j = 0; j < XVECLEN (x, i); j++)
- reset_used_flags (XVECEXP (x, i, j));
+ reset_used_flags_1 (XVECEXP (x, i, j), handle_insn);
break;
}
}