aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp84
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));