Go to the documentation of this file.
14 #ifndef LLVM_ADT_SMALLVECTOR_H
15 #define LLVM_ADT_SMALLVECTOR_H
25 #include <initializer_list>
30 #include <type_traits>
35 template <
typename T>
class ArrayRef;
37 template <
typename IteratorT>
class iterator_range;
39 template <
class Iterator>
41 typename std::iterator_traits<Iterator>::iterator_category,
42 std::input_iterator_tag>::value>;
69 void *
mallocForGrow(
void *FirstEl,
size_t MinSize,
size_t TSize,
75 void grow_pod(
void *FirstEl,
size_t MinSize,
size_t TSize);
109 std::conditional_t<
sizeof(
T) < 4 &&
sizeof(
void *) >= 8,
uint64_t,
122 template <
typename T,
typename =
void>
132 return const_cast<void *
>(
reinterpret_cast<const void *
>(
133 reinterpret_cast<const char *
>(
this) +
157 std::less<> LessThan;
158 return !LessThan(V,
First) && LessThan(V,
Last);
170 std::less<> LessThan;
172 !LessThan(this->
end(), Last);
183 if (NewSize <= this->
size())
184 return Elt < this->
begin() + NewSize;
193 "Attempting to reference an element of the vector in an operation "
194 "that invalidates it");
212 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>,
T *>::value,
225 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>,
T *>::value,
234 size_t NewSize =
This->size() +
N;
238 bool ReferencesStorage =
false;
240 if (!U::TakesParamByValue) {
242 ReferencesStorage =
true;
247 return ReferencesStorage ?
This->begin() +
Index : &Elt;
329 template <
typename T,
bool = (is_trivially_copy_constructible<T>::value) &&
330 (is_trivially_move_constructible<T>::value) &&
331 std::is_trivially_destructible<T>::value>
350 template<
typename It1,
typename It2>
352 std::uninitialized_move(
I,
E, Dest);
357 template<
typename It1,
typename It2>
359 std::uninitialized_copy(
I,
E, Dest);
365 void grow(
size_t MinSize = 0);
387 return const_cast<T *
>(
398 std::uninitialized_fill_n(NewElts, NumElts, Elt);
408 ::new ((
void *)(NewElts + this->
size()))
T(std::forward<ArgTypes>(
Args)...);
435 template <
typename T,
bool TriviallyCopyable>
438 T *NewElts = mallocForGrow(MinSize, NewCapacity);
439 moveElementsForGrow(NewElts);
440 takeAllocationForGrow(NewElts, NewCapacity);
443 template <
typename T,
bool TriviallyCopyable>
445 size_t MinSize,
size_t &NewCapacity) {
446 return static_cast<T *
>(
448 this->getFirstEl(), MinSize,
sizeof(
T), NewCapacity));
452 template <
typename T,
bool TriviallyCopyable>
456 this->uninitialized_move(this->
begin(), this->
end(), NewElts);
459 destroy_range(this->
begin(), this->
end());
463 template <
typename T,
bool TriviallyCopyable>
465 T *NewElts,
size_t NewCapacity) {
467 if (!this->isSmall())
470 this->BeginX = NewElts;
471 this->Capacity = NewCapacity;
478 template <
typename T>
489 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
498 template<
typename It1,
typename It2>
506 template<
typename It1,
typename It2>
509 std::uninitialized_copy(
I,
E, Dest);
514 template <
typename T1,
typename T2>
517 std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>::value> * =
524 memcpy(
reinterpret_cast<void *
>(Dest),
I, (
E -
I) *
sizeof(
T));
540 return const_cast<T *
>(
552 std::uninitialized_fill_n(this->
begin(), NumElts, Elt);
567 memcpy(
reinterpret_cast<void *
>(this->
end()), EltPtr,
sizeof(
T));
576 template <
typename T>
577 class SmallVectorImpl :
public SmallVectorTemplateBase<T> {
578 using SuperClass = SmallVectorTemplateBase<T>;
595 this->destroy_range(this->
begin(), this->
end());
596 if (!this->isSmall())
598 this->BeginX =
RHS.BeginX;
599 this->Size =
RHS.Size;
600 this->Capacity =
RHS.Capacity;
610 if (!this->isSmall())
615 this->destroy_range(this->
begin(), this->
end());
623 template <
bool ForOverwrite>
void resizeImpl(
size_type N) {
624 if (
N == this->
size())
627 if (N < this->
size()) {
633 for (
auto I = this->
end(),
E = this->
begin() + N;
I !=
E; ++
I)
649 assert(this->
size() >= N &&
"Cannot increase size with truncate");
650 this->destroy_range(this->
begin() + N, this->
end());
655 if (
N == this->
size())
658 if (N < this->
size()) {
668 if (this->capacity() <
N)
686 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
688 this->assertSafeToAddRange(in_start, in_end);
689 size_type NumInputs = std::distance(in_start, in_end);
691 this->uninitialized_copy(in_start, in_end, this->
end());
692 this->set_size(this->
size() + NumInputs);
697 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
698 std::uninitialized_fill_n(this->
end(), NumInputs, *EltPtr);
699 this->set_size(this->
size() + NumInputs);
702 void append(std::initializer_list<T> IL) {
703 append(IL.begin(), IL.end());
710 if (NumElts > this->capacity()) {
711 this->growAndAssign(NumElts, Elt);
717 if (NumElts > this->
size())
718 std::uninitialized_fill_n(this->
end(), NumElts - this->
size(), Elt);
719 else if (NumElts < this->
size())
720 this->destroy_range(this->
begin() + NumElts, this->
end());
721 this->set_size(NumElts);
727 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
729 this->assertSafeToReferenceAfterClear(in_start, in_end);
734 void assign(std::initializer_list<T> IL) {
745 assert(this->isReferenceToStorage(CI) &&
"Iterator to erase is out of bounds.");
760 assert(this->isRangeInStorage(
S,
E) &&
"Range to erase is out of bounds.");
766 this->destroy_range(
I, this->
end());
767 this->set_size(
I - this->
begin());
775 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
777 "ArgType must be derived from T!");
779 if (
I == this->
end()) {
780 this->push_back(::std::forward<ArgType>(Elt));
781 return this->
end()-1;
784 assert(this->isReferenceToStorage(
I) &&
"Insertion iterator is out of bounds.");
788 std::remove_reference_t<ArgType> *EltPtr =
789 this->reserveForParamAndGetAddress(Elt);
799 static_assert(!TakesParamByValue ||
std::is_same<ArgType, T>::value,
800 "ArgType must
be 'T' when taking by value!");
801 if (!TakesParamByValue &&
this->isReferenceToRange(EltPtr,
I,
this->
end()))
804 *
I = ::
std::forward<ArgType>(*EltPtr);
810 return insert_one_impl(
I, this->forward_value_param(
std::move(Elt)));
814 return insert_one_impl(
I, this->forward_value_param(Elt));
819 size_t InsertElt =
I - this->
begin();
821 if (I == this->
end()) {
823 return this->
begin()+InsertElt;
826 assert(this->isReferenceToStorage(
I) &&
"Insertion iterator is out of bounds.");
830 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
833 I = this->
begin()+InsertElt;
839 if (
size_t(this->
end()-I) >= NumToInsert) {
840 T *OldEnd = this->
end();
841 append(std::move_iterator<iterator>(this->
end() - NumToInsert),
842 std::move_iterator<iterator>(this->
end()));
845 std::move_backward(
I, OldEnd-NumToInsert, OldEnd);
849 if (!TakesParamByValue &&
I <= EltPtr && EltPtr < this->
end())
850 EltPtr += NumToInsert;
852 std::fill_n(
I, NumToInsert, *EltPtr);
860 T *OldEnd = this->
end();
861 this->set_size(this->
size() + NumToInsert);
862 size_t NumOverwritten = OldEnd-
I;
863 this->uninitialized_move(
I, OldEnd, this->
end()-NumOverwritten);
867 if (!TakesParamByValue &&
I <= EltPtr && EltPtr < this->
end())
868 EltPtr += NumToInsert;
871 std::fill_n(
I, NumOverwritten, *EltPtr);
874 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
878 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
881 size_t InsertElt =
I - this->
begin();
883 if (I == this->
end()) {
885 return this->
begin()+InsertElt;
888 assert(this->isReferenceToStorage(
I) &&
"Insertion iterator is out of bounds.");
891 this->assertSafeToAddRange(
From, To);
893 size_t NumToInsert = std::distance(
From, To);
899 I = this->
begin()+InsertElt;
905 if (
size_t(this->
end()-I) >= NumToInsert) {
906 T *OldEnd = this->
end();
907 append(std::move_iterator<iterator>(this->
end() - NumToInsert),
908 std::move_iterator<iterator>(this->
end()));
911 std::move_backward(
I, OldEnd-NumToInsert, OldEnd);
921 T *OldEnd = this->
end();
922 this->set_size(this->
size() + NumToInsert);
923 size_t NumOverwritten = OldEnd-
I;
924 this->uninitialized_move(
I, OldEnd, this->
end()-NumOverwritten);
927 for (
T *J =
I; NumOverwritten > 0; --NumOverwritten) {
933 this->uninitialized_copy(
From, To, OldEnd);
938 insert(
I, IL.begin(), IL.end());
943 return this->growAndEmplaceBack(std::forward<ArgTypes>(
Args)...);
945 ::new ((
void *)this->
end())
T(std::forward<ArgTypes>(
Args)...);
946 this->set_size(this->
size() + 1);
955 if (this->
size() != RHS.size())
return false;
959 return !(*
this ==
RHS);
963 return std::lexicographical_compare(this->
begin(), this->
end(),
964 RHS.begin(),
RHS.end());
971 template <
typename T>
973 if (
this == &
RHS)
return;
976 if (!this->isSmall() && !
RHS.isSmall()) {
986 size_t NumShared = this->
size();
987 if (NumShared >
RHS.size()) NumShared =
RHS.size();
992 if (this->
size() > RHS.size()) {
993 size_t EltDiff = this->
size() - RHS.size();
994 this->uninitialized_copy(this->
begin()+NumShared, this->
end(), RHS.end());
995 RHS.set_size(
RHS.size() + EltDiff);
996 this->destroy_range(this->
begin()+NumShared, this->
end());
997 this->set_size(NumShared);
998 }
else if (
RHS.size() >
this->size()) {
999 size_t EltDiff =
RHS.size() - this->
size();
1000 this->uninitialized_copy(
RHS.begin()+NumShared,
RHS.end(),
this->end());
1001 this->set_size(this->
size() + EltDiff);
1002 this->destroy_range(
RHS.begin()+NumShared,
RHS.end());
1003 RHS.set_size(NumShared);
1007 template <
typename T>
1011 if (
this == &
RHS)
return *
this;
1015 size_t RHSSize =
RHS.size();
1016 size_t CurSize = this->
size();
1017 if (CurSize >= RHSSize) {
1023 NewEnd = this->
begin();
1026 this->destroy_range(NewEnd, this->
end());
1029 this->set_size(RHSSize);
1036 if (this->capacity() < RHSSize) {
1040 this->grow(RHSSize);
1041 }
else if (CurSize) {
1047 this->uninitialized_copy(
RHS.begin()+CurSize,
RHS.end(),
1048 this->begin()+CurSize);
1051 this->set_size(RHSSize);
1055 template <
typename T>
1058 if (
this == &
RHS)
return *
this;
1061 if (!
RHS.isSmall()) {
1068 size_t RHSSize =
RHS.size();
1069 size_t CurSize = this->
size();
1070 if (CurSize >= RHSSize) {
1077 this->destroy_range(NewEnd, this->
end());
1078 this->set_size(RHSSize);
1090 if (this->capacity() < RHSSize) {
1094 this->grow(RHSSize);
1095 }
else if (CurSize) {
1101 this->uninitialized_move(
RHS.begin()+CurSize,
RHS.end(),
1102 this->begin()+CurSize);
1105 this->set_size(RHSSize);
1113 template <
typename T,
unsigned N>
1115 alignas(
T)
char InlineElts[
N *
sizeof(T)];
1141 static constexpr
size_t kPreferredSmallVectorSizeof = 64;
1167 "You are trying to use a default number of inlined elements for "
1168 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1169 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1170 "sure you really want that much inline storage.");
1174 static constexpr
size_t PreferredInlineBytes =
1176 static constexpr
size_t NumElementsThatFit = PreferredInlineBytes /
sizeof(
T);
1177 static constexpr
size_t value =
1178 NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
1197 template <
typename T,
1206 this->destroy_range(this->
begin(), this->
end());
1214 template <
typename ItTy,
typename = EnableIfConvertibleToInputIterator<ItTy>>
1219 template <
typename RangeTy>
1229 template <
typename U,
1230 typename = std::enable_if_t<std::is_convertible<U, T>::value>>
1265 this->destroy_range(this->
begin(), this->
end());
1284 template <
typename T,
unsigned N>
1286 return X.capacity_in_bytes();
1289 template <
typename RangeType>
1291 std::remove_const_t<std::remove_reference_t<decltype(*
std::begin(
1292 std::declval<RangeType &>()))>>;
1297 template <
unsigned Size,
typename R>
1301 template <
typename R>
1306 template <
typename Out,
unsigned Size,
typename R>
1317 #if SIZE_MAX > UINT32_MAX
1326 template<
typename T>
1333 template<
typename T,
unsigned N>
1341 #endif // LLVM_ADT_SMALLVECTOR_H
const_reference operator[](size_type idx) const
bool isReferenceToStorage(const void *V) const
Return true if V is an internal reference to this vector.
static T && forward_value_param(T &&V)
bool isReferenceToRange(const void *V, const void *First, const void *Last) const
Return true if V is an internal reference to the given range.
SmallVectorImpl(unsigned N)
bool isRangeInStorage(const void *First, const void *Last) const
Return true if First and Last form a valid (possibly empty) range in this vector's storage.
This is an optimization pass for GlobalISel generic memory operations.
iterator erase(const_iterator CI)
bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Return true unless Elt will be invalidated by resizing the vector to NewSize.
SmallVector & operator=(SmallVectorImpl< T > &&RHS)
SmallVector(SmallVectorImpl< T > &&RHS)
SmallVector(std::initializer_list< T > IL)
void append(const SmallVectorImpl &RHS)
void append(size_type NumInputs, ValueParamT Elt)
Append NumInputs copies of Elt to the end.
void append(std::initializer_list< T > IL)
void assign(std::initializer_list< T > IL)
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
const_iterator begin() const
static const T * reserveForParamAndGetAddressImpl(U *This, const T &Elt, size_t N)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
#define offsetof(TYPE, MEMBER)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static ValueParamT forward_value_param(ValueParamT V)
Copy V or return a reference, depending on ValueParamT.
void * mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize, size_t &NewCapacity)
This is a helper for grow() that's out of line to reduce code duplication.
void grow(size_t MinSize=0)
Double the size of the allocated memory, guaranteeing space for at least one more element or MinSize ...
void * replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity, size_t VSize=0)
If vector was first created with capacity 0, getFirstEl() points to the memory right after,...
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize)
This is an implementation of the grow() method which only works on POD-like data types and is out of ...
iterator insert(iterator I, ItTy From, ItTy To)
#define LLVM_GSL_OWNER
LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable lifetime warnings.
static void destroy_range(T *S, T *E)
void assign(const SmallVectorImpl &RHS)
SmallVector< Out, Size > to_vector_of(R &&Range)
static constexpr bool TakesParamByValue
BitVector::size_type capacity_in_bytes(const BitVector &X)
void moveElementsForGrow(T *NewElts)
Move existing elements over to the new allocation NewElts, the middle section of grow().
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Storage for the SmallVector elements.
const T & const_reference
void resetToSmall()
Put this vector in a state of being small.
size_type max_size() const
iterator erase(const_iterator CS, const_iterator CE)
DiagnosticInfoOptimizationBase::Argument NV
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it.
std::reverse_iterator< iterator > reverse_iterator
void * getFirstEl() const
Find the address of the first element.
bool operator>(const SmallVectorImpl &RHS) const
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
std::conditional_t< TakesParamByValue, T, const T & > ValueParamT
Either const T& or T, depending on whether it's cheap enough to take parameters by value.
reverse_iterator rbegin()
void growAndAssign(size_t NumElts, const T &Elt)
std::conditional_t< sizeof(T)< 4 &&sizeof(void *) >=8, uint64_t, uint32_t > SmallVectorSizeType
static const T & forward_value_param(const T &V)
void assign(ItTy in_start, ItTy in_end)
void truncate(size_type N)
Like resize, but requires that N is less than size().
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
SmallVector(const SmallVector &RHS)
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Move the range [I, E) into the uninitialized memory starting with "Dest", constructing elements as ne...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt)
void grow(size_t MinSize=0)
Grow the allocated memory (without initializing new elements), doubling the size of the allocated mem...
SmallVector(const iterator_range< RangeTy > &R)
into llvm powi allowing the code generator to produce balanced multiplication trees First
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can be
void push_back(ValueParamT Elt)
const_reverse_iterator rbegin() const
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
SmallVector(ItTy S, ItTy E)
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
SmallVector & operator=(SmallVector &&RHS)
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Move the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const_iterator end() const
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
This is the part of SmallVectorTemplateBase which does not depend on whether the type T is a POD.
SmallVectorImpl & operator=(const SmallVectorImpl &RHS)
bool operator==(const SmallVectorImpl &RHS) const
void set_size(size_t N)
Set the array size to N, which the current array must have enough capacity for.
void push_back(const T &Elt)
reference operator[](size_type idx)
void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Check whether Elt will be invalidated by resizing the vector to NewSize.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
void grow_pod(size_t MinSize, size_t TSize)
T & growAndEmplaceBack(ArgTypes &&... Args)
typename SuperClass::const_iterator const_iterator
void assignRemote(SmallVectorImpl &&RHS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
void resize(size_type N, ValueParamT NV)
const_reverse_iterator rend() const
void takeAllocationForGrow(T *NewElts, size_t NewCapacity)
Transfer ownership of the allocation, finishing up grow().
pointer data()
Return a pointer to the vector's buffer, even if empty().
T & growAndEmplaceBack(ArgTypes &&... Args)
SmallVector(ArrayRef< U > A)
size_type size_in_bytes() const
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
SmallVector(SmallVector &&RHS)
std::enable_if_t< std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::input_iterator_tag >::value > EnableIfConvertibleToInputIterator
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void assertSafeToReferenceAfterClear(ItTy, ItTy)
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Analysis the ScalarEvolution expression for r is this
const_reference front() const
if(llvm_vc STREQUAL "") set(fake_version_inc "$
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
bool operator!=(const SmallVectorImpl &RHS) const
void assertSafeToAdd(const void *Elt, size_t N=1)
Check whether Elt will be invalidated by increasing the size of the vector by N.
size_t capacity_in_bytes() const
T * mallocForGrow(size_t MinSize, size_t &NewCapacity)
Create a new allocation big enough for MinSize and pass back its size in NewCapacity.
void growAndAssign(size_t NumElts, T Elt)
std::reverse_iterator< const_iterator > const_reverse_iterator
void swap(SmallVectorImpl &RHS)
void assign(size_type NumElts, ValueParamT Elt)
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements as ne...
Figure out the offset of the first element.
void assertSafeToReferenceAfterClear(const T *From, const T *To)
Check whether any part of the range will be invalidated by clearing.
static void destroy_range(T *, T *)
iterator insert(iterator I, const T &Elt)
std::remove_const_t< std::remove_reference_t< decltype(*std::begin(std::declval< RangeType & >()))> > ValueTypeFromRangeType
typename SuperClass::ValueParamT ValueParamT
bool operator<=(const SmallVectorImpl &RHS) const
void assertSafeToAddRange(const T *From, const T *To)
Check whether any part of the range will be invalidated by growing.
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical This
Helper class for calculating the default number of inline elements for SmallVector<T>.
void pop_back_n(size_type NumItems)
SmallVectorTemplateCommon(size_t Size)
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
SmallVector & operator=(std::initializer_list< T > IL)
typename SuperClass::iterator iterator
A range adaptor for a pair of iterators.
#define LLVM_LIKELY(EXPR)
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
typename SuperClass::size_type size_type
SmallVectorTemplateBase(size_t Size)
SmallVector(size_t Size, const T &Value=T())
bool operator>=(const SmallVectorImpl &RHS) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest, std::enable_if_t< std::is_same< std::remove_const_t< T1 >, T2 >::value > *=nullptr)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
void insert(iterator I, std::initializer_list< T > IL)
ArrayRef(const T &OneElt) -> ArrayRef< T >
SmallVectorTemplateBase(size_t Size)
BlockVerifier::State From
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
#define LLVM_UNLIKELY(EXPR)
char Base[sizeof(SmallVectorBase< SmallVectorSizeType< T >>)]
void reserve(size_type N)
This is all the stuff common to all SmallVectors.
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
SmallVector & operator=(const SmallVector &RHS)
bool operator<(const SmallVectorImpl &RHS) const
LLVM Value Representation.
typename SuperClass::reference reference
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method implementations that...
void assertSafeToAddRange(ItTy, ItTy)
reference emplace_back(ArgTypes &&... Args)
iterator insert(iterator I, T &&Elt)
const_reference back() const