diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AllocationOrder.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AllocationOrder.h | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetRegisterInfo.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp | 81 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZRegisterInfo.h | 7 |
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; |