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

Side by Side Diff: src/IceUtils.h

Issue 1783113002: Subzero: Improve the behavior of resizing vectors. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 9 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 unified diff | Download patch
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/PNaClTranslator.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceUtils.h - Utility functions ---------------*- C++ -*-===// 1 //===- subzero/src/IceUtils.h - Utility functions ---------------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 18 matching lines...) Expand all
29 static_assert(sizeof(D) <= sizeof(S), 29 static_assert(sizeof(D) <= sizeof(S),
30 "bitCopy between incompatible type widths"); 30 "bitCopy between incompatible type widths");
31 static_assert(!std::is_pointer<S>::value, ""); 31 static_assert(!std::is_pointer<S>::value, "");
32 D Destination; 32 D Destination;
33 // This use of memcpy is safe: source and destination cannot overlap. 33 // This use of memcpy is safe: source and destination cannot overlap.
34 memcpy(&Destination, reinterpret_cast<const void *>(&Source), sizeof(D)); 34 memcpy(&Destination, reinterpret_cast<const void *>(&Source), sizeof(D));
35 return Destination; 35 return Destination;
36 } 36 }
37 37
38 /// Check whether an N-bit two's-complement representation can hold value. 38 /// Check whether an N-bit two's-complement representation can hold value.
39 template <typename T> static inline bool IsInt(int N, T value) { 39 template <typename T> inline bool IsInt(int N, T value) {
40 assert((0 < N) && 40 assert((0 < N) &&
41 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value)))); 41 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
42 T limit = static_cast<T>(1) << (N - 1); 42 T limit = static_cast<T>(1) << (N - 1);
43 return (-limit <= value) && (value < limit); 43 return (-limit <= value) && (value < limit);
44 } 44 }
45 45
46 template <typename T> static inline bool IsUint(int N, T value) { 46 template <typename T> inline bool IsUint(int N, T value) {
47 assert((0 < N) && 47 assert((0 < N) &&
48 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value)))); 48 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
49 T limit = static_cast<T>(1) << N; 49 T limit = static_cast<T>(1) << N;
50 return (0 <= value) && (value < limit); 50 return (0 <= value) && (value < limit);
51 } 51 }
52 52
53 /// Check whether the magnitude of value fits in N bits, i.e., whether an 53 /// Check whether the magnitude of value fits in N bits, i.e., whether an
54 /// (N+1)-bit sign-magnitude representation can hold value. 54 /// (N+1)-bit sign-magnitude representation can hold value.
55 template <typename T> static inline bool IsAbsoluteUint(int N, T Value) { 55 template <typename T> inline bool IsAbsoluteUint(int N, T Value) {
56 assert((0 < N) && 56 assert((0 < N) &&
57 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value)))); 57 (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value))));
58 if (Value < 0) 58 if (Value < 0)
59 Value = -Value; 59 Value = -Value;
60 return IsUint(N, Value); 60 return IsUint(N, Value);
61 } 61 }
62 62
63 /// Return true if the addition X + Y will cause integer overflow for integers 63 /// Return true if the addition X + Y will cause integer overflow for integers
64 /// of type T. 64 /// of type T.
65 template <typename T> static inline bool WouldOverflowAdd(T X, T Y) { 65 template <typename T> inline bool WouldOverflowAdd(T X, T Y) {
66 return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) || 66 return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
67 (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y))); 67 (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
68 } 68 }
69 69
70 /// Adds x to y and stores the result in sum. Returns true if the addition 70 /// Adds x to y and stores the result in sum. Returns true if the addition
71 /// overflowed. 71 /// overflowed.
72 static inline bool add_overflow(uint32_t x, uint32_t y, uint32_t *sum) { 72 inline bool add_overflow(uint32_t x, uint32_t y, uint32_t *sum) {
73 static_assert(std::is_same<uint32_t, unsigned>::value, "Must match type"); 73 static_assert(std::is_same<uint32_t, unsigned>::value, "Must match type");
74 #if __has_builtin(__builtin_uadd_overflow) 74 #if __has_builtin(__builtin_uadd_overflow)
75 return __builtin_uadd_overflow(x, y, sum); 75 return __builtin_uadd_overflow(x, y, sum);
76 #else 76 #else
77 *sum = x + y; 77 *sum = x + y;
78 return WouldOverflowAdd(x, y); 78 return WouldOverflowAdd(x, y);
79 #endif 79 #endif
80 } 80 }
81 81
82 /// Return true if X is already aligned by N, where N is a power of 2. 82 /// Return true if X is already aligned by N, where N is a power of 2.
83 template <typename T> static inline bool IsAligned(T X, intptr_t N) { 83 template <typename T> inline bool IsAligned(T X, intptr_t N) {
84 assert(llvm::isPowerOf2_64(N)); 84 assert(llvm::isPowerOf2_64(N));
85 return (X & (N - 1)) == 0; 85 return (X & (N - 1)) == 0;
86 } 86 }
87 87
88 /// Return Value adjusted to the next highest multiple of Alignment. 88 /// Return Value adjusted to the next highest multiple of Alignment.
89 static inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) { 89 inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) {
90 assert(llvm::isPowerOf2_32(Alignment)); 90 assert(llvm::isPowerOf2_32(Alignment));
91 return (Value + Alignment - 1) & -Alignment; 91 return (Value + Alignment - 1) & -Alignment;
92 } 92 }
93 93
94 /// Return amount which must be added to adjust Pos to the next highest 94 /// Return amount which must be added to adjust Pos to the next highest
95 /// multiple of Align. 95 /// multiple of Align.
96 static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) { 96 inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) {
97 assert(llvm::isPowerOf2_64(Align)); 97 assert(llvm::isPowerOf2_64(Align));
98 uint64_t Mod = Pos & (Align - 1); 98 uint64_t Mod = Pos & (Align - 1);
99 if (Mod == 0) 99 if (Mod == 0)
100 return 0; 100 return 0;
101 return Align - Mod; 101 return Align - Mod;
102 } 102 }
103 103
104 /// Rotate the value bit pattern to the left by shift bits. 104 /// Rotate the value bit pattern to the left by shift bits.
105 /// Precondition: 0 <= shift < 32 105 /// Precondition: 0 <= shift < 32
106 static inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) { 106 inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) {
107 if (shift == 0) 107 if (shift == 0)
108 return value; 108 return value;
109 return (value << shift) | (value >> (32 - shift)); 109 return (value << shift) | (value >> (32 - shift));
110 } 110 }
111 111
112 /// Rotate the value bit pattern to the right by shift bits. 112 /// Rotate the value bit pattern to the right by shift bits.
113 static inline uint32_t rotateRight32(uint32_t value, uint32_t shift) { 113 inline uint32_t rotateRight32(uint32_t value, uint32_t shift) {
114 if (shift == 0) 114 if (shift == 0)
115 return value; 115 return value;
116 return (value >> shift) | (value << (32 - shift)); 116 return (value >> shift) | (value << (32 - shift));
117 } 117 }
118 118
119 /// Returns true if Val is +0.0. It requires T to be a floating point type. 119 /// Returns true if Val is +0.0. It requires T to be a floating point type.
120 template <typename T> static bool isPositiveZero(T Val) { 120 template <typename T> bool isPositiveZero(T Val) {
121 static_assert(std::is_floating_point<T>::value, 121 static_assert(std::is_floating_point<T>::value,
122 "Input type must be floating point"); 122 "Input type must be floating point");
123 return Val == 0 && !std::signbit(Val); 123 return Val == 0 && !std::signbit(Val);
124 } 124 }
125 125
126 /// Resize a vector (or other suitable container) to a particular size, and also
127 /// reserve possibly a larger size to avoid repeatedly recopying as the
128 /// container grows. It uses a strategy of doubling capacity up to a certain
129 /// point, after which it bumps the capacity by a fixed amount.
130 template <typename Container>
131 inline void reserveAndResize(Container &V, uint32_t Size,
132 uint32_t ChunkSizeBits = 10) {
133 #if __has_builtin(__builtin_clz)
134 // Don't call reserve() if Size==0.
135 if (Size > 0) {
136 uint32_t Mask;
137 if (Size <= (1 << ChunkSizeBits)) {
138 // For smaller sizes, reserve the smallest power of 2 greater than or
139 // equal to Size.
140 Mask =
141 ((1 << (CHAR_BIT * sizeof(uint32_t) - __builtin_clz(Size))) - 1) - 1;
142 } else {
143 // For larger sizes, round up to the smallest multiple of 1<<ChunkSizeBits
144 // greater than or equal to Size.
145 Mask = (1 << ChunkSizeBits) - 1;
146 }
147 V.reserve((Size + Mask) & ~Mask);
148 }
149 #endif
150 V.resize(Size);
151 }
152
126 /// An RAII class to ensure that a boolean flag is restored to its previous 153 /// An RAII class to ensure that a boolean flag is restored to its previous
127 /// value upon function exit. 154 /// value upon function exit.
128 /// 155 ///
129 /// Used in places like RandomizationPoolingPause and generating target helper 156 /// Used in places like RandomizationPoolingPause and generating target helper
130 /// calls. 157 /// calls.
131 class BoolFlagSaver { 158 class BoolFlagSaver {
132 BoolFlagSaver() = delete; 159 BoolFlagSaver() = delete;
133 BoolFlagSaver(const BoolFlagSaver &) = delete; 160 BoolFlagSaver(const BoolFlagSaver &) = delete;
134 BoolFlagSaver &operator=(const BoolFlagSaver &) = delete; 161 BoolFlagSaver &operator=(const BoolFlagSaver &) = delete;
135 162
136 public: 163 public:
137 BoolFlagSaver(bool &F, bool NewValue) : OldValue(F), Flag(F) { F = NewValue; } 164 BoolFlagSaver(bool &F, bool NewValue) : OldValue(F), Flag(F) { F = NewValue; }
138 ~BoolFlagSaver() { Flag = OldValue; } 165 ~BoolFlagSaver() { Flag = OldValue; }
139 166
140 private: 167 private:
141 const bool OldValue; 168 const bool OldValue;
142 bool &Flag; 169 bool &Flag;
143 }; 170 };
144 171
145 } // end of namespace Utils 172 } // end of namespace Utils
146 } // end of namespace Ice 173 } // end of namespace Ice
147 174
148 #endif // SUBZERO_SRC_ICEUTILS_H 175 #endif // SUBZERO_SRC_ICEUTILS_H
OLDNEW
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | src/PNaClTranslator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698