diff options
author | Rong Xu <xur@google.com> | 2014-07-21 16:47:22 -0700 |
---|---|---|
committer | Rong Xu <xur@google.com> | 2014-07-29 15:31:03 -0700 |
commit | 38a8aecfb882072900434499696b5c32a2274515 (patch) | |
tree | 2aac97f0ae24b03cd98c1a06e989c031c173f889 /gcc-4.9/gcc/lra-constraints.c | |
parent | c231900e5dcc14d8296bd9f62b45997a49d4d5e7 (diff) | |
download | toolchain_gcc-38a8aecfb882072900434499696b5c32a2274515.tar.gz toolchain_gcc-38a8aecfb882072900434499696b5c32a2274515.tar.bz2 toolchain_gcc-38a8aecfb882072900434499696b5c32a2274515.zip |
[4.9] Switch gcc-4.9 to use google/gcc-4_9 branch.
This source drop uses svn version r212828 of google/gcc-4.9 branch.
We also cherry-picked r213062, r213063 and r213064 to fix windows
build issues.
All gcc-4.9 patches before July 3rd are ported to google/gcc-4.9.
The following prior commits has not been merged to google branch yet.
(They are included in this commit).
e7af147f979e657fe2df00808e5b4319b0e088c6,
baf87df3cb2683649ba7e9872362a7e721117c23, and
c231900e5dcc14d8296bd9f62b45997a49d4d5e7.
Change-Id: I4bea3ea470387ff751c2be4cb0d4a12059b9299b
Diffstat (limited to 'gcc-4.9/gcc/lra-constraints.c')
-rw-r--r-- | gcc-4.9/gcc/lra-constraints.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/gcc-4.9/gcc/lra-constraints.c b/gcc-4.9/gcc/lra-constraints.c index b7bfc57a5..ec28b7ff8 100644 --- a/gcc-4.9/gcc/lra-constraints.c +++ b/gcc-4.9/gcc/lra-constraints.c @@ -1343,6 +1343,8 @@ insert_move_for_subreg (rtx *before, rtx *after, rtx origreg, rtx newreg) } } +static int valid_address_p (enum machine_mode mode, rtx addr, addr_space_t as); + /* Make reloads for subreg in operand NOP with internal subreg mode REG_MODE, add new reloads for further processing. Return true if any reload was generated. */ @@ -1373,10 +1375,26 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode) equivalences in function lra_constraints) and because for spilled pseudos we allocate stack memory enough for the biggest corresponding paradoxical subreg. */ - if ((MEM_P (reg) - && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg)) - || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode))) - || (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER)) + if (MEM_P (reg) + && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg)) + || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode))) + { + rtx subst, old = *curr_id->operand_loc[nop]; + + alter_subreg (curr_id->operand_loc[nop], false); + subst = *curr_id->operand_loc[nop]; + lra_assert (MEM_P (subst)); + if (! valid_address_p (GET_MODE (reg), XEXP (reg, 0), + MEM_ADDR_SPACE (reg)) + || valid_address_p (GET_MODE (subst), XEXP (subst, 0), + MEM_ADDR_SPACE (subst))) + return true; + /* If the address was valid and became invalid, prefer to reload + the memory. Typical case is when the index scale should + correspond the memory. */ + *curr_id->operand_loc[nop] = old; + } + else if (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER) { alter_subreg (curr_id->operand_loc[nop], false); return true; @@ -2879,9 +2897,14 @@ equiv_address_substitution (struct address_info *ad) Add reloads to the lists *BEFORE and *AFTER. We might need to add reloads to *AFTER because of inc/dec, {pre, post} modify in the - address. Return true for any RTL change. */ + address. Return true for any RTL change. + + The function is a helper function which does not produce all + transformations which can be necessary. It does just basic steps. + To do all necessary transformations use function + process_address. */ static bool -process_address (int nop, rtx *before, rtx *after) +process_address_1 (int nop, rtx *before, rtx *after) { struct address_info ad; rtx new_reg; @@ -3071,6 +3094,13 @@ process_address (int nop, rtx *before, rtx *after) *ad.inner = simplify_gen_binary (PLUS, GET_MODE (new_reg), new_reg, *ad.index); } + else if (get_index_scale (&ad) == 1) + { + /* The last transformation to one reg will be made in + curr_insn_transform function. */ + end_sequence (); + return false; + } else { /* base + scale * index => base + new_reg, @@ -3088,6 +3118,18 @@ process_address (int nop, rtx *before, rtx *after) return true; } +/* Do address reloads until it is necessary. Use process_address_1 as + a helper function. Return true for any RTL changes. */ +static bool +process_address (int nop, rtx *before, rtx *after) +{ + bool res = false; + + while (process_address_1 (nop, before, after)) + res = true; + return res; +} + /* Emit insns to reload VALUE into a new register. VALUE is an auto-increment or auto-decrement RTX whose operand is a register or memory location; so reloading involves incrementing that location. @@ -3372,7 +3414,7 @@ curr_insn_transform (void) change_p = true; lra_update_dup (curr_id, i); } - + if (change_p) /* If we've changed the instruction then any alternative that we chose previously may no longer be valid. */ |