summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/TargetRegisterInfo.cpp9
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp14
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp15
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp14
4 files changed, 30 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index 0a7042ac3db..fc88629b5c8 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -388,6 +388,15 @@ bool TargetRegisterInfo::needsStackRealignment(
return false;
}
+bool TargetRegisterInfo::regmaskSubsetEqual(const uint32_t *mask0,
+ const uint32_t *mask1) const {
+ unsigned N = (getNumRegs()+31) / 32;
+ for (unsigned I = 0; I < N; ++I)
+ if ((mask0[I] & mask1[I]) != mask0[I])
+ return false;
+ return true;
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void
TargetRegisterInfo::dumpReg(unsigned Reg, unsigned SubRegIndex,
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 318f7c90220..6d8f3eebff3 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -2816,13 +2816,6 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
CallingConv::ID CallerCC = CallerF->getCallingConv();
bool CCMatch = CallerCC == CalleeCC;
- // Disable tailcall for CXX_FAST_TLS when callee and caller have different
- // calling conventions, given that CXX_FAST_TLS has a bigger CSR set.
- if (!CCMatch &&
- (CallerCC == CallingConv::CXX_FAST_TLS ||
- CalleeCC == CallingConv::CXX_FAST_TLS))
- return false;
-
// Byval parameters hand the function a pointer directly into the stack area
// we want to reuse during a tail call. Working around this *is* possible (see
// X86) but less efficient and uglier in LowerCall.
@@ -2882,6 +2875,13 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
CCAssignFnForCall(CalleeCC, isVarArg),
CCAssignFnForCall(CallerCC, isVarArg)))
return false;
+ // The callee has to preserve all registers the caller needs to preserve.
+ if (!CCMatch) {
+ const AArch64RegisterInfo *TRI = Subtarget->getRegisterInfo();
+ if (!TRI->regmaskSubsetEqual(TRI->getCallPreservedMask(MF, CallerCC),
+ TRI->getCallPreservedMask(MF, CalleeCC)))
+ return false;
+ }
// Nothing more to check if the callee is taking no arguments
if (Outs.empty())
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 908f40db587..f950adb9159 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2101,14 +2101,6 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
MachineFunction &MF = DAG.getMachineFunction();
const Function *CallerF = MF.getFunction();
CallingConv::ID CallerCC = CallerF->getCallingConv();
- bool CCMatch = CallerCC == CalleeCC;
-
- // Disable tailcall for CXX_FAST_TLS when callee and caller have different
- // calling conventions, given that CXX_FAST_TLS has a bigger CSR set.
- if (!CCMatch &&
- (CallerCC == CallingConv::CXX_FAST_TLS ||
- CalleeCC == CallingConv::CXX_FAST_TLS))
- return false;
assert(Subtarget->supportsTailCall());
@@ -2152,6 +2144,13 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
CCAssignFnForNode(CalleeCC, true, isVarArg),
CCAssignFnForNode(CallerCC, true, isVarArg)))
return false;
+ // The callee has to preserve all registers the caller needs to preserve.
+ if (CalleeCC != CallerCC) {
+ const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
+ if (!TRI->regmaskSubsetEqual(TRI->getCallPreservedMask(MF, CallerCC),
+ TRI->getCallPreservedMask(MF, CalleeCC)))
+ return false;
+ }
// If Caller's vararg or byval argument has been split between registers and
// stack, do not perform tail call, since part of the argument is in caller's
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8c17a47674d..9ba8f1e8e01 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3818,13 +3818,6 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(
if (IsCalleeWin64 != IsCallerWin64)
return false;
- // Disable tailcall for CXX_FAST_TLS when callee and caller have different
- // calling conventions, given that CXX_FAST_TLS has a bigger CSR set.
- if (!CCMatch &&
- (CallerCC == CallingConv::CXX_FAST_TLS ||
- CalleeCC == CallingConv::CXX_FAST_TLS))
- return false;
-
if (DAG.getTarget().Options.GuaranteedTailCallOpt) {
if (canGuaranteeTCO(CalleeCC) && CCMatch)
return true;
@@ -3888,6 +3881,13 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(
if (!CCState::resultsCompatible(CalleeCC, CallerCC, MF, C, Ins,
RetCC_X86, RetCC_X86))
return false;
+ // The callee has to preserve all registers the caller needs to preserve.
+ if (!CCMatch) {
+ const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
+ if (!TRI->regmaskSubsetEqual(TRI->getCallPreservedMask(MF, CallerCC),
+ TRI->getCallPreservedMask(MF, CalleeCC)))
+ return false;
+ }
unsigned StackArgsSize = 0;
OpenPOWER on IntegriCloud