[PATCH] D67511: [AArch64][GlobalISel] Support tail calling with swiftself parameters
Jessica Paquette via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 12 12:04:45 PDT 2019
paquette created this revision.
paquette added a reviewer: aemerson.
Herald added subscribers: Petar.Avramovic, hiraditya, kristof.beyls, rovka.
Herald added a project: LLVM.
paquette added a parent revision: D67471: [AArch64][GlobalISel] Support sibling calls with outgoing arguments.
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.
https://reviews.llvm.org/D67511
Files:
llvm/lib/Target/AArch64/AArch64CallLowering.cpp
llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
Index: llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
===================================================================
--- llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
+++ llvm/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
@@ -192,3 +192,24 @@
tail call void @llvm.lifetime.end.p0i8(i64 1, i8* %t)
ret void
}
+
+; We can tail call when the callee swiftself is the same as the caller one.
+; It would be nice to move this to swiftself.ll, but it's important to verify
+; that we get the COPY that makes this safe in the first place.
+declare i8* @pluto()
+define hidden swiftcc i64 @swiftself_indirect_tail(i64* swiftself %arg) {
+ ; COMMON-LABEL: name: swiftself_indirect_tail
+ ; COMMON: bb.1 (%ir-block.0):
+ ; COMMON: liveins: $x20
+ ; COMMON: [[COPY:%[0-9]+]]:_(p0) = COPY $x20
+ ; COMMON: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; COMMON: BL @pluto, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit-def $x0
+ ; COMMON: [[COPY1:%[0-9]+]]:tcgpr64(p0) = COPY $x0
+ ; COMMON: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; COMMON: $x20 = COPY [[COPY]](p0)
+ ; COMMON: TCRETURNri [[COPY1]](p0), 0, csr_aarch64_aapcs, implicit $sp, implicit $x20
+ %tmp = call i8* @pluto()
+ %tmp1 = bitcast i8* %tmp to i64 (i64*)*
+ %tmp2 = tail call swiftcc i64 %tmp1(i64* swiftself %arg)
+ ret i64 %tmp2
+}
Index: llvm/lib/Target/AArch64/AArch64CallLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -508,8 +508,10 @@
// 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;
@@ -520,12 +522,37 @@
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67511.219964.patch
Type: text/x-patch
Size: 3569 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190912/1ca5fb3b/attachment-0001.bin>
More information about the llvm-commits
mailing list