llvm.org GIT mirror llvm / b171245
Perform trivial tail call optimization for callees with "C" ABI. These are done even when -tailcallopt is not specified and it does not require changing ABI. First case is the most trivial one. Perform tail call optimization when both the caller and callee do not return values and when the callee does not take any input arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94664 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
5 changed file(s) with 45 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
1111 //
1212 //===----------------------------------------------------------------------===//
1313
14 #define DEBUG_TYPE "x86-isel"
1415 #include "X86.h"
1516 #include "X86InstrBuilder.h"
1617 #include "X86ISelLowering.h"
3839 #include "llvm/MC/MCSymbol.h"
3940 #include "llvm/ADT/BitVector.h"
4041 #include "llvm/ADT/SmallSet.h"
42 #include "llvm/ADT/Statistic.h"
4143 #include "llvm/ADT/StringExtras.h"
4244 #include "llvm/ADT/VectorExtras.h"
4345 #include "llvm/Support/CommandLine.h"
4648 #include "llvm/Support/MathExtras.h"
4749 #include "llvm/Support/raw_ostream.h"
4850 using namespace llvm;
51
52 STATISTIC(NumTailCalls, "Number of tail calls");
4953
5054 static cl::opt
5155 DisableMMX("disable-mmx", cl::Hidden, cl::desc("Disable use of MMX"));
17871791 if (isTailCall)
17881792 // Check if it's really possible to do a tail call.
17891793 isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
1790 Ins, DAG);
1794 Outs, Ins, DAG);
17911795
17921796 assert(!(isVarArg && CallConv == CallingConv::Fast) &&
17931797 "Var args not supported with calling convention fastcc");
18051809
18061810 int FPDiff = 0;
18071811 if (isTailCall) {
1812 ++NumTailCalls;
1813
18081814 // Lower arguments at fp - stackoffset + fpdiff.
18091815 unsigned NumBytesCallerPushed =
18101816 MF.getInfo()->getBytesToPopOnReturn();
22362242 X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
22372243 CallingConv::ID CalleeCC,
22382244 bool isVarArg,
2239 const SmallVectorImpl &Ins,
2245 const SmallVectorImpl &Outs,
2246 const SmallVectorImpl &Ins,
22402247 SelectionDAG& DAG) const {
2241 if (CalleeCC == CallingConv::Fast &&
2242 DAG.getMachineFunction().getFunction()->getCallingConv() == CalleeCC)
2248 // If -tailcallopt is specified, make fastcc functions tail-callable.
2249 const Function *F = DAG.getMachineFunction().getFunction();
2250 if (PerformTailCallOpt &&
2251 CalleeCC == CallingConv::Fast && F->getCallingConv() == CalleeCC)
22432252 return true;
2253
2254 if (CalleeCC != CallingConv::Fast &&
2255 CalleeCC != CallingConv::C)
2256 return false;
2257
2258 // Look for obvious safe cases to perform tail call optimization.
2259 // For now, only consider callees which take no arguments and no return
2260 // values.
2261 if (!Outs.empty())
2262 return false;
2263
2264 if (Ins.empty())
2265 // If the caller does not return a value, then this is obviously safe.
2266 return F->getReturnType()->isVoidTy();
2267
22442268 return false;
22452269 }
22462270
629629 bool IsEligibleForTailCallOptimization(SDValue Callee,
630630 CallingConv::ID CalleeCC,
631631 bool isVarArg,
632 const SmallVectorImpl &Ins,
632 const SmallVectorImpl &Outs,
633 const SmallVectorImpl &Ins,
633634 SelectionDAG& DAG) const;
634635 bool IsCalleePop(bool isVarArg, CallingConv::ID CallConv);
635636 SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr,
189189 ; LINUX: .L8$pb:
190190 ; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.Lpicbaseref8-.L8$pb),
191191 ; LINUX: addl .LJTI8_0@GOTOFF(
192 ; LINUX: jmpl *%ecx
192 ; LINUX: jmpl *
193193
194194 ; LINUX: .LJTI8_0:
195195 ; LINUX: .long .LBB8_2@GOTOFF
33
44 define fastcc i32 @tailcaller(i32 %in1, i32 %in2) nounwind {
55 entry:
6 %tmp11 = tail call fastcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2)
7 ret i32 %tmp11
6 %tmp11 = tail call fastcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2)
7 ret i32 %tmp11
88 }
99
1010 declare fastcc i8* @alias_callee()
0 ; RUN: llc < %s -march=x86 -asm-verbose=false | FileCheck %s
1 ; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s
2
3 define void @bar(i32 %x) nounwind ssp {
4 entry:
5 ; CHECK: bar:
6 ; CHECK: jmp _foo
7 tail call void @foo() nounwind
8 ret void
9 }
10
11 declare void @foo()