[llvm] 16c93aa - [Hexagon] Establish size limit for RegisterSet in hexbit

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 20 14:16:41 PDT 2022


Author: Krzysztof Parzyszek
Date: 2022-04-20T14:16:24-07:00
New Revision: 16c93aaa4a955676fe05f876bd036719a1b14b2d

URL: https://github.com/llvm/llvm-project/commit/16c93aaa4a955676fe05f876bd036719a1b14b2d
DIFF: https://github.com/llvm/llvm-project/commit/16c93aaa4a955676fe05f876bd036719a1b14b2d.diff

LOG: [Hexagon] Establish size limit for RegisterSet in hexbit

This should reduce compilation time for huge functions.

Added: 
    

Modified: 
    llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp b/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp
index 5f1b156bffda6..673b397ef3c52 100644
--- a/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp
@@ -39,6 +39,7 @@
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
+#include <deque>
 #include <iterator>
 #include <limits>
 #include <utility>
@@ -62,6 +63,9 @@ static cl::opt<unsigned> MaxBitSplit("hexbit-max-bitsplit", cl::Hidden,
   cl::init(std::numeric_limits<unsigned>::max()));
 static unsigned CountBitSplit = 0;
 
+static cl::opt<unsigned> RegisterSetLimit("hexbit-registerset-limit",
+  cl::Hidden, cl::init(1000));
+
 namespace llvm {
 
   void initializeHexagonBitSimplifyPass(PassRegistry& Registry);
@@ -72,23 +76,29 @@ namespace llvm {
 namespace {
 
   // Set of virtual registers, based on BitVector.
-  struct RegisterSet : private BitVector {
+  struct RegisterSet {
     RegisterSet() = default;
-    explicit RegisterSet(unsigned s, bool t = false) : BitVector(s, t) {}
+    explicit RegisterSet(unsigned s, bool t = false) : Bits(s, t) {}
     RegisterSet(const RegisterSet &RS) = default;
 
-    using BitVector::clear;
-    using BitVector::count;
+    void clear() {
+      Bits.clear();
+      LRU.clear();
+    }
+
+    unsigned count() const {
+      return Bits.count();
+    }
 
     unsigned find_first() const {
-      int First = BitVector::find_first();
+      int First = Bits.find_first();
       if (First < 0)
         return 0;
       return x2v(First);
     }
 
     unsigned find_next(unsigned Prev) const {
-      int Next = BitVector::find_next(v2x(Prev));
+      int Next = Bits.find_next(v2x(Prev));
       if (Next < 0)
         return 0;
       return x2v(Next);
@@ -97,54 +107,72 @@ namespace {
     RegisterSet &insert(unsigned R) {
       unsigned Idx = v2x(R);
       ensure(Idx);
-      return static_cast<RegisterSet&>(BitVector::set(Idx));
+      bool Exists = Bits.test(Idx);
+      Bits.set(Idx);
+      if (!Exists) {
+        LRU.push_back(Idx);
+        if (LRU.size() > RegisterSetLimit) {
+          unsigned T = LRU.front();
+          Bits.reset(T);
+          LRU.pop_front();
+        }
+      }
+      return *this;
     }
     RegisterSet &remove(unsigned R) {
       unsigned Idx = v2x(R);
-      if (Idx >= size())
-        return *this;
-      return static_cast<RegisterSet&>(BitVector::reset(Idx));
+      if (Idx < Bits.size()) {
+        bool Exists = Bits.test(Idx);
+        Bits.reset(Idx);
+        if (Exists) {
+          auto F = llvm::find(LRU, Idx);
+          assert(F != LRU.end());
+          LRU.erase(F);
+        }
+      }
+      return *this;
     }
 
     RegisterSet &insert(const RegisterSet &Rs) {
-      return static_cast<RegisterSet&>(BitVector::operator|=(Rs));
+      for (unsigned R = Rs.find_first(); R; R = Rs.find_next(R))
+        insert(R);
+      return *this;
     }
     RegisterSet &remove(const RegisterSet &Rs) {
-      return static_cast<RegisterSet&>(BitVector::reset(Rs));
+      for (unsigned R = Rs.find_first(); R; R = Rs.find_next(R))
+        remove(R);
+      return *this;
     }
 
-    reference operator[](unsigned R) {
-      unsigned Idx = v2x(R);
-      ensure(Idx);
-      return BitVector::operator[](Idx);
-    }
     bool operator[](unsigned R) const {
       unsigned Idx = v2x(R);
-      assert(Idx < size());
-      return BitVector::operator[](Idx);
+      return Idx < Bits.size() ? Bits[Idx] : false;
     }
     bool has(unsigned R) const {
       unsigned Idx = v2x(R);
-      if (Idx >= size())
+      if (Idx >= Bits.size())
         return false;
-      return BitVector::test(Idx);
+      return Bits.test(Idx);
     }
 
     bool empty() const {
-      return !BitVector::any();
+      return !Bits.any();
     }
     bool includes(const RegisterSet &Rs) const {
-      // A.BitVector::test(B)  <=>  A-B != {}
-      return !Rs.BitVector::test(*this);
+      // A.test(B)  <=>  A-B != {}
+      return !Rs.Bits.test(Bits);
     }
     bool intersects(const RegisterSet &Rs) const {
-      return BitVector::anyCommon(Rs);
+      return Bits.anyCommon(Rs.Bits);
     }
 
   private:
+    BitVector Bits;
+    std::deque<unsigned> LRU;
+
     void ensure(unsigned Idx) {
-      if (size() <= Idx)
-        resize(std::max(Idx+1, 32U));
+      if (Bits.size() <= Idx)
+        Bits.resize(std::max(Idx+1, 32U));
     }
 
     static inline unsigned v2x(unsigned v) {


        


More information about the llvm-commits mailing list