diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h index a5666cd81ab4..5bf4a49c8b3b 100644 --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -136,9 +136,9 @@ private: /// started. BitVector ReservedRegs; - using VRegToTypeMap = DenseMap; - /// Map generic virtual registers to their actual size. - mutable std::unique_ptr VRegToType; + using VRegToTypeMap = IndexedMap; + /// Map generic virtual registers to their low-level type. + VRegToTypeMap VRegToType; /// Keep track of the physical registers that are live in to the function. /// Live in values are typically arguments in registers. LiveIn values are @@ -717,17 +717,13 @@ public: unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name = ""); - /// Accessor for VRegToType. This accessor should only be used - /// by global-isel related work. - VRegToTypeMap &getVRegToType() const { - if (!VRegToType) - VRegToType.reset(new VRegToTypeMap); - return *VRegToType.get(); - } - - /// Get the low-level type of \p VReg or LLT{} if VReg is not a generic + /// Get the low-level type of \p Reg or LLT{} if Reg is not a generic /// (target independent) virtual register. - LLT getType(unsigned VReg) const; + LLT getType(unsigned Reg) const { + if (TargetRegisterInfo::isVirtualRegister(Reg) && VRegToType.inBounds(Reg)) + return VRegToType[Reg]; + return LLT{}; + } /// Set the low-level type of \p VReg to \p Ty. void setType(unsigned VReg, LLT Ty); diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 7d37a6ce4604..f483419c92ff 100644 --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -77,7 +77,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { // FIXME: There are many other MF/MFI fields we need to initialize. - const MachineRegisterInfo &MRI = MF.getRegInfo(); + MachineRegisterInfo &MRI = MF.getRegInfo(); #ifndef NDEBUG // Check that our input is fully legal: we require the function to have the // Legalized property, so it should be. @@ -167,7 +167,6 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { unsigned DstReg = MI.getOperand(0).getReg(); if (TargetRegisterInfo::isVirtualRegister(SrcReg) && TargetRegisterInfo::isVirtualRegister(DstReg)) { - MachineRegisterInfo &MRI = MF.getRegInfo(); auto SrcRC = MRI.getRegClass(SrcReg); auto DstRC = MRI.getRegClass(DstReg); if (SrcRC == DstRC) { @@ -181,27 +180,29 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { // Now that selection is complete, there are no more generic vregs. Verify // that the size of the now-constrained vreg is unchanged and that it has a // register class. - for (auto &VRegToType : MRI.getVRegToType()) { - unsigned VReg = VRegToType.first; - auto *RC = MRI.getRegClassOrNull(VReg); + for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { + unsigned VReg = TargetRegisterInfo::index2VirtReg(I); + MachineInstr *MI = nullptr; if (!MRI.def_empty(VReg)) MI = &*MRI.def_instr_begin(VReg); else if (!MRI.use_empty(VReg)) MI = &*MRI.use_instr_begin(VReg); + if (!MI) + continue; - if (MI && !RC) { + const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg); + if (!RC) { reportGISelFailure(MF, TPC, MORE, "gisel-select", "VReg has no regclass after selection", *MI); return false; - } else if (!RC) - continue; + } - if (VRegToType.second.isValid() && - VRegToType.second.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { - reportGISelFailure(MF, TPC, MORE, "gisel-select", - "VReg has explicit size different from class size", - *MI); + const LLT Ty = MRI.getType(VReg); + if (Ty.isValid() && Ty.getSizeInBits() > TRI.getRegSizeInBits(*RC)) { + reportGISelFailure( + MF, TPC, MORE, "gisel-select", + "VReg's low-level type and register class have different sizes", *MI); return false; } } @@ -234,7 +235,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { // If we successfully selected the function nothing is going to use the vreg // types after us (otherwise MIRPrinter would need them). Make sure the types // disappear. - MRI.getVRegToType().clear(); + MRI.clearVirtRegTypes(); // FIXME: Should we accurately track changes? return true; diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp index 544a4f101a73..6095bdd06b69 100644 --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -177,17 +177,13 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass, return Reg; } -LLT MachineRegisterInfo::getType(unsigned VReg) const { - VRegToTypeMap::const_iterator TypeIt = getVRegToType().find(VReg); - return TypeIt != getVRegToType().end() ? TypeIt->second : LLT{}; -} - void MachineRegisterInfo::setType(unsigned VReg, LLT Ty) { // Check that VReg doesn't have a class. assert((getRegClassOrRegBank(VReg).isNull() || !getRegClassOrRegBank(VReg).is()) && "Can't set the size of a non-generic virtual register"); - getVRegToType()[VReg] = Ty; + VRegToType.grow(VReg); + VRegToType[VReg] = Ty; } unsigned @@ -196,15 +192,13 @@ MachineRegisterInfo::createGenericVirtualRegister(LLT Ty, StringRef Name) { unsigned Reg = createIncompleteVirtualRegister(Name); // FIXME: Should we use a dummy register class? VRegInfo[Reg].first = static_cast(nullptr); - getVRegToType()[Reg] = Ty; + setType(Reg, Ty); if (TheDelegate) TheDelegate->MRI_NoteNewVirtualRegister(Reg); return Reg; } -void MachineRegisterInfo::clearVirtRegTypes() { - getVRegToType().clear(); -} +void MachineRegisterInfo::clearVirtRegTypes() { VRegToType.clear(); } /// clearVirtRegs - Remove all virtual registers (after physreg assignment). void MachineRegisterInfo::clearVirtRegs() { diff --git a/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp b/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp index dbc4581c7a94..88d550e14a39 100644 --- a/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp +++ b/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp @@ -49,7 +49,7 @@ namespace { // or not, nothing is going to use the vreg types after us. Make sure they // disappear. auto ClearVRegTypesOnReturn = - make_scope_exit([&MF]() { MF.getRegInfo().getVRegToType().clear(); }); + make_scope_exit([&MF]() { MF.getRegInfo().clearVirtRegTypes(); }); if (MF.getProperties().hasProperty( MachineFunctionProperties::Property::FailedISel)) {