diff options
| author | Stephen Hines <srhines@google.com> | 2012-09-14 10:29:25 -0700 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2012-09-14 10:29:25 -0700 |
| commit | c4da91ec92a6b478cd1f9d53868161d8165ae054 (patch) | |
| tree | 52800183ec2d22164b8f396842142c3a8aab912a /include/llvm/ADT/SmallVector.h | |
| parent | fe223da25317da59bda88512e9e11e1d031d167c (diff) | |
| parent | 78c041bd883d86c81c42b98f326660277e6d0d9a (diff) | |
| download | external_llvm-c4da91ec92a6b478cd1f9d53868161d8165ae054.zip external_llvm-c4da91ec92a6b478cd1f9d53868161d8165ae054.tar.gz external_llvm-c4da91ec92a6b478cd1f9d53868161d8165ae054.tar.bz2 | |
am 78c041bd: am 1c4ad5ef: Merge branch \'upstream\' into merge-2012_09_10
* commit '78c041bd883d86c81c42b98f326660277e6d0d9a': (446 commits)
Revert r163556. Missed updates to tablegen files.
Update function names to conform to guidelines. No functional change intended.
test/CodeGen/X86/ms-inline-asm.ll: Relax for non-darwin x86 targets. '##InlineAsm' could not be seen in other hosts.
[ms-inline asm] Properly emit the asm directives when the AsmPrinterVariant and InlineAsmVariant don't match.
Update test case for Release builds.
Remove redundant semicolons which are null statements.
Disable stack coloring because it makes dragonegg fail bootstrapping.
[ms-inline asm] Pass the correct AsmVariant to the PrintAsmOperand() function and update the printOperand() function accordingly.
[ms-inline asm] Add support for .att_syntax directive.
Enable stack coloring.
Don't attempt to use flags from predicated instructions.
[Object] Extract Elf_Ehdr. Patch by Hemant Kulkarni!
Stack Coloring: Handle the case where END markers come before BEGIN markers properly.
Enhance PR11334 fix to support extload from v2f32/v4f32
Add "blocked" heuristic to the Hexagon MI scheduler.
Fold multiply by 0 or 1 when in UnsafeFPMath mode in SelectionDAG::getNode().
whitespace
Add boolean simplification support from CMOV
Fix an assertion failure when optimising a shufflevector incorrectly into concat_vectors, and a followup bug with SelectionDAG::getNode() creating nodes with invalid types.
Minor cleanup. No functional change.
...
Diffstat (limited to 'include/llvm/ADT/SmallVector.h')
| -rw-r--r-- | include/llvm/ADT/SmallVector.h | 152 |
1 files changed, 55 insertions, 97 deletions
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 9fbbbe4..769b7dc 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_SMALLVECTOR_H #define LLVM_ADT_SMALLVECTOR_H +#include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" #include <algorithm> @@ -32,44 +33,20 @@ class SmallVectorBase { protected: void *BeginX, *EndX, *CapacityX; - // Allocate raw space for N elements of type T. If T has a ctor or dtor, we - // don't want it to be automatically run, so we need to represent the space as - // something else. An array of char would work great, but might not be - // aligned sufficiently. Instead we use some number of union instances for - // the space, which guarantee maximal alignment. - union U { - double D; - long double LD; - long long L; - void *P; - } FirstEl; - // Space after 'FirstEl' is clobbered, do not add any instance vars after it. - protected: - SmallVectorBase(size_t Size) - : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {} - - /// isSmall - Return true if this is a smallvector which has not had dynamic - /// memory allocated for it. - bool isSmall() const { - return BeginX == static_cast<const void*>(&FirstEl); - } - - /// resetToSmall - Put this vector in a state of being small. - void resetToSmall() { - BeginX = EndX = CapacityX = &FirstEl; - } + SmallVectorBase(void *FirstEl, size_t Size) + : BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {} /// grow_pod - This is an implementation of the grow() method which only works /// on POD-like data types and is out of line to reduce code duplication. - void grow_pod(size_t MinSizeInBytes, size_t TSize); + void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize); public: /// size_in_bytes - This returns size()*sizeof(T). size_t size_in_bytes() const { return size_t((char*)EndX - (char*)BeginX); } - + /// capacity_in_bytes - This returns capacity()*sizeof(T). size_t capacity_in_bytes() const { return size_t((char*)CapacityX - (char*)BeginX); @@ -78,11 +55,41 @@ public: bool empty() const { return BeginX == EndX; } }; +template <typename T, unsigned N> struct SmallVectorStorage; -template <typename T> +/// SmallVectorTemplateCommon - This is the part of SmallVectorTemplateBase +/// which does not depend on whether the type T is a POD. The extra dummy +/// template argument is used by ArrayRef to avoid unnecessarily requiring T +/// to be complete. +template <typename T, typename = void> class SmallVectorTemplateCommon : public SmallVectorBase { +private: + template <typename, unsigned> friend struct SmallVectorStorage; + + // Allocate raw space for N elements of type T. If T has a ctor or dtor, we + // don't want it to be automatically run, so we need to represent the space as + // something else. Use an array of char of sufficient alignment. + typedef llvm::AlignedCharArrayUnion<T> U; + U FirstEl; + // Space after 'FirstEl' is clobbered, do not add any instance vars after it. + protected: - SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {} + SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {} + + void grow_pod(size_t MinSizeInBytes, size_t TSize) { + SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize); + } + + /// isSmall - Return true if this is a smallvector which has not had dynamic + /// memory allocated for it. + bool isSmall() const { + return BeginX == static_cast<const void*>(&FirstEl); + } + + /// resetToSmall - Put this vector in a state of being small. + void resetToSmall() { + BeginX = EndX = CapacityX = &FirstEl; + } void setEnd(T *P) { this->EndX = P; } public: @@ -844,6 +851,17 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { } #endif +/// Storage for the SmallVector elements which aren't contained in +/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1' +/// element is in the base class. This is specialized for the N=1 and N=0 cases +/// to avoid allocating unnecessary storage. +template <typename T, unsigned N> +struct SmallVectorStorage { + typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1]; +}; +template <typename T> struct SmallVectorStorage<T, 1> {}; +template <typename T> struct SmallVectorStorage<T, 0> {}; + /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized /// for the case when the array is small. It contains some number of elements /// in-place, which allows it to avoid heap allocation when the actual number of @@ -854,41 +872,23 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { /// template <typename T, unsigned N> class SmallVector : public SmallVectorImpl<T> { - /// InlineElts - These are 'N-1' elements that are stored inline in the body - /// of the vector. The extra '1' element is stored in SmallVectorImpl. - typedef typename SmallVectorImpl<T>::U U; - enum { - // MinUs - The number of U's require to cover N T's. - MinUs = (static_cast<unsigned int>(sizeof(T))*N + - static_cast<unsigned int>(sizeof(U)) - 1) / - static_cast<unsigned int>(sizeof(U)), - - // NumInlineEltsElts - The number of elements actually in this array. There - // is already one in the parent class, and we have to round up to avoid - // having a zero-element array. - NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1, - - // NumTsAvailable - The number of T's we actually have space for, which may - // be more than N due to rounding. - NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/ - static_cast<unsigned int>(sizeof(T)) - }; - U InlineElts[NumInlineEltsElts]; + /// Storage - Inline space for elements which aren't stored in the base class. + SmallVectorStorage<T, N> Storage; public: - SmallVector() : SmallVectorImpl<T>(NumTsAvailable) { + SmallVector() : SmallVectorImpl<T>(N) { } explicit SmallVector(unsigned Size, const T &Value = T()) - : SmallVectorImpl<T>(NumTsAvailable) { + : SmallVectorImpl<T>(N) { this->assign(Size, Value); } template<typename ItTy> - SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) { + SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) { this->append(S, E); } - SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) { + SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(RHS); } @@ -899,7 +899,7 @@ public: } #if LLVM_USE_RVALUE_REFERENCES - SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(NumTsAvailable) { + SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { if (!RHS.empty()) SmallVectorImpl<T>::operator=(::std::move(RHS)); } @@ -912,48 +912,6 @@ public: }; -/// Specialize SmallVector at N=0. This specialization guarantees -/// that it can be instantiated at an incomplete T if none of its -/// members are required. -template <typename T> -class SmallVector<T,0> : public SmallVectorImpl<T> { -public: - SmallVector() : SmallVectorImpl<T>(0) { - } - - explicit SmallVector(unsigned Size, const T &Value = T()) - : SmallVectorImpl<T>(0) { - this->assign(Size, Value); - } - - template<typename ItTy> - SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) { - this->append(S, E); - } - - SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) { - if (!RHS.empty()) - SmallVectorImpl<T>::operator=(RHS); - } - - const SmallVector &operator=(const SmallVector &RHS) { - SmallVectorImpl<T>::operator=(RHS); - return *this; - } - -#if LLVM_USE_RVALUE_REFERENCES - SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(0) { - if (!RHS.empty()) - SmallVectorImpl<T>::operator=(::std::move(RHS)); - } - - const SmallVector &operator=(SmallVector &&RHS) { - SmallVectorImpl<T>::operator=(::std::move(RHS)); - return *this; - } -#endif -}; - template<typename T, unsigned N> static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) { return X.capacity_in_bytes(); |
