aboutsummaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-06-07 15:38:10 +0200
committerMartin Liska <mliska@suse.cz>2021-06-07 15:38:10 +0200
commit6467a4e9a6cceae84be71007d11dfc61b47b43a4 (patch)
treefec0feb43d7f9ce092ad6e9a90f598cde22e1fd4 /gcc/reg-stack.c
parent7584ede940802ce5f6401bc6122a5550106f5925 (diff)
parent4d3907c222646174ec7e405491435aefc50bf1bb (diff)
downloadgcc-6467a4e9a6cceae84be71007d11dfc61b47b43a4.zip
gcc-6467a4e9a6cceae84be71007d11dfc61b47b43a4.tar.gz
gcc-6467a4e9a6cceae84be71007d11dfc61b47b43a4.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 25210f0c..1d9ea03 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -174,6 +174,7 @@
#include "reload.h"
#include "tree-pass.h"
#include "rtl-iter.h"
+#include "function-abi.h"
#ifdef STACK_REGS
@@ -2368,6 +2369,18 @@ subst_asm_stack_regs (rtx_insn *insn, stack_ptr regstack)
}
}
}
+
+/* Return true if a function call is allowed to alter some or all bits
+ of any stack reg. */
+static bool
+callee_clobbers_any_stack_reg (const function_abi & callee_abi)
+{
+ for (unsigned regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
+ if (callee_abi.clobbers_at_least_part_of_reg_p (regno))
+ return true;
+ return false;
+}
+
/* Substitute stack hard reg numbers for stack virtual registers in
INSN. Non-stack register numbers are not changed. REGSTACK is the
@@ -2382,7 +2395,10 @@ subst_stack_regs (rtx_insn *insn, stack_ptr regstack)
bool control_flow_insn_deleted = false;
int i;
- if (CALL_P (insn))
+ /* If the target of the call doesn't clobber any stack registers,
+ Don't clear the arguments. */
+ if (CALL_P (insn)
+ && callee_clobbers_any_stack_reg (insn_callee_abi (insn)))
{
int top = regstack->top;