[PowerPC] Add support for -mlongcall

The "long call" option forces the use of the indirect calling sequence for all
calls (even those that don't really need it). GCC provides this option; This is
helpful, under certain circumstances, for building very-large binaries, and
some other specialized use cases.

Fixes PR19098.

llvm-svn: 280040
This commit is contained in:
Hal Finkel 2016-08-30 00:59:23 +00:00
parent f3f0f64ccf
commit 62419dd0e2
5 changed files with 41 additions and 1 deletions

View File

@ -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",

View File

@ -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,

View File

@ -105,6 +105,7 @@ void PPCSubtarget::initializeEnvironment() {
HasFusion = false;
HasFloat128 = false;
IsISA3_0 = false;
UseLongCalls = false;
HasPOPCNTD = POPCNTD_Unavailable;
}

View File

@ -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; }

View File

@ -0,0 +1,26 @@
; RUN: llc < %s | FileCheck %s
target datalayout = "E-m:e-i64:64-n32:64"
target triple = "powerpc64-unknown-linux-gnu"
; Function Attrs: nounwind
define void @bar() local_unnamed_addr #0 {
entry:
tail call void @foo() #1
ret void
; CHECK-LABEL: @bar
; CHECK: ld [[FD:[0-9]+]], .LC0@toc@l({{[0-9]+}})
; CHECK: ld [[ADDR:[0-9]+]], 0([[FD]])
; CHECK: mtctr [[ADDR]]
; CHECK: bctrl
; CHECK-NOT: bl foo
; CHECK: blr
}
; CHECK: .tc foo
declare void @foo() local_unnamed_addr
attributes #0 = { nounwind "target-cpu"="ppc64" "target-features"="+longcall" }
attributes #1 = { nounwind }