[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 16:00:14 PDT 2019


This revision was automatically updated to reflect the committed changes.
Closed by commit rL371788: [AArch64][GlobalISel] Support tail calling with swiftself parameters (authored by paquette, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D67511?vs=219964&id=220024#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67511/new/

https://reviews.llvm.org/D67511

Files:
  llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
  llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll


Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
===================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/call-translator-tail-call.ll
+++ llvm/trunk/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/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
===================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
+++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -509,8 +509,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;
@@ -521,12 +523,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.220024.patch
Type: text/x-patch
Size: 3605 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190912/99b83457/attachment.bin>


More information about the llvm-commits mailing list