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.
This commit is contained in:
parent
7d6987e90d
commit
16465ceb06
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user