diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPC.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCSubtarget.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCSubtarget.h | 2 |
4 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td index b40b530f4c5..ac1c3060046 100644 --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -136,6 +136,8 @@ def FeatureInvariantFunctionDescriptors : SubtargetFeature<"invariant-function-descriptors", "HasInvariantFunctionDescriptors", "true", "Assume function descriptors are invariant">; +def FeatureLongCall : SubtargetFeature<"longcall", "UseLongCalls", "true", + "Always use indirect calls">; def FeatureHTM : SubtargetFeature<"htm", "HasHTM", "true", "Enable Hardware Transactional Memory instructions">; def FeatureMFTB : SubtargetFeature<"", "FeatureMFTB", "true", diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index f895b06ac68..09887c3e4d1 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -4695,7 +4695,9 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, ImmutableCallSite *CS = CLI.CS; if (isTailCall) { - if (Subtarget.isSVR4ABI() && Subtarget.isPPC64()) + if (Subtarget.useLongCalls() && !(CS && CS->isMustTailCall())) + isTailCall = false; + else if (Subtarget.isSVR4ABI() && Subtarget.isPPC64()) isTailCall = IsEligibleForTailCallOptimization_64SVR4(Callee, CallConv, CS, isVarArg, Outs, Ins, DAG); @@ -4725,6 +4727,13 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, report_fatal_error("failed to perform tail call elimination on a call " "site marked musttail"); + // When long calls (i.e. indirect calls) are always used, calls are always + // made via function pointer. If we have a function name, first translate it + // into a pointer. + if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) && + !isTailCall) + Callee = LowerGlobalAddress(Callee, DAG); + if (Subtarget.isSVR4ABI()) { if (Subtarget.isPPC64()) return LowerCall_64SVR4(Chain, Callee, CallConv, isVarArg, diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp index 603f0fccc7c..19570735295 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -105,6 +105,7 @@ void PPCSubtarget::initializeEnvironment() { HasFusion = false; HasFloat128 = false; IsISA3_0 = false; + UseLongCalls = false; HasPOPCNTD = POPCNTD_Unavailable; } diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h index 9fe286a3b7a..f58c7c10c8b 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.h +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h @@ -132,6 +132,7 @@ protected: bool HasFusion; bool HasFloat128; bool IsISA3_0; + bool UseLongCalls; POPCNTDKind HasPOPCNTD; @@ -275,6 +276,7 @@ public: bool hasFusion() const { return HasFusion; } bool hasFloat128() const { return HasFloat128; } bool isISA3_0() const { return IsISA3_0; } + bool useLongCalls() const { return UseLongCalls; } POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } |