[PATCH] VirtRegRewriter compile time reduction.

Puyan Lotfi plotfi at apple.com
Thu May 21 00:54:57 PDT 2015


Hi

I have a patch (attached) for reducing compile time in VirtRegRewriter
(especially for targets with a very high number of registers).

The patch changes how VirtRegRewriter::addMBBLiveIns adds registers to
each MachineBasicBlock's LiveIns vector by adding registers to
MachineBasicBlock::LiveIns without a isLiveIn check (the vector should
be sorted and not have duplicates), and after all registers are added
the LiveIns vector for each MachineBasicBlock for the current
MachineFunction is sorted and uniqued (a call to sortUniqueLiveIns).
This improves compile time by avoiding the O(LiveIns.size()) checks at
every addLiveIn attempt which can get expensive if MRI->getNumVirtRegs()
is high as this is number of iterations of the outer loop.

I'd like any feedback.

Thanks

PL

-------------- next part --------------
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 1440b96..c101a9b 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -315,10 +315,19 @@ public:
 
   // LiveIn management methods.
 
-  /// addLiveIn - Add the specified register as a live in.  Note that it
-  /// is an error to add the same register to the same set more than once.
+  /// addLiveIn - Add the specified register as a live in. Note that it is
+  /// an error to add the same register to the same set more than once unless the
+  /// intention is to call sortUniqueLiveIns after all registers have been added.
   void addLiveIn(unsigned Reg)  { LiveIns.push_back(Reg); }
 
+  /// sortUniqueLiveIns - Sorts and uniques the LiveIns vector. It can be
+  /// significantly faster to do this than repeatedly calling isLiveIn before
+  /// calling addLiveIn for every LiveIn insertion.
+  void sortUniqueLiveIns() {
+    std::sort(LiveIns.begin(), LiveIns.end());
+    LiveIns.erase(std::unique(LiveIns.begin(), LiveIns.end()), LiveIns.end());
+  }
+
   /// Add PhysReg as live in to this block, and ensure that there is a copy of
   /// PhysReg to a virtual register of class RC. Return the virtual register
   /// that is a copy of the live in PhysReg.
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index d9adfdf..cd8b4d4 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -264,8 +264,7 @@ void VirtRegRewriter::addMBBLiveIns() {
             if ((SubRegLaneMask & S.LaneMask) == 0)
               continue;
             for (unsigned i = 0, e = LiveIn.size(); i != e; ++i) {
-              if (!LiveIn[i]->isLiveIn(SubReg))
-                LiveIn[i]->addLiveIn(SubReg);
+              LiveIn[i]->addLiveIn(SubReg);
             }
           }
           LiveIn.clear();
@@ -277,12 +276,17 @@ void VirtRegRewriter::addMBBLiveIns() {
         if (!Indexes->findLiveInMBBs(Seg.start, Seg.end, LiveIn))
           continue;
         for (unsigned i = 0, e = LiveIn.size(); i != e; ++i)
-          if (!LiveIn[i]->isLiveIn(PhysReg))
-            LiveIn[i]->addLiveIn(PhysReg);
+          LiveIn[i]->addLiveIn(PhysReg);
         LiveIn.clear();
       }
     }
   }
+
+  // Sort and unique MBB LiveIns as we've not checked if SubReg/PhysReg were in
+  // each MBB's LiveIns set before calling addLiveIn on them.
+  for (auto MBBI = MF->begin(), MBBE = MF->end(); MBBI != MBBE; ++MBBI)
+    MBBI->sortUniqueLiveIns();
+
 }
 
 void VirtRegRewriter::rewrite() {


More information about the llvm-commits mailing list