Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 807b212

Browse files
committed
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263092 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d7c5c63 commit 807b212

File tree

5 files changed

+55
-1
lines changed

5 files changed

+55
-1
lines changed

lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,7 @@ def CSR_AArch64_AllRegs
323323
(sequence "Q%u", 0, 31))>;
324324

325325
def CSR_AArch64_NoRegs : CalleeSavedRegs<(add)>;
326+
327+
def CSR_AArch64_RT_MostRegs : CalleeSavedRegs<(add CSR_AArch64_AAPCS,
328+
(sequence "X%u", 9, 14))>;
329+

lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2412,6 +2412,7 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC,
24122412
return CC_AArch64_GHC;
24132413
case CallingConv::C:
24142414
case CallingConv::Fast:
2415+
case CallingConv::PreserveMost:
24152416
if (!Subtarget->isTargetDarwin())
24162417
return CC_AArch64_AAPCS;
24172418
return IsVarArg ? CC_AArch64_DarwinPCS_VarArg : CC_AArch64_DarwinPCS;
@@ -2901,7 +2902,8 @@ bool AArch64TargetLowering::DoesCalleeRestoreStack(CallingConv::ID CallCC,
29012902
}
29022903

29032904
bool AArch64TargetLowering::IsTailCallConvention(CallingConv::ID CallCC) const {
2904-
return CallCC == CallingConv::Fast;
2905+
return CallCC == CallingConv::Fast ||
2906+
CallCC == CallingConv::PreserveMost;
29052907
}
29062908

29072909
/// LowerCall - Lower a call to a callseq_start + CALL + callseq_end chain,

lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
5454
if (MF->getFunction()->getAttributes().hasAttrSomewhere(
5555
Attribute::SwiftError))
5656
return CSR_AArch64_AAPCS_SwiftError_SaveList;
57+
if (MF->getFunction()->getCallingConv() == CallingConv::PreserveMost)
58+
return CSR_AArch64_RT_MostRegs_SaveList;
5759
else
5860
return CSR_AArch64_AAPCS_SaveList;
5961
}
@@ -72,6 +74,8 @@ AArch64RegisterInfo::getCalleeSavedRegsForLayout(
7274
return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
7375
CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
7476
CSR_AArch64_CXX_TLS_Darwin_SaveList;
77+
if (MF->getFunction()->getCallingConv() == CallingConv::PreserveMost)
78+
return CSR_AArch64_RT_MostRegs_SaveList;
7579
else
7680
return CSR_AArch64_AAPCS_SaveList;
7781
}
@@ -97,6 +101,8 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
97101
return CSR_AArch64_CXX_TLS_Darwin_RegMask;
98102
if (MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
99103
return CSR_AArch64_AAPCS_SwiftError_RegMask;
104+
if (CC == CallingConv::PreserveMost)
105+
return CSR_AArch64_RT_MostRegs_RegMask;
100106
else
101107
return CSR_AArch64_AAPCS_RegMask;
102108
}

lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,8 @@ ARMTargetLowering::getEffectiveCallingConv(CallingConv::ID CC,
13751375
case CallingConv::ARM_APCS:
13761376
case CallingConv::GHC:
13771377
return CC;
1378+
case CallingConv::PreserveMost:
1379+
return CallingConv::PreserveMost;
13781380
case CallingConv::ARM_AAPCS_VFP:
13791381
return isVarArg ? CallingConv::ARM_AAPCS : CallingConv::ARM_AAPCS_VFP;
13801382
case CallingConv::C:
@@ -1418,6 +1420,8 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
14181420
return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
14191421
case CallingConv::GHC:
14201422
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
1423+
case CallingConv::PreserveMost:
1424+
return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
14211425
}
14221426
}
14231427

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llc < %s -mtriple=arm64-apple-ios-8.0.0 | FileCheck %s
2+
3+
declare void @standard_cc_func()
4+
declare preserve_mostcc void @preserve_mostcc_func()
5+
6+
; Registers r9-r15 should be saved before the call of a function
7+
; with a standard calling convention.
8+
define preserve_mostcc void @preserve_mostcc1() nounwind {
9+
entry:
10+
;CHECK-LABEL: preserve_mostcc1
11+
;CHECK-NOT: stp
12+
;CHECK-NOT: str
13+
;CHECK: stp x14, x13,
14+
;CHECK-NEXT: stp x12, x11,
15+
;CHECK-NEXT: stp x10, x9,
16+
;CHECK: bl _standard_cc_func
17+
call void @standard_cc_func()
18+
;CHECK: ldp x10, x9,
19+
;CHECK-NEXT: ldp x12, x11,
20+
;CHECK-NEXT: ldp x14, x13,
21+
ret void
22+
}
23+
24+
; Registers r9-r15 don't need to be saved if one
25+
; function with preserve_mostcc calling convention calls another
26+
; function with preserve_mostcc calling convention, because the
27+
; callee wil save these registers anyways.
28+
define preserve_mostcc void @preserve_mostcc2() nounwind {
29+
entry:
30+
;CHECK-LABEL: preserve_mostcc2
31+
;CHECK-NOT: x14
32+
;CHECK: stp x29, x30,
33+
;CHECK-NOT: x14
34+
;CHECK: bl _preserve_mostcc_func
35+
call preserve_mostcc void @preserve_mostcc_func()
36+
ret void
37+
}
38+

0 commit comments

Comments
 (0)