LLVM 20.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
21#include <numeric>
22
23namespace llvm {
24
25class raw_ostream;
26
27/// This class provides support for dynamic arbitrary-precision arithmetic.
28///
29/// Unlike APInt, this extends the precision as necessary to prevent overflows
30/// and supports operations between objects with differing internal precisions.
31///
32/// This is optimized for small-values by providing fast-paths for the cases
33/// when the value stored fits in 64-bits. We annotate all fastpaths by using
34/// the LLVM_LIKELY/LLVM_UNLIKELY annotations. Removing these would result in
35/// a 1.2x performance slowdown.
36///
37/// We always_inline all operations; removing these results in a 1.5x
38/// performance slowdown.
39///
40/// When isLarge returns true, a SlowMPInt is held in the union. If isSmall
41/// returns true, the int64_t is held. We don't have a separate field for
42/// indicating this, and instead "steal" memory from ValLarge when it is not in
43/// use because we know that the memory layout of APInt is such that BitWidth
44/// doesn't overlap with ValSmall (see static_assert_layout). Using std::variant
45/// instead would lead to significantly worse performance.
47 union {
48 int64_t ValSmall;
50 };
51
52 LLVM_ATTRIBUTE_ALWAYS_INLINE void initSmall(int64_t O) {
53 if (LLVM_UNLIKELY(isLarge()))
54 ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();
55 ValSmall = O;
56 ValLarge.Val.BitWidth = 0;
57 }
59 initLarge(const detail::SlowDynamicAPInt &O) {
60 if (LLVM_LIKELY(isSmall())) {
61 // The data in memory could be in an arbitrary state, not necessarily
62 // corresponding to any valid state of ValLarge; we cannot call any member
63 // functions, e.g. the assignment operator on it, as they may access the
64 // invalid internal state. We instead construct a new object using
65 // placement new.
66 new (&ValLarge) detail::SlowDynamicAPInt(O);
67 } else {
68 // In this case, we need to use the assignment operator, because if we use
69 // placement-new as above we would lose track of allocated memory
70 // and leak it.
71 ValLarge = O;
72 }
73 }
74
76 const detail::SlowDynamicAPInt &Val)
77 : ValLarge(Val) {}
78 LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr bool isSmall() const {
79 return ValLarge.Val.BitWidth == 0;
80 }
81 LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr bool isLarge() const {
82 return !isSmall();
83 }
84 /// Get the stored value. For getSmall/Large,
85 /// the stored value should be small/large.
86 LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t getSmall() const {
87 assert(isSmall() &&
88 "getSmall should only be called when the value stored is small!");
89 return ValSmall;
90 }
91 LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t &getSmall() {
92 assert(isSmall() &&
93 "getSmall should only be called when the value stored is small!");
94 return ValSmall;
95 }
96 LLVM_ATTRIBUTE_ALWAYS_INLINE const detail::SlowDynamicAPInt &
97 getLarge() const {
98 assert(isLarge() &&
99 "getLarge should only be called when the value stored is large!");
100 return ValLarge;
101 }
102 LLVM_ATTRIBUTE_ALWAYS_INLINE detail::SlowDynamicAPInt &getLarge() {
103 assert(isLarge() &&
104 "getLarge should only be called when the value stored is large!");
105 return ValLarge;
106 }
107 explicit operator detail::SlowDynamicAPInt() const {
108 if (isSmall())
109 return detail::SlowDynamicAPInt(getSmall());
110 return getLarge();
111 }
112
113public:
115 : ValSmall(Val) {
116 ValLarge.Val.BitWidth = 0;
117 }
120 if (LLVM_UNLIKELY(isLarge()))
121 ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();
122 }
124 : ValSmall(O.ValSmall) {
125 ValLarge.Val.BitWidth = 0;
126 if (LLVM_UNLIKELY(O.isLarge()))
127 initLarge(O.ValLarge);
128 }
130 if (LLVM_LIKELY(O.isSmall())) {
131 initSmall(O.ValSmall);
132 return *this;
133 }
134 initLarge(O.ValLarge);
135 return *this;
136 }
138 initSmall(X);
139 return *this;
140 }
141 LLVM_ATTRIBUTE_ALWAYS_INLINE explicit operator int64_t() const {
142 if (isSmall())
143 return getSmall();
144 return static_cast<int64_t>(getLarge());
145 }
146
147 bool operator==(const DynamicAPInt &O) const;
148 bool operator!=(const DynamicAPInt &O) const;
149 bool operator>(const DynamicAPInt &O) const;
150 bool operator<(const DynamicAPInt &O) const;
151 bool operator<=(const DynamicAPInt &O) const;
152 bool operator>=(const DynamicAPInt &O) const;
153 DynamicAPInt operator+(const DynamicAPInt &O) const;
154 DynamicAPInt operator-(const DynamicAPInt &O) const;
155 DynamicAPInt operator*(const DynamicAPInt &O) const;
156 DynamicAPInt operator/(const DynamicAPInt &O) const;
157 DynamicAPInt operator%(const DynamicAPInt &O) const;
163 DynamicAPInt operator-() const;
166
167 // Divide by a number that is known to be positive.
168 // This is slightly more efficient because it saves an overflow check.
171
172 friend DynamicAPInt abs(const DynamicAPInt &X);
173 friend DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS);
175 const DynamicAPInt &RHS);
176 // The operands must be non-negative for gcd.
177 friend DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B);
178 friend DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B);
179 friend DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS);
180
181 /// ---------------------------------------------------------------------------
182 /// Convenience operator overloads for int64_t.
183 /// ---------------------------------------------------------------------------
184 friend DynamicAPInt &operator+=(DynamicAPInt &A, int64_t B);
185 friend DynamicAPInt &operator-=(DynamicAPInt &A, int64_t B);
186 friend DynamicAPInt &operator*=(DynamicAPInt &A, int64_t B);
187 friend DynamicAPInt &operator/=(DynamicAPInt &A, int64_t B);
188 friend DynamicAPInt &operator%=(DynamicAPInt &A, int64_t B);
189
190 friend bool operator==(const DynamicAPInt &A, int64_t B);
191 friend bool operator!=(const DynamicAPInt &A, int64_t B);
192 friend bool operator>(const DynamicAPInt &A, int64_t B);
193 friend bool operator<(const DynamicAPInt &A, int64_t B);
194 friend bool operator<=(const DynamicAPInt &A, int64_t B);
195 friend bool operator>=(const DynamicAPInt &A, int64_t B);
196 friend DynamicAPInt operator+(const DynamicAPInt &A, int64_t B);
197 friend DynamicAPInt operator-(const DynamicAPInt &A, int64_t B);
198 friend DynamicAPInt operator*(const DynamicAPInt &A, int64_t B);
199 friend DynamicAPInt operator/(const DynamicAPInt &A, int64_t B);
200 friend DynamicAPInt operator%(const DynamicAPInt &A, int64_t B);
201
202 friend bool operator==(int64_t A, const DynamicAPInt &B);
203 friend bool operator!=(int64_t A, const DynamicAPInt &B);
204 friend bool operator>(int64_t A, const DynamicAPInt &B);
205 friend bool operator<(int64_t A, const DynamicAPInt &B);
206 friend bool operator<=(int64_t A, const DynamicAPInt &B);
207 friend bool operator>=(int64_t A, const DynamicAPInt &B);
208 friend DynamicAPInt operator+(int64_t A, const DynamicAPInt &B);
209 friend DynamicAPInt operator-(int64_t A, const DynamicAPInt &B);
210 friend DynamicAPInt operator*(int64_t A, const DynamicAPInt &B);
211 friend DynamicAPInt operator/(int64_t A, const DynamicAPInt &B);
212 friend DynamicAPInt operator%(int64_t A, const DynamicAPInt &B);
213
214 friend hash_code hash_value(const DynamicAPInt &x); // NOLINT
215
216 void static_assert_layout(); // NOLINT
217
219 LLVM_DUMP_METHOD void dump() const;
220};
221
223 X.print(OS);
224 return OS;
225}
226
227/// Redeclarations of friend declaration above to
228/// make it discoverable by lookups.
229hash_code hash_value(const DynamicAPInt &X); // NOLINT
230
231/// This just calls through to the operator int64_t, but it's useful when a
232/// function pointer is required. (Although this is marked inline, it is still
233/// possible to obtain and use a function pointer to this.)
234static inline int64_t int64fromDynamicAPInt(const DynamicAPInt &X) {
235 return int64_t(X);
236}
238 return DynamicAPInt(X);
239}
240
241// The RHS is always expected to be positive, and the result
242/// is always non-negative.
243LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS,
244 const DynamicAPInt &RHS);
245
246/// We define the operations here in the header to facilitate inlining.
247
248/// ---------------------------------------------------------------------------
249/// Comparison operators.
250/// ---------------------------------------------------------------------------
253 if (LLVM_LIKELY(isSmall() && O.isSmall()))
254 return getSmall() == O.getSmall();
256}
259 if (LLVM_LIKELY(isSmall() && O.isSmall()))
260 return getSmall() != O.getSmall();
262}
265 if (LLVM_LIKELY(isSmall() && O.isSmall()))
266 return getSmall() > O.getSmall();
268}
271 if (LLVM_LIKELY(isSmall() && O.isSmall()))
272 return getSmall() < O.getSmall();
274}
277 if (LLVM_LIKELY(isSmall() && O.isSmall()))
278 return getSmall() <= O.getSmall();
280}
283 if (LLVM_LIKELY(isSmall() && O.isSmall()))
284 return getSmall() >= O.getSmall();
286}
287
288/// ---------------------------------------------------------------------------
289/// Arithmetic operators.
290/// ---------------------------------------------------------------------------
291
294 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
295 DynamicAPInt Result;
296 bool Overflow = AddOverflow(getSmall(), O.getSmall(), Result.getSmall());
297 if (LLVM_LIKELY(!Overflow))
298 return Result;
301 }
304}
307 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
308 DynamicAPInt Result;
309 bool Overflow = SubOverflow(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 = MulOverflow(getSmall(), O.getSmall(), Result.getSmall());
323 if (LLVM_LIKELY(!Overflow))
324 return Result;
327 }
330}
331
332// Division overflows only occur when negating the minimal possible value.
335 assert(O > 0);
336 if (LLVM_LIKELY(isSmall() && O.isSmall()))
337 return DynamicAPInt(getSmall() / O.getSmall());
340}
341
344 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
345 // Division overflows only occur when negating the minimal possible value.
346 if (LLVM_UNLIKELY(divideSignedWouldOverflow(getSmall(), O.getSmall())))
347 return -*this;
348 return DynamicAPInt(getSmall() / O.getSmall());
349 }
352}
353
355 return DynamicAPInt(X >= 0 ? X : -X);
356}
357// Division overflows only occur when negating the minimal possible value.
359 const DynamicAPInt &RHS) {
360 if (LLVM_LIKELY(LHS.isSmall() && RHS.isSmall())) {
361 if (LLVM_UNLIKELY(
362 divideSignedWouldOverflow(LHS.getSmall(), RHS.getSmall())))
363 return -LHS;
364 return DynamicAPInt(divideCeilSigned(LHS.getSmall(), RHS.getSmall()));
365 }
366 return DynamicAPInt(
368}
370 const DynamicAPInt &RHS) {
371 if (LLVM_LIKELY(LHS.isSmall() && RHS.isSmall())) {
372 if (LLVM_UNLIKELY(
373 divideSignedWouldOverflow(LHS.getSmall(), RHS.getSmall())))
374 return -LHS;
375 return DynamicAPInt(divideFloorSigned(LHS.getSmall(), RHS.getSmall()));
376 }
377 return DynamicAPInt(
379}
380// The RHS is always expected to be positive, and the result
381/// is always non-negative.
383 const DynamicAPInt &RHS) {
384 if (LLVM_LIKELY(LHS.isSmall() && RHS.isSmall()))
385 return DynamicAPInt(mod(LHS.getSmall(), RHS.getSmall()));
386 return DynamicAPInt(
388}
389
391 const DynamicAPInt &B) {
392 assert(A >= 0 && B >= 0 && "operands must be non-negative!");
393 if (LLVM_LIKELY(A.isSmall() && B.isSmall()))
394 return DynamicAPInt(std::gcd(A.getSmall(), B.getSmall()));
395 return DynamicAPInt(
397}
398
399/// Returns the least common multiple of A and B.
401 const DynamicAPInt &B) {
402 DynamicAPInt X = abs(A);
403 DynamicAPInt Y = abs(B);
404 return (X * Y) / gcd(X, Y);
405}
406
407/// This operation cannot overflow.
410 if (LLVM_LIKELY(isSmall() && O.isSmall()))
411 return DynamicAPInt(getSmall() % O.getSmall());
414}
415
417 if (LLVM_LIKELY(isSmall())) {
418 if (LLVM_LIKELY(getSmall() != std::numeric_limits<int64_t>::min()))
419 return DynamicAPInt(-getSmall());
421 }
423}
424
425/// ---------------------------------------------------------------------------
426/// Assignment operators, preincrement, predecrement.
427/// ---------------------------------------------------------------------------
430 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
431 int64_t Result = getSmall();
432 bool Overflow = AddOverflow(getSmall(), O.getSmall(), Result);
433 if (LLVM_LIKELY(!Overflow)) {
434 getSmall() = Result;
435 return *this;
436 }
437 // Note: this return is not strictly required but
438 // removing it leads to a performance regression.
439 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) +
441 }
442 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) +
444}
447 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
448 int64_t Result = getSmall();
449 bool Overflow = SubOverflow(getSmall(), O.getSmall(), Result);
450 if (LLVM_LIKELY(!Overflow)) {
451 getSmall() = Result;
452 return *this;
453 }
454 // Note: this return is not strictly required but
455 // removing it leads to a performance regression.
456 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) -
458 }
459 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) -
461}
464 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
465 int64_t Result = getSmall();
466 bool Overflow = MulOverflow(getSmall(), O.getSmall(), Result);
467 if (LLVM_LIKELY(!Overflow)) {
468 getSmall() = Result;
469 return *this;
470 }
471 // Note: this return is not strictly required but
472 // removing it leads to a performance regression.
473 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) *
475 }
476 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) *
478}
481 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
482 // Division overflows only occur when negating the minimal possible value.
483 if (LLVM_UNLIKELY(divideSignedWouldOverflow(getSmall(), O.getSmall())))
484 return *this = -*this;
485 getSmall() /= O.getSmall();
486 return *this;
487 }
488 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) /
490}
491
492// Division overflows only occur when the divisor is -1.
495 assert(O > 0);
496 if (LLVM_LIKELY(isSmall() && O.isSmall())) {
497 getSmall() /= O.getSmall();
498 return *this;
499 }
500 return *this = DynamicAPInt(detail::SlowDynamicAPInt(*this) /
502}
503
506 return *this = *this % O;
507}
509 return *this += 1;
510}
512 return *this -= 1;
513}
514
515/// ----------------------------------------------------------------------------
516/// Convenience operator overloads for int64_t.
517/// ----------------------------------------------------------------------------
519 int64_t B) {
520 return A = A + B;
521}
523 int64_t B) {
524 return A = A - B;
525}
527 int64_t B) {
528 return A = A * B;
529}
531 int64_t B) {
532 return A = A / B;
533}
535 int64_t B) {
536 return A = A % B;
537}
539 int64_t B) {
540 return A + DynamicAPInt(B);
541}
543 int64_t B) {
544 return A - DynamicAPInt(B);
545}
547 int64_t B) {
548 return A * DynamicAPInt(B);
549}
551 int64_t B) {
552 return A / DynamicAPInt(B);
553}
555 int64_t B) {
556 return A % DynamicAPInt(B);
557}
559 const DynamicAPInt &B) {
560 return DynamicAPInt(A) + B;
561}
563 const DynamicAPInt &B) {
564 return DynamicAPInt(A) - B;
565}
567 const DynamicAPInt &B) {
568 return DynamicAPInt(A) * B;
569}
571 const DynamicAPInt &B) {
572 return DynamicAPInt(A) / B;
573}
575 const DynamicAPInt &B) {
576 return DynamicAPInt(A) % B;
577}
578
579/// We provide special implementations of the comparison operators rather than
580/// calling through as above, as this would result in a 1.2x slowdown.
582 if (LLVM_LIKELY(A.isSmall()))
583 return A.getSmall() == B;
584 return A.getLarge() == B;
585}
587 if (LLVM_LIKELY(A.isSmall()))
588 return A.getSmall() != B;
589 return A.getLarge() != B;
590}
592 if (LLVM_LIKELY(A.isSmall()))
593 return A.getSmall() > B;
594 return A.getLarge() > B;
595}
597 if (LLVM_LIKELY(A.isSmall()))
598 return A.getSmall() < B;
599 return A.getLarge() < B;
600}
602 if (LLVM_LIKELY(A.isSmall()))
603 return A.getSmall() <= B;
604 return A.getLarge() <= B;
605}
607 if (LLVM_LIKELY(A.isSmall()))
608 return A.getSmall() >= B;
609 return A.getLarge() >= B;
610}
612 if (LLVM_LIKELY(B.isSmall()))
613 return A == B.getSmall();
614 return A == B.getLarge();
615}
617 if (LLVM_LIKELY(B.isSmall()))
618 return A != B.getSmall();
619 return A != B.getLarge();
620}
622 if (LLVM_LIKELY(B.isSmall()))
623 return A > B.getSmall();
624 return A > B.getLarge();
625}
627 if (LLVM_LIKELY(B.isSmall()))
628 return A < B.getSmall();
629 return A < B.getLarge();
630}
632 if (LLVM_LIKELY(B.isSmall()))
633 return A <= B.getSmall();
634 return A <= B.getLarge();
635}
637 if (LLVM_LIKELY(B.isSmall()))
638 return A >= B.getSmall();
639 return A >= B.getLarge();
640}
641} // namespace llvm
642
643#endif // LLVM_ADT_DYNAMICAPINT_H
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:237
#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:257
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:533
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:236
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Value * RHS
Value * LHS
This class provides support for dynamic arbitrary-precision arithmetic.
Definition: DynamicAPInt.h:46
friend DynamicAPInt & operator%=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:534
raw_ostream & print(raw_ostream &OS) const
friend bool operator>=(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:606
friend bool operator>(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:591
friend DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:358
friend bool operator!=(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:586
DynamicAPInt & operator--()
Definition: DynamicAPInt.h:511
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(const DynamicAPInt &O)
Definition: DynamicAPInt.h:129
friend DynamicAPInt abs(const DynamicAPInt &X)
Definition: DynamicAPInt.h:354
friend DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:390
friend DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
Definition: DynamicAPInt.h:400
friend DynamicAPInt operator+(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:538
friend DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:518
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt()
Definition: DynamicAPInt.h:118
friend DynamicAPInt operator/(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:550
friend DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:526
friend DynamicAPInt operator%(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:554
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(int X)
Definition: DynamicAPInt.h:137
detail::SlowDynamicAPInt ValLarge
Definition: DynamicAPInt.h:49
friend bool operator<(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:596
DynamicAPInt divByPositive(const DynamicAPInt &O) const
Definition: DynamicAPInt.h:334
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(const DynamicAPInt &O)
Definition: DynamicAPInt.h:123
friend DynamicAPInt & operator/=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:530
DynamicAPInt operator-() const
Definition: DynamicAPInt.h:416
LLVM_DUMP_METHOD void dump() const
friend hash_code hash_value(const DynamicAPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
DynamicAPInt & operator++()
Definition: DynamicAPInt.h:508
friend bool operator<=(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:601
friend DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
Definition: DynamicAPInt.h:382
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:581
LLVM_ATTRIBUTE_ALWAYS_INLINE ~DynamicAPInt()
Definition: DynamicAPInt.h:119
friend DynamicAPInt floorDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:369
friend DynamicAPInt operator*(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:546
friend DynamicAPInt & operator-=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:522
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(int64_t Val)
Definition: DynamicAPInt.h:114
DynamicAPInt & divByPositiveInPlace(const DynamicAPInt &O)
Definition: DynamicAPInt.h:494
A simple class providing dynamic arbitrary-precision arithmetic.
An opaque object representing a hash code.
Definition: Hashing.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
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:361
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:390
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:753
constexpr bool divideSignedWouldOverflow(U Numerator, V Denominator)
Definition: MathExtras.h:419
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
Definition: DynamicAPInt.h:382
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:127
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2182
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1446
constexpr T divideFloorSigned(U Numerator, V Denominator)
Returns the integer floor(Numerator / Denominator).
Definition: MathExtras.h:442
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2060
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:518
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator-=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:522
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt floorDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:369
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt operator%(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:554
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:526
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator/=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:530
bool operator>(int64_t V1, const APSInt &V2)
Definition: APSInt.h:362
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition: DynamicAPInt.h:358
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:234
constexpr T divideCeilSigned(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition: MathExtras.h:426
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:292
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
Definition: DynamicAPInt.h:400
APInt operator-(APInt)
Definition: APInt.h:2135
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt dynamicAPIntFromInt64(int64_t X)
Definition: DynamicAPInt.h:237
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:701
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2140
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:727
bool operator<=(int64_t V1, const APSInt &V2)
Definition: APSInt.h:359
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator%=(DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:534
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt operator/(const DynamicAPInt &A, int64_t B)
Definition: DynamicAPInt.h:550