summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorBryan Chan <bryan.chan@ca.ibm.com>2016-04-28 00:17:23 +0000
committerBryan Chan <bryan.chan@ca.ibm.com>2016-04-28 00:17:23 +0000
commit893110ecafee4113b24319f6d47b3ef341d9d803 (patch)
tree8b0dfa05cdd5b797144b018f3fa8b688e6131d04 /llvm/lib
parent1b70d666ae57d74ad14711c29a3a5e68e05bc388 (diff)
downloadbcm5719-llvm-893110ecafee4113b24319f6d47b3ef341d9d803.tar.gz
bcm5719-llvm-893110ecafee4113b24319f6d47b3ef341d9d803.zip
[SystemZ] Support Swift Calling Convention
Summary: Port rL265480, rL264754, rL265997 and rL266252 to SystemZ, in order to enable the Swift port on the architecture. SwiftSelf and SwiftError are assigned to R10 and R9, respectively, which are normally callee-saved registers. For more information, see: RFC: Implementing the Swift calling convention in LLVM and Clang https://groups.google.com/forum/#!topic/llvm-dev/epDd2w93kZ0 Reviewers: kbarton, manmanren, rjmccall, uweigand Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D19414 llvm-svn: 267823
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZCallingConv.td12
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.cpp10
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelLowering.h4
-rw-r--r--llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp8
4 files changed, 31 insertions, 3 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.td b/llvm/lib/Target/SystemZ/SystemZCallingConv.td
index 2404b96642c..2bf5ac29865 100644
--- a/llvm/lib/Target/SystemZ/SystemZCallingConv.td
+++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.td
@@ -33,6 +33,9 @@ def RetCC_SystemZ : CallingConv<[
// Promote i32 to i64 if it has an explicit extension type.
CCIfType<[i32], CCIfExtend<CCPromoteToType<i64>>>,
+ // A SwiftError is returned in R9.
+ CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R9D]>>>,
+
// ABI-compliant code returns 64-bit integers in R2. Make the other
// call-clobbered argument registers available for code that doesn't
// care about the ABI. (R6 is an argument register too, but is
@@ -65,6 +68,12 @@ def CC_SystemZ : CallingConv<[
// are smaller than 64 bits shouldn't.
CCIfType<[i32], CCIfExtend<CCPromoteToType<i64>>>,
+ // A SwiftSelf is passed in callee-saved R10.
+ CCIfSwiftSelf<CCIfType<[i64], CCAssignToReg<[R10D]>>>,
+
+ // A SwiftError is passed in callee-saved R9.
+ CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R9D]>>>,
+
// Force long double values to the stack and pass i64 pointers to them.
CCIfType<[f128], CCPassIndirect<i64>>,
// Same for i128 values. These are already split into two i64 here,
@@ -108,3 +117,6 @@ def CC_SystemZ : CallingConv<[
//===----------------------------------------------------------------------===//
def CSR_SystemZ : CalleeSavedRegs<(add (sequence "R%dD", 6, 15),
(sequence "F%dD", 8, 15))>;
+
+// R9 is used to return SwiftError; remove it from CSR.
+def CSR_SystemZ_SwiftError : CalleeSavedRegs<(sub CSR_SystemZ, R9D)>;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 51ef0d208ff..7eaa3ee73a1 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1004,9 +1004,11 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
}
static bool canUseSiblingCall(const CCState &ArgCCInfo,
- SmallVectorImpl<CCValAssign> &ArgLocs) {
+ SmallVectorImpl<CCValAssign> &ArgLocs,
+ SmallVectorImpl<ISD::OutputArg> &Outs) {
// Punt if there are any indirect or stack arguments, or if the call
- // needs the call-saved argument register R6.
+ // needs the callee-saved argument register R6, or if the call uses
+ // the callee-saved register arguments SwiftSelf and SwiftError.
for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
CCValAssign &VA = ArgLocs[I];
if (VA.getLocInfo() == CCValAssign::Indirect)
@@ -1016,6 +1018,8 @@ static bool canUseSiblingCall(const CCState &ArgCCInfo,
unsigned Reg = VA.getLocReg();
if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D)
return false;
+ if (Outs[I].Flags.isSwiftSelf() || Outs[I].Flags.isSwiftError())
+ return false;
}
return true;
}
@@ -1049,7 +1053,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
// We don't support GuaranteedTailCallOpt, only automatically-detected
// sibling calls.
- if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs))
+ if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs, Outs))
IsTailCall = false;
// Get a count of how many bytes are to be pushed on the stack.
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index ae761758b84..fe6966aafe2 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -459,6 +459,10 @@ public:
SelectionDAG &DAG) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
+ bool supportSwiftError() const override {
+ return true;
+ }
+
private:
const SystemZSubtarget &Subtarget;
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index 8d872b75d2e..b5e5fd4bfc4 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -24,12 +24,20 @@ SystemZRegisterInfo::SystemZRegisterInfo()
const MCPhysReg *
SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+ if (MF->getSubtarget().getTargetLowering()->supportSwiftError() &&
+ MF->getFunction()->getAttributes().hasAttrSomewhere(
+ Attribute::SwiftError))
+ return CSR_SystemZ_SwiftError_SaveList;
return CSR_SystemZ_SaveList;
}
const uint32_t *
SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const {
+ if (MF.getSubtarget().getTargetLowering()->supportSwiftError() &&
+ MF.getFunction()->getAttributes().hasAttrSomewhere(
+ Attribute::SwiftError))
+ return CSR_SystemZ_SwiftError_RegMask;
return CSR_SystemZ_RegMask;
}
OpenPOWER on IntegriCloud