Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: src/IceBitVector.h

Issue 1738443002: Subzero. Performance tweaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments -- all of them Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceAssembler.h ('k') | src/IceCfg.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceBitVector.h
diff --git a/src/IceBitVector.h b/src/IceBitVector.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c99e8aebd9d801d65961329faef612a0af5aae0
--- /dev/null
+++ b/src/IceBitVector.h
@@ -0,0 +1,245 @@
+//===- subzero/src/IceBitVector.h - Inline bit vector. ----------*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines and implements a bit vector with inline storage. It is a drop
+/// in replacement for llvm::SmallBitVector in subzero -- i.e., not all of
+/// llvm::SmallBitVector interface is implemented.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEBITVECTOR_H
+#define SUBZERO_SRC_ICEBITVECTOR_H
+
+#include "IceDefs.h"
+#include "IceOperand.h"
+
+#include "llvm/Support/MathExtras.h"
+
+#include <algorithm>
+#include <climits>
+#include <memory>
+#include <type_traits>
+
+namespace Ice {
+class SmallBitVector {
+public:
+ using ElementType = uint64_t;
+ static constexpr SizeT BitIndexSize = 6; // log2(NumBitsPerPos);
+ static constexpr SizeT NumBitsPerPos = sizeof(ElementType) * CHAR_BIT;
+ static_assert(1 << BitIndexSize == NumBitsPerPos, "Invalid BitIndexSize.");
+
+ SmallBitVector(const SmallBitVector &BV) { *this = BV; }
+
+ SmallBitVector &operator=(const SmallBitVector &BV) {
+ if (&BV != this) {
+ resize(BV.size());
+ memcpy(Bits, BV.Bits, sizeof(Bits));
+ }
+ return *this;
+ }
+
+ SmallBitVector() { reset(); }
+
+ explicit SmallBitVector(SizeT S) : SmallBitVector() {
+ assert(S <= MaxBits);
+ resize(S);
+ }
+
+ class Reference {
+ Reference() = delete;
+
+ public:
+ Reference(const Reference &) = default;
+ Reference &operator=(const Reference &Rhs) { return *this = (bool)Rhs; }
+ Reference &operator=(bool t) {
+ if (t) {
+ *Data |= _1 << Bit;
+ } else {
+ *Data &= ~(_1 << Bit);
+ }
+ return *this;
+ }
+ operator bool() const { return (*Data & (_1 << Bit)) != 0; }
+
+ private:
+ friend class SmallBitVector;
+ Reference(ElementType *D, SizeT B) : Data(D), Bit(B) {
+ assert(B < NumBitsPerPos);
+ }
+
+ ElementType *const Data;
+ const SizeT Bit;
+ };
+
+ Reference operator[](unsigned Idx) {
+ assert(Idx < size());
+ return Reference(Bits + (Idx >> BitIndexSize),
+ Idx & ((_1 << BitIndexSize) - 1));
+ }
+
+ bool operator[](unsigned Idx) const {
+ assert(Idx < size());
+ return Bits[Idx >> BitIndexSize] &
+ (_1 << (Idx & ((_1 << BitIndexSize) - 1)));
+ }
+
+ int find_first() const { return find_first<0>(); }
+
+ int find_next(unsigned Prev) const { return find_next<0>(Prev); }
+
+ bool any() const {
+ for (SizeT i = 0; i < BitsElements; ++i) {
+ if (Bits[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ SizeT size() const { return Size; }
+
+ void resize(SizeT Size) {
+ assert(Size <= MaxBits);
+ this->Size = Size;
+ }
+
+ void reserve(SizeT Size) {
+ assert(Size <= MaxBits);
+ (void)Size;
+ }
+
+ void set(unsigned Idx) { (*this)[Idx] = true; }
+
+ void set() {
+ for (SizeT ii = 0; ii < size(); ++ii) {
+ (*this)[ii] = true;
+ }
+ }
+
+ SizeT count() const {
+ SizeT Count = 0;
+ for (SizeT i = 0; i < BitsElements; ++i) {
+ Count += llvm::countPopulation(Bits[i]);
+ }
+ return Count;
+ }
+
+ SmallBitVector operator&(const SmallBitVector &Rhs) const {
+ assert(size() == Rhs.size());
+ SmallBitVector Ret(std::max(size(), Rhs.size()));
+ for (SizeT i = 0; i < BitsElements; ++i) {
+ Ret.Bits[i] = Bits[i] & Rhs.Bits[i];
+ }
+ return Ret;
+ }
+
+ SmallBitVector operator~() const {
+ SmallBitVector Ret = *this;
+ Ret.invert<0>();
+ return Ret;
+ }
+
+ SmallBitVector &operator|=(const SmallBitVector &Rhs) {
+ assert(size() == Rhs.size());
+ resize(std::max(size(), Rhs.size()));
+ for (SizeT i = 0; i < BitsElements; ++i) {
+ Bits[i] |= Rhs.Bits[i];
+ }
+ return *this;
+ }
+
+ SmallBitVector operator|(const SmallBitVector &Rhs) const {
+ assert(size() == Rhs.size());
+ SmallBitVector Ret(std::max(size(), Rhs.size()));
+ for (SizeT i = 0; i < BitsElements; ++i) {
+ Ret.Bits[i] = Bits[i] | Rhs.Bits[i];
+ }
+ return Ret;
+ }
+
+ void reset() { memset(Bits, 0, sizeof(Bits)); }
+
+ void reset(const SmallBitVector &Mask) {
+ for (const auto V : RegNumBVIter(Mask)) {
+ (*this)[unsigned(V)] = false;
+ }
+ }
+
+private:
+ // _1 is the constant 1 of type ElementType.
+ static constexpr ElementType _1 = ElementType(1);
+
+ static constexpr SizeT BitsElements = 2;
+ ElementType Bits[BitsElements];
+
+ // MaxBits is defined here because it needs Bits to be defined.
+ static constexpr SizeT MaxBits = sizeof(Bits) * CHAR_BIT;
+ static_assert(sizeof(Bits) == 16, "Bits must be 16 bytes wide.");
+ SizeT Size = 0;
+
+ template <SizeT Pos>
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), int>::type
+ find_first() const {
+ return -1;
+ }
+
+ template <SizeT Pos>
+ typename std::enable_if <
+ Pos<sizeof(Bits) / sizeof(Bits[0]), int>::type find_first() const {
+ if (Bits[Pos] != 0) {
+ return NumBitsPerPos * Pos + llvm::countTrailingZeros(Bits[Pos]);
+ }
+ return find_first<Pos + 1>();
+ }
+
+ template <SizeT Pos>
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), int>::type
+ find_next(unsigned) const {
+ return -1;
+ }
+
+ template <SizeT Pos>
+ typename std::enable_if < Pos<sizeof(Bits) / sizeof(Bits[0]), int>::type
+ find_next(unsigned Prev) const {
+ if (Prev + 1 < (Pos + 1) * NumBitsPerPos) {
+ const ElementType Mask =
+ (ElementType(1) << ((Prev + 1) - Pos * NumBitsPerPos)) - 1;
+ const ElementType B = Bits[Pos] & ~Mask;
+ if (B != 0) {
+ return NumBitsPerPos * Pos + llvm::countTrailingZeros(B);
+ }
+ Prev = (1 + Pos) * NumBitsPerPos - 1;
+ }
+ return find_next<Pos + 1>(Prev);
+ }
+
+ template <SizeT Pos>
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), void>::type
+ invert() {}
+
+ template <SizeT Pos>
+ typename std::enable_if <
+ Pos<sizeof(Bits) / sizeof(Bits[0]), void>::type invert() {
+ if (size() < Pos * NumBitsPerPos) {
+ Bits[Pos] = 0;
+ } else if ((Pos + 1) * NumBitsPerPos < size()) {
+ Bits[Pos] ^= ~ElementType(0);
+ } else {
+ const ElementType Mask =
+ (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1;
+ Bits[Pos] ^= Mask;
+ }
+ invert<Pos + 1>();
+ }
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEBITVECTOR_H
« no previous file with comments | « src/IceAssembler.h ('k') | src/IceCfg.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698