summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AllocationOrder.cpp5
-rw-r--r--llvm/lib/CodeGen/AllocationOrder.h8
-rw-r--r--llvm/lib/CodeGen/TargetRegisterInfo.cpp9
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp7
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.h2
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp6
-rw-r--r--llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp81
-rw-r--r--llvm/lib/Target/SystemZ/SystemZRegisterInfo.h7
8 files changed, 115 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/AllocationOrder.cpp b/llvm/lib/CodeGen/AllocationOrder.cpp
index d840a2f69ab..3d106945e19 100644
--- a/llvm/lib/CodeGen/AllocationOrder.cpp
+++ b/llvm/lib/CodeGen/AllocationOrder.cpp
@@ -31,11 +31,12 @@ AllocationOrder::AllocationOrder(unsigned VirtReg,
const VirtRegMap &VRM,
const RegisterClassInfo &RegClassInfo,
const LiveRegMatrix *Matrix)
- : Pos(0) {
+ : Pos(0), HardHints(false) {
const MachineFunction &MF = VRM.getMachineFunction();
const TargetRegisterInfo *TRI = &VRM.getTargetRegInfo();
Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
- TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix);
+ if (TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix))
+ HardHints = true;
rewind();
DEBUG({
diff --git a/llvm/lib/CodeGen/AllocationOrder.h b/llvm/lib/CodeGen/AllocationOrder.h
index 8223a52e333..467bcc2edc6 100644
--- a/llvm/lib/CodeGen/AllocationOrder.h
+++ b/llvm/lib/CodeGen/AllocationOrder.h
@@ -32,7 +32,11 @@ class LLVM_LIBRARY_VISIBILITY AllocationOrder {
ArrayRef<MCPhysReg> Order;
int Pos;
+ // If HardHints is true, *only* Hints will be returned.
+ bool HardHints;
+
public:
+
/// Create a new AllocationOrder for VirtReg.
/// @param VirtReg Virtual register to allocate for.
/// @param VRM Virtual register map for function.
@@ -51,6 +55,8 @@ public:
unsigned next(unsigned Limit = 0) {
if (Pos < 0)
return Hints.end()[Pos++];
+ if (HardHints)
+ return 0;
if (!Limit)
Limit = Order.size();
while (Pos < int(Limit)) {
@@ -68,6 +74,8 @@ public:
unsigned nextWithDups(unsigned Limit) {
if (Pos < 0)
return Hints.end()[Pos++];
+ if (HardHints)
+ return 0;
if (Pos < int(Limit))
return Order[Pos++];
return 0;
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index 758fdabf5dd..eb8bcc320c1 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -360,7 +360,7 @@ bool TargetRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
}
// Compute target-independent register allocator hints to help eliminate copies.
-void
+bool
TargetRegisterInfo::getRegAllocationHints(unsigned VirtReg,
ArrayRef<MCPhysReg> Order,
SmallVectorImpl<MCPhysReg> &Hints,
@@ -382,17 +382,18 @@ TargetRegisterInfo::getRegAllocationHints(unsigned VirtReg,
// Check that Phys is a valid hint in VirtReg's register class.
if (!isPhysicalRegister(Phys))
- return;
+ return false;
if (MRI.isReserved(Phys))
- return;
+ return false;
// Check that Phys is in the allocation order. We shouldn't heed hints
// from VirtReg's register class if they aren't in the allocation order. The
// target probably has a reason for removing the register.
if (!is_contained(Order, Phys))
- return;
+ return false;
// All clear, tell the register allocator to prefer this register.
Hints.push_back(Phys);
+ return false;
}
bool TargetRegisterInfo::canRealignStack(const MachineFunction &MF) const {
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index eaa8d4c0f1a..798b8241eee 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -280,7 +280,7 @@ static unsigned getPairedGPR(unsigned Reg, bool Odd, const MCRegisterInfo *RI) {
}
// Resolve the RegPairEven / RegPairOdd register allocator hints.
-void
+bool
ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg,
ArrayRef<MCPhysReg> Order,
SmallVectorImpl<MCPhysReg> &Hints,
@@ -300,7 +300,7 @@ ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg,
break;
default:
TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
- return;
+ return false;
}
// This register should preferably be even (Odd == 0) or odd (Odd == 1).
@@ -308,7 +308,7 @@ ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg,
// the paired register as the first hint.
unsigned Paired = Hint.second;
if (Paired == 0)
- return;
+ return false;
unsigned PairedPhys = 0;
if (TargetRegisterInfo::isPhysicalRegister(Paired)) {
@@ -331,6 +331,7 @@ ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg,
continue;
Hints.push_back(Reg);
}
+ return false;
}
void
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
index a8e947184ea..8fce0560df5 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -145,7 +145,7 @@ public:
unsigned getRegPressureLimit(const TargetRegisterClass *RC,
MachineFunction &MF) const override;
- void getRegAllocationHints(unsigned VirtReg,
+ bool getRegAllocationHints(unsigned VirtReg,
ArrayRef<MCPhysReg> Order,
SmallVectorImpl<MCPhysReg> &Hints,
const MachineFunction &MF,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 19ce7776fed..7aad709bcf1 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -16,6 +16,7 @@
#include "SystemZ.h"
#include "SystemZInstrBuilder.h"
#include "SystemZSubtarget.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveVariables.h"
@@ -45,6 +46,9 @@ using namespace llvm;
#define GET_INSTRMAP_INFO
#include "SystemZGenInstrInfo.inc"
+#define DEBUG_TYPE "systemz-II"
+STATISTIC(LOCRMuxJumps, "Number of LOCRMux jump-sequences (lower is better)");
+
// Return a mask with Count low bits set.
static uint64_t allOnes(unsigned int Count) {
return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1;
@@ -209,6 +213,8 @@ void SystemZInstrInfo::expandLOCRPseudo(MachineInstr &MI, unsigned LowOpcode,
MI.setDesc(get(LowOpcode));
else if (DestIsHigh && SrcIsHigh)
MI.setDesc(get(HighOpcode));
+ else
+ LOCRMuxJumps++;
// If we were unable to implement the pseudo with a single instruction, we
// need to convert it back into a branch sequence. This cannot be done here
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index a44fae523fe..35c4f6ac549 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -11,9 +11,11 @@
#include "SystemZInstrInfo.h"
#include "SystemZSubtarget.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/VirtRegMap.h"
using namespace llvm;
@@ -23,6 +25,85 @@ using namespace llvm;
SystemZRegisterInfo::SystemZRegisterInfo()
: SystemZGenRegisterInfo(SystemZ::R14D) {}
+// Given that MO is a GRX32 operand, return either GR32 or GRH32 if MO
+// somehow belongs in it. Otherwise, return GRX32.
+static const TargetRegisterClass *getRC32(MachineOperand &MO,
+ const VirtRegMap *VRM,
+ const MachineRegisterInfo *MRI) {
+ const TargetRegisterClass *RC = MRI->getRegClass(MO.getReg());
+
+ if (SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
+ MO.getSubReg() == SystemZ::subreg_l32)
+ return &SystemZ::GR32BitRegClass;
+ if (SystemZ::GRH32BitRegClass.hasSubClassEq(RC) ||
+ MO.getSubReg() == SystemZ::subreg_h32)
+ return &SystemZ::GRH32BitRegClass;
+
+ if (VRM && VRM->hasPhys(MO.getReg())) {
+ unsigned PhysReg = VRM->getPhys(MO.getReg());
+ if (SystemZ::GR32BitRegClass.contains(PhysReg))
+ return &SystemZ::GR32BitRegClass;
+ assert (SystemZ::GRH32BitRegClass.contains(PhysReg) &&
+ "Phys reg not in GR32 or GRH32?");
+ return &SystemZ::GRH32BitRegClass;
+ }
+
+ assert (RC == &SystemZ::GRX32BitRegClass);
+ return RC;
+}
+
+bool
+SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg,
+ ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF,
+ const VirtRegMap *VRM,
+ const LiveRegMatrix *Matrix) const {
+ const MachineRegisterInfo *MRI = &MF.getRegInfo();
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+ if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {
+ SmallVector<unsigned, 8> Worklist;
+ SmallSet<unsigned, 4> DoneRegs;
+ Worklist.push_back(VirtReg);
+ while (Worklist.size()) {
+ unsigned Reg = Worklist.pop_back_val();
+ if (!DoneRegs.insert(Reg).second)
+ continue;
+
+ for (auto &Use : MRI->use_instructions(Reg))
+ // For LOCRMux, see if the other operand is already a high or low
+ // register, and in that case give the correpsonding hints for
+ // VirtReg. LOCR instructions need both operands in either high or
+ // low parts.
+ if (Use.getOpcode() == SystemZ::LOCRMux) {
+ MachineOperand &TrueMO = Use.getOperand(1);
+ MachineOperand &FalseMO = Use.getOperand(2);
+ const TargetRegisterClass *RC =
+ TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI),
+ getRC32(TrueMO, VRM, MRI));
+ if (RC && RC != &SystemZ::GRX32BitRegClass) {
+ for (MCPhysReg Reg : Order)
+ if (RC->contains(Reg) && !MRI->isReserved(Reg))
+ Hints.push_back(Reg);
+ // Return true to make these hints the only regs available to
+ // RA. This may mean extra spilling but since the alternative is
+ // a jump sequence expansion of the LOCRMux, it is preferred.
+ return true;
+ }
+
+ // Add the other operand of the LOCRMux to the worklist.
+ unsigned OtherReg =
+ (TrueMO.getReg() == Reg ? FalseMO.getReg() : TrueMO.getReg());
+ if (MRI->getRegClass(OtherReg) == &SystemZ::GRX32BitRegClass)
+ Worklist.push_back(OtherReg);
+ }
+ }
+ }
+
+ return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF,
+ VRM, Matrix);
+}
+
const MCPhysReg *
SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
if (MF->getSubtarget().getTargetLowering()->supportSwiftError() &&
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
index 8b690e6da9f..a58bfec98d0 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
@@ -44,6 +44,13 @@ public:
return &SystemZ::ADDR64BitRegClass;
}
+ bool getRegAllocationHints(unsigned VirtReg,
+ ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF,
+ const VirtRegMap *VRM,
+ const LiveRegMatrix *Matrix) const override;
+
// Override TargetRegisterInfo.h.
bool requiresRegisterScavenging(const MachineFunction &MF) const override {
return true;
OpenPOWER on IntegriCloud