aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2023-08-11 07:57:37 -0400
committerVladimir N. Makarov <vmakarov@redhat.com>2023-08-11 11:14:02 -0400
commitef96754d8aa6f21e3a76c3fe26fc0203fb703837 (patch)
tree40ac5ce87208a6325b95f5b0f516d2595e1b6fb0
parentc19b542a177b7b65b013e535ae9f384352808d11 (diff)
downloadgcc-ef96754d8aa6f21e3a76c3fe26fc0203fb703837.zip
gcc-ef96754d8aa6f21e3a76c3fe26fc0203fb703837.tar.gz
gcc-ef96754d8aa6f21e3a76c3fe26fc0203fb703837.tar.bz2
[LRA]: Implement output stack pointer reloads
LRA prohibited output stack pointer reloads but it resulted in LRA failure for AVR target which has no arithmetic insns working with the stack pointer register. Given patch implements the output stack pointer reloads. gcc/ChangeLog: * lra-constraints.cc (goal_alt_out_sp_reload_p): New flag. (process_alt_operands): Set the flag. (curr_insn_transform): Modify stack pointer offsets if output stack pointer reload is generated.
-rw-r--r--gcc/lra-constraints.cc38
1 files changed, 32 insertions, 6 deletions
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 09ff6de..2623990 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -1466,6 +1466,8 @@ static int goal_alt_dont_inherit_ops[MAX_RECOG_OPERANDS];
static bool goal_alt_swapped;
/* The chosen insn alternative. */
static int goal_alt_number;
+/* True if output reload of the stack pointer should be generated. */
+static bool goal_alt_out_sp_reload_p;
/* True if the corresponding operand is the result of an equivalence
substitution. */
@@ -2128,6 +2130,9 @@ process_alt_operands (int only_alternative)
int curr_alt_dont_inherit_ops_num;
/* Numbers of operands whose reload pseudos should not be inherited. */
int curr_alt_dont_inherit_ops[MAX_RECOG_OPERANDS];
+ /* True if output stack pointer reload should be generated for the current
+ alternative. */
+ bool curr_alt_out_sp_reload_p;
rtx op;
/* The register when the operand is a subreg of register, otherwise the
operand itself. */
@@ -2211,7 +2216,8 @@ process_alt_operands (int only_alternative)
}
reject += static_reject;
early_clobbered_regs_num = 0;
-
+ curr_alt_out_sp_reload_p = false;
+
for (nop = 0; nop < n_operands; nop++)
{
const char *p;
@@ -2682,12 +2688,10 @@ process_alt_operands (int only_alternative)
bool no_regs_p;
reject += op_reject;
- /* Never do output reload of stack pointer. It makes
- impossible to do elimination when SP is changed in
- RTL. */
- if (op == stack_pointer_rtx && ! frame_pointer_needed
+ /* Mark output reload of the stack pointer. */
+ if (op == stack_pointer_rtx
&& curr_static_id->operand[nop].type != OP_IN)
- goto fail;
+ curr_alt_out_sp_reload_p = true;
/* If this alternative asks for a specific reg class, see if there
is at least one allocatable register in that class. */
@@ -3317,6 +3321,7 @@ process_alt_operands (int only_alternative)
for (nop = 0; nop < curr_alt_dont_inherit_ops_num; nop++)
goal_alt_dont_inherit_ops[nop] = curr_alt_dont_inherit_ops[nop];
goal_alt_swapped = curr_swapped;
+ goal_alt_out_sp_reload_p = curr_alt_out_sp_reload_p;
best_overall = overall;
best_losers = losers;
best_reload_nregs = reload_nregs;
@@ -4836,6 +4841,27 @@ curr_insn_transform (bool check_only_p)
lra_asm_insn_error (curr_insn);
}
lra_process_new_insns (curr_insn, before, after, "Inserting insn reload");
+ if (goal_alt_out_sp_reload_p)
+ {
+ /* We have an output stack pointer reload -- update sp offset: */
+ rtx set;
+ bool done_p = false;
+ poly_int64 sp_offset = curr_id->sp_offset;
+ for (rtx_insn *insn = after; insn != NULL_RTX; insn = NEXT_INSN (insn))
+ if ((set = single_set (insn)) != NULL_RTX
+ && SET_DEST (set) == stack_pointer_rtx)
+ {
+ lra_assert (!done_p);
+ curr_id->sp_offset = 0;
+ lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+ id->sp_offset = sp_offset;
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " Moving sp offset from insn %u to %u\n",
+ INSN_UID (curr_insn), INSN_UID (insn));
+ }
+ lra_assert (!done_p);
+ }
return change_p;
}