aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-02-02 02:22:50 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-02-02 02:22:50 +0000
commitb2c9290a01c5a6f2206f4c47c702086834b65339 (patch)
tree710528533b35dd5503bf95bfc12a26f49a685385
parentd74667e226c3053128f34c6f2c6c9ebfe5b98e50 (diff)
Perform sibcall in some cases when arguments are passes memory. Look for cases
where callee's arguments are already in the caller's own caller's stack and they line up perfectly. e.g. extern int foo(int a, int b, int c); int bar(int a, int b, int c) { return foo(a, b, c); } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95053 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp55
-rw-r--r--test/CodeGen/X86/tailcall2.ll13
2 files changed, 62 insertions, 6 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index a8308b80a9..d05de21be3 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1807,6 +1807,10 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
unsigned NumBytes = CCInfo.getNextStackOffset();
if (FuncIsMadeTailCallSafe(CallConv))
NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
+ else if (isTailCall && !PerformTailCallOpt)
+ // This is a sibcall. The memory operands are available in caller's
+ // own caller's stack.
+ NumBytes = 0;
int FPDiff = 0;
if (isTailCall) {
@@ -1976,9 +1980,11 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
int FI = 0;
// Do not flag preceeding copytoreg stuff together with the following stuff.
InFlag = SDValue();
- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
- CCValAssign &VA = ArgLocs[i];
- if (!VA.isRegLoc()) {
+ if (PerformTailCallOpt) {
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ if (VA.isRegLoc())
+ continue;
assert(VA.isMemLoc());
SDValue Arg = Outs[i].Val;
ISD::ArgFlagsTy Flags = Outs[i].Flags;
@@ -2259,11 +2265,14 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
return false;
}
+
+ // Look for obvious safe cases to perform tail call optimization that does not
+ // requite ABI changes. This is what gcc calls sibcall.
+
// Do not tail call optimize vararg calls for now.
if (isVarArg)
return false;
- // Look for obvious safe cases to perform tail call optimization.
// If the callee takes no arguments then go on to check the results of the
// call.
if (!Outs.empty()) {
@@ -2273,8 +2282,42 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
CCState CCInfo(CalleeCC, isVarArg, getTargetMachine(),
ArgLocs, *DAG.getContext());
CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForNode(CalleeCC));
- if (CCInfo.getNextStackOffset())
- return false;
+ if (CCInfo.getNextStackOffset()) {
+ MachineFunction &MF = DAG.getMachineFunction();
+ if (MF.getInfo<X86MachineFunctionInfo>()->getBytesToPopOnReturn())
+ return false;
+ if (Subtarget->isTargetWin64())
+ // Win64 ABI has additional complications.
+ return false;
+
+ // Check if the arguments are already laid out in the right way as
+ // the caller's fixed stack objects.
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ArgLocs[i];
+ EVT RegVT = VA.getLocVT();
+ SDValue Arg = Outs[i].Val;
+ ISD::ArgFlagsTy Flags = Outs[i].Flags;
+ if (Flags.isByVal())
+ return false; // TODO
+ if (VA.getLocInfo() == CCValAssign::Indirect)
+ return false;
+ if (!VA.isRegLoc()) {
+ LoadSDNode *Ld = dyn_cast<LoadSDNode>(Arg);
+ if (!Ld)
+ return false;
+ SDValue Ptr = Ld->getBasePtr();
+ FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
+ if (!FINode)
+ return false;
+ int FI = FINode->getIndex();
+ if (!MFI->isFixedObjectIndex(FI))
+ return false;
+ if (VA.getLocMemOffset() != MFI->getObjectOffset(FI))
+ return false;
+ }
+ }
+ }
}
// If the caller does not return a value, then this is obviously safe.
diff --git a/test/CodeGen/X86/tailcall2.ll b/test/CodeGen/X86/tailcall2.ll
index 1e288f5765..e41e3da4f8 100644
--- a/test/CodeGen/X86/tailcall2.ll
+++ b/test/CodeGen/X86/tailcall2.ll
@@ -89,3 +89,16 @@ bb1:
}
declare i32 @bar(i32)
+
+define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind ssp {
+entry:
+; 32: t7:
+; 32: jmp {{_?}}bar2
+
+; 64: t7:
+; 64: jmp {{_?}}bar2
+ %0 = tail call i32 @bar2(i32 %a, i32 %b, i32 %c) nounwind
+ ret i32 %0
+}
+
+declare i32 @bar2(i32, i32, i32)