diff options
author | Jessica Paquette <jpaquette@apple.com> | 2019-09-12 23:00:59 +0000 |
---|---|---|
committer | Jessica Paquette <jpaquette@apple.com> | 2019-09-12 23:00:59 +0000 |
commit | 0c283cb50418e56fc3ad92d552480273751534d5 (patch) | |
tree | 91873eee09003154c956be70893c95faaf2963d9 /llvm/lib/Target/AArch64/AArch64CallLowering.cpp | |
parent | f7d2376b98728a10143bd3bb715f07b01ee2f5d1 (diff) | |
download | bcm5719-llvm-0c283cb50418e56fc3ad92d552480273751534d5.tar.gz bcm5719-llvm-0c283cb50418e56fc3ad92d552480273751534d5.zip |
[AArch64][GlobalISel] Support tail calling with swiftself parameters
Swiftself uses a callee-saved register. We can tail call when the register used
in the caller and callee is the same.
This behaviour is equivalent to that in `TargetLowering::parametersInCSRMatch`.
Update call-translator-tail-call.ll to verify that we can do this. When we
support inline assembly, we can write a check similar to the one in the
general swiftself.ll. For now, we need to verify that we get the correct COPY
instruction after call lowering.
Differential Revision: https://reviews.llvm.org/D67511
llvm-svn: 371788
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64CallLowering.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64CallLowering.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp index bad8fb3ab0d..a3a212c5128 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -509,8 +509,10 @@ bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable( // supported. auto TRI = MF.getSubtarget<AArch64Subtarget>().getRegisterInfo(); const uint32_t *CallerPreservedMask = TRI->getCallPreservedMask(MF, CallerCC); + MachineRegisterInfo &MRI = MF.getRegInfo(); - for (auto &ArgLoc : OutLocs) { + for (unsigned i = 0; i < OutLocs.size(); ++i) { + auto &ArgLoc = OutLocs[i]; // If it's not a register, it's fine. if (!ArgLoc.isRegLoc()) continue; @@ -521,12 +523,37 @@ bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable( if (MachineOperand::clobbersPhysReg(CallerPreservedMask, Reg)) continue; - // TODO: Port the remainder of this check from TargetLowering to support - // tail calling swiftself. LLVM_DEBUG( dbgs() - << "... Cannot handle callee-saved registers in outgoing args yet.\n"); - return false; + << "... Call has an argument passed in a callee-saved register.\n"); + + // Check if it was copied from. + ArgInfo &OutInfo = OutArgs[i]; + + if (OutInfo.Regs.size() > 1) { + LLVM_DEBUG( + dbgs() << "... Cannot handle arguments in multiple registers.\n"); + return false; + } + + // Check if we copy the register, walking through copies from virtual + // registers. Note that getDefIgnoringCopies does not ignore copies from + // physical registers. + MachineInstr *RegDef = getDefIgnoringCopies(OutInfo.Regs[0], MRI); + if (!RegDef || RegDef->getOpcode() != TargetOpcode::COPY) { + LLVM_DEBUG( + dbgs() + << "... Parameter was not copied into a VReg, cannot tail call.\n"); + return false; + } + + // Got a copy. Verify that it's the same as the register we want. + Register CopyRHS = RegDef->getOperand(1).getReg(); + if (CopyRHS != Reg) { + LLVM_DEBUG(dbgs() << "... Callee-saved register was not copied into " + "VReg, cannot tail call.\n"); + return false; + } } return true; |