diff options
author | Jeff Law <law@redhat.com> | 2010-03-02 11:56:50 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2010-03-02 11:56:50 -0700 |
commit | f6c86fab11ce055b9ba4604b26ae6d7f18a62766 (patch) | |
tree | 80025d6478b1b1df18e8c90787c4addeda028ef9 /gcc/reload1.c | |
parent | 500cdcb007a8d5238dc60b62e2c3adc1e5cd6697 (diff) | |
download | gcc-f6c86fab11ce055b9ba4604b26ae6d7f18a62766.zip gcc-f6c86fab11ce055b9ba4604b26ae6d7f18a62766.tar.gz gcc-f6c86fab11ce055b9ba4604b26ae6d7f18a62766.tar.bz2 |
reload1.c (rtx_p, [...]): Declare.
* 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.
From-SVN: r157168
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index ee90f35..02fef2d 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -378,6 +378,21 @@ static int first_label_num; 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; @@ -1448,6 +1463,8 @@ reload (rtx first, int global) REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; #endif + VEC_free (rtx_p, heap, substitute_stack); + return failure; } @@ -5147,9 +5164,8 @@ reloads_unique_chain_p (int r1, int r2) 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) { @@ -5162,6 +5178,8 @@ 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; } @@ -5209,7 +5227,9 @@ substitute (rtx *where, const_rtx what, rtx repl) 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 (); @@ -5225,7 +5245,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2) 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 @@ -5259,12 +5279,16 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2) } 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. |