summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/PowerPC/PPCCallingConv.td5
-rw-r--r--llvm/lib/Target/PowerPC/PPCFastISel.cpp6
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp27
-rw-r--r--llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h7
-rw-r--r--llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp20
-rw-r--r--llvm/lib/Target/PowerPC/PPCRegisterInfo.td41
6 files changed, 96 insertions, 10 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.td b/llvm/lib/Target/PowerPC/PPCCallingConv.td
index 56176f14533..3eaec6ba54d 100644
--- a/llvm/lib/Target/PowerPC/PPCCallingConv.td
+++ b/llvm/lib/Target/PowerPC/PPCCallingConv.td
@@ -224,9 +224,12 @@ def CSR_SVR464 : CalleeSavedRegs<(add X14, X15, X16, X17, X18, X19, X20,
F27, F28, F29, F30, F31, CR2, CR3, CR4
)>;
-
def CSR_SVR464_Altivec : CalleeSavedRegs<(add CSR_SVR464, CSR_Altivec)>;
+def CSR_SVR464_R2 : CalleeSavedRegs<(add CSR_SVR464, X2)>;
+
+def CSR_SVR464_R2_Altivec : CalleeSavedRegs<(add CSR_SVR464_Altivec, X2)>;
+
def CSR_NoRegs : CalleeSavedRegs<(add)>;
def CSR_64_AllRegs: CalleeSavedRegs<(add X0, (sequence "X%u", 3, 10),
diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index 44a3924f479..a929efa42cb 100644
--- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
@@ -17,6 +17,7 @@
#include "MCTargetDesc/PPCPredicates.h"
#include "PPCCallingConv.h"
#include "PPCISelLowering.h"
+#include "PPCMachineFunctionInfo.h"
#include "PPCSubtarget.h"
#include "PPCTargetMachine.h"
#include "llvm/ADT/Optional.h"
@@ -86,6 +87,7 @@ class PPCFastISel final : public FastISel {
const TargetMachine &TM;
const PPCSubtarget *PPCSubTarget;
+ PPCFunctionInfo *PPCFuncInfo;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
LLVMContext *Context;
@@ -95,6 +97,7 @@ class PPCFastISel final : public FastISel {
const TargetLibraryInfo *LibInfo)
: FastISel(FuncInfo, LibInfo), TM(FuncInfo.MF->getTarget()),
PPCSubTarget(&FuncInfo.MF->getSubtarget<PPCSubtarget>()),
+ PPCFuncInfo(FuncInfo.MF->getInfo<PPCFunctionInfo>()),
TII(*PPCSubTarget->getInstrInfo()),
TLI(*PPCSubTarget->getTargetLowering()),
Context(&FuncInfo.Fn->getContext()) {}
@@ -1526,6 +1529,7 @@ bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
// Direct calls, in both the ELF V1 and V2 ABIs, need the TOC register live
// into the call.
+ PPCFuncInfo->setUsesTOCBasePtr();
MIB.addReg(PPC::X2, RegState::Implicit);
// Add a register mask with the call-preserved registers. Proper
@@ -1864,6 +1868,7 @@ unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
unsigned Opc = (VT == MVT::f32) ? PPC::LFS : PPC::LFD;
unsigned TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
+ PPCFuncInfo->setUsesTOCBasePtr();
// For small code model, generate a LF[SD](0, LDtocCPT(Idx, X2)).
if (CModel == CodeModel::Small || CModel == CodeModel::JITDefault) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::LDtocCPT),
@@ -1913,6 +1918,7 @@ unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
if (GV->isThreadLocal())
return 0;
+ PPCFuncInfo->setUsesTOCBasePtr();
// For small code model, generate a simple TOC load.
if (CModel == CodeModel::Small || CModel == CodeModel::JITDefault)
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::LDtoc),
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index df2437c0211..b4416148571 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1590,6 +1590,15 @@ static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC,
return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
}
+static void setUsesTOCBasePtr(MachineFunction &MF) {
+ PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+ FuncInfo->setUsesTOCBasePtr();
+}
+
+static void setUsesTOCBasePtr(SelectionDAG &DAG) {
+ setUsesTOCBasePtr(DAG.getMachineFunction());
+}
+
SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
SelectionDAG &DAG) const {
EVT PtrVT = Op.getValueType();
@@ -1599,6 +1608,7 @@ SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
// 64-bit SVR4 ABI code is always position-independent.
// The actual address of the GlobalValue is stored in the TOC.
if (Subtarget.isSVR4ABI() && Subtarget.isPPC64()) {
+ setUsesTOCBasePtr(DAG);
SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0);
return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(CP), MVT::i64, GA,
DAG.getRegister(PPC::X2, MVT::i64));
@@ -1630,6 +1640,7 @@ SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
// 64-bit SVR4 ABI code is always position-independent.
// The actual address of the GlobalValue is stored in the TOC.
if (Subtarget.isSVR4ABI() && Subtarget.isPPC64()) {
+ setUsesTOCBasePtr(DAG);
SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(JT), MVT::i64, GA,
DAG.getRegister(PPC::X2, MVT::i64));
@@ -1661,6 +1672,7 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
// 64-bit SVR4 ABI code is always position-independent.
// The actual BlockAddress is stored in the TOC.
if (Subtarget.isSVR4ABI() && Subtarget.isPPC64()) {
+ setUsesTOCBasePtr(DAG);
SDValue GA = DAG.getTargetBlockAddress(BA, PtrVT, BASDN->getOffset());
return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(BASDN), MVT::i64, GA,
DAG.getRegister(PPC::X2, MVT::i64));
@@ -1729,6 +1741,7 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
PPCII::MO_TLS);
SDValue GOTPtr;
if (is64bit) {
+ setUsesTOCBasePtr(DAG);
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
PtrVT, GOTReg, TGA);
@@ -1744,6 +1757,7 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
PPCII::MO_TLSGD);
SDValue GOTPtr;
if (is64bit) {
+ setUsesTOCBasePtr(DAG);
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
GOTReg, TGA);
@@ -1764,6 +1778,7 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
PPCII::MO_TLSLD);
SDValue GOTPtr;
if (is64bit) {
+ setUsesTOCBasePtr(DAG);
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
GOTReg, TGA);
@@ -1796,6 +1811,7 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
// 64-bit SVR4 ABI code is always position-independent.
// The actual address of the GlobalValue is stored in the TOC.
if (Subtarget.isSVR4ABI() && Subtarget.isPPC64()) {
+ setUsesTOCBasePtr(DAG);
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset());
return DAG.getNode(PPCISD::TOC_ENTRY, DL, MVT::i64, GA,
DAG.getRegister(PPC::X2, MVT::i64));
@@ -3763,6 +3779,7 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
MPI.getWithOffset(8), false, false,
LoadsInv, 8);
+ setUsesTOCBasePtr(DAG);
SDValue TOCVal = DAG.getCopyToReg(Chain, dl, PPC::X2, TOCPtr,
InFlag);
Chain = TOCVal.getValue(0);
@@ -3831,8 +3848,10 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
// All calls, in both the ELF V1 and V2 ABIs, need the TOC register live
// into the call.
- if (isSVR4ABI && isPPC64 && !IsPatchPoint)
+ if (isSVR4ABI && isPPC64 && !IsPatchPoint) {
+ setUsesTOCBasePtr(DAG);
Ops.push_back(DAG.getRegister(PPC::X2, PtrVT));
+ }
return CallOpc;
}
@@ -4794,6 +4813,7 @@ PPCTargetLowering::LowerCall_64SVR4(SDValue Chain, SDValue Callee,
!isFunctionGlobalAddress(Callee) &&
!isa<ExternalSymbolSDNode>(Callee)) {
// Load r2 into a virtual register and store it to the TOC save area.
+ setUsesTOCBasePtr(DAG);
SDValue Val = DAG.getCopyFromReg(Chain, dl, PPC::X2, MVT::i64);
// TOC save area offset.
unsigned TOCSaveOffset = PPCFrameLowering::getTOCSaveOffset(isELFv2ABI);
@@ -7190,6 +7210,7 @@ PPCTargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
unsigned BufReg = MI->getOperand(1).getReg();
if (Subtarget.isPPC64() && Subtarget.isSVR4ABI()) {
+ setUsesTOCBasePtr(*MBB->getParent());
MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::STD))
.addReg(PPC::X2)
.addImm(TOCOffset)
@@ -7353,6 +7374,7 @@ PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
// Reload TOC
if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
+ setUsesTOCBasePtr(*MBB->getParent());
MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), PPC::X2)
.addImm(TOCOffset)
.addReg(BufReg);
@@ -7381,6 +7403,7 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
// way to mark the dependence as implicit there, and so the stackmap code
// will confuse it with a regular operand. Instead, add the dependence
// here.
+ setUsesTOCBasePtr(*BB->getParent());
MI->addOperand(MachineOperand::CreateReg(PPC::X2, false, true));
}
@@ -9769,7 +9792,7 @@ unsigned PPCTargetLowering::getRegisterByName(const char* RegName,
bool is64Bit = isPPC64 && VT == MVT::i64;
unsigned Reg = StringSwitch<unsigned>(RegName)
.Case("r1", is64Bit ? PPC::X1 : PPC::R1)
- .Case("r2", isDarwinABI ? 0 : (is64Bit ? PPC::X2 : PPC::R2))
+ .Case("r2", (isDarwinABI || isPPC64) ? 0 : PPC::R2)
.Case("r13", (!isPPC64 && isDarwinABI) ? 0 :
(is64Bit ? PPC::X13 : PPC::R13))
.Default(0);
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index 37b2ff83c45..607cdf612ee 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -62,6 +62,9 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// entry, even though LR may otherwise apparently not be used.
bool LRStoreRequired;
+ /// This function makes use of the PPC64 ELF TOC base pointer (register r2).
+ bool UsesTOCBasePtr;
+
/// MinReservedArea - This is the frame size that is at least reserved in a
/// potential caller (parameter+linkage area).
unsigned MinReservedArea;
@@ -112,6 +115,7 @@ public:
SpillsCR(false),
SpillsVRSAVE(false),
LRStoreRequired(false),
+ UsesTOCBasePtr(false),
MinReservedArea(0),
TailCallSPDelta(0),
HasFastCall(false),
@@ -164,6 +168,9 @@ public:
void setLRStoreRequired() { LRStoreRequired = true; }
bool isLRStoreRequired() const { return LRStoreRequired; }
+ void setUsesTOCBasePtr() { UsesTOCBasePtr = true; }
+ bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
+
void setHasFastCall() { HasFastCall = true; }
bool hasFastCall() const { return HasFastCall;}
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 2645b1cc3a7..b0b20a037f2 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -115,9 +115,14 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
CSR_Darwin32_Altivec_SaveList :
CSR_Darwin32_SaveList);
+ // On PPC64, we might need to save r2 (but only if it is not reserved).
+ bool SaveR2 = MF->getRegInfo().isAllocatable(PPC::X2);
+
return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
- CSR_SVR464_Altivec_SaveList :
- CSR_SVR464_SaveList) :
+ (SaveR2 ? CSR_SVR464_R2_Altivec_SaveList :
+ CSR_SVR464_Altivec_SaveList) :
+ (SaveR2 ? CSR_SVR464_R2_SaveList :
+ CSR_SVR464_SaveList)) :
(Subtarget.hasAltivec() ?
CSR_SVR432_Altivec_SaveList :
CSR_SVR432_SaveList);
@@ -216,7 +221,16 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// The 64-bit SVR4 ABI reserves r2 for the TOC pointer.
if (Subtarget.isSVR4ABI()) {
- Reserved.set(PPC::X2);
+ // We only reserve r2 if we need to use the TOC pointer. If we have no
+ // explicit uses of the TOC pointer (meaning we're a leaf function with
+ // no constant-pool loads, etc.) and we have no potential uses inside an
+ // inline asm block, then we can treat r2 has an ordinary callee-saved
+ // register.
+ const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+ if (FuncInfo->usesTOCBasePtr() || MF.hasInlineAsm())
+ Reserved.set(PPC::X2);
+ else
+ Reserved.reset(PPC::R2);
}
}
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
index 2fdf04eaaee..a495ae04899 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -219,17 +219,50 @@ def RM: PPCReg<"**ROUNDING MODE**">;
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
def GPRC : RegisterClass<"PPC", [i32], 32, (add (sequence "R%u", 2, 12),
(sequence "R%u", 30, 13),
- R31, R0, R1, FP, BP)>;
+ R31, R0, R1, FP, BP)> {
+ // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+ // put it at the end of the list.
+ let AltOrders = [(add (sub GPRC, R2), R2)];
+ let AltOrderSelect = [{
+ const PPCSubtarget &S = MF.getTarget().getSubtarget<PPCSubtarget>();
+ return S.isPPC64() && S.isSVR4ABI();
+ }];
+}
def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12),
(sequence "X%u", 30, 14),
- X31, X13, X0, X1, FP8, BP8)>;
+ X31, X13, X0, X1, FP8, BP8)> {
+ // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+ // put it at the end of the list.
+ let AltOrders = [(add (sub G8RC, X2), X2)];
+ let AltOrderSelect = [{
+ const PPCSubtarget &S = MF.getTarget().getSubtarget<PPCSubtarget>();
+ return S.isPPC64() && S.isSVR4ABI();
+ }];
+}
// For some instructions r0 is special (representing the value 0 instead of
// the value in the r0 register), and we use these register subclasses to
// prevent r0 from being allocated for use by those instructions.
-def GPRC_NOR0 : RegisterClass<"PPC", [i32], 32, (add (sub GPRC, R0), ZERO)>;
-def G8RC_NOX0 : RegisterClass<"PPC", [i64], 64, (add (sub G8RC, X0), ZERO8)>;
+def GPRC_NOR0 : RegisterClass<"PPC", [i32], 32, (add (sub GPRC, R0), ZERO)> {
+ // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+ // put it at the end of the list.
+ let AltOrders = [(add (sub GPRC_NOR0, R2), R2)];
+ let AltOrderSelect = [{
+ const PPCSubtarget &S = MF.getTarget().getSubtarget<PPCSubtarget>();
+ return S.isPPC64() && S.isSVR4ABI();
+ }];
+}
+
+def G8RC_NOX0 : RegisterClass<"PPC", [i64], 64, (add (sub G8RC, X0), ZERO8)> {
+ // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+ // put it at the end of the list.
+ let AltOrders = [(add (sub G8RC_NOX0, X2), X2)];
+ let AltOrderSelect = [{
+ const PPCSubtarget &S = MF.getTarget().getSubtarget<PPCSubtarget>();
+ return S.isPPC64() && S.isSVR4ABI();
+ }];
+}
// Allocate volatiles first, then non-volatiles in reverse order. With the SVR4
// ABI the size of the Floating-point register save area is determined by the
OpenPOWER on IntegriCloud