[llvm] r333125 - [GlobalISel] NFCI, Getting GlobalISel ~5% faster

Roman Tereshin via llvm-commits llvm-commits at lists.llvm.org
Wed May 23 14:12:02 PDT 2018


Author: rtereshin
Date: Wed May 23 14:12:02 2018
New Revision: 333125

URL: http://llvm.org/viewvc/llvm-project?rev=333125&view=rev
Log:
[GlobalISel] NFCI, Getting GlobalISel ~5% faster

by replacing DenseMap with IndexedMap for LLTs within MRI, as
benchmarked by cross-compiling sqlite3 amalgamation for AArch64
on x86 machine.

Reviewed By: qcolombet

Differential Revision: https://reviews.llvm.org/D46809

Modified:
    llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h
    llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelect.cpp
    llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp
    llvm/trunk/lib/CodeGen/ResetMachineFunctionPass.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h?rev=333125&r1=333124&r2=333125&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineRegisterInfo.h Wed May 23 14:12:02 2018
@@ -136,9 +136,9 @@ private:
   /// started.
   BitVector ReservedRegs;
 
-  using VRegToTypeMap = DenseMap<unsigned, LLT>;
-  /// Map generic virtual registers to their actual size.
-  mutable std::unique_ptr<VRegToTypeMap> VRegToType;
+  using VRegToTypeMap = IndexedMap<LLT, VirtReg2IndexFunctor>;
+  /// 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);

Modified: llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelect.cpp?rev=333125&r1=333124&r2=333125&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelect.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/InstructionSelect.cpp Wed May 23 14:12:02 2018
@@ -77,7 +77,7 @@ bool InstructionSelect::runOnMachineFunc
 
   // 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::runOnMachineFunc
       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::runOnMachineFunc
   // 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::runOnMachineFunc
   // 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;

Modified: llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp?rev=333125&r1=333124&r2=333125&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineRegisterInfo.cpp Wed May 23 14:12:02 2018
@@ -177,17 +177,13 @@ MachineRegisterInfo::createVirtualRegist
   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<const TargetRegisterClass *>()) &&
          "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::createGenericVirtua
   unsigned Reg = createIncompleteVirtualRegister(Name);
   // FIXME: Should we use a dummy register class?
   VRegInfo[Reg].first = static_cast<RegisterBank *>(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() {

Modified: llvm/trunk/lib/CodeGen/ResetMachineFunctionPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ResetMachineFunctionPass.cpp?rev=333125&r1=333124&r2=333125&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ResetMachineFunctionPass.cpp (original)
+++ llvm/trunk/lib/CodeGen/ResetMachineFunctionPass.cpp Wed May 23 14:12:02 2018
@@ -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)) {




More information about the llvm-commits mailing list