LLVM 24.0.0git
SmallVector.h
Go to the documentation of this file.
1//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the SmallVector class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_SMALLVECTOR_H
15#define LLVM_ADT_SMALLVECTOR_H
16
17#include "llvm/ADT/ADL.h"
20#include <algorithm>
21#include <cassert>
22#include <cstddef>
23#include <cstdint>
24#include <cstdlib>
25#include <cstring>
26#include <functional>
27#include <initializer_list>
28#include <iterator>
29#include <limits>
30#include <memory>
31#include <new>
32#include <type_traits>
33#include <utility>
34
35namespace llvm {
36
37template <typename T> class ArrayRef;
38
39template <typename IteratorT> class iterator_range;
40
41template <class Iterator, class Tag>
42using HasIteratorTag = std::is_convertible<
43 typename std::iterator_traits<Iterator>::iterator_category, Tag>;
44
45template <class Iterator>
47 std::enable_if_t<HasIteratorTag<Iterator, std::input_iterator_tag>::value>;
48
49/// This is all the stuff common to all SmallVectors.
50///
51/// The template parameter specifies the type which should be used to hold the
52/// Size and Capacity of the SmallVector, so it can be adjusted.
53/// Using 32 bit size is desirable to shrink the size of the SmallVector.
54/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
55/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
56/// buffering bitcode output - which can exceed 4GB.
57template <class Size_T> class SmallVectorBase {
58protected:
59 void *BeginX;
60 Size_T Size = 0, Capacity;
61
62 /// The maximum value of the Size_T used.
63 static constexpr size_t SizeTypeMax() {
64 return std::numeric_limits<Size_T>::max();
65 }
66
67 SmallVectorBase() = delete;
68 SmallVectorBase(void *FirstEl, size_t TotalCapacity)
69 : BeginX(FirstEl), Capacity(static_cast<Size_T>(TotalCapacity)) {}
70
71 /// This is a helper for \a grow() that's out of line to reduce code
72 /// duplication. This function will report a fatal error if it can't grow at
73 /// least to \p MinSize.
74 LLVM_ABI void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
75 size_t &NewCapacity);
76
77 /// This is an implementation of the grow() method which only works
78 /// on POD-like data types and is out of line to reduce code duplication.
79 /// This function will report a fatal error if it cannot increase capacity.
80 LLVM_ABI void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
81
82public:
83 size_t size() const { return Size; }
84 size_t capacity() const { return Capacity; }
85
86 [[nodiscard]] bool empty() const { return !Size; }
87
88protected:
89 /// Set the array size to \p N, which the current array must have enough
90 /// capacity for.
91 ///
92 /// This does not construct or destroy any elements in the vector.
93 void set_size(size_t N) {
94 assert(N <= capacity()); // implies no overflow in assignment
95 Size = static_cast<Size_T>(N);
96 }
97
98 /// Set the array data pointer to \p Begin and capacity to \p N.
99 ///
100 /// This does not construct or destroy any elements in the vector.
101 // This does not clean up any existing allocation.
102 void set_allocation_range(void *Begin, size_t N) {
103 assert(N <= SizeTypeMax());
104 BeginX = Begin;
105 Capacity = static_cast<Size_T>(N);
106 }
107};
108
109template <class T>
111 std::conditional_t<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
112 uint32_t>;
113
114/// Figure out the offset of the first element.
115template <class T, typename = void> struct SmallVectorAlignmentAndSize {
118 alignas(T) char FirstEl[sizeof(T)];
119};
120
121/// This is the part of SmallVectorTemplateBase which does not depend on whether
122/// the type T is a POD. The extra dummy template argument is used by ArrayRef
123/// to avoid unnecessarily requiring T to be complete.
124template <typename T, typename = void>
126 : public SmallVectorBase<SmallVectorSizeType<T>> {
128
129protected:
130 /// Find the address of the first element. For this pointer math to be valid
131 /// with small-size of 0 for T with lots of alignment, it's important that
132 /// SmallVectorStorage is properly-aligned even for small-size of 0.
133 void *getFirstEl() const {
134 return const_cast<void *>(reinterpret_cast<const void *>(
135 reinterpret_cast<const char *>(this) +
137 }
138 // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
139
140 SmallVectorTemplateCommon(size_t SizeArg) : Base(getFirstEl(), SizeArg) {}
141
142 void grow_pod(size_t MinSize, size_t TSize) {
143 Base::grow_pod(getFirstEl(), MinSize, TSize);
144 }
145
146 /// Return true if this is a smallvector which has not had dynamic
147 /// memory allocated for it.
148 bool isSmall() const { return this->BeginX == getFirstEl(); }
149
150 /// Put this vector in a state of being small.
152 this->BeginX = getFirstEl();
153 this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
154 }
155
156 /// Return true if V is an internal reference to the given range.
157 bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
158 // Use std::less to avoid UB.
159 std::less<> LessThan;
160 return !LessThan(V, First) && LessThan(V, Last);
161 }
162
163 /// Return true if V is an internal reference to this vector.
164 bool isReferenceToStorage(const void *V) const {
165 return isReferenceToRange(V, this->begin(), this->end());
166 }
167
168 /// Return true if First and Last form a valid (possibly empty) range in this
169 /// vector's storage.
170 bool isRangeInStorage(const void *First, const void *Last) const {
171 // Use std::less to avoid UB.
172 std::less<> LessThan;
173 return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
174 !LessThan(this->end(), Last);
175 }
176
177 /// Return true unless Elt will be invalidated by resizing the vector to
178 /// NewSize.
179 bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
180 // Past the end.
182 return true;
183
184 // Return false if Elt will be destroyed by shrinking.
185 if (NewSize <= this->size())
186 return Elt < this->begin() + NewSize;
187
188 // Return false if we need to grow.
189 return NewSize <= this->capacity();
190 }
191
192 /// Check whether Elt will be invalidated by resizing the vector to NewSize.
193 void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
194 assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
195 "Attempting to reference an element of the vector in an operation "
196 "that invalidates it");
197 }
198
199 /// Check whether Elt will be invalidated by increasing the size of the
200 /// vector by N.
201 void assertSafeToAdd(const void *Elt, size_t N = 1) {
202 this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
203 }
204
205 /// Check whether any part of the range will be invalidated by clearing.
206 template <class ItTy>
208 if constexpr (std::is_pointer_v<ItTy> &&
209 std::is_same_v<
210 std::remove_const_t<std::remove_pointer_t<ItTy>>,
211 std::remove_const_t<T>>) {
212 if (From == To)
213 return;
215 this->assertSafeToReferenceAfterResize(To - 1, 0);
216 }
217 (void)From;
218 (void)To;
219 }
220
221 /// Check whether any part of the range will be invalidated by growing.
222 template <class ItTy> void assertSafeToAddRange(ItTy From, ItTy To) {
223 if constexpr (std::is_pointer_v<ItTy> &&
224 std::is_same_v<std::remove_cv_t<std::remove_pointer_t<ItTy>>,
225 T>) {
226 if (From == To)
227 return;
228 this->assertSafeToAdd(From, To - From);
229 this->assertSafeToAdd(To - 1, To - From);
230 }
231 (void)From;
232 (void)To;
233 }
234
235 /// Reserve enough space to add one element, and return the updated element
236 /// pointer in case it was a reference to the storage.
237 template <class U>
238 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
239 size_t N) {
240 size_t NewSize = This->size() + N;
241 if (LLVM_LIKELY(NewSize <= This->capacity()))
242 return &Elt;
243
244 bool ReferencesStorage = false;
245 int64_t Index = -1;
246 if (!U::TakesParamByValue) {
247 if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
248 ReferencesStorage = true;
249 Index = &Elt - This->begin();
250 }
251 }
252 This->grow(NewSize);
253 return ReferencesStorage ? This->begin() + Index : &Elt;
254 }
255
256public:
259 using value_type = T;
260 using iterator = T *;
261 using const_iterator = const T *;
262
263 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
264 using reverse_iterator = std::reverse_iterator<iterator>;
265
266 using reference = T &;
267 using const_reference = const T &;
268 using pointer = T *;
269 using const_pointer = const T *;
270
271 using Base::capacity;
272 using Base::empty;
273 using Base::size;
274
275 // forward iterator creation methods.
276 iterator begin() { return (iterator)this->BeginX; }
277 const_iterator begin() const { return (const_iterator)this->BeginX; }
278 iterator end() { return begin() + size(); }
279 const_iterator end() const { return begin() + size(); }
280
281 // reverse iterator creation methods.
286
287 size_type size_in_bytes() const { return size() * sizeof(T); }
289 return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
290 }
291
292 size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
293
294 /// Return a pointer to the vector's buffer, even if empty().
295 pointer data() { return pointer(begin()); }
296 /// Return a pointer to the vector's buffer, even if empty().
297 const_pointer data() const { return const_pointer(begin()); }
298
300 assert(idx < size());
301 return begin()[idx];
302 }
304 assert(idx < size());
305 return begin()[idx];
306 }
307
309 assert(!empty());
310 return begin()[0];
311 }
313 assert(!empty());
314 return begin()[0];
315 }
316
318 assert(!empty());
319 return end()[-1];
320 }
322 assert(!empty());
323 return end()[-1];
324 }
325};
326
327/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put
328/// method implementations that are designed to work with non-trivial T's.
329///
330/// We approximate is_trivially_copyable with trivial move/copy construction and
331/// trivial destruction. While the standard doesn't specify that you're allowed
332/// copy these types with memcpy, there is no way for the type to observe this.
333/// This catches the important case of std::pair<POD, POD>, which is not
334/// trivially assignable.
335template <typename T, bool = (std::is_trivially_copy_constructible<T>::value) &&
336 (std::is_trivially_move_constructible<T>::value) &&
337 std::is_trivially_destructible<T>::value>
339 friend class SmallVectorTemplateCommon<T>;
340
341protected:
342 static constexpr bool TakesParamByValue = false;
343 using ValueParamT = const T &;
344
346 : SmallVectorTemplateCommon<T>(SizeArg) {}
347
348 static void destroy_range(T *S, T *E) {
349 while (S != E) {
350 --E;
351 E->~T();
352 }
353 }
354
355 /// Move the range [I, E) into the uninitialized memory starting with "Dest",
356 /// constructing elements as needed.
357 template<typename It1, typename It2>
358 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
359 std::uninitialized_move(I, E, Dest);
360 }
361
362 /// Copy the range [I, E) onto the uninitialized memory starting with "Dest",
363 /// constructing elements as needed.
364 template<typename It1, typename It2>
365 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
366 std::uninitialized_copy(I, E, Dest);
367 }
368
369 /// Grow the allocated memory (without initializing new elements), doubling
370 /// the size of the allocated memory. Guarantees space for at least one more
371 /// element, or MinSize more elements if specified.
372 void grow(size_t MinSize = 0);
373
374 /// Create a new allocation big enough for \p MinSize and pass back its size
375 /// in \p NewCapacity. This is the first section of \a grow().
376 T *mallocForGrow(size_t MinSize, size_t &NewCapacity);
377
378 /// Move existing elements over to the new allocation \p NewElts, the middle
379 /// section of \a grow().
380 void moveElementsForGrow(T *NewElts);
381
382 /// Transfer ownership of the allocation, finishing up \a grow().
383 void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
384
385 /// Reserve enough space to add one element, and return the updated element
386 /// pointer in case it was a reference to the storage.
387 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
388 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
389 }
390
391 /// Reserve enough space to add one element, and return the updated element
392 /// pointer in case it was a reference to the storage.
393 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
394 return const_cast<T *>(
395 this->reserveForParamAndGetAddressImpl(this, Elt, N));
396 }
397
398 static T &&forward_value_param(T &&V) { return std::move(V); }
399 static const T &forward_value_param(const T &V) { return V; }
400
401 void growAndAssign(size_t NumElts, const T &Elt) {
402 // Grow manually in case Elt is an internal reference.
403 size_t NewCapacity;
404 T *NewElts = mallocForGrow(NumElts, NewCapacity);
405 std::uninitialized_fill_n(NewElts, NumElts, Elt);
406 this->destroy_range(this->begin(), this->end());
407 takeAllocationForGrow(NewElts, NewCapacity);
408 this->set_size(NumElts);
409 }
410
411 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
412 // Grow manually in case one of Args is an internal reference.
413 size_t NewCapacity;
414 T *NewElts = mallocForGrow(0, NewCapacity);
415 ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
416 moveElementsForGrow(NewElts);
417 takeAllocationForGrow(NewElts, NewCapacity);
418 this->set_size(this->size() + 1);
419 return this->back();
420 }
421
422public:
423 void push_back(const T &Elt) {
424 const T *EltPtr = reserveForParamAndGetAddress(Elt);
425 ::new ((void *)this->end()) T(*EltPtr);
426 this->set_size(this->size() + 1);
427 }
428
429 void push_back(T &&Elt) {
430 T *EltPtr = reserveForParamAndGetAddress(Elt);
431 ::new ((void *)this->end()) T(::std::move(*EltPtr));
432 this->set_size(this->size() + 1);
433 }
434
435 void pop_back() {
436 this->set_size(this->size() - 1);
437 this->end()->~T();
438 }
439};
440
441// Define this out-of-line to dissuade the C++ compiler from inlining it.
442template <typename T, bool TriviallyCopyable>
444 size_t NewCapacity;
445 T *NewElts = mallocForGrow(MinSize, NewCapacity);
446 moveElementsForGrow(NewElts);
447 takeAllocationForGrow(NewElts, NewCapacity);
448}
449
450template <typename T, bool TriviallyCopyable>
452 size_t MinSize, size_t &NewCapacity) {
453 return static_cast<T *>(
455 this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
456}
457
458// Define this out-of-line to dissuade the C++ compiler from inlining it.
459template <typename T, bool TriviallyCopyable>
461 T *NewElts) {
462 // Move the elements over.
463 this->uninitialized_move(this->begin(), this->end(), NewElts);
464
465 // Destroy the original elements.
466 destroy_range(this->begin(), this->end());
467}
468
469// Define this out-of-line to dissuade the C++ compiler from inlining it.
470template <typename T, bool TriviallyCopyable>
472 T *NewElts, size_t NewCapacity) {
473 // If this wasn't grown from the inline copy, deallocate the old space.
474 if (!this->isSmall())
475 free(this->begin());
476
477 this->set_allocation_range(NewElts, NewCapacity);
478}
479
480/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
481/// method implementations that are designed to work with trivially copyable
482/// T's. This allows using memcpy in place of copy/move construction and
483/// skipping destruction.
484template <typename T>
486 friend class SmallVectorTemplateCommon<T>;
487
488protected:
489 /// True if it's cheap enough to take parameters by value. Doing so avoids
490 /// overhead related to mitigations for reference invalidation.
491 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
492
493 /// Either const T& or T, depending on whether it's cheap enough to take
494 /// parameters by value.
495 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>;
496
498 : SmallVectorTemplateCommon<T>(SizeArg) {}
499
500 // No need to do a destroy loop for POD's.
501 static void destroy_range(T *, T *) {}
502
503 /// Move the range [I, E) onto the uninitialized memory
504 /// starting with "Dest", constructing elements into it as needed.
505 template <typename It1, typename It2>
506 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
507 // Just do a copy.
508 uninitialized_copy(I, E, Dest);
509 }
510
511 /// Copy the range [I, E) onto the uninitialized memory
512 /// starting with "Dest", constructing elements into it as needed.
513 template <typename It1, typename It2>
514 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
515 if constexpr (std::is_pointer_v<It1> && std::is_pointer_v<It2> &&
516 std::is_same_v<
517 std::remove_const_t<std::remove_pointer_t<It1>>,
518 std::remove_pointer_t<It2>>) {
519 // Use memcpy for PODs iterated by pointers (which includes SmallVector
520 // iterators): std::uninitialized_copy optimizes to memmove, but we can
521 // use memcpy here. Note that I and E are iterators and thus might be
522 // invalid for memcpy if they are equal.
523 if (I != E)
524 std::memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
525 } else {
526 // Arbitrary iterator types; just use the basic implementation.
527 std::uninitialized_copy(I, E, Dest);
528 }
529 }
530
531 /// Double the size of the allocated memory, guaranteeing space for at
532 /// least one more element or MinSize if specified.
533 void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
534
535 /// Reserve enough space to add one element, and return the updated element
536 /// pointer in case it was a reference to the storage.
537 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
538 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
539 }
540
541 /// Reserve enough space to add one element, and return the updated element
542 /// pointer in case it was a reference to the storage.
543 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
544 return const_cast<T *>(
545 this->reserveForParamAndGetAddressImpl(this, Elt, N));
546 }
547
548 /// Copy \p V or return a reference, depending on \a ValueParamT.
550
551 void growAndAssign(size_t NumElts, T Elt) {
552 // Elt has been copied in case it's an internal reference, side-stepping
553 // reference invalidation problems without losing the realloc optimization.
554 this->set_size(0);
555 this->grow(NumElts);
556 std::uninitialized_fill_n(this->begin(), NumElts, Elt);
557 this->set_size(NumElts);
558 }
559
560 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
561 // Use push_back with a copy in case Args has an internal reference,
562 // side-stepping reference invalidation problems without losing the realloc
563 // optimization.
564 push_back(T(std::forward<ArgTypes>(Args)...));
565 return this->back();
566 }
567
568 // Out-of-line slow path so the inline push_back needs no callee-saved
569 // registers or stack frame on its hot path.
571 // Copy in case Elt is an internal reference invalidated by grow.
572 T Tmp = Elt;
573 this->grow(this->size() + 1);
574 std::memcpy(reinterpret_cast<void *>(this->end()), &Tmp, sizeof(T));
575 this->set_size(this->size() + 1);
576 }
577
578public:
580 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
581 return growAndPushBack(Elt);
582 std::memcpy(reinterpret_cast<void *>(this->end()), &Elt, sizeof(T));
583 this->set_size(this->size() + 1);
584 }
585
586 void pop_back() { this->set_size(this->size() - 1); }
587};
588
589/// This class consists of common code factored out of the SmallVector class to
590/// reduce code duplication based on the SmallVector 'N' template parameter.
591template <typename T>
593 using SuperClass = SmallVectorTemplateBase<T>;
594
595public:
600
601protected:
604
605 // Default ctor - Initialize to empty.
606 explicit SmallVectorImpl(unsigned N)
608
610 this->destroy_range(this->begin(), this->end());
611 if (!this->isSmall())
612 free(this->begin());
613 this->BeginX = RHS.BeginX;
614 this->Size = RHS.Size;
615 this->Capacity = RHS.Capacity;
616 RHS.resetToSmall();
617 }
618
620 assert(this->empty() && "move construction requires an empty vector");
621 if (!RHS.isSmall()) {
622 assignRemote(std::move(RHS));
623 return;
624 }
625
626 // Construct inline elements directly instead of requiring T to be move
627 // assignable through the general move-assignment implementation.
628 size_type RHSSize = RHS.size();
629 reserve(RHSSize);
630 this->uninitialized_move(RHS.begin(), RHS.end(), this->begin());
631 this->set_size(RHSSize);
632 RHS.clear();
633 }
634
636 // Subclass has already destructed this vector's elements.
637 // If this wasn't grown from the inline copy, deallocate the old space.
638 if (!this->isSmall())
639 free(this->begin());
640 }
641
642public:
644
645 void clear() {
646 this->destroy_range(this->begin(), this->end());
647 this->Size = 0;
648 }
649
650private:
651 // Make set_size() private to avoid misuse in subclasses.
653
654 template <bool ForOverwrite> void resizeImpl(size_type N) {
655 if (N == this->size())
656 return;
657
658 if (N < this->size()) {
659 this->truncate(N);
660 return;
661 }
662
663 this->reserve(N);
664 for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
665 if (ForOverwrite)
666 new (&*I) T;
667 else
668 new (&*I) T();
669 this->set_size(N);
670 }
671
672public:
673 void resize(size_type N) { resizeImpl<false>(N); }
674
675 /// Like resize, but \ref T is POD, the new values won't be initialized.
676 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
677
678 /// Like resize, but requires that \p N is less than \a size().
680 assert(this->size() >= N && "Cannot increase size with truncate");
681 this->destroy_range(this->begin() + N, this->end());
682 this->set_size(N);
683 }
684
686 if (N == this->size())
687 return;
688
689 if (N < this->size()) {
690 this->truncate(N);
691 return;
692 }
693
694 // N > this->size(). Defer to append.
695 this->append(N - this->size(), NV);
696 }
697
699 if (this->capacity() < N)
700 this->grow(N);
701 }
702
703 void pop_back_n(size_type NumItems) {
704 assert(this->size() >= NumItems);
705 truncate(this->size() - NumItems);
706 }
707
708 [[nodiscard]] T pop_back_val() {
709 T Result = ::std::move(this->back());
710 this->pop_back();
711 return Result;
712 }
713
715
716 /// Add the specified range to the end of the SmallVector.
717 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
718 void append(ItTy in_start, ItTy in_end) {
720 this->assertSafeToAddRange(in_start, in_end);
721 size_type NumInputs = std::distance(in_start, in_end);
722 this->reserve(this->size() + NumInputs);
723 this->uninitialized_copy(in_start, in_end, this->end());
724 this->set_size(this->size() + NumInputs);
725 } else {
726 // Input iterator, we can't know ahead how many elements we'll add.
727 for (; in_start != in_end; ++in_start)
728 this->emplace_back(*in_start);
729 }
730 }
731
732 /// Append \p NumInputs copies of \p Elt to the end.
733 void append(size_type NumInputs, ValueParamT Elt) {
734 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
735 std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
736 this->set_size(this->size() + NumInputs);
737 }
738
739 void append(std::initializer_list<T> IL) {
740 append(IL.begin(), IL.end());
741 }
742
743 void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
744
745 void assign(size_type NumElts, ValueParamT Elt) {
746 // Note that Elt could be an internal reference.
747 if (NumElts > this->capacity()) {
748 this->growAndAssign(NumElts, Elt);
749 return;
750 }
751
752 // Assign over existing elements.
753 std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
754 if (NumElts > this->size())
755 std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
756 else if (NumElts < this->size())
757 this->destroy_range(this->begin() + NumElts, this->end());
758 this->set_size(NumElts);
759 }
760
761 // FIXME: Consider assigning over existing elements, rather than clearing &
762 // re-initializing them - for all assign(...) variants.
763
764 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
765 void assign(ItTy in_start, ItTy in_end) {
766 this->assertSafeToReferenceAfterClear(in_start, in_end);
767 clear();
768 append(in_start, in_end);
769 }
770
771 void assign(std::initializer_list<T> IL) {
772 clear();
773 append(IL);
774 }
775
776 void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
777
778 template <typename U,
779 typename = std::enable_if_t<std::is_convertible_v<U, T>>>
781 assign(AR.begin(), AR.end());
782 }
783
785 // Just cast away constness because this is a non-const member function.
786 iterator I = const_cast<iterator>(CI);
787
788 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
789
790 iterator N = I;
791 // Shift all elts down one.
792 std::move(I+1, this->end(), I);
793 // Drop the last elt.
794 this->pop_back();
795 return(N);
796 }
797
799 // Just cast away constness because this is a non-const member function.
800 iterator S = const_cast<iterator>(CS);
801 iterator E = const_cast<iterator>(CE);
802
803 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
804
805 iterator N = S;
806 // Shift all elts down.
807 iterator I = std::move(E, this->end(), S);
808 // Drop the last elts.
809 this->destroy_range(I, this->end());
810 this->set_size(I - this->begin());
811 return(N);
812 }
813
814private:
815 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
816 // Callers ensure that ArgType is derived from T.
817 static_assert(
818 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
819 T>::value,
820 "ArgType must be derived from T!");
821
822 if (I == this->end()) { // Important special case for empty vector.
823 this->push_back(::std::forward<ArgType>(Elt));
824 return this->end()-1;
825 }
826
827 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
828
829 // Grow if necessary.
830 size_t Index = I - this->begin();
831 std::remove_reference_t<ArgType> *EltPtr =
833 I = this->begin() + Index;
834
835 ::new ((void*) this->end()) T(::std::move(this->back()));
836 // Push everything else over.
837 std::move_backward(I, this->end()-1, this->end());
838 this->set_size(this->size() + 1);
839
840 // If we just moved the element we're inserting, be sure to update
841 // the reference (never happens if TakesParamByValue).
842 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
843 "ArgType must be 'T' when taking by value!");
844 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
845 ++EltPtr;
846
847 *I = ::std::forward<ArgType>(*EltPtr);
848 return I;
849 }
850
851public:
853 return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
854 }
855
856 iterator insert(iterator I, const T &Elt) {
857 return insert_one_impl(I, this->forward_value_param(Elt));
858 }
859
861 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
862 size_t InsertElt = I - this->begin();
863
864 if (I == this->end()) { // Important special case for empty vector.
865 append(NumToInsert, Elt);
866 return this->begin()+InsertElt;
867 }
868
869 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
870
871 // Ensure there is enough space, and get the (maybe updated) address of
872 // Elt.
873 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
874
875 // Uninvalidate the iterator.
876 I = this->begin()+InsertElt;
877
878 // If there are more elements between the insertion point and the end of the
879 // range than there are being inserted, we can use a simple approach to
880 // insertion. Since we already reserved space, we know that this won't
881 // reallocate the vector.
882 if (size_t(this->end()-I) >= NumToInsert) {
883 T *OldEnd = this->end();
884 append(std::move_iterator<iterator>(this->end() - NumToInsert),
885 std::move_iterator<iterator>(this->end()));
886
887 // Copy the existing elements that get replaced.
888 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
889
890 // If we just moved the element we're inserting, be sure to update
891 // the reference (never happens if TakesParamByValue).
892 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
893 EltPtr += NumToInsert;
894
895 std::fill_n(I, NumToInsert, *EltPtr);
896 return I;
897 }
898
899 // Otherwise, we're inserting more elements than exist already, and we're
900 // not inserting at the end.
901
902 // Move over the elements that we're about to overwrite.
903 T *OldEnd = this->end();
904 this->set_size(this->size() + NumToInsert);
905 size_t NumOverwritten = OldEnd-I;
906 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
907
908 // If we just moved the element we're inserting, be sure to update
909 // the reference (never happens if TakesParamByValue).
910 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
911 EltPtr += NumToInsert;
912
913 // Replace the overwritten part.
914 std::fill_n(I, NumOverwritten, *EltPtr);
915
916 // Insert the non-overwritten middle part.
917 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
918 return I;
919 }
920
921 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
923 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
924 size_t InsertElt = I - this->begin();
925
926 if (I == this->end()) { // Important special case for empty vector.
927 append(From, To);
928 return this->begin()+InsertElt;
929 }
930
932 // For input iterators, we don't know the number of elements to insert.
933 size_t OldSize = this->size();
934 append(From, To);
935 I = this->begin() + InsertElt; // Uninvalidate the iterator.
936 std::rotate(I, this->begin() + OldSize, this->end());
937 return I;
938 }
939
940 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
941
942 // Check that the reserve that follows doesn't invalidate the iterators.
943 this->assertSafeToAddRange(From, To);
944
945 size_t NumToInsert = std::distance(From, To);
946
947 // Ensure there is enough space.
948 reserve(this->size() + NumToInsert);
949
950 // Uninvalidate the iterator.
951 I = this->begin()+InsertElt;
952
953 // If there are more elements between the insertion point and the end of the
954 // range than there are being inserted, we can use a simple approach to
955 // insertion. Since we already reserved space, we know that this won't
956 // reallocate the vector.
957 if (size_t(this->end()-I) >= NumToInsert) {
958 T *OldEnd = this->end();
959 append(std::move_iterator<iterator>(this->end() - NumToInsert),
960 std::move_iterator<iterator>(this->end()));
961
962 // Copy the existing elements that get replaced.
963 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
964
965 std::copy(From, To, I);
966 return I;
967 }
968
969 // Otherwise, we're inserting more elements than exist already, and we're
970 // not inserting at the end.
971
972 // Move over the elements that we're about to overwrite.
973 T *OldEnd = this->end();
974 this->set_size(this->size() + NumToInsert);
975 size_t NumOverwritten = OldEnd-I;
976 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
977
978 // Replace the overwritten part.
979 for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
980 *J = *From;
981 ++J; ++From;
982 }
983
984 // Insert the non-overwritten middle part.
985 this->uninitialized_copy(From, To, OldEnd);
986 return I;
987 }
988
989 void insert(iterator I, std::initializer_list<T> IL) {
990 insert(I, IL.begin(), IL.end());
991 }
992
993 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
994 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
995 return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
996
997 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
998 this->set_size(this->size() + 1);
999 return this->back();
1000 }
1001
1003
1005
1006 bool operator==(const SmallVectorImpl &RHS) const {
1007 if (this->size() != RHS.size()) return false;
1008 return std::equal(this->begin(), this->end(), RHS.begin());
1009 }
1010 bool operator!=(const SmallVectorImpl &RHS) const {
1011 return !(*this == RHS);
1012 }
1013
1014 bool operator<(const SmallVectorImpl &RHS) const {
1015 return std::lexicographical_compare(this->begin(), this->end(),
1016 RHS.begin(), RHS.end());
1017 }
1018 bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; }
1019 bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); }
1020 bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); }
1021};
1022
1023template <typename T>
1025 if (this == &RHS) return;
1026
1027 // We can only avoid copying elements if neither vector is small.
1028 if (!this->isSmall() && !RHS.isSmall()) {
1029 std::swap(this->BeginX, RHS.BeginX);
1030 std::swap(this->Size, RHS.Size);
1031 std::swap(this->Capacity, RHS.Capacity);
1032 return;
1033 }
1034 this->reserve(RHS.size());
1035 RHS.reserve(this->size());
1036
1037 // Swap the shared elements.
1038 size_t NumShared = this->size();
1039 if (NumShared > RHS.size()) NumShared = RHS.size();
1040 for (size_type i = 0; i != NumShared; ++i)
1041 std::swap((*this)[i], RHS[i]);
1042
1043 // Copy over the extra elts.
1044 if (this->size() > RHS.size()) {
1045 size_t EltDiff = this->size() - RHS.size();
1046 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
1047 RHS.set_size(RHS.size() + EltDiff);
1048 this->destroy_range(this->begin()+NumShared, this->end());
1049 this->set_size(NumShared);
1050 } else if (RHS.size() > this->size()) {
1051 size_t EltDiff = RHS.size() - this->size();
1052 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
1053 this->set_size(this->size() + EltDiff);
1054 this->destroy_range(RHS.begin()+NumShared, RHS.end());
1055 RHS.set_size(NumShared);
1056 }
1057}
1058
1059template <typename T>
1062 // Avoid self-assignment.
1063 if (this == &RHS) return *this;
1064
1065 // If we already have sufficient space, assign the common elements, then
1066 // destroy any excess.
1067 size_t RHSSize = RHS.size();
1068 size_t CurSize = this->size();
1069 if (CurSize >= RHSSize) {
1070 // Assign common elements.
1071 iterator NewEnd;
1072 if (RHSSize)
1073 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
1074 else
1075 NewEnd = this->begin();
1076
1077 // Destroy excess elements.
1078 this->destroy_range(NewEnd, this->end());
1079
1080 // Trim.
1081 this->set_size(RHSSize);
1082 return *this;
1083 }
1084
1085 // If we have to grow to have enough elements, destroy the current elements.
1086 // This allows us to avoid copying them during the grow.
1087 // FIXME: don't do this if they're efficiently moveable.
1088 if (this->capacity() < RHSSize) {
1089 // Destroy current elements.
1090 this->clear();
1091 CurSize = 0;
1092 this->grow(RHSSize);
1093 } else if (CurSize) {
1094 // Otherwise, use assignment for the already-constructed elements.
1095 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
1096 }
1097
1098 // Copy construct the new elements in place.
1099 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
1100 this->begin()+CurSize);
1101
1102 // Set end.
1103 this->set_size(RHSSize);
1104 return *this;
1105}
1106
1107template <typename T>
1109 // Avoid self-assignment.
1110 if (this == &RHS) return *this;
1111
1112 // If the RHS isn't small, clear this vector and then steal its buffer.
1113 if (!RHS.isSmall()) {
1114 this->assignRemote(std::move(RHS));
1115 return *this;
1116 }
1117
1118 // If we already have sufficient space, assign the common elements, then
1119 // destroy any excess.
1120 size_t RHSSize = RHS.size();
1121 size_t CurSize = this->size();
1122 if (CurSize >= RHSSize) {
1123 // Assign common elements.
1124 iterator NewEnd = this->begin();
1125 if (RHSSize)
1126 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1127
1128 // Destroy excess elements and trim the bounds.
1129 this->destroy_range(NewEnd, this->end());
1130 this->set_size(RHSSize);
1131
1132 // Clear the RHS.
1133 RHS.clear();
1134
1135 return *this;
1136 }
1137
1138 // If we have to grow to have enough elements, destroy the current elements.
1139 // This allows us to avoid copying them during the grow.
1140 // FIXME: this may not actually make any sense if we can efficiently move
1141 // elements.
1142 if (this->capacity() < RHSSize) {
1143 // Destroy current elements.
1144 this->clear();
1145 CurSize = 0;
1146 this->grow(RHSSize);
1147 } else if (CurSize) {
1148 // Otherwise, use assignment for the already-constructed elements.
1149 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin());
1150 }
1151
1152 // Move-construct the new elements in place.
1153 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
1154 this->begin()+CurSize);
1155
1156 // Set end.
1157 this->set_size(RHSSize);
1158
1159 RHS.clear();
1160 return *this;
1161}
1162
1163/// Storage for the SmallVector elements. This is specialized for the N=0 case
1164/// to avoid allocating unnecessary storage.
1165template <typename T, unsigned N>
1167 alignas(T) char InlineElts[N * sizeof(T)];
1168};
1169
1170/// We need the storage to be properly aligned even for small-size of 0 so that
1171/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
1172/// well-defined.
1173template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
1174
1175/// Forward declaration of SmallVector so that
1176/// calculateSmallVectorDefaultInlinedElements can reference
1177/// `sizeof(SmallVector<T, 0>)`.
1178template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
1179
1180/// Helper class for calculating the default number of inline elements for
1181/// `SmallVector<T>`.
1182///
1183/// This should be migrated to a constexpr function when our minimum
1184/// compiler support is enough for multi-statement constexpr functions.
1186 // Parameter controlling the default number of inlined elements
1187 // for `SmallVector<T>`.
1188 //
1189 // The default number of inlined elements ensures that
1190 // 1. There is at least one inlined element.
1191 // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
1192 // it contradicts 1.
1193 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1194
1195 // static_assert that sizeof(T) is not "too big".
1196 //
1197 // Because our policy guarantees at least one inlined element, it is possible
1198 // for an arbitrarily large inlined element to allocate an arbitrarily large
1199 // amount of inline storage. We generally consider it an antipattern for a
1200 // SmallVector to allocate an excessive amount of inline storage, so we want
1201 // to call attention to these cases and make sure that users are making an
1202 // intentional decision if they request a lot of inline storage.
1203 //
1204 // We want this assertion to trigger in pathological cases, but otherwise
1205 // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
1206 // larger than kPreferredSmallVectorSizeof (otherwise,
1207 // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
1208 // pattern seems useful in practice).
1209 //
1210 // One wrinkle is that this assertion is in theory non-portable, since
1211 // sizeof(T) is in general platform-dependent. However, we don't expect this
1212 // to be much of an issue, because most LLVM development happens on 64-bit
1213 // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
1214 // 32-bit hosts, dodging the issue. The reverse situation, where development
1215 // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
1216 // 64-bit host, is expected to be very rare.
1217 static_assert(
1218 sizeof(T) <= 256,
1219 "You are trying to use a default number of inlined elements for "
1220 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1221 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1222 "sure you really want that much inline storage.");
1223
1224 // Discount the size of the header itself when calculating the maximum inline
1225 // bytes.
1226 static constexpr size_t PreferredInlineBytes =
1228 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
1229 static constexpr size_t value =
1231};
1232
1233/// This is a 'vector' (really, a variable-sized array), optimized
1234/// for the case when the array is small. It contains some number of elements
1235/// in-place, which allows it to avoid heap allocation when the actual number of
1236/// elements is below that threshold. This allows normal "small" cases to be
1237/// fast without losing generality for large inputs.
1238///
1239/// \note
1240/// In the absence of a well-motivated choice for the number of inlined
1241/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
1242/// omitting the \p N). This will choose a default number of inlined elements
1243/// reasonable for allocation on the stack (for example, trying to keep \c
1244/// sizeof(SmallVector<T>) around 64 bytes).
1245///
1246/// \warning This does not attempt to be exception safe.
1247///
1248/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
1249template <typename T,
1252 SmallVectorStorage<T, N> {
1253public:
1255
1257 // Destroy the constructed elements in the vector.
1258 this->destroy_range(this->begin(), this->end());
1259 }
1260
1261 explicit SmallVector(size_t SizeArg) : SmallVectorImpl<T>(N) {
1262 this->resize(SizeArg);
1263 }
1264
1265 SmallVector(size_t SizeArg, const T &Value) : SmallVectorImpl<T>(N) {
1266 this->assign(SizeArg, Value);
1267 }
1268
1269 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>>
1271 this->append(S, E);
1272 }
1273
1274 template <typename RangeTy>
1276 : SmallVectorImpl<T>(N) {
1277 this->append(R.begin(), R.end());
1278 }
1279
1280 SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
1281 this->append(IL);
1282 }
1283
1284 template <typename U,
1285 typename = std::enable_if_t<std::is_convertible_v<U, T>>>
1287 this->append(A.begin(), A.end());
1288 }
1289
1291 if (!RHS.empty())
1293 }
1294
1297 return *this;
1298 }
1299
1300 // Reuse the move-assignment instantiation for trivially move-assignable
1301 // elements. Calling moveConstructFrom unconditionally would emit an
1302 // additional per-T wrapper at -O0, increasing object size.
1303 // std::is_move_assignable_v<T> is too broad: it can be a false positive for
1304 // types with an unconstrained assignment operator whose body is ill-formed.
1306 if (!RHS.empty()) {
1307 if constexpr (std::is_trivially_move_assignable_v<T>)
1308 SmallVectorImpl<T>::operator=(::std::move(RHS));
1309 else
1310 this->moveConstructFrom(::std::move(RHS));
1311 }
1312 }
1313
1315 if (!RHS.empty()) {
1316 if constexpr (std::is_trivially_move_assignable_v<T>)
1317 SmallVectorImpl<T>::operator=(::std::move(RHS));
1318 else
1319 this->moveConstructFrom(::std::move(RHS));
1320 }
1321 }
1322
1324 if (N) {
1325 SmallVectorImpl<T>::operator=(::std::move(RHS));
1326 return *this;
1327 }
1328 // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the
1329 // case.
1330 if (this == &RHS)
1331 return *this;
1332 if (RHS.empty()) {
1333 this->destroy_range(this->begin(), this->end());
1334 this->Size = 0;
1335 } else {
1336 this->assignRemote(std::move(RHS));
1337 }
1338 return *this;
1339 }
1340
1342 SmallVectorImpl<T>::operator=(::std::move(RHS));
1343 return *this;
1344 }
1345
1346 SmallVector &operator=(std::initializer_list<T> IL) {
1347 this->assign(IL);
1348 return *this;
1349 }
1350};
1351
1352template <typename T, unsigned N>
1354 return X.capacity_in_bytes();
1355}
1356
1357template <typename RangeType>
1359 std::remove_const_t<detail::ValueOfRange<RangeType>>;
1360
1361/// Given a range of type R, iterate the entire range and return a
1362/// SmallVector with elements of the vector. This is useful, for example,
1363/// when you want to iterate a range and then sort the results.
1364template <unsigned Size, typename R>
1369template <typename R>
1374
1375template <typename Out, unsigned Size, typename R>
1379
1380template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
1382}
1383
1384// Explicit instantiations
1385extern template class llvm::SmallVectorBase<uint32_t>;
1386#if SIZE_MAX > UINT32_MAX
1387extern template class llvm::SmallVectorBase<uint64_t>;
1388#endif
1389
1390// Provide DenseMapInfo for SmallVector of a type which has info.
1391template <typename T, unsigned N> struct DenseMapInfo<llvm::SmallVector<T, N>> {
1392 static unsigned getHashValue(const SmallVector<T, N> &V) {
1393 return static_cast<unsigned>(hash_combine_range(V));
1394 }
1395
1396 static bool isEqual(const SmallVector<T, N> &LHS,
1397 const SmallVector<T, N> &RHS) {
1398 return LHS == RHS;
1399 }
1400};
1401
1402} // end namespace llvm
1403
1404namespace std {
1405
1406 /// Implement std::swap in terms of SmallVector swap.
1407 template<typename T>
1408 inline void
1412
1413 /// Implement std::swap in terms of SmallVector swap.
1414 template<typename T, unsigned N>
1415 inline void
1419
1420} // end namespace std
1421
1422#endif // LLVM_ADT_SMALLVECTOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:344
#define LLVM_GSL_OWNER
LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable lifetime warnings.
Definition Compiler.h:438
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
Definition Compiler.h:354
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:343
This file defines DenseMapInfo traits for DenseMap.
#define offsetof(TYPE, MEMBER)
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
if(PassOpts->AAPipeline)
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
This is all the stuff common to all SmallVectors.
Definition SmallVector.h:57
LLVM_ABI 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 ...
LLVM_ABI 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 set_allocation_range(void *Begin, size_t N)
Set the array data pointer to Begin and capacity to N.
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
Definition SmallVector.h:68
void set_size(size_t N)
Set the array size to N, which the current array must have enough capacity for.
Definition SmallVector.h:93
size_t capacity() const
Definition SmallVector.h:84
size_t size() const
Definition SmallVector.h:83
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
Definition SmallVector.h:63
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void moveConstructFrom(SmallVectorImpl &&RHS)
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
void append(const SmallVectorImpl &RHS)
void pop_back_n(size_type NumItems)
void assign(const SmallVectorImpl &RHS)
SmallVectorImpl(const SmallVectorImpl &)=delete
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
bool operator==(const SmallVectorImpl &RHS) const
void reserve(size_type N)
typename SuperClass::reference reference
iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt)
iterator erase(const_iterator CI)
iterator insert(iterator I, ItTy From, ItTy To)
typename SuperClass::const_iterator const_iterator
void assignRemote(SmallVectorImpl &&RHS)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void resize(size_type N, ValueParamT NV)
iterator insert(iterator I, MemoryLocation &&Elt)
bool operator>(const SmallVectorImpl &RHS) const
bool operator<(const SmallVectorImpl &RHS) const
iterator erase(const_iterator CS, const_iterator CE)
bool operator!=(const SmallVectorImpl &RHS) const
void truncate(size_type N)
Like resize, but requires that N is less than size().
void assign(ItTy in_start, ItTy in_end)
void assign(std::initializer_list< T > IL)
void assign(ArrayRef< U > AR)
SmallVectorImpl(unsigned N)
void swap(SmallVectorImpl &RHS)
typename SuperClass::iterator iterator
bool operator<=(const SmallVectorImpl &RHS) const
typename SuperClass::size_type size_type
void append(std::initializer_list< T > IL)
void append(size_type NumInputs, ValueParamT Elt)
Append NumInputs copies of Elt to the end.
void resize(size_type N)
SmallVectorImpl & operator=(const SmallVectorImpl &RHS)
void insert(iterator I, std::initializer_list< T > IL)
SmallVectorImpl & operator=(SmallVectorImpl &&RHS)
typename SuperClass::ValueParamT ValueParamT
bool operator>=(const SmallVectorImpl &RHS) const
iterator insert(iterator I, const T &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 into ...
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 ...
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.
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...
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...
static ValueParamT forward_value_param(ValueParamT V)
Copy V or return a reference, depending on ValueParamT.
T & growAndEmplaceBack(ArgTypes &&... Args)
static constexpr bool TakesParamByValue
True if it's cheap enough to take parameters by value.
void growAndAssign(size_t NumElts, T Elt)
void grow(size_t MinSize=0)
Double the size of the allocated memory, guaranteeing space for at least one more element or MinSize ...
LLVM_ATTRIBUTE_NOINLINE void growAndPushBack(ValueParamT Elt)
void moveElementsForGrow(T *NewElts)
Move existing elements over to the new allocation NewElts, the middle section of grow().
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...
static T && forward_value_param(T &&V)
static void destroy_range(T *S, T *E)
T * mallocForGrow(size_t MinSize, size_t &NewCapacity)
Create a new allocation big enough for MinSize and pass back its size in NewCapacity.
static constexpr bool TakesParamByValue
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...
void takeAllocationForGrow(T *NewElts, size_t NewCapacity)
Transfer ownership of the allocation, finishing up grow().
void growAndAssign(size_t NumElts, const T &Elt)
static const T & forward_value_param(const T &V)
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...
void grow(size_t MinSize=0)
Grow the allocated memory (without initializing new elements), doubling the size of the allocated mem...
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...
SmallVectorTemplateBase(size_t SizeArg)
T & growAndEmplaceBack(ArgTypes &&... Args)
void push_back(const T &Elt)
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it.
const_iterator end() 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...
SmallVectorTemplateCommon(size_t SizeArg)
const_reference operator[](size_type idx) const
void resetToSmall()
Put this vector in a state of being small.
bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Return true unless Elt will be invalidated by resizing the vector to NewSize.
std::reverse_iterator< const_iterator > const_reverse_iterator
pointer data()
Return a pointer to the vector's buffer, even if empty().
bool isReferenceToRange(const void *V, const void *First, const void *Last) const
Return true if V is an internal reference to the given range.
void grow_pod(size_t MinSize, size_t TSize)
const_reverse_iterator rbegin() const
const_iterator begin() const
reference operator[](size_type idx)
size_type size_in_bytes() const
bool isReferenceToStorage(const void *V) const
Return true if V is an internal reference to this vector.
const_reference back() const
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.
const_reference front() 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.
void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Check whether Elt will be invalidated by resizing the vector to NewSize.
void assertSafeToAddRange(ItTy From, ItTy To)
Check whether any part of the range will be invalidated by growing.
std::reverse_iterator< iterator > reverse_iterator
void assertSafeToReferenceAfterClear(ItTy From, ItTy To)
Check whether any part of the range will be invalidated by clearing.
const_reverse_iterator rend() const
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
void * getFirstEl() const
Find the address of the first element.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SmallVector(std::initializer_list< T > IL)
SmallVector(SmallVectorImpl< T > &&RHS)
SmallVector(ArrayRef< U > A)
SmallVector & operator=(const SmallVector &RHS)
SmallVector(const iterator_range< RangeTy > &R)
SmallVector & operator=(std::initializer_list< T > IL)
SmallVector(ItTy S, ItTy E)
SmallVector(size_t SizeArg)
SmallVector(SmallVector &&RHS)
SmallVector & operator=(SmallVector &&RHS)
SmallVector(size_t SizeArg, const T &Value)
SmallVector(const SmallVector &RHS)
SmallVector & operator=(SmallVectorImpl< T > &&RHS)
LLVM Value Representation.
Definition Value.h:75
A range adaptor for a pair of iterators.
This is an optimization pass for GlobalISel generic memory operations.
std::remove_const_t< detail::ValueOfRange< RangeType > > ValueTypeFromRangeType
constexpr auto adl_begin(RangeT &&range) -> decltype(adl_detail::begin_impl(std::forward< RangeT >(range)))
Returns the begin iterator to range using std::begin and function found through Argument-Dependent Lo...
Definition ADL.h:78
BitVector::size_type capacity_in_bytes(const BitVector &X)
Definition BitVector.h:863
std::enable_if_t< HasIteratorTag< Iterator, std::input_iterator_tag >::value > EnableIfConvertibleToInputIterator
Definition SmallVector.h:46
std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, Tag > HasIteratorTag
Definition SmallVector.h:42
constexpr auto adl_end(RangeT &&range) -> decltype(adl_detail::end_impl(std::forward< RangeT >(range)))
Returns the end iterator to range using std::end and functions found through Argument-Dependent Looku...
Definition ADL.h:86
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...
std::conditional_t< sizeof(T)< 4 &&sizeof(void *) >=8, uint64_t, uint32_t > SmallVectorSizeType
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
SmallVector< Out, Size > to_vector_of(R &&Range)
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition Hashing.h:285
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
Helper class for calculating the default number of inline elements for SmallVector<T>.
static bool isEqual(const SmallVector< T, N > &LHS, const SmallVector< T, N > &RHS)
static unsigned getHashValue(const SmallVector< T, N > &V)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Figure out the offset of the first element.
char Base[sizeof(SmallVectorBase< SmallVectorSizeType< T > >)]
Storage for the SmallVector elements.
char InlineElts[N *sizeof(T)]