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

Commit 9556d6f

Browse files
manman-renManman Ren
authored andcommitted
Swift Calling Convention: swifterror target support.
Differential Revision: http://reviews.llvm.org/D18716 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265997 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 558061c commit 9556d6f

16 files changed

+291
-134
lines changed

lib/Target/AArch64/AArch64CallingConvention.td

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,8 @@ def CSR_AArch64_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22,
278278
// case)
279279
def CSR_AArch64_AAPCS_ThisReturn : CalleeSavedRegs<(add CSR_AArch64_AAPCS, X0)>;
280280

281-
def CSR_AArch64_AAPCS_SwiftError : CalleeSavedRegs<(add LR, FP, X20, X21, X22,
282-
X23, X24, X25, X26, X27, X28,
283-
D8, D9, D10, D11,
284-
D12, D13, D14, D15)>;
281+
def CSR_AArch64_AAPCS_SwiftError
282+
: CalleeSavedRegs<(sub CSR_AArch64_AAPCS, X19)>;
285283

286284
// The function used by Darwin to obtain the address of a thread-local variable
287285
// guarantees more than a normal AAPCS function. x16 and x17 are used on the

lib/Target/AArch64/AArch64FastISel.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,14 +1905,18 @@ bool AArch64FastISel::selectLoad(const Instruction *I) {
19051905
return false;
19061906

19071907
const Value *SV = I->getOperand(0);
1908-
if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1909-
if (Arg->hasSwiftErrorAttr() && TLI.supportSwiftError())
1910-
return false;
1911-
}
1908+
if (TLI.supportSwiftError()) {
1909+
// Swifterror values can come from either a function parameter with
1910+
// swifterror attribute or an alloca with swifterror attribute.
1911+
if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1912+
if (Arg->hasSwiftErrorAttr())
1913+
return false;
1914+
}
19121915

1913-
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1914-
if (Alloca->isSwiftError() && TLI.supportSwiftError())
1915-
return false;
1916+
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1917+
if (Alloca->isSwiftError())
1918+
return false;
1919+
}
19161920
}
19171921

19181922
// See if we can handle this address.
@@ -2080,14 +2084,18 @@ bool AArch64FastISel::selectStore(const Instruction *I) {
20802084
return false;
20812085

20822086
const Value *PtrV = I->getOperand(1);
2083-
if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
2084-
if (Arg->hasSwiftErrorAttr() && TLI.supportSwiftError())
2085-
return false;
2086-
}
2087+
if (TLI.supportSwiftError()) {
2088+
// Swifterror values can come from either a function parameter with
2089+
// swifterror attribute or an alloca with swifterror attribute.
2090+
if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
2091+
if (Arg->hasSwiftErrorAttr())
2092+
return false;
2093+
}
20872094

2088-
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
2089-
if (Alloca->isSwiftError() && TLI.supportSwiftError())
2090-
return false;
2095+
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
2096+
if (Alloca->isSwiftError())
2097+
return false;
2098+
}
20912099
}
20922100

20932101
// Get the value to be stored into a register. Use the zero register directly
@@ -3671,8 +3679,8 @@ bool AArch64FastISel::selectRet(const Instruction *I) {
36713679
if (F.isVarArg())
36723680
return false;
36733681

3674-
if (F.getAttributes().hasAttrSomewhere(Attribute::SwiftError) &&
3675-
TLI.supportSwiftError())
3682+
if (TLI.supportSwiftError() &&
3683+
F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
36763684
return false;
36773685

36783686
if (TLI.supportSplitCSR(FuncInfo.MF))

lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ class AArch64TargetLowering : public TargetLowering {
394394
MachineBasicBlock *Entry,
395395
const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;
396396

397+
bool supportSwiftError() const override {
398+
return true;
399+
}
400+
397401
private:
398402
bool isExtFreeImpl(const Instruction *Ext) const override;
399403

@@ -405,10 +409,6 @@ class AArch64TargetLowering : public TargetLowering {
405409
void addDRTypeForNEON(MVT VT);
406410
void addQRTypeForNEON(MVT VT);
407411

408-
bool supportSwiftError() const override {
409-
return true;
410-
}
411-
412412
SDValue
413413
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
414414
const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc DL,

lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
5151
return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
5252
CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
5353
CSR_AArch64_CXX_TLS_Darwin_SaveList;
54-
if (MF->getFunction()->getAttributes().hasAttrSomewhere(
55-
Attribute::SwiftError))
54+
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
55+
->supportSwiftError() &&
56+
MF->getFunction()->getAttributes().hasAttrSomewhere(
57+
Attribute::SwiftError))
5658
return CSR_AArch64_AAPCS_SwiftError_SaveList;
5759
if (MF->getFunction()->getCallingConv() == CallingConv::PreserveMost)
5860
return CSR_AArch64_RT_MostRegs_SaveList;
@@ -99,7 +101,9 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
99101
return CSR_AArch64_AllRegs_RegMask;
100102
if (CC == CallingConv::CXX_FAST_TLS)
101103
return CSR_AArch64_CXX_TLS_Darwin_RegMask;
102-
if (MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
104+
if (MF.getSubtarget<AArch64Subtarget>().getTargetLowering()
105+
->supportSwiftError() &&
106+
MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
103107
return CSR_AArch64_AAPCS_SwiftError_RegMask;
104108
if (CC == CallingConv::PreserveMost)
105109
return CSR_AArch64_RT_MostRegs_RegMask;

lib/Target/ARM/ARMBaseRegisterInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
8484
}
8585
}
8686

87-
if (STI.isTargetDarwin() &&
87+
if (STI.isTargetDarwin() && STI.getTargetLowering()->supportSwiftError() &&
8888
F->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
8989
return CSR_iOS_SwiftError_SaveList;
9090

@@ -112,7 +112,7 @@ ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
112112
// This is academic becase all GHC calls are (supposed to be) tail calls
113113
return CSR_NoRegs_RegMask;
114114

115-
if (STI.isTargetDarwin() &&
115+
if (STI.isTargetDarwin() && STI.getTargetLowering()->supportSwiftError() &&
116116
MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
117117
return CSR_iOS_SwiftError_RegMask;
118118

lib/Target/ARM/ARMCallingConv.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def RetCC_ARM_APCS : CallingConv<[
4848
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
4949
CCIfType<[f32], CCBitConvertToType<i32>>,
5050

51-
// An SwiftError is returned in R6.
51+
// A SwiftError is returned in R6.
5252
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R6]>>>,
5353

5454
// Handle all vector types as either f64 or v2f64.
@@ -176,7 +176,7 @@ def RetCC_ARM_AAPCS : CallingConv<[
176176
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
177177
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
178178

179-
// An SwiftError is returned in R6.
179+
// A SwiftError is returned in R6.
180180
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R6]>>>,
181181

182182
CCIfType<[f64, v2f64], CCCustom<"RetCC_ARM_AAPCS_Custom_f64">>,
@@ -218,7 +218,7 @@ def RetCC_ARM_AAPCS_VFP : CallingConv<[
218218
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
219219
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
220220

221-
// An SwiftError is returned in R6.
221+
// A SwiftError is returned in R6.
222222
CCIfSwiftError<CCIfType<[i32], CCAssignToReg<[R6]>>>,
223223

224224
CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,

lib/Target/ARM/ARMFastISel.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,14 +1063,18 @@ bool ARMFastISel::SelectLoad(const Instruction *I) {
10631063
return false;
10641064

10651065
const Value *SV = I->getOperand(0);
1066-
if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1067-
if (Arg->hasSwiftErrorAttr() && TLI.supportSwiftError())
1068-
return false;
1069-
}
1066+
if (TLI.supportSwiftError()) {
1067+
// Swifterror values can come from either a function parameter with
1068+
// swifterror attribute or an alloca with swifterror attribute.
1069+
if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1070+
if (Arg->hasSwiftErrorAttr())
1071+
return false;
1072+
}
10701073

1071-
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1072-
if (Alloca->isSwiftError() && TLI.supportSwiftError())
1073-
return false;
1074+
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1075+
if (Alloca->isSwiftError())
1076+
return false;
1077+
}
10741078
}
10751079

10761080
// Verify we have a legal type before going any further.
@@ -1189,14 +1193,18 @@ bool ARMFastISel::SelectStore(const Instruction *I) {
11891193
return false;
11901194

11911195
const Value *PtrV = I->getOperand(1);
1192-
if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
1193-
if (Arg->hasSwiftErrorAttr() && TLI.supportSwiftError())
1194-
return false;
1195-
}
1196+
if (TLI.supportSwiftError()) {
1197+
// Swifterror values can come from either a function parameter with
1198+
// swifterror attribute or an alloca with swifterror attribute.
1199+
if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
1200+
if (Arg->hasSwiftErrorAttr())
1201+
return false;
1202+
}
11961203

1197-
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
1198-
if (Alloca->isSwiftError() && TLI.supportSwiftError())
1199-
return false;
1204+
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
1205+
if (Alloca->isSwiftError())
1206+
return false;
1207+
}
12001208
}
12011209

12021210
// Verify we have a legal type before going any further.
@@ -2107,8 +2115,8 @@ bool ARMFastISel::SelectRet(const Instruction *I) {
21072115
if (!FuncInfo.CanLowerReturn)
21082116
return false;
21092117

2110-
if (F.getAttributes().hasAttrSomewhere(Attribute::SwiftError) &&
2111-
TLI.supportSwiftError())
2118+
if (TLI.supportSwiftError() &&
2119+
F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
21122120
return false;
21132121

21142122
if (TLI.supportSplitCSR(FuncInfo.MF))

lib/Target/ARM/ARMISelLowering.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,10 @@ namespace llvm {
468468
bool isCheapToSpeculateCttz() const override;
469469
bool isCheapToSpeculateCtlz() const override;
470470

471+
bool supportSwiftError() const override {
472+
return true;
473+
}
474+
471475
protected:
472476
std::pair<const TargetRegisterClass *, uint8_t>
473477
findRepresentativeClass(const TargetRegisterInfo *TRI,
@@ -580,10 +584,6 @@ namespace llvm {
580584
SmallVectorImpl<SDValue> &InVals,
581585
bool isThisReturn, SDValue ThisVal) const;
582586

583-
bool supportSwiftError() const override {
584-
return true;
585-
}
586-
587587
bool supportSplitCSR(MachineFunction *MF) const override {
588588
return MF->getFunction()->getCallingConv() == CallingConv::CXX_FAST_TLS &&
589589
MF->getFunction()->hasFnAttribute(Attribute::NoUnwind);

lib/Target/X86/X86CallingConv.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def CC_X86_64_C : CallingConv<[
300300
// A SwiftSelf is passed in R10.
301301
CCIfSwiftSelf<CCIfType<[i64], CCAssignToReg<[R10]>>>,
302302

303-
// An SwiftError is passed in R12.
303+
// A SwiftError is passed in R12.
304304
CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R12]>>>,
305305

306306
// The first 6 integer arguments are passed in integer registers.
@@ -849,7 +849,7 @@ def CSR_NoRegs : CalleeSavedRegs<(add)>;
849849
def CSR_32 : CalleeSavedRegs<(add ESI, EDI, EBX, EBP)>;
850850
def CSR_64 : CalleeSavedRegs<(add RBX, R12, R13, R14, R15, RBP)>;
851851

852-
def CSR_64_SwiftError : CalleeSavedRegs<(add RBX, R13, R14, R15, RBP)>;
852+
def CSR_64_SwiftError : CalleeSavedRegs<(sub CSR_64, R12)>;
853853

854854
def CSR_32EHRet : CalleeSavedRegs<(add EAX, EDX, CSR_32)>;
855855
def CSR_64EHRet : CalleeSavedRegs<(add RAX, RDX, CSR_64)>;

lib/Target/X86/X86FastISel.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -973,14 +973,18 @@ bool X86FastISel::X86SelectStore(const Instruction *I) {
973973
return false;
974974

975975
const Value *PtrV = I->getOperand(1);
976-
if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
977-
if (Arg->hasSwiftErrorAttr() && TLI.supportSwiftError())
978-
return false;
979-
}
976+
if (TLI.supportSwiftError()) {
977+
// Swifterror values can come from either a function parameter with
978+
// swifterror attribute or an alloca with swifterror attribute.
979+
if (const Argument *Arg = dyn_cast<Argument>(PtrV)) {
980+
if (Arg->hasSwiftErrorAttr())
981+
return false;
982+
}
980983

981-
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
982-
if (Alloca->isSwiftError() && TLI.supportSwiftError())
983-
return false;
984+
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) {
985+
if (Alloca->isSwiftError())
986+
return false;
987+
}
984988
}
985989

986990
const Value *Val = S->getValueOperand();
@@ -1013,8 +1017,8 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
10131017
if (!FuncInfo.CanLowerReturn)
10141018
return false;
10151019

1016-
if (F.getAttributes().hasAttrSomewhere(Attribute::SwiftError) &&
1017-
TLI.supportSwiftError())
1020+
if (TLI.supportSwiftError() &&
1021+
F.getAttributes().hasAttrSomewhere(Attribute::SwiftError))
10181022
return false;
10191023

10201024
if (TLI.supportSplitCSR(FuncInfo.MF))
@@ -1149,14 +1153,18 @@ bool X86FastISel::X86SelectLoad(const Instruction *I) {
11491153
return false;
11501154

11511155
const Value *SV = I->getOperand(0);
1152-
if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1153-
if (Arg->hasSwiftErrorAttr() && TLI.supportSwiftError())
1154-
return false;
1155-
}
1156+
if (TLI.supportSwiftError()) {
1157+
// Swifterror values can come from either a function parameter with
1158+
// swifterror attribute or an alloca with swifterror attribute.
1159+
if (const Argument *Arg = dyn_cast<Argument>(SV)) {
1160+
if (Arg->hasSwiftErrorAttr())
1161+
return false;
1162+
}
11561163

1157-
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1158-
if (Alloca->isSwiftError() && TLI.supportSwiftError())
1159-
return false;
1164+
if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) {
1165+
if (Alloca->isSwiftError())
1166+
return false;
1167+
}
11601168
}
11611169

11621170
MVT VT;

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,6 +2301,25 @@ X86TargetLowering::LowerReturn(SDValue Chain,
23012301
// false, then an sret argument may be implicitly inserted in the SelDAG. In
23022302
// either case FuncInfo->setSRetReturnReg() will have been called.
23032303
if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) {
2304+
// When we have both sret and another return value, we should use the
2305+
// original Chain stored in RetOps[0], instead of the current Chain updated
2306+
// in the above loop. If we only have sret, RetOps[0] equals to Chain.
2307+
2308+
// For the case of sret and another return value, we have
2309+
// Chain_0 at the function entry
2310+
// Chain_1 = getCopyToReg(Chain_0) in the above loop
2311+
// If we use Chain_1 in getCopyFromReg, we will have
2312+
// Val = getCopyFromReg(Chain_1)
2313+
// Chain_2 = getCopyToReg(Chain_1, Val) from below
2314+
2315+
// getCopyToReg(Chain_0) will be glued together with
2316+
// getCopyToReg(Chain_1, Val) into Unit A, getCopyFromReg(Chain_1) will be
2317+
// in Unit B, and we will have cyclic dependency between Unit A and Unit B:
2318+
// Data dependency from Unit B to Unit A due to usage of Val in
2319+
// getCopyToReg(Chain_1, Val)
2320+
// Chain dependency from Unit A to Unit B
2321+
2322+
// So here, we use RetOps[0] (i.e Chain_0) for getCopyFromReg.
23042323
SDValue Val = DAG.getCopyFromReg(RetOps[0], dl, SRetReg,
23052324
getPointerTy(MF.getDataLayout()));
23062325

lib/Target/X86/X86ISelLowering.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,10 @@ namespace llvm {
954954

955955
bool isIntDivCheap(EVT VT, AttributeSet Attr) const override;
956956

957+
bool supportSwiftError() const override {
958+
return true;
959+
}
960+
957961
protected:
958962
std::pair<const TargetRegisterClass *, uint8_t>
959963
findRepresentativeClass(const TargetRegisterInfo *TRI,
@@ -1065,10 +1069,6 @@ namespace llvm {
10651069
SDValue LowerGC_TRANSITION_START(SDValue Op, SelectionDAG &DAG) const;
10661070
SDValue LowerGC_TRANSITION_END(SDValue Op, SelectionDAG &DAG) const;
10671071

1068-
bool supportSwiftError() const override {
1069-
return true;
1070-
}
1071-
10721072
SDValue
10731073
LowerFormalArguments(SDValue Chain,
10741074
CallingConv::ID CallConv, bool isVarArg,

0 commit comments

Comments
 (0)