+2010-03-02 Jeff Law <law@redhat.com>
+
+ * reload1.c (rtx_p, substitute_stack): Declare.
+ (substitute): Record addresses of changed rtxs.
+ (gen_reload_chain_without_interm_reg_p): Don't use copy_rtx anymore.
+ Restore the original rtx when complete.
+ (reload): Free subsitute_stack when complete.
+
2010-03-02 Janis Johnson <janis187@us.ibm.com>
* doc/gccint.texi (menu): Add Testsuites as a chapter.
static char *offsets_known_at;
static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
+/* Stack of addresses where an rtx has been changed. We can undo the
+ changes by popping items off the stack and restoring the original
+ value at each location.
+
+ We use this simplistic undo capability rather than copy_rtx as copy_rtx
+ will not make a deep copy of a normally sharable rtx, such as
+ (const (plus (symbol_ref) (const_int))). If such an expression appears
+ as R1 in gen_reload_chain_without_interm_reg_p, then a shared
+ rtx expression would be changed. See PR 42431. */
+
+typedef rtx *rtx_p;
+DEF_VEC_P(rtx_p);
+DEF_VEC_ALLOC_P(rtx_p,heap);
+static VEC(rtx_p,heap) *substitute_stack;
+
/* Number of labels in the current function. */
static int num_labels;
REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
#endif
+ VEC_free (rtx_p, heap, substitute_stack);
+
return failure;
}
return true;
}
-
/* The recursive function change all occurrences of WHAT in *WHERE
- onto REPL. */
+ to REPL. */
static void
substitute (rtx *where, const_rtx what, rtx repl)
{
if (*where == what || rtx_equal_p (*where, what))
{
+ /* Record the location of the changed rtx. */
+ VEC_safe_push (rtx_p, heap, substitute_stack, where);
*where = repl;
return;
}
static bool
gen_reload_chain_without_interm_reg_p (int r1, int r2)
{
- bool result;
+ /* Assume other cases in gen_reload are not possible for
+ chain reloads or do need an intermediate hard registers. */
+ bool result = true;
int regno, n, code;
rtx out, in, tem, insn;
rtx last = get_last_insn ();
regno = rld[r1].regno >= 0 ? rld[r1].regno : rld[r2].regno;
gcc_assert (regno >= 0);
out = gen_rtx_REG (rld[r1].mode, regno);
- in = copy_rtx (rld[r1].in);
+ in = rld[r1].in;
substitute (&in, rld[r2].in, gen_rtx_REG (rld[r2].mode, regno));
/* If IN is a paradoxical SUBREG, remove it and try to put the
}
delete_insns_since (last);
- return result;
}
- /* It looks like other cases in gen_reload are not possible for
- chain reloads or do need an intermediate hard registers. */
- return true;
+ /* Restore the original value at each changed address within R1. */
+ while (!VEC_empty (rtx_p, substitute_stack))
+ {
+ rtx *where = VEC_pop (rtx_p, substitute_stack);
+ *where = rld[r2].in;
+ }
+
+ return result;
}
/* Return 1 if the reloads denoted by R1 and R2 cannot share a register.