diff options
| author | Hal Finkel <hfinkel@anl.gov> | 2016-08-30 00:59:23 +0000 | 
|---|---|---|
| committer | Hal Finkel <hfinkel@anl.gov> | 2016-08-30 00:59:23 +0000 | 
| commit | b074a608ceb2514ff5c8967b0f36c168fb54576e (patch) | |
| tree | f34276831928cad569fd5763ac8d398a78a8fc32 /llvm | |
| parent | 455d3569d84c0e999257b7e7b87b9b7e46dd8774 (diff) | |
| download | bcm5719-llvm-b074a608ceb2514ff5c8967b0f36c168fb54576e.tar.gz bcm5719-llvm-b074a608ceb2514ff5c8967b0f36c168fb54576e.zip  | |
[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
Diffstat (limited to 'llvm')
| -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 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/longcall.ll | 26 | 
5 files changed, 41 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; } diff --git a/llvm/test/CodeGen/PowerPC/longcall.ll b/llvm/test/CodeGen/PowerPC/longcall.ll new file mode 100644 index 00000000000..9645ca8d31f --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/longcall.ll @@ -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 } +  | 

