summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
diff options
context:
space:
mode:
authorJessica Paquette <jpaquette@apple.com>2019-09-12 23:00:59 +0000
committerJessica Paquette <jpaquette@apple.com>2019-09-12 23:00:59 +0000
commit0c283cb50418e56fc3ad92d552480273751534d5 (patch)
tree91873eee09003154c956be70893c95faaf2963d9 /llvm/lib/Target/AArch64/AArch64CallLowering.cpp
parentf7d2376b98728a10143bd3bb715f07b01ee2f5d1 (diff)
downloadbcm5719-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.cpp37
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;
OpenPOWER on IntegriCloud