Add support for reloading a frame address with an invalid base
gcc/ * lra-constraints.c (base_to_reg): New function. (process_address): Use new function. From-SVN: r211802
This commit is contained in:
parent
786077082e
commit
c31d2d11a9
|
@ -1,3 +1,8 @@
|
|||
2014-06-18 Robert Suchanek <robert.suchanek@imgtec.com>
|
||||
|
||||
* lra-constraints.c (base_to_reg): New function.
|
||||
(process_address): Use new function.
|
||||
|
||||
2014-06-18 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* config/aarch64/aarch64-protos.h (aarch64_emit_call_insn): Declare.
|
||||
|
|
|
@ -2556,6 +2556,39 @@ process_alt_operands (int only_alternative)
|
|||
return ok_p;
|
||||
}
|
||||
|
||||
/* Make reload base reg from address AD. */
|
||||
static rtx
|
||||
base_to_reg (struct address_info *ad)
|
||||
{
|
||||
enum reg_class cl;
|
||||
int code = -1;
|
||||
rtx new_inner = NULL_RTX;
|
||||
rtx new_reg = NULL_RTX;
|
||||
rtx insn;
|
||||
rtx last_insn = get_last_insn();
|
||||
|
||||
lra_assert (ad->base == ad->base_term && ad->disp == ad->disp_term);
|
||||
cl = base_reg_class (ad->mode, ad->as, ad->base_outer_code,
|
||||
get_index_code (ad));
|
||||
new_reg = lra_create_new_reg (GET_MODE (*ad->base_term), NULL_RTX,
|
||||
cl, "base");
|
||||
new_inner = simplify_gen_binary (PLUS, GET_MODE (new_reg), new_reg,
|
||||
ad->disp_term == NULL
|
||||
? gen_int_mode (0, ad->mode)
|
||||
: *ad->disp_term);
|
||||
if (!valid_address_p (ad->mode, new_inner, ad->as))
|
||||
return NULL_RTX;
|
||||
insn = emit_insn (gen_rtx_SET (ad->mode, new_reg, *ad->base_term));
|
||||
code = recog_memoized (insn);
|
||||
if (code < 0)
|
||||
{
|
||||
delete_insns_since (last_insn);
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
return new_inner;
|
||||
}
|
||||
|
||||
/* Make reload base reg + disp from address AD. Return the new pseudo. */
|
||||
static rtx
|
||||
base_plus_disp_to_reg (struct address_info *ad)
|
||||
|
@ -2775,6 +2808,8 @@ process_address_1 (int nop, rtx *before, rtx *after)
|
|||
|
||||
3) the address is a frame address with an invalid offset.
|
||||
|
||||
4) the address is a frame address with an invalid base.
|
||||
|
||||
All these cases involve a non-autoinc address, so there is no
|
||||
point revalidating other types. */
|
||||
if (ad.autoinc_p || valid_address_p (&ad))
|
||||
|
@ -2856,13 +2891,18 @@ process_address_1 (int nop, rtx *before, rtx *after)
|
|||
int regno;
|
||||
enum reg_class cl;
|
||||
rtx set, insns, last_insn;
|
||||
/* Try to reload base into register only if the base is invalid
|
||||
for the address but with valid offset, case (4) above. */
|
||||
start_sequence ();
|
||||
new_reg = base_to_reg (&ad);
|
||||
|
||||
/* base + disp => new base, cases (1) and (3) above. */
|
||||
/* Another option would be to reload the displacement into an
|
||||
index register. However, postreload has code to optimize
|
||||
address reloads that have the same base and different
|
||||
displacements, so reloading into an index register would
|
||||
not necessarily be a win. */
|
||||
start_sequence ();
|
||||
if (new_reg == NULL_RTX)
|
||||
new_reg = base_plus_disp_to_reg (&ad);
|
||||
insns = get_insns ();
|
||||
last_insn = get_last_insn ();
|
||||
|
|
Loading…
Reference in New Issue