diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -907,7 +907,7 @@ /// /// Reserved registers may belong to an allocatable register class, but the /// target has explicitly requested that they are not used. - bool isReserved(Register PhysReg) const { + bool isReserved(MCRegister PhysReg) const { return getReservedRegs().test(PhysReg.id()); } diff --git a/llvm/include/llvm/CodeGen/RegAllocPBQP.h b/llvm/include/llvm/CodeGen/RegAllocPBQP.h --- a/llvm/include/llvm/CodeGen/RegAllocPBQP.h +++ b/llvm/include/llvm/CodeGen/RegAllocPBQP.h @@ -22,6 +22,8 @@ #include "llvm/CodeGen/PBQP/Math.h" #include "llvm/CodeGen/PBQP/ReductionRules.h" #include "llvm/CodeGen/PBQP/Solution.h" +#include "llvm/CodeGen/Register.h" +#include "llvm/MC/MCRegister.h" #include "llvm/Support/ErrorHandling.h" #include #include @@ -96,13 +98,13 @@ AllowedRegVector() = default; AllowedRegVector(AllowedRegVector &&) = default; - AllowedRegVector(const std::vector &OptVec) - : NumOpts(OptVec.size()), Opts(new unsigned[NumOpts]) { + AllowedRegVector(const std::vector &OptVec) + : NumOpts(OptVec.size()), Opts(new MCRegister[NumOpts]) { std::copy(OptVec.begin(), OptVec.end(), Opts.get()); } unsigned size() const { return NumOpts; } - unsigned operator[](size_t I) const { return Opts[I]; } + MCRegister operator[](size_t I) const { return Opts[I]; } bool operator==(const AllowedRegVector &Other) const { if (NumOpts != Other.NumOpts) @@ -116,12 +118,12 @@ private: unsigned NumOpts = 0; - std::unique_ptr Opts; + std::unique_ptr Opts; }; inline hash_code hash_value(const AllowedRegVector &OptRegs) { - unsigned *OStart = OptRegs.Opts.get(); - unsigned *OEnd = OptRegs.Opts.get() + OptRegs.NumOpts; + MCRegister *OStart = OptRegs.Opts.get(); + MCRegister *OEnd = OptRegs.Opts.get() + OptRegs.NumOpts; return hash_combine(OptRegs.NumOpts, hash_combine_range(OStart, OEnd)); } @@ -143,11 +145,11 @@ LiveIntervals &LIS; MachineBlockFrequencyInfo &MBFI; - void setNodeIdForVReg(unsigned VReg, GraphBase::NodeId NId) { - VRegToNodeId[VReg] = NId; + void setNodeIdForVReg(Register VReg, GraphBase::NodeId NId) { + VRegToNodeId[VReg.id()] = NId; } - GraphBase::NodeId getNodeIdForVReg(unsigned VReg) const { + GraphBase::NodeId getNodeIdForVReg(Register VReg) const { auto VRegItr = VRegToNodeId.find(VReg); if (VRegItr == VRegToNodeId.end()) return GraphBase::invalidNodeId(); @@ -159,7 +161,7 @@ } private: - DenseMap VRegToNodeId; + DenseMap VRegToNodeId; AllowedRegVecPool AllowedRegVecs; }; @@ -197,8 +199,8 @@ NodeMetadata(NodeMetadata &&) = default; NodeMetadata& operator=(NodeMetadata &&) = default; - void setVReg(unsigned VReg) { this->VReg = VReg; } - unsigned getVReg() const { return VReg; } + void setVReg(Register VReg) { this->VReg = VReg; } + Register getVReg() const { return VReg; } void setAllowedRegs(GraphMetadata::AllowedRegVecRef AllowedRegs) { this->AllowedRegs = std::move(AllowedRegs); @@ -256,7 +258,7 @@ unsigned NumOpts = 0; unsigned DeniedOpts = 0; std::unique_ptr OptUnsafeEdges; - unsigned VReg = 0; + Register VReg; GraphMetadata::AllowedRegVecRef AllowedRegs; #ifndef NDEBUG diff --git a/llvm/include/llvm/MC/MCRegister.h b/llvm/include/llvm/MC/MCRegister.h --- a/llvm/include/llvm/MC/MCRegister.h +++ b/llvm/include/llvm/MC/MCRegister.h @@ -20,6 +20,7 @@ /// Wrapper class representing physical registers. Should be passed by value. class MCRegister { + friend hash_code hash_value(const MCRegister &); unsigned Reg; public: @@ -105,6 +106,9 @@ } }; +inline hash_code hash_value(const MCRegister &Reg) { + return hash_value(Reg.id()); +} } #endif // ifndef LLVM_MC_REGISTER_H diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp --- a/llvm/lib/CodeGen/RegAllocPBQP.cpp +++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp @@ -147,7 +147,7 @@ using AllowedSetMap = std::vector; using RegPair = std::pair; using CoalesceMap = std::map; - using RegSet = std::set; + using RegSet = std::set; char *customPassID; @@ -331,7 +331,7 @@ // Start by building the inactive set. for (auto NId : G.nodeIds()) { - unsigned VReg = G.getNodeMetadata(NId).getVReg(); + Register VReg = G.getNodeMetadata(NId).getVReg(); LiveInterval &LI = LIS.getInterval(VReg); assert(!LI.empty() && "PBQP graph contains node for empty interval"); Inactive.push(std::make_tuple(&LI, 0, NId)); @@ -413,9 +413,9 @@ PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0); bool NodesInterfere = false; for (unsigned I = 0; I != NRegs.size(); ++I) { - unsigned PRegN = NRegs[I]; + MCRegister PRegN = NRegs[I]; for (unsigned J = 0; J != MRegs.size(); ++J) { - unsigned PRegM = MRegs[J]; + MCRegister PRegM = MRegs[J]; if (TRI.regsOverlap(PRegN, PRegM)) { M[I + 1][J + 1] = std::numeric_limits::infinity(); NodesInterfere = true; @@ -448,8 +448,8 @@ if (!CP.setRegisters(&MI) || CP.getSrcReg() == CP.getDstReg()) continue; - unsigned DstReg = CP.getDstReg(); - unsigned SrcReg = CP.getSrcReg(); + Register DstReg = CP.getDstReg(); + Register SrcReg = CP.getSrcReg(); PBQP::PBQPNum CBenefit = MBFI.getBlockFreqRelativeToEntryBlock(&MBB); @@ -463,7 +463,7 @@ G.getNodeMetadata(NId).getAllowedRegs(); unsigned PRegOpt = 0; - while (PRegOpt < Allowed.size() && Allowed[PRegOpt] != DstReg) + while (PRegOpt < Allowed.size() && Allowed[PRegOpt].id() != DstReg) ++PRegOpt; if (PRegOpt < Allowed.size()) { @@ -508,9 +508,9 @@ assert(CostMat.getRows() == Allowed1.size() + 1 && "Size mismatch."); assert(CostMat.getCols() == Allowed2.size() + 1 && "Size mismatch."); for (unsigned I = 0; I != Allowed1.size(); ++I) { - unsigned PReg1 = Allowed1[I]; + MCRegister PReg1 = Allowed1[I]; for (unsigned J = 0; J != Allowed2.size(); ++J) { - unsigned PReg2 = Allowed2[J]; + MCRegister PReg2 = Allowed2[J]; if (PReg1 == PReg2) CostMat[I + 1][J + 1] -= Benefit; } @@ -571,18 +571,19 @@ // Iterate over all live ranges. for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { - unsigned Reg = Register::index2VirtReg(I); + Register Reg = Register::index2VirtReg(I); if (MRI.reg_nodbg_empty(Reg)) continue; VRegsToAlloc.insert(Reg); } } -static bool isACalleeSavedRegister(unsigned reg, const TargetRegisterInfo &TRI, +static bool isACalleeSavedRegister(MCRegister Reg, + const TargetRegisterInfo &TRI, const MachineFunction &MF) { const MCPhysReg *CSR = MF.getRegInfo().getCalleeSavedRegs(); for (unsigned i = 0; CSR[i] != 0; ++i) - if (TRI.regsOverlap(reg, CSR[i])) + if (TRI.regsOverlap(Reg, CSR[i])) return true; return false; } @@ -596,12 +597,12 @@ const TargetRegisterInfo &TRI = *G.getMetadata().MF.getSubtarget().getRegisterInfo(); - std::vector Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end()); + std::vector Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end()); - std::map> VRegAllowedMap; + std::map> VRegAllowedMap; while (!Worklist.empty()) { - unsigned VReg = Worklist.back(); + Register VReg = Worklist.back(); Worklist.pop_back(); LiveInterval &VRegLI = LIS.getInterval(VReg); @@ -621,10 +622,10 @@ LIS.checkRegMaskInterference(VRegLI, RegMaskOverlaps); // Compute an initial allowed set for the current vreg. - std::vector VRegAllowed; + std::vector VRegAllowed; ArrayRef RawPRegOrder = TRC->getRawAllocationOrder(MF); for (unsigned I = 0; I != RawPRegOrder.size(); ++I) { - unsigned PReg = RawPRegOrder[I]; + MCRegister PReg(RawPRegOrder[I]); if (MRI.isReserved(PReg)) continue; @@ -731,11 +732,11 @@ // Iterate over the nodes mapping the PBQP solution to a register // assignment. for (auto NId : G.nodeIds()) { - unsigned VReg = G.getNodeMetadata(NId).getVReg(); - unsigned AllocOption = Solution.getSelection(NId); + Register VReg = G.getNodeMetadata(NId).getVReg(); + unsigned AllocOpt = Solution.getSelection(NId); - if (AllocOption != PBQP::RegAlloc::getSpillOptionIdx()) { - unsigned PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOption - 1]; + if (AllocOpt != PBQP::RegAlloc::getSpillOptionIdx()) { + MCRegister PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOpt - 1]; LLVM_DEBUG(dbgs() << "VREG " << printReg(VReg, &TRI) << " -> " << TRI.getName(PReg) << "\n"); assert(PReg != 0 && "Invalid preg selected."); @@ -763,7 +764,7 @@ I != E; ++I) { LiveInterval &LI = LIS.getInterval(*I); - unsigned PReg = MRI.getSimpleHint(LI.reg()); + Register PReg = MRI.getSimpleHint(LI.reg()); if (PReg == 0) { const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg()); @@ -884,7 +885,7 @@ return Printable([NId, &G](raw_ostream &OS) { const MachineRegisterInfo &MRI = G.getMetadata().MF.getRegInfo(); const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); - unsigned VReg = G.getNodeMetadata(NId).getVReg(); + Register VReg = G.getNodeMetadata(NId).getVReg(); const char *RegClassName = TRI->getRegClassName(MRI.getRegClass(VReg)); OS << NId << " (" << RegClassName << ':' << printReg(VReg, TRI) << ')'; }); diff --git a/llvm/lib/CodeGen/RegisterCoalescer.h b/llvm/lib/CodeGen/RegisterCoalescer.h --- a/llvm/lib/CodeGen/RegisterCoalescer.h +++ b/llvm/lib/CodeGen/RegisterCoalescer.h @@ -61,9 +61,9 @@ /// Create a CoalescerPair representing a virtreg-to-physreg copy. /// No need to call setRegisters(). - CoalescerPair(unsigned VirtReg, unsigned PhysReg, + CoalescerPair(Register VirtReg, MCRegister PhysReg, const TargetRegisterInfo &tri) - : TRI(tri), DstReg(PhysReg), SrcReg(VirtReg) {} + : TRI(tri), DstReg(PhysReg), SrcReg(VirtReg) {} /// Set registers to match the copy instruction MI. Return /// false if MI is not a coalescable copy instruction. diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -137,13 +137,13 @@ /// ordered-by-slot-index set of DBG_VALUEs, to help quick /// identification of whether coalescing may change location validity. using DbgValueLoc = std::pair; - DenseMap> DbgVRegToValues; + DenseMap> DbgVRegToValues; /// VRegs may be repeatedly coalesced, and have many DBG_VALUEs attached. /// To avoid repeatedly merging sets of DbgValueLocs, instead record /// which vregs have been coalesced, and where to. This map is from /// vreg => {set of vregs merged in}. - DenseMap> DbgMergedVRegNums; + DenseMap> DbgMergedVRegNums; /// A LaneMask to remember on which subregister live ranges we need to call /// shrinkToUses() later. @@ -351,7 +351,7 @@ JoinVals &LHSVals, LiveRange &RHS, JoinVals &RHSVals); - void checkMergingChangesDbgValuesImpl(unsigned Reg, LiveRange &OtherRange, + void checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherRange, LiveRange &RegRange, JoinVals &Vals2); public: @@ -388,8 +388,8 @@ "Simple Register Coalescing", false, false) LLVM_NODISCARD static bool isMoveInstr(const TargetRegisterInfo &tri, - const MachineInstr *MI, unsigned &Src, - unsigned &Dst, unsigned &SrcSub, + const MachineInstr *MI, Register &Src, + Register &Dst, unsigned &SrcSub, unsigned &DstSub) { if (MI->isCopy()) { Dst = MI->getOperand(0).getReg(); @@ -429,7 +429,8 @@ NewRC = nullptr; Flipped = CrossClass = false; - unsigned Src, Dst, SrcSub, DstSub; + Register Src, Dst; + unsigned SrcSub, DstSub; if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub)) return false; Partial = SrcSub || DstSub; @@ -523,7 +524,8 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const { if (!MI) return false; - unsigned Src, Dst, SrcSub, DstSub; + Register Src, Dst; + unsigned SrcSub, DstSub; if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub)) return false; @@ -1228,7 +1230,7 @@ /// Returns true if @p MI defines the full vreg @p Reg, as opposed to just /// defining a subregister. -static bool definesFullReg(const MachineInstr &MI, unsigned Reg) { +static bool definesFullReg(const MachineInstr &MI, Register Reg) { assert(!Register::isPhysicalRegister(Reg) && "This code cannot handle physreg aliasing"); for (const MachineOperand &Op : MI.operands()) { @@ -1296,7 +1298,7 @@ const TargetRegisterClass *DefRC = TII->getRegClass(MCID, 0, TRI, *MF); if (!DefMI->isImplicitDef()) { if (Register::isPhysicalRegister(DstReg)) { - unsigned NewDstReg = DstReg; + Register NewDstReg = DstReg; unsigned NewDstIdx = TRI->composeSubRegIndices(CP.getSrcIdx(), DefMI->getOperand(0).getSubReg()); @@ -1370,7 +1372,7 @@ // NewMI may have dead implicit defs (E.g. EFLAGS for MOVr0 on X86). // We need to remember these so we can add intervals once we insert // NewMI into SlotIndexes. - SmallVector NewMIImplDefs; + SmallVector NewMIImplDefs; for (unsigned i = NewMI.getDesc().getNumOperands(), e = NewMI.getNumOperands(); i != e; ++i) { @@ -1378,7 +1380,7 @@ if (MO.isReg() && MO.isDef()) { assert(MO.isImplicit() && MO.isDead() && Register::isPhysicalRegister(MO.getReg())); - NewMIImplDefs.push_back(MO.getReg()); + NewMIImplDefs.push_back(MO.getReg().asMCReg()); } } @@ -1517,7 +1519,7 @@ SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI); for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) { - unsigned Reg = NewMIImplDefs[i]; + MCRegister Reg = NewMIImplDefs[i]; for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) if (LiveRange *LR = LIS->getCachedRegUnit(*Units)) LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator()); @@ -1575,7 +1577,8 @@ // Note that we do not query CoalescerPair here but redo isMoveInstr as the // CoalescerPair may have a new register class with adjusted subreg indices // at this point. - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + Register SrcReg, DstReg; + unsigned SrcSubIdx, DstSubIdx; if(!isMoveInstr(*TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) return nullptr; @@ -2223,7 +2226,7 @@ LiveRange &LR; /// (Main) register we work on. - const unsigned Reg; + const Register Reg; /// Reg (and therefore the values in this liverange) will end up as /// subregister SubIdx in the coalesced register. Either CP.DstIdx or @@ -2343,7 +2346,7 @@ LaneBitmask computeWriteLanes(const MachineInstr *DefMI, bool &Redef) const; /// Find the ultimate value that VNI was copied from. - std::pair followCopyChain(const VNInfo *VNI) const; + std::pair followCopyChain(const VNInfo *VNI) const; bool valuesIdentical(VNInfo *Value0, VNInfo *Value1, const JoinVals &Other) const; @@ -2382,7 +2385,7 @@ /// Return true if MI uses any of the given Lanes from Reg. /// This does not include partial redefinitions of Reg. - bool usesLanes(const MachineInstr &MI, unsigned, unsigned, LaneBitmask) const; + bool usesLanes(const MachineInstr &MI, Register, unsigned, LaneBitmask) const; /// Determine if ValNo is a copy of a value number in LR or Other.LR that will /// be pruned: @@ -2467,9 +2470,9 @@ return L; } -std::pair JoinVals::followCopyChain( - const VNInfo *VNI) const { - unsigned TrackReg = Reg; +std::pair +JoinVals::followCopyChain(const VNInfo *VNI) const { + Register TrackReg = Reg; while (!VNI->isPHIDef()) { SlotIndex Def = VNI->def; @@ -2523,13 +2526,13 @@ bool JoinVals::valuesIdentical(VNInfo *Value0, VNInfo *Value1, const JoinVals &Other) const { const VNInfo *Orig0; - unsigned Reg0; + Register Reg0; std::tie(Orig0, Reg0) = followCopyChain(Value0); if (Orig0 == Value1 && Reg0 == Other.Reg) return true; const VNInfo *Orig1; - unsigned Reg1; + Register Reg1; std::tie(Orig1, Reg1) = Other.followCopyChain(Value1); // If both values are undefined, and the source registers are the same // register, the values are identical. Filter out cases where only one @@ -2880,7 +2883,7 @@ return true; } -bool JoinVals::usesLanes(const MachineInstr &MI, unsigned Reg, unsigned SubIdx, +bool JoinVals::usesLanes(const MachineInstr &MI, Register Reg, unsigned SubIdx, LaneBitmask Lanes) const { if (MI.isDebugInstr()) return false; @@ -3524,20 +3527,20 @@ JoinVals &LHSVals, LiveRange &RHS, JoinVals &RHSVals) { - auto ScanForDstReg = [&](unsigned Reg) { + auto ScanForDstReg = [&](Register Reg) { checkMergingChangesDbgValuesImpl(Reg, RHS, LHS, LHSVals); }; - auto ScanForSrcReg = [&](unsigned Reg) { + auto ScanForSrcReg = [&](Register Reg) { checkMergingChangesDbgValuesImpl(Reg, LHS, RHS, RHSVals); }; // Scan for potentially unsound DBG_VALUEs: examine first the register number // Reg, and then any other vregs that may have been merged into it. - auto PerformScan = [this](unsigned Reg, std::function Func) { + auto PerformScan = [this](Register Reg, std::function Func) { Func(Reg); if (DbgMergedVRegNums.count(Reg)) - for (unsigned X : DbgMergedVRegNums[Reg]) + for (Register X : DbgMergedVRegNums[Reg]) Func(X); }; @@ -3546,7 +3549,7 @@ PerformScan(CP.getDstReg(), ScanForDstReg); } -void RegisterCoalescer::checkMergingChangesDbgValuesImpl(unsigned Reg, +void RegisterCoalescer::checkMergingChangesDbgValuesImpl(Register Reg, LiveRange &OtherLR, LiveRange &RegLR, JoinVals &RegVals) { @@ -3706,7 +3709,7 @@ /// Check if DstReg is a terminal node. /// I.e., it does not have any affinity other than \p Copy. -static bool isTerminalReg(unsigned DstReg, const MachineInstr &Copy, +static bool isTerminalReg(Register DstReg, const MachineInstr &Copy, const MachineRegisterInfo *MRI) { assert(Copy.isCopyLike()); // Check if the destination of this copy as any other affinity. @@ -3720,7 +3723,8 @@ assert(Copy.isCopyLike()); if (!UseTerminalRule) return false; - unsigned DstReg, DstSubReg, SrcReg, SrcSubReg; + Register SrcReg, DstReg; + unsigned SrcSubReg, DstSubReg; if (!isMoveInstr(*TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg)) return false; // Check if the destination of this copy has any other affinity. @@ -3744,7 +3748,8 @@ // For now, just consider the copies that are in the same block. if (&MI == &Copy || !MI.isCopyLike() || MI.getParent() != OrigBB) continue; - unsigned OtherReg, OtherSubReg, OtherSrcReg, OtherSrcSubReg; + Register OtherSrcReg, OtherReg; + unsigned OtherSrcSubReg, OtherSubReg; if (!isMoveInstr(*TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg, OtherSubReg)) return false; @@ -3929,7 +3934,7 @@ LLVM_DEBUG(dbgs() << "Trying to inflate " << InflateRegs.size() << " regs.\n"); for (unsigned i = 0, e = InflateRegs.size(); i != e; ++i) { - unsigned Reg = InflateRegs[i]; + Register Reg = InflateRegs[i]; if (MRI->reg_nodbg_empty(Reg)) continue; if (MRI->recomputeRegClass(Reg)) {