diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp b/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp index b2a842233bb8..673b397ef3c5 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) { @@ -1997,7 +2025,7 @@ bool BitSimplification::genStoreImmediate(MachineInstr *MI) { if (!isInt<8>(V)) return false; - MI->RemoveOperand(2); + MI->removeOperand(2); switch (Opc) { case Hexagon::S2_storerb_io: MI->setDesc(HII.get(Hexagon::S4_storeirb_io)); |