Commit c31d2d11 by Robert Suchanek Committed by Matthew Fortune

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
parent 78607708
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> 2014-06-18 Tom de Vries <tom@codesourcery.com>
* config/aarch64/aarch64-protos.h (aarch64_emit_call_insn): Declare. * config/aarch64/aarch64-protos.h (aarch64_emit_call_insn): Declare.
......
...@@ -2556,6 +2556,39 @@ process_alt_operands (int only_alternative) ...@@ -2556,6 +2556,39 @@ process_alt_operands (int only_alternative)
return ok_p; 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. */ /* Make reload base reg + disp from address AD. Return the new pseudo. */
static rtx static rtx
base_plus_disp_to_reg (struct address_info *ad) base_plus_disp_to_reg (struct address_info *ad)
...@@ -2775,6 +2808,8 @@ process_address_1 (int nop, rtx *before, rtx *after) ...@@ -2775,6 +2808,8 @@ process_address_1 (int nop, rtx *before, rtx *after)
3) the address is a frame address with an invalid offset. 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 All these cases involve a non-autoinc address, so there is no
point revalidating other types. */ point revalidating other types. */
if (ad.autoinc_p || valid_address_p (&ad)) if (ad.autoinc_p || valid_address_p (&ad))
...@@ -2856,13 +2891,18 @@ process_address_1 (int nop, rtx *before, rtx *after) ...@@ -2856,13 +2891,18 @@ process_address_1 (int nop, rtx *before, rtx *after)
int regno; int regno;
enum reg_class cl; enum reg_class cl;
rtx set, insns, last_insn; 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. */ /* base + disp => new base, cases (1) and (3) above. */
/* Another option would be to reload the displacement into an /* Another option would be to reload the displacement into an
index register. However, postreload has code to optimize index register. However, postreload has code to optimize
address reloads that have the same base and different address reloads that have the same base and different
displacements, so reloading into an index register would displacements, so reloading into an index register would
not necessarily be a win. */ not necessarily be a win. */
start_sequence (); if (new_reg == NULL_RTX)
new_reg = base_plus_disp_to_reg (&ad); new_reg = base_plus_disp_to_reg (&ad);
insns = get_insns (); insns = get_insns ();
last_insn = get_last_insn (); last_insn = get_last_insn ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment