[llvm] r263092 - Add support for a preserve_most calling convention to the AArch64 backend.

Roman Levenstein via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 9 20:35:09 PST 2016


Author: swiftix
Date: Wed Mar  9 22:35:09 2016
New Revision: 263092

URL: http://llvm.org/viewvc/llvm-project?rev=263092&view=rev
Log:
Add support for a preserve_most calling convention to the AArch64 backend.

This change adds a support for a preserve_most calling convention to the AArch64 backend, similar to how it was done for X86-64.

There is also a subsequent patch on top of this one to add a tail-calls support for this calling convention.

Differential Revision: http://reviews.llvm.org/D18016

Added:
    llvm/trunk/test/CodeGen/AArch64/preserve_mostcc.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td
    llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp

Modified: llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td?rev=263092&r1=263091&r2=263092&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64CallingConvention.td Wed Mar  9 22:35:09 2016
@@ -310,3 +310,7 @@ def CSR_AArch64_AllRegs
                            (sequence "Q%u", 0, 31))>;
 
 def CSR_AArch64_NoRegs : CalleeSavedRegs<(add)>;
+
+def CSR_AArch64_RT_MostRegs :  CalleeSavedRegs<(add CSR_AArch64_AAPCS,
+                                                (sequence "X%u", 9, 15))>;
+

Modified: llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp?rev=263092&r1=263091&r2=263092&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp Wed Mar  9 22:35:09 2016
@@ -723,10 +723,13 @@ static void computeCalleeSaveRegisterPai
 
   AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
   MachineFrameInfo *MFI = MF.getFrameInfo();
+  CallingConv::ID CC = MF.getFunction()->getCallingConv();
   unsigned Count = CSI.size();
+  (void)CC;
   // MachO's compact unwind format relies on all registers being stored in
   // pairs.
   assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() ||
+          CC == CallingConv::PreserveMost ||
           (Count & 1) == 0) &&
          "Odd number of callee-saved regs to spill!");
   unsigned Offset = AFI->getCalleeSavedStackSize();
@@ -760,6 +763,7 @@ static void computeCalleeSaveRegisterPai
     // MachO's compact unwind format relies on all registers being stored in
     // adjacent register pairs.
     assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() ||
+            CC == CallingConv::PreserveMost ||
             (RPI.isPaired() &&
              ((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
               RPI.Reg1 + 1 == RPI.Reg2))) &&

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=263092&r1=263091&r2=263092&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Wed Mar  9 22:35:09 2016
@@ -2455,6 +2455,7 @@ CCAssignFn *AArch64TargetLowering::CCAss
     return CC_AArch64_GHC;
   case CallingConv::C:
   case CallingConv::Fast:
+  case CallingConv::PreserveMost:
     if (!Subtarget->isTargetDarwin())
       return CC_AArch64_AAPCS;
     return IsVarArg ? CC_AArch64_DarwinPCS_VarArg : CC_AArch64_DarwinPCS;
@@ -2942,7 +2943,8 @@ bool AArch64TargetLowering::DoesCalleeRe
 }
 
 bool AArch64TargetLowering::IsTailCallConvention(CallingConv::ID CallCC) const {
-  return CallCC == CallingConv::Fast;
+  return CallCC == CallingConv::Fast ||
+         CallCC == CallingConv::PreserveMost;
 }
 
 /// LowerCall - Lower a call to a callseq_start + CALL + callseq_end chain,

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp?rev=263092&r1=263091&r2=263092&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp Wed Mar  9 22:35:09 2016
@@ -51,6 +51,8 @@ AArch64RegisterInfo::getCalleeSavedRegs(
     return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
            CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
            CSR_AArch64_CXX_TLS_Darwin_SaveList;
+  if (MF->getFunction()->getCallingConv() == CallingConv::PreserveMost)
+    return CSR_AArch64_RT_MostRegs_SaveList;
   else
     return CSR_AArch64_AAPCS_SaveList;
 }
@@ -74,6 +76,8 @@ AArch64RegisterInfo::getCallPreservedMas
     return CSR_AArch64_AllRegs_RegMask;
   if (CC == CallingConv::CXX_FAST_TLS)
     return CSR_AArch64_CXX_TLS_Darwin_RegMask;
+  if (CC == CallingConv::PreserveMost)
+    return CSR_AArch64_RT_MostRegs_RegMask;
   else
     return CSR_AArch64_AAPCS_RegMask;
 }

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=263092&r1=263091&r2=263092&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Mar  9 22:35:09 2016
@@ -1378,6 +1378,8 @@ ARMTargetLowering::getEffectiveCallingCo
   case CallingConv::ARM_APCS:
   case CallingConv::GHC:
     return CC;
+  case CallingConv::PreserveMost:
+    return CallingConv::PreserveMost;
   case CallingConv::ARM_AAPCS_VFP:
     return isVarArg ? CallingConv::ARM_AAPCS : CallingConv::ARM_AAPCS_VFP;
   case CallingConv::C:
@@ -1420,6 +1422,8 @@ CCAssignFn *ARMTargetLowering::CCAssignF
     return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
   case CallingConv::GHC:
     return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
+  case CallingConv::PreserveMost:
+    return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
   }
 }
 

Added: llvm/trunk/test/CodeGen/AArch64/preserve_mostcc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/preserve_mostcc.ll?rev=263092&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/preserve_mostcc.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/preserve_mostcc.ll Wed Mar  9 22:35:09 2016
@@ -0,0 +1,40 @@
+; RUN: llc < %s -mtriple=arm64-apple-ios-8.0.0 | FileCheck %s
+
+declare void @standard_cc_func()
+declare preserve_mostcc void @preserve_mostcc_func()
+
+; Registers r9-r15 should be saved before the call of a function
+; with a standard calling convention.
+define preserve_mostcc void @preserve_mostcc1() nounwind {
+entry:
+;CHECK-LABEL: preserve_mostcc1
+;CHECK-NOT:   stp
+;CHECK-NOT:   str
+;CHECK:       str     x15
+;CHECK-NEXT:  stp     x14, x13,
+;CHECK-NEXT:  stp     x12, x11,
+;CHECK-NEXT:  stp     x10, x9,
+;CHECK:       bl      _standard_cc_func
+  call void @standard_cc_func()
+;CHECK:       ldp     x10, x9,
+;CHECK-NEXT:  ldp     x12, x11,
+;CHECK-NEXT:  ldp     x14, x13,
+;CHECK-NEXT:  ldr     x15
+  ret void
+}
+
+; Registers r9-r15 don't need to be saved if one
+; function with preserve_mostcc calling convention calls another
+; function with preserve_mostcc calling convention, because the
+; callee wil save these registers anyways.
+define preserve_mostcc void @preserve_mostcc2() nounwind {
+entry:
+;CHECK-LABEL: preserve_mostcc2
+;CHECK-NOT: x14
+;CHECK:     stp     x29, x30,
+;CHECK-NOT: x14
+;CHECK:     bl      _preserve_mostcc_func
+  call preserve_mostcc void @preserve_mostcc_func()
+  ret void
+}
+




More information about the llvm-commits mailing list