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

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: Undoes Makefile changes. 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
Index: src/IceBitVector.h
diff --git a/src/IceBitVector.h b/src/IceBitVector.h
new file mode 100644
index 0000000000000000000000000000000000000000..37dbc663e11f3ca418c9a42b59e0e5c58cebdf72
--- /dev/null
+++ b/src/IceBitVector.h
@@ -0,0 +1,251 @@
+
Jim Stichnoth 2016/02/24 23:11:39 remove leading blank line
John 2016/02/24 23:46:05 Done.
+//===- 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
Jim Stichnoth 2016/02/24 23:11:38 reflow comment
John 2016/02/24 23:46:05 Done.
+/// drop in replacement for llvm::SmallSmallBitVector in subzero -- i.e., not
Jim Stichnoth 2016/02/24 23:11:39 SmallSmall here and below
John 2016/02/24 23:46:05 Done.
+/// all of
+/// llvm::SmallSmallBitVector 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 NumBitsPerPos = sizeof(ElementType) * CHAR_BIT;
+
+ 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() {
+ static_assert(sizeof(Bits) == 16, "");
Jim Stichnoth 2016/02/24 23:11:38 Can you remove this? Seems to be also tested belo
John 2016/02/24 23:46:05 Done.
+ memset(Bits, 0, sizeof(Bits));
+ }
+
+ explicit SmallBitVector(SizeT S) : SmallBitVector() {
+ resize(S);
+ assert(Size <= sizeof(Bits) * CHAR_BIT);
Jim Stichnoth 2016/02/24 23:11:39 constexpr
John 2016/02/24 23:46:05 Done.
+ }
+
+ 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 |= 1ull << Bit;
+ } else {
+ *Data &= ~(1ull << Bit);
+ }
+ return *this;
+ }
+ operator bool() const { return (*Data & (1ull << Bit)) != 0; }
+
+ private:
+ friend class SmallBitVector;
+ Reference(uint64_t *D, SizeT B) : Data(D), Bit(B) {
Jim Stichnoth 2016/02/24 23:11:38 ElementType instead of uint64_t ?
John 2016/02/24 23:46:05 Done.
+ assert(B < CHAR_BIT * sizeof(*D));
+ }
+
+ uint64_t *const Data;
+ const SizeT Bit;
+ };
+
+ Reference operator[](unsigned Idx) {
+ assert(Idx < size());
+ // return Reference(Bits + (Idx >> llvm::Log2_64(NumBitsPerPos)),
Jim Stichnoth 2016/02/24 23:11:39 remove commented code
John 2016/02/24 23:46:05 Done.
+ // Idx & ((1ull << llvm::Log2_64(NumBitsPerPos))-1));
+ return Reference(Bits + (Idx >> 6), Idx & ((1ull << 6) - 1));
Jim Stichnoth 2016/02/24 23:11:39 All these "6" should be constexpr, with a static_a
John 2016/02/24 23:46:05 Done.
+ }
+
+ bool operator[](unsigned Idx) const {
+ assert(Idx < size());
+ return Bits[Idx >> 6] & (1ull << (Idx & ((1ull << 6) - 1)));
Jim Stichnoth 2016/02/24 23:11:39 I think it would be nicer for the 1ull to be a con
John 2016/02/24 23:46:05 Done.
+ }
+
+ int find_first() const { return find_first<0>(); }
+
+ int find_next(unsigned Prev) const { return find_next<0>(Prev); }
+
+ bool any() const { return Bits[0] != 0 || Bits[1] != 0; }
Jim Stichnoth 2016/02/24 23:11:39 Either unroll this automatically like above, or st
John 2016/02/24 23:46:05 Done.
+
+ SizeT size() const { return Size; }
+
+ void resize(SizeT Size) {
+ assert(Size <= sizeof(Bits) * CHAR_BIT);
+ this->Size = Size;
+ }
+
+ void reserve(SizeT Size) {
+ assert(Size <= sizeof(Bits) * CHAR_BIT);
+ (void)Size;
+ }
+
+ void set(unsigned Idx) {
+ // TODO(jpp): improve.
+ (*this)[Idx] = true;
+ }
+
+ void set() {
+ // TODO(jpp): improve.
+ for (SizeT ii = 0; ii < size(); ++ii) {
+ (*this)[ii] = true;
+ }
+ // set_all<0>();
Jim Stichnoth 2016/02/24 23:11:38 remove comment
John 2016/02/24 23:46:05 Done.
+ }
+
+ SizeT count() const {
+ return llvm::countPopulation(Bits[0]) + llvm::countPopulation(Bits[1]);
Jim Stichnoth 2016/02/24 23:11:39 inline/static_assert here and below
John 2016/02/24 23:46:05 Done.
+ }
+
+ SmallBitVector operator&(const SmallBitVector &Rhs) const {
+ assert(size() == Rhs.size());
+ SmallBitVector Ret(std::max(size(), Rhs.size()));
+ Ret.Bits[0] = Bits[0] & Rhs.Bits[0];
+ Ret.Bits[1] = Bits[1] & Rhs.Bits[1];
+ 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()));
+ Bits[0] |= Rhs.Bits[0];
+ Bits[1] |= Rhs.Bits[1];
+ return *this;
+ }
+
+ SmallBitVector operator|(const SmallBitVector &Rhs) const {
+ assert(size() == Rhs.size());
+ SmallBitVector Ret(std::max(size(), Rhs.size()));
+ Ret.Bits[0] = Bits[0] | Rhs.Bits[0];
+ Ret.Bits[1] = Bits[1] | Rhs.Bits[1];
+ 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:
+ ElementType Bits[2];
+ 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>();
+ }
+
+ template <SizeT Pos>
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), void>::type
+ set_all() {}
+
+ template <SizeT Pos>
+ typename std::enable_if <
+ Pos<sizeof(Bits) / sizeof(Bits[0]), void>::type set_all() {
+ 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;
+ }
+ set_all<Pos + 1>();
+ }
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEBITVECTOR_H

Powered by Google App Engine
This is Rietveld 408576698