LLVM 22.0.0git
DynamicAPInt.h
Go to the documentation of this file.
1//===- DynamicAPInt.h - DynamicAPInt Class ----------------------*- 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// This is a simple class to represent arbitrary precision signed integers.
10// Unlike APInt, one does not have to specify a fixed maximum size, and the
11// integer can take on any arbitrary values. This is optimized for small-values
12// by providing fast-paths for the cases when the value stored fits in 64-bits.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_ADT_DYNAMICAPINT_H
17#define LLVM_ADT_DYNAMICAPINT_H
18
19#include "llvm/ADT/APInt.h"
23#include <numeric>
24
25namespace llvm {
26
27class raw_ostream;
28
29/// This class provides support for dynamic arbitrary-precision arithmetic.
30///
31/// Unlike APInt, this extends the precision as necessary to prevent overflows
32/// and supports operations between objects with differing internal precisions.
33///
34/// This is optimized for small-values by providing fast-paths for the cases
35/// when the value stored fits in 64-bits. We annotate all fastpaths by using
36/// the LLVM_LIKELY/LLVM_UNLIKELY annotations. Removing these would result in
37/// a 1.2x performance slowdown.
38///
39/// We always_inline all operations; removing these results in a 1.5x
40/// performance slowdown.
41///
42/// When isLarge returns true, a SlowMPInt is held in the union. If isSmall
43/// returns true, the int64_t is held. We don't have a separate field for
44/// indicating this, and instead "steal" memory from ValLarge when it is not in
45/// use because we know that the memory layout of APInt is such that BitWidth
46/// doesn't overlap with ValSmall (see static_assert_layout). Using std::variant
47/// instead would lead to significantly worse performance.
49 union {
50 int64_t ValSmall;
52 };
53
54 LLVM_ATTRIBUTE_ALWAYS_INLINE void initSmall(int64_t O) {
55 if (LLVM_UNLIKELY(isLarge()))
56 ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();
57 ValSmall = O;
58 ValLarge.Val.BitWidth = 0;
59 }
61 initLarge(const detail::SlowDynamicAPInt &O) {
62 if (LLVM_LIKELY(isSmall())) {
63 // The data in memory could be in an arbitrary state, not necessarily
64 // corresponding to any valid state of ValLarge; we cannot call any member
65 // functions, e.g. the assignment operator on it, as they may access the
66 // invalid internal state. We instead construct a new object using
67 // placement new.
68 new (&ValLarge) detail::SlowDynamicAPInt(O);
69 } else {
70 // In this case, we need to use the assignment operator, because if we use
71 // placement-new as above we would lose track of allocated memory
72 // and leak it.
73 ValLarge = O;
74 }
75 }
76
78 const detail::SlowDynamicAPInt &Val)
79 : ValLarge(Val) {}
80 LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr bool isSmall() const {
81 return ValLarge.Val.BitWidth == 0;
82 }
83 LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr bool isLarge() const {
84 return !isSmall();
85 }
86 /// Get the stored value. For getSmall/Large,
87 /// the stored value should be small/large.
88 LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t getSmall() const {
89 assert(isSmall() &&
90 "getSmall should only be called when the value stored is small!");
91 return ValSmall;
92 }
93 LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t &getSmall() {
94 assert(isSmall() &&
95 "getSmall should only be called when the value stored is small!");
96 return ValSmall;
97 }
98 LLVM_ATTRIBUTE_ALWAYS_INLINE const detail::SlowDynamicAPInt &
99 getLarge() const {
100 assert(isLarge() &&
101 "getLarge should only be called when the value stored is large!");
102 return ValLarge;
103 }
104 LLVM_ATTRIBUTE_ALWAYS_INLINE detail::SlowDynamicAPInt &getLarge() {
105 assert(isLarge() &&
106 "getLarge should only be called when the value stored is large!");
107 return ValLarge;
108 }
109 explicit operator detail::SlowDynamicAPInt() const {
110 if (isSmall())
111 return detail::SlowDynamicAPInt(getSmall());
112 return getLarge();
113 }
114
115public:
117 : ValSmall(Val) {
118 ValLarge.Val.BitWidth = 0;
119 }
121 if (Val.getBitWidth() <= 64) {
122 ValSmall = Val.getSExtValue();
123 ValLarge.Val.BitWidth = 0;
124 } else {
126 }
127 }
130 if (LLVM_UNLIKELY(isLarge()))
131 ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();
132 }
134 : ValSmall(O.ValSmall) {
135 ValLarge.Val.BitWidth = 0;
136 if (LLVM_UNLIKELY(O.isLarge()))
137 initLarge(O.ValLarge);
138 }
140 if (LLVM_LIKELY(O.isSmall())) {
141 initSmall(O.ValSmall);
142 return *this;
143 }
144 initLarge(O.ValLarge);
145 return *this;
146 }
148 initSmall(X);
149 return *this;
150 }
151 LLVM_ATTRIBUTE_ALWAYS_INLINE explicit operator int64_t() const {
152 if (isSmall())
153 return getSmall();
154 return static_cast<int64_t>(getLarge());
155 }
156
157 bool operator==(const DynamicAPInt &O) const;
158 bool operator!=(const DynamicAPInt &O) const;
159 bool operator>(const DynamicAPInt &O) const;
160 bool operator<(const DynamicAPInt &O) const;
161 bool operator<=(const DynamicAPInt &O) const;
162 bool operator>=(const DynamicAPInt &O) const;
163 DynamicAPInt operator+(const DynamicAPInt &O) const;
164 DynamicAPInt operator-(const DynamicAPInt &O) const;
165 DynamicAPInt operator*(const DynamicAPInt &O) const;
166 DynamicAPInt operator/(const DynamicAPInt &O) const;
167 DynamicAPInt operator%(const DynamicAPInt &O) const;
173 DynamicAPInt operator-() const;
176
177 // Divide by a number that is known to be positive.
178 // This is slightly more efficient because it saves an overflow check.
181
182 friend DynamicAPInt abs(const DynamicAPInt &X);
183 friend DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS);
185 const DynamicAPInt &RHS);
186 // The operands must be non-negative for gcd.
187 friend DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B);
188 friend DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B);
189 friend DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS);
190
191 /// ---------------------------------------------------------------------------
192 /// Convenience operator overloads for int64_t.
193 /// ---------------------------------------------------------------------------
194 friend DynamicAPInt &operator+=(DynamicAPInt &A, int64_t B);
195 friend DynamicAPInt &operator-=(DynamicAPInt &A, int64_t B);
196 friend DynamicAPInt &operator*=(DynamicAPInt &A, int64_t B);
197 friend DynamicAPInt &operator/=(DynamicAPInt &A, int64_t B);
198 friend DynamicAPInt &operator%=(DynamicAPInt &A, int64_t B);
199
200 friend bool operator==(const DynamicAPInt &A, int64_t B);
201 friend bool operator!=(const DynamicAPInt &A, int64_t B);
202 friend bool operator>(const DynamicAPInt &A, int64_t B);
203 friend bool operator<(const DynamicAPInt &A, int64_t B);
204 friend bool operator<=(const DynamicAPInt &A, int64_t B);
205 friend bool operator>=(const DynamicAPInt &A, int64_t B);
206 friend DynamicAPInt operator+(const DynamicAPInt &A, int64_t B);
207 friend DynamicAPInt operator-(const DynamicAPInt &A, int64_t B);
208 friend DynamicAPInt operator*(const DynamicAPInt &A, int64_t B);
209 friend DynamicAPInt operator/(const DynamicAPInt &A, int64_t B);
210 friend DynamicAPInt operator%(const DynamicAPInt &A, int64_t B);
211
212 friend bool operator==(int64_t A, const DynamicAPInt &B);
213 friend bool operator!=(int64_t A, const DynamicAPInt &B);
214 friend bool operator>(int64_t A, const DynamicAPInt &B);
215 friend bool operator<(int64_t A, const DynamicAPInt &B);
216 friend bool operator<=(int64_t A, const DynamicAPInt &B);
217 friend bool operator>=(int64_t A, const DynamicAPInt &B);
218 friend DynamicAPInt operator+(int64_t A, const DynamicAPInt &B);
219 friend DynamicAPInt operator-(int64_t A, const DynamicAPInt &B);
220 friend DynamicAPInt operator*(int64_t A, const DynamicAPInt &B);
221 friend DynamicAPInt operator/(int64_t A, const DynamicAPInt &B);
222 friend DynamicAPInt operator%(int64_t A, const DynamicAPInt &B);
223
224 LLVM_ABI friend hash_code hash_value(const DynamicAPInt &x); // NOLINT
225
226 LLVM_ABI void static_assert_layout(); // NOLINT
227
229
230#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
231 LLVM_DUMP_METHOD void dump() const;
232#endif
233};
234
236 X.print(OS);
237 return OS;
238}
239
240/// Redeclarations of friend declaration above to
241/// make it discoverable by lookups.
242LLVM_ABI hash_code hash_value(const DynamicAPInt &X); // NOLINT
243
244/// This just calls through to the operator int64_t, but it's useful when a
245/// function pointer is required. (Although this is marked inline, it is still
246/// possible to obtain and use a function pointer to this.)
247static inline int64_t int64fromDynamicAPInt(const DynamicAPInt &X) {
248 return int64_t(X);
249}
251 return DynamicAPInt(X);
252}
253
254// The RHS is always expected to be positive, and the result
255/// is always non-negative.
256LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS,
257 const DynamicAPInt &RHS);
258
259/// We define the operations here in the header to facilitate inlining.
260
261/// ---------------------------------------------------------------------------
262/// Comparison operators.
263/// ---------------------------------------------------------------------------
266 if (LLVM_LIKELY(isSmall() && O.isSmall()))
267 return getSmall() == O.getSmall();
269}
272 if (LLVM_LIKELY(isSmall() && O.isSmall()))
273 return getSmall() != O.getSmall();
275}
278 if (LLVM_LIKELY(isSmall() && O.isSmall()))
279 return getSmall() > O.getSmall();
281}
284 if (LLVM_LIKELY(isSmall() && O.isSmall()))
285 return getSmall() < O.getSmall();
287}
290 if (LLVM_LIKELY(isSmall() && O.isSmall()))
291 return getSmall() <= O.getSmall();
293}
296 if (LLVM_LIKELY(isSmall() && O.isSmall()))
297 return getSmall() >= O.getSmall();
299}
300
301/// ---------------------------------------------------------------------------
302/// Arithmetic operators.
303/// ---------------------------------------------------------------------------
304
307 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
308 DynamicAPInt Result;
309 bool Overflow = AddOverflow(getSmall(), O.getSmall(), Result.getSmall());
310 if (LLVM_LIKELY(!Overflow))
311 return Result;
314 }
317}
320 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
321 DynamicAPInt Result;
322 bool Overflow = SubOverflow(getSmall(), O.getSmall(), Result.getSmall());
323 if (LLVM_LIKELY(!Overflow))
324 return Result;
327 }
330}
333 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
334 DynamicAPInt Result;
335 bool Overflow = MulOverflow(getSmall(), O.getSmall(), Result.getSmall());
336 if (LLVM_LIKELY(!Overflow))
337 return Result;
340 }
343}
344
345// Division overflows only occur when negating the minimal possible value.
348 assert(O > 0);
349 if (LLVM_LIKELY(isSmall() && O.isSmall()))
350 return DynamicAPInt(getSmall() / O.getSmall());
353}
354
357 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
358 // Division overflows only occur when negating the minimal possible value.
359 if (LLVM_UNLIKELY(divideSignedWouldOverflow(getSmall(), O.getSmall())))
360 return -*this;
361 return DynamicAPInt(getSmall() / O.getSmall());
362 }
365}
366
368 return DynamicAPInt(X >= 0 ? X : -X);
369}
370// Division overflows only occur when negating the minimal possible value.
372 const DynamicAPInt &RHS) {
373 if (LLVM_LIKELY(LHS.isSmall() && RHS.isSmall())) {
374 if (LLVM_UNLIKELY(
375 divideSignedWouldOverflow(LHS.getSmall(), RHS.getSmall())))
376 return -LHS;
377 return DynamicAPInt(divideCeilSigned(LHS.getSmall(), RHS.getSmall()));
378 }
379 return DynamicAPInt(
381}
383 const DynamicAPInt &RHS) {
384 if (LLVM_LIKELY(LHS.isSmall() && RHS.isSmall())) {
385 if (LLVM_UNLIKELY(
386 divideSignedWouldOverflow(LHS.getSmall(), RHS.getSmall())))
387 return -LHS;
388 return DynamicAPInt(divideFloorSigned(LHS.getSmall(), RHS.getSmall()));
389 }
390 return DynamicAPInt(
392}
393// The RHS is always expected to be positive, and the result
394/// is always non-negative.
396 const DynamicAPInt &RHS) {
397 if (LLVM_LIKELY(LHS.isSmall() && RHS.isSmall()))
398 return DynamicAPInt(mod(LHS.getSmall(), RHS.getSmall()));
399 return DynamicAPInt(
401}
402
404 const DynamicAPInt &B) {
405 assert(A >= 0 && B >= 0 && "operands must be non-negative!");
406 if (LLVM_LIKELY(A.isSmall() && B.isSmall()))
407 return DynamicAPInt(std::gcd(A.getSmall(), B.getSmall()));
408 return DynamicAPInt(
410}
411
412/// Returns the least common multiple of A and B.
414 const DynamicAPInt &B) {
415 DynamicAPInt X = abs(A);
416 DynamicAPInt Y = abs(B);
417 return (X * Y) / gcd(X, Y);
418}
419
420/// This operation cannot overflow.
423 if (LLVM_LIKELY(isSmall() && O.isSmall()))
424 return DynamicAPInt(getSmall() % O.getSmall());
427}
428
430 if (LLVM_LIKELY(isSmall())) {
431 if (LLVM_LIKELY(getSmall() != std::numeric_limits<int64_t>::min()))
432 return DynamicAPInt(-getSmall());
434 }
436}
437
438/// ---------------------------------------------------------------------------
439/// Assignment operators, preincrement, predecrement.
440/// ---------------------------------------------------------------------------
443 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
444 int64_t Result = getSmall();
445 bool Overflow = AddOverflow(getSmall(), O.getSmall(), Result);
446 if (LLVM_LIKELY(!Overflow)) {
447 getSmall() = Result;
448 return *this;
449 }
450 // Note: this return is not strictly required but
451 // removing it leads to a performance regression.
452 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) +
454 }
455 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) +
457}
460 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
461 int64_t Result = getSmall();
462 bool Overflow = SubOverflow(getSmall(), O.getSmall(), Result);
463 if (LLVM_LIKELY(!Overflow)) {
464 getSmall() = Result;
465 return *this;
466 }
467 // Note: this return is not strictly required but
468 // removing it leads to a performance regression.
469 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) -
471 }
472 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) -
474}
477 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
478 int64_t Result = getSmall();
479 bool Overflow = MulOverflow(getSmall(), O.getSmall(), Result);
480 if (LLVM_LIKELY(!Overflow)) {
481 getSmall() = Result;
482 return *this;
483 }
484 // Note: this return is not strictly required but
485 // removing it leads to a performance regression.
486 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) *
488 }
489 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) *
491}
494 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
495 // Division overflows only occur when negating the minimal possible value.
496 if (LLVM_UNLIKELY(divideSignedWouldOverflow(getSmall(), O.getSmall())))
497 return *this = -*this;
498 getSmall() /= O.getSmall();
499 return *this;
500 }
501 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) /
503}
504
505// Division overflows only occur when the divisor is -1.
508 assert(O > 0);
509 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
510 getSmall() /= O.getSmall();
511 return *this;
512 }
513 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) /
515}
516
519 return *this = *this % O;
520}
522 return *this += 1;
523}
525 return *this -= 1;
526}
527
528/// ----------------------------------------------------------------------------
529/// Convenience operator overloads for int64_t.
530/// ----------------------------------------------------------------------------
532 int64_t B) {
533 return A = A + B;
534}
536 int64_t B) {
537 return A = A - B;
538}
540 int64_t B) {
541 return A = A * B;
542}
544 int64_t B) {
545 return A = A / B;
546}
548 int64_t B) {
549 return A = A % B;
550}
552 int64_t B) {
553 return A + DynamicAPInt(B);
554}
556 int64_t B) {
557 return A - DynamicAPInt(B);
558}
560 int64_t B) {
561 return A * DynamicAPInt(B);
562}
564 int64_t B) {
565 return A / DynamicAPInt(B);
566}
568 int64_t B) {
569 return A % DynamicAPInt(B);
570}
572 const DynamicAPInt &B) {
573 return DynamicAPInt(A) + B;
574}
576 const DynamicAPInt &B) {
577 return DynamicAPInt(A) - B;
578}
580 const DynamicAPInt &B) {
581 return DynamicAPInt(A) * B;
582}
584 const DynamicAPInt &B) {
585 return DynamicAPInt(A) / B;
586}
588 const DynamicAPInt &B) {
589 return DynamicAPInt(A) % B;
590}
591
592/// We provide special implementations of the comparison operators rather than
593/// calling through as above, as this would result in a 1.2x slowdown.
595 if (LLVM_LIKELY(A.isSmall()))
596 return A.getSmall() == B;
597 return A.getLarge() == B;
598}
600 if (LLVM_LIKELY(A.isSmall()))
601 return A.getSmall() != B;
602 return A.getLarge() != B;
603}
605 if (LLVM_LIKELY(A.isSmall()))
606 return A.getSmall() > B;
607 return A.getLarge() > B;
608}
610 if (LLVM_LIKELY(A.isSmall()))
611 return A.getSmall() < B;
612 return A.getLarge() < B;
613}
615 if (LLVM_LIKELY(A.isSmall()))
616 return A.getSmall() <= B;
617 return A.getLarge() <= B;
618}
620 if (LLVM_LIKELY(A.isSmall()))
621 return A.getSmall() >= B;
622 return A.getLarge() >= B;
623}
625 if (LLVM_LIKELY(B.isSmall()))
626 return A == B.getSmall();
627 return A == B.getLarge();
628}
630 if (LLVM_LIKELY(B.isSmall()))
631 return A != B.getSmall();
632 return A != B.getLarge();
633}
635 if (LLVM_LIKELY(B.isSmall()))
636 return A > B.getSmall();
637 return A > B.getLarge();
638}
640 if (LLVM_LIKELY(B.isSmall()))
641 return A < B.getSmall();
642 return A < B.getLarge();
643}
645 if (LLVM_LIKELY(B.isSmall()))
646 return A <= B.getSmall();
647 return A <= B.getLarge();
648}
650 if (LLVM_LIKELY(B.isSmall()))
651 return A >= B.getSmall();
652 return A >= B.getLarge();
653}
654} // namespace llvm
655
656#endif // LLVM_ADT_DYNAMICAPINT_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_UNLIKELY(EXPR)
Definition: Compiler.h:336
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
Definition: Compiler.h:356
#define LLVM_ABI
Definition: Compiler.h:213
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:638
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:335
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
raw_pwrite_stream & OS
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1488
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1562
This class provides support for dynamic arbitrary-precision arithmetic.
Definition: DynamicAPInt.h:48
friend DynamicAPInt & operator%=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:547
LLVM_ABI raw_ostream & print(raw_ostream &OS) const
friend bool operator>=(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:619
friend bool operator>(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:604
friend DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:371
friend bool operator!=(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:599
DynamicAPInt & operator--()
Definition: DynamicAPInt.h:524
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(const DynamicAPInt &O)
Definition: DynamicAPInt.h:139
friend DynamicAPInt abs(const DynamicAPInt &X)
Definition: DynamicAPInt.h:367
friend DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:403
friend DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
Definition: DynamicAPInt.h:413
friend DynamicAPInt operator+(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:551
friend DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:531
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt()
Definition: DynamicAPInt.h:128
friend DynamicAPInt operator/(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:563
friend DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:539
friend DynamicAPInt operator%(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:567
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(int X)
Definition: DynamicAPInt.h:147
detail::SlowDynamicAPInt ValLarge
Definition: DynamicAPInt.h:51
friend bool operator<(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:609
LLVM_ABI void static_assert_layout()
DynamicAPInt divByPositive(const DynamicAPInt &O) const
Definition: DynamicAPInt.h:347
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(const DynamicAPInt &O)
Definition: DynamicAPInt.h:133
friend DynamicAPInt & operator/=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:543
LLVM_ABI friend hash_code hash_value(const DynamicAPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
DynamicAPInt operator-() const
Definition: DynamicAPInt.h:429
LLVM_DUMP_METHOD void dump() const
DynamicAPInt & operator++()
Definition: DynamicAPInt.h:521
friend bool operator<=(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:614
friend DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
Definition: DynamicAPInt.h:395
friend bool operator==(const DynamicAPInt &A, int64_t B)
We provide special implementations of the comparison operators rather than calling through as above,...
Definition: DynamicAPInt.h:594
LLVM_ATTRIBUTE_ALWAYS_INLINE ~DynamicAPInt()
Definition: DynamicAPInt.h:129
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(const APInt &Val)
Definition: DynamicAPInt.h:120
friend DynamicAPInt floorDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:382
friend DynamicAPInt operator*(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:559
friend DynamicAPInt & operator-=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:535
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(int64_t Val)
Definition: DynamicAPInt.h:116
DynamicAPInt & divByPositiveInPlace(const DynamicAPInt &O)
Definition: DynamicAPInt.h:507
A simple class providing dynamic arbitrary-precision arithmetic.
An opaque object representing a hash code.
Definition: Hashing.h:76
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:362
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:403
std::enable_if_t< std::is_signed_v< T >, T > MulOverflow(T X, T Y, T &Result)
Multiply two signed integers, computing the two's complement truncated result, returning true if an o...
Definition: MathExtras.h:758
constexpr bool divideSignedWouldOverflow(U Numerator, V Denominator)
Definition: MathExtras.h:415
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
Definition: DynamicAPInt.h:395
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:137
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2235
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1563
constexpr T divideFloorSigned(U Numerator, V Denominator)
Returns the integer floor(Numerator / Denominator).
Definition: MathExtras.h:438
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2113
bool operator>=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:361
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:531
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator-=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:535
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt floorDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:382
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt operator%(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:567
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:539
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator/=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:543
bool operator>(int64_t V1, const APSInt &V2)
Definition: APSInt.h:363
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:371
static int64_t int64fromDynamicAPInt(const DynamicAPInt &X)
This just calls through to the operator int64_t, but it's useful when a function pointer is required.
Definition: DynamicAPInt.h:247
constexpr T divideCeilSigned(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition: MathExtras.h:422
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:312
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
Definition: DynamicAPInt.h:413
APInt operator-(APInt)
Definition: APInt.h:2188
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt dynamicAPIntFromInt64(int64_t X)
Definition: DynamicAPInt.h:250
std::enable_if_t< std::is_signed_v< T >, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
Definition: MathExtras.h:706
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2193
std::enable_if_t< std::is_signed_v< T >, T > SubOverflow(T X, T Y, T &Result)
Subtract two signed integers, computing the two's complement truncated result, returning true if an o...
Definition: MathExtras.h:732
bool operator<=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:360
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator%=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:547
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt operator/(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:563