Go to the documentation of this file.
80 #ifndef LLVM_ADT_SEQUENCE_H
81 #define LLVM_ADT_SEQUENCE_H
86 #include <type_traits>
120 (TopT < TopU && Value >
static_cast<U
>(TopT)));
129 template <
typename Integral,
typename std::enable_if_t<
130 std::is_integral<Integral>::value,
bool> = 0>
132 if (!canTypeFitValue<intmax_t>(FromValue))
135 Result.Value =
static_cast<intmax_t
>(FromValue);
140 template <
typename Enum,
141 typename std::enable_if_t<std::is_enum<Enum>::value,
bool> = 0>
144 return from<type>(
static_cast<type>(FromValue));
166 template <
typename Integral,
typename std::enable_if_t<
167 std::is_integral<Integral>::value,
bool> = 0>
168 Integral
to()
const {
169 if (!canTypeFitValue<Integral>(
Value))
171 return static_cast<Integral
>(
Value);
176 template <
typename Enum,
177 typename std::enable_if_t<std::is_enum<Enum>::value,
bool> = 0>
180 return Enum(to<type>());
184 static void assertOutOfBounds() {
assert(
false &&
"Out of bounds"); }
221 const auto Copy = *
this;
226 const auto Copy = *
this;
241 return IsReverse ?
O.SI - SI : SI -
O.SI;
247 static intmax_t getOffset(intmax_t Offset) {
248 return IsReverse ? -Offset : Offset;
251 CheckedInt add(intmax_t Offset)
const {
return SI + getOffset(Offset); }
253 void offset(intmax_t Offset) { SI = SI + getOffset(Offset); }
275 : BeginValue(Begin), PastEndValue(End) {
276 assert(Begin <= End &&
"Begin must be less or equal to End.");
281 size_t size()
const {
return PastEndValue - BeginValue; }
282 bool empty()
const {
return BeginValue == PastEndValue; }
291 static_assert(std::is_integral<T>::value || std::is_enum<T>::value,
292 "T must be an integral or enum type");
293 static_assert(std::is_same<T, std::remove_cv_t<T>>::value,
294 "T must not be const nor volatile");
304 template <typename T, typename = std::enable_if_t<std::is_integral<T>::value &&
305 !std::is_enum<T>::value>>
306 auto seq(T Begin, T End) {
314 template <typename T, typename = std::enable_if_t<std::is_integral<T>::value &&
315 !std::is_enum<T>::value>>
326 template <
typename EnumT,
327 typename = std::enable_if_t<std::is_enum<EnumT>::value>>
330 "Enum type is not marked as iterable.");
341 template <
typename EnumT,
342 typename = std::enable_if_t<std::is_enum<EnumT>::value>>
353 template <
typename EnumT,
354 typename = std::enable_if_t<std::is_enum<EnumT>::value>>
357 "Enum type is not marked as iterable.");
368 template <
typename EnumT,
369 typename = std::enable_if_t<std::is_enum<EnumT>::value>>
377 #endif // LLVM_ADT_SEQUENCE_H
void operator-=(intmax_t Offset)
auto enum_seq_inclusive(EnumT Begin, EnumT End)
Iterate over an enum type from Begin to End inclusive.
SafeIntIterator operator+(intmax_t Offset) const
This is an optimization pass for GlobalISel generic memory operations.
bool operator==(const SafeIntIterator &O) const
bool operator>(const SafeIntIterator &O) const
SafeIntIterator operator--(int)
bool operator>=(const SafeIntIterator &O) const
std::random_access_iterator_tag iterator_category
static CheckedInt from(Enum FromValue)
reverse_iterator const_reverse_iterator
const T & const_reference
CheckedInt operator+(intmax_t Offset) const
friend struct SafeIntIterator
auto seq_inclusive(T Begin, T End)
Iterate over an integral type from Begin to End inclusive.
detail::SafeIntIterator< value_type, false > iterator
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
bool operator<(const SafeIntIterator &O) const
value_type operator[](intmax_t Offset) const
intmax_t operator-(const SafeIntIterator &O) const
SafeIntIterator operator++(int)
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
std::enable_if_t< std::is_signed< T >::value, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
value_type operator*() const
bool operator!=(const SafeIntIterator &O) const
force_iteration_on_noniterable_enum_t()=default
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
intmax_t operator-(CheckedInt Other) const
StandardInstrumentations SI(Debug, VerifyEach)
bool operator==(const CheckedInt &O) const
SafeIntIterator operator-(intmax_t Offset) const
static constexpr bool is_iterable
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
auto enum_seq(EnumT Begin, EnumT End)
Iterate over an enum type from Begin up to - but not including - End.
void operator+=(intmax_t Offset)
std::enable_if_t< std::is_signed< T >::value, T > SubOverflow(T X, T Y, T &Result)
Subtract two signed integers, computing the two's complement truncated result, returning true if an o...
constexpr force_iteration_on_noniterable_enum_t force_iteration_on_noniterable_enum
detail::SafeIntIterator< value_type, true > reverse_iterator
SafeIntIterator(const SafeIntIterator< T, !IsReverse > &O)
iota_range(T Begin, T End, bool Inclusive)
bool operator<=(const SafeIntIterator &O) const
LLVM Value Representation.
bool canTypeFitValue(const U Value)
static CheckedInt from(Integral FromValue)
bool operator!=(const CheckedInt &O) const
Optional< std::vector< StOtherPiece > > Other