mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-07 11:51:13 +00:00
[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:
parent
f3f0f64ccf
commit
62419dd0e2
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -105,6 +105,7 @@ void PPCSubtarget::initializeEnvironment() {
|
||||
HasFusion = false;
|
||||
HasFloat128 = false;
|
||||
IsISA3_0 = false;
|
||||
UseLongCalls = false;
|
||||
|
||||
HasPOPCNTD = POPCNTD_Unavailable;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
|
26
test/CodeGen/PowerPC/longcall.ll
Normal file
26
test/CodeGen/PowerPC/longcall.ll
Normal 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 }
|
||||
|
Loading…
Reference in New Issue
Block a user