diff options
author | liuhongt <hongtao.liu@intel.com> | 2021-06-01 09:00:57 +0800 |
---|---|---|
committer | liuhongt <hongtao.liu@intel.com> | 2021-06-07 10:25:03 +0800 |
commit | 16465ceb06cc1f65cfca3c0eb2c1ee27ab03bdfd (patch) | |
tree | 7afa0001810636d4623eff17ba18d988d79b4ac4 /gcc | |
parent | 7d6987e90d1181de8dc51f9ba2313052faea080e (diff) | |
download | gcc-16465ceb06cc1f65cfca3c0eb2c1ee27ab03bdfd.zip gcc-16465ceb06cc1f65cfca3c0eb2c1ee27ab03bdfd.tar.gz gcc-16465ceb06cc1f65cfca3c0eb2c1ee27ab03bdfd.tar.bz2 |
CALL_INSN may not be a real function call.
Use "used" flag for CALL_INSN to indicate it's a fake call. If it's a
fake call, it won't have its own function stack.
gcc/ChangeLog
PR target/82735
* df-scan.c (df_get_call_refs): When call_insn is a fake call,
it won't use stack pointer reg.
* final.c (leaf_function_p): When call_insn is a fake call, it
won't affect caller as a leaf function.
* reg-stack.c (callee_clobbers_any_stack_reg): New.
(subst_stack_regs): When call_insn doesn't clobber any stack
reg, don't clear the arguments.
* rtl.c (shallow_copy_rtx): Don't clear flag used when orig is
a insn.
* shrink-wrap.c (requires_stack_frame_p): No need for stack
frame for a fake call.
* rtl.h (FAKE_CALL_P): New macro.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/df-scan.c | 3 | ||||
-rw-r--r-- | gcc/final.c | 3 | ||||
-rw-r--r-- | gcc/reg-stack.c | 18 | ||||
-rw-r--r-- | gcc/rtl.c | 6 | ||||
-rw-r--r-- | gcc/rtl.h | 5 | ||||
-rw-r--r-- | gcc/shrink-wrap.c | 2 |
6 files changed, 31 insertions, 6 deletions
diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 6691c3e..1268536 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -3090,7 +3090,8 @@ df_get_call_refs (class df_collection_rec *collection_rec, for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { - if (i == STACK_POINTER_REGNUM) + if (i == STACK_POINTER_REGNUM + && !FAKE_CALL_P (insn_info->insn)) /* The stack ptr is used (honorarily) by a CALL insn. */ df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i], NULL, bb, insn_info, DF_REF_REG_USE, diff --git a/gcc/final.c b/gcc/final.c index 38c3d70..dba0b0a 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -4106,7 +4106,8 @@ leaf_function_p (void) for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) { if (CALL_P (insn) - && ! SIBLING_CALL_P (insn)) + && ! SIBLING_CALL_P (insn) + && ! FAKE_CALL_P (insn)) return 0; if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE 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; @@ -395,8 +395,10 @@ shallow_copy_rtx (const_rtx orig MEM_STAT_DECL) case SCRATCH: break; default: - /* For all other RTXes clear the used flag on the copy. */ - RTX_FLAG (copy, used) = 0; + /* For all other RTXes clear the used flag on the copy. + CALL_INSN use "used" flag to indicate it's a fake call. */ + if (!INSN_P (orig)) + RTX_FLAG (copy, used) = 0; break; } return copy; @@ -839,6 +839,11 @@ struct GTY(()) rtvec_def { /* Predicate yielding nonzero iff X is a call insn. */ #define CALL_P(X) (GET_CODE (X) == CALL_INSN) +/* 1 if RTX is a call_insn for a fake call. + CALL_INSN use "used" flag to indicate it's a fake call. */ +#define FAKE_CALL_P(RTX) \ + (RTL_FLAG_CHECK1 ("FAKE_CALL_P", (RTX), CALL_INSN)->used) + /* Predicate yielding nonzero iff X is an insn that cannot jump. */ #define NONJUMP_INSN_P(X) (GET_CODE (X) == INSN) diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index ba7b5cd..5e60f34 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -57,7 +57,7 @@ requires_stack_frame_p (rtx_insn *insn, HARD_REG_SET prologue_used, HARD_REG_SET hardregs; unsigned regno; - if (CALL_P (insn)) + if (CALL_P (insn) && !FAKE_CALL_P (insn)) return !SIBLING_CALL_P (insn); /* We need a frame to get the unique CFA expected by the unwinder. */ |