Movatterモバイル変換


[0]ホーム

URL:


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
19#include "llvm/ADT/SlowDynamicAPInt.h"
20#include "llvm/Support/MathExtras.h"
21#include <numeric>
22
23namespacellvm {
24
25classraw_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.
46classDynamicAPInt {
47union{
48 int64_tValSmall;
49detail::SlowDynamicAPIntValLarge;
50 };
51
52LLVM_ATTRIBUTE_ALWAYS_INLINEvoid initSmall(int64_t O) {
53if (LLVM_UNLIKELY(isLarge()))
54ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();
55ValSmall = O;
56ValLarge.Val.BitWidth = 0;
57 }
58LLVM_ATTRIBUTE_ALWAYS_INLINEvoid
59 initLarge(const detail::SlowDynamicAPInt &O) {
60if (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.
66new (&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.
71ValLarge =O;
72 }
73 }
74
75LLVM_ATTRIBUTE_ALWAYS_INLINEexplicitDynamicAPInt(
76const detail::SlowDynamicAPInt &Val)
77 :ValLarge(Val) {}
78LLVM_ATTRIBUTE_ALWAYS_INLINEconstexprbool isSmall() const{
79returnValLarge.Val.BitWidth == 0;
80 }
81LLVM_ATTRIBUTE_ALWAYS_INLINEconstexprbool isLarge() const{
82return !isSmall();
83 }
84 /// Get the stored value. For getSmall/Large,
85 /// the stored value should be small/large.
86LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t getSmall() const{
87assert(isSmall() &&
88"getSmall should only be called when the value stored is small!");
89returnValSmall;
90 }
91LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t &getSmall() {
92assert(isSmall() &&
93"getSmall should only be called when the value stored is small!");
94returnValSmall;
95 }
96LLVM_ATTRIBUTE_ALWAYS_INLINEconst detail::SlowDynamicAPInt &
97 getLarge() const{
98assert(isLarge() &&
99"getLarge should only be called when the value stored is large!");
100returnValLarge;
101 }
102LLVM_ATTRIBUTE_ALWAYS_INLINE detail::SlowDynamicAPInt &getLarge() {
103assert(isLarge() &&
104"getLarge should only be called when the value stored is large!");
105returnValLarge;
106 }
107explicitoperator detail::SlowDynamicAPInt() const{
108if (isSmall())
109return detail::SlowDynamicAPInt(getSmall());
110return getLarge();
111 }
112
113public:
114LLVM_ATTRIBUTE_ALWAYS_INLINEexplicitDynamicAPInt(int64_t Val)
115 :ValSmall(Val) {
116ValLarge.Val.BitWidth = 0;
117 }
118LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt() :DynamicAPInt(0) {}
119LLVM_ATTRIBUTE_ALWAYS_INLINE~DynamicAPInt() {
120if (LLVM_UNLIKELY(isLarge()))
121ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();
122 }
123LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt(constDynamicAPInt &O)
124 :ValSmall(O.ValSmall) {
125ValLarge.Val.BitWidth = 0;
126if (LLVM_UNLIKELY(O.isLarge()))
127 initLarge(O.ValLarge);
128 }
129LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator=(constDynamicAPInt &O) {
130if (LLVM_LIKELY(O.isSmall())) {
131 initSmall(O.ValSmall);
132return *this;
133 }
134 initLarge(O.ValLarge);
135return *this;
136 }
137LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator=(intX) {
138 initSmall(X);
139return *this;
140 }
141LLVM_ATTRIBUTE_ALWAYS_INLINEexplicitoperator int64_t() const{
142if (isSmall())
143return getSmall();
144returnstatic_cast<int64_t>(getLarge());
145 }
146
147booloperator==(constDynamicAPInt &O)const;
148booloperator!=(constDynamicAPInt &O)const;
149booloperator>(constDynamicAPInt &O)const;
150booloperator<(constDynamicAPInt &O)const;
151booloperator<=(constDynamicAPInt &O)const;
152booloperator>=(constDynamicAPInt &O)const;
153DynamicAPIntoperator+(constDynamicAPInt &O)const;
154DynamicAPIntoperator-(constDynamicAPInt &O)const;
155DynamicAPIntoperator*(constDynamicAPInt &O)const;
156DynamicAPIntoperator/(constDynamicAPInt &O)const;
157DynamicAPIntoperator%(constDynamicAPInt &O)const;
158DynamicAPInt &operator+=(constDynamicAPInt &O);
159DynamicAPInt &operator-=(constDynamicAPInt &O);
160DynamicAPInt &operator*=(constDynamicAPInt &O);
161DynamicAPInt &operator/=(constDynamicAPInt &O);
162DynamicAPInt &operator%=(constDynamicAPInt &O);
163DynamicAPIntoperator-()const;
164DynamicAPInt &operator++();
165DynamicAPInt &operator--();
166
167// Divide by a number that is known to be positive.
168// This is slightly more efficient because it saves an overflow check.
169DynamicAPIntdivByPositive(constDynamicAPInt &O)const;
170DynamicAPInt &divByPositiveInPlace(constDynamicAPInt &O);
171
172friendDynamicAPIntabs(constDynamicAPInt &X);
173friendDynamicAPIntceilDiv(constDynamicAPInt &LHS,constDynamicAPInt &RHS);
174friendDynamicAPIntfloorDiv(constDynamicAPInt &LHS,
175constDynamicAPInt &RHS);
176// The operands must be non-negative for gcd.
177friendDynamicAPIntgcd(constDynamicAPInt &A,constDynamicAPInt &B);
178friendDynamicAPIntlcm(constDynamicAPInt &A,constDynamicAPInt &B);
179friendDynamicAPIntmod(constDynamicAPInt &LHS,constDynamicAPInt &RHS);
180
181 /// ---------------------------------------------------------------------------
182 /// Convenience operator overloads for int64_t.
183 /// ---------------------------------------------------------------------------
184friendDynamicAPInt &operator+=(DynamicAPInt &A, int64_tB);
185friendDynamicAPInt &operator-=(DynamicAPInt &A, int64_tB);
186friendDynamicAPInt &operator*=(DynamicAPInt &A, int64_tB);
187friendDynamicAPInt &operator/=(DynamicAPInt &A, int64_tB);
188friendDynamicAPInt &operator%=(DynamicAPInt &A, int64_tB);
189
190friendbooloperator==(constDynamicAPInt &A, int64_tB);
191friendbooloperator!=(constDynamicAPInt &A, int64_tB);
192friendbooloperator>(constDynamicAPInt &A, int64_tB);
193friendbooloperator<(constDynamicAPInt &A, int64_tB);
194friendbooloperator<=(constDynamicAPInt &A, int64_tB);
195friendbooloperator>=(constDynamicAPInt &A, int64_tB);
196friendDynamicAPIntoperator+(constDynamicAPInt &A, int64_tB);
197friendDynamicAPIntoperator-(constDynamicAPInt &A, int64_tB);
198friendDynamicAPIntoperator*(constDynamicAPInt &A, int64_tB);
199friendDynamicAPIntoperator/(constDynamicAPInt &A, int64_tB);
200friendDynamicAPIntoperator%(constDynamicAPInt &A, int64_tB);
201
202friendbooloperator==(int64_tA,constDynamicAPInt &B);
203friendbooloperator!=(int64_tA,constDynamicAPInt &B);
204friendbooloperator>(int64_tA,constDynamicAPInt &B);
205friendbooloperator<(int64_tA,constDynamicAPInt &B);
206friendbooloperator<=(int64_tA,constDynamicAPInt &B);
207friendbooloperator>=(int64_tA,constDynamicAPInt &B);
208friendDynamicAPIntoperator+(int64_tA,constDynamicAPInt &B);
209friendDynamicAPIntoperator-(int64_tA,constDynamicAPInt &B);
210friendDynamicAPIntoperator*(int64_tA,constDynamicAPInt &B);
211friendDynamicAPIntoperator/(int64_tA,constDynamicAPInt &B);
212friendDynamicAPIntoperator%(int64_tA,constDynamicAPInt &B);
213
214friendhash_codehash_value(constDynamicAPInt &x);// NOLINT
215
216voidstatic_assert_layout();// NOLINT
217
218raw_ostream &print(raw_ostream &OS)const;
219LLVM_DUMP_METHODvoiddump()const;
220};
221
222inlineraw_ostream &operator<<(raw_ostream &OS,constDynamicAPInt &X) {
223X.print(OS);
224returnOS;
225}
226
227/// Redeclarations of friend declaration above to
228/// make it discoverable by lookups.
229hash_codehash_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.)
234staticinline int64_tint64fromDynamicAPInt(constDynamicAPInt &X) {
235return int64_t(X);
236}
237LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntdynamicAPIntFromInt64(int64_tX) {
238returnDynamicAPInt(X);
239}
240
241// The RHS is always expected to be positive, and the result
242/// is always non-negative.
243LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPIntmod(const DynamicAPInt &LHS,
244const DynamicAPInt &RHS);
245
246/// We define the operations here in the header to facilitate inlining.
247
248/// ---------------------------------------------------------------------------
249/// Comparison operators.
250/// ---------------------------------------------------------------------------
251LLVM_ATTRIBUTE_ALWAYS_INLINEbool
252DynamicAPInt::operator==(constDynamicAPInt &O) const{
253if (LLVM_LIKELY(isSmall() && O.isSmall()))
254return getSmall() == O.getSmall();
255returndetail::SlowDynamicAPInt(*this) ==detail::SlowDynamicAPInt(O);
256}
257LLVM_ATTRIBUTE_ALWAYS_INLINEbool
258DynamicAPInt::operator!=(constDynamicAPInt &O) const{
259if (LLVM_LIKELY(isSmall() && O.isSmall()))
260return getSmall() != O.getSmall();
261returndetail::SlowDynamicAPInt(*this) !=detail::SlowDynamicAPInt(O);
262}
263LLVM_ATTRIBUTE_ALWAYS_INLINEbool
264DynamicAPInt::operator>(constDynamicAPInt &O) const{
265if (LLVM_LIKELY(isSmall() && O.isSmall()))
266return getSmall() > O.getSmall();
267returndetail::SlowDynamicAPInt(*this) >detail::SlowDynamicAPInt(O);
268}
269LLVM_ATTRIBUTE_ALWAYS_INLINEbool
270DynamicAPInt::operator<(constDynamicAPInt &O) const{
271if (LLVM_LIKELY(isSmall() && O.isSmall()))
272return getSmall() < O.getSmall();
273returndetail::SlowDynamicAPInt(*this) <detail::SlowDynamicAPInt(O);
274}
275LLVM_ATTRIBUTE_ALWAYS_INLINEbool
276DynamicAPInt::operator<=(constDynamicAPInt &O) const{
277if (LLVM_LIKELY(isSmall() && O.isSmall()))
278return getSmall() <= O.getSmall();
279returndetail::SlowDynamicAPInt(*this) <=detail::SlowDynamicAPInt(O);
280}
281LLVM_ATTRIBUTE_ALWAYS_INLINEbool
282DynamicAPInt::operator>=(constDynamicAPInt &O) const{
283if (LLVM_LIKELY(isSmall() && O.isSmall()))
284return getSmall() >= O.getSmall();
285returndetail::SlowDynamicAPInt(*this) >=detail::SlowDynamicAPInt(O);
286}
287
288/// ---------------------------------------------------------------------------
289/// Arithmetic operators.
290/// ---------------------------------------------------------------------------
291
292LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt
293DynamicAPInt::operator+(constDynamicAPInt &O) const{
294if (LLVM_LIKELY(isSmall() && O.isSmall())) {
295DynamicAPInt Result;
296bool Overflow =AddOverflow(getSmall(), O.getSmall(), Result.getSmall());
297if (LLVM_LIKELY(!Overflow))
298return Result;
299returnDynamicAPInt(detail::SlowDynamicAPInt(*this) +
300detail::SlowDynamicAPInt(O));
301 }
302returnDynamicAPInt(detail::SlowDynamicAPInt(*this) +
303detail::SlowDynamicAPInt(O));
304}
305LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt
306DynamicAPInt::operator-(constDynamicAPInt &O) const{
307if (LLVM_LIKELY(isSmall() && O.isSmall())) {
308DynamicAPInt Result;
309bool Overflow =SubOverflow(getSmall(), O.getSmall(), Result.getSmall());
310if (LLVM_LIKELY(!Overflow))
311return Result;
312returnDynamicAPInt(detail::SlowDynamicAPInt(*this) -
313detail::SlowDynamicAPInt(O));
314 }
315returnDynamicAPInt(detail::SlowDynamicAPInt(*this) -
316detail::SlowDynamicAPInt(O));
317}
318LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt
319DynamicAPInt::operator*(constDynamicAPInt &O) const{
320if (LLVM_LIKELY(isSmall() && O.isSmall())) {
321DynamicAPInt Result;
322bool Overflow =MulOverflow(getSmall(), O.getSmall(), Result.getSmall());
323if (LLVM_LIKELY(!Overflow))
324return Result;
325returnDynamicAPInt(detail::SlowDynamicAPInt(*this) *
326detail::SlowDynamicAPInt(O));
327 }
328returnDynamicAPInt(detail::SlowDynamicAPInt(*this) *
329detail::SlowDynamicAPInt(O));
330}
331
332// Division overflows only occur when negating the minimal possible value.
333LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt
334DynamicAPInt::divByPositive(constDynamicAPInt &O) const{
335assert(O > 0);
336if (LLVM_LIKELY(isSmall() && O.isSmall()))
337returnDynamicAPInt(getSmall() / O.getSmall());
338returnDynamicAPInt(detail::SlowDynamicAPInt(*this) /
339detail::SlowDynamicAPInt(O));
340}
341
342LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt
343DynamicAPInt::operator/(constDynamicAPInt &O) const{
344if (LLVM_LIKELY(isSmall() && O.isSmall())) {
345// Division overflows only occur when negating the minimal possible value.
346if (LLVM_UNLIKELY(divideSignedWouldOverflow(getSmall(), O.getSmall())))
347return -*this;
348returnDynamicAPInt(getSmall() / O.getSmall());
349 }
350returnDynamicAPInt(detail::SlowDynamicAPInt(*this) /
351detail::SlowDynamicAPInt(O));
352}
353
354LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntabs(constDynamicAPInt &X) {
355returnDynamicAPInt(X >= 0 ?X : -X);
356}
357// Division overflows only occur when negating the minimal possible value.
358LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntceilDiv(constDynamicAPInt &LHS,
359constDynamicAPInt &RHS) {
360if (LLVM_LIKELY(LHS.isSmall() &&RHS.isSmall())) {
361if (LLVM_UNLIKELY(
362divideSignedWouldOverflow(LHS.getSmall(),RHS.getSmall())))
363return -LHS;
364returnDynamicAPInt(divideCeilSigned(LHS.getSmall(),RHS.getSmall()));
365 }
366returnDynamicAPInt(
367ceilDiv(detail::SlowDynamicAPInt(LHS),detail::SlowDynamicAPInt(RHS)));
368}
369LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntfloorDiv(constDynamicAPInt &LHS,
370constDynamicAPInt &RHS) {
371if (LLVM_LIKELY(LHS.isSmall() &&RHS.isSmall())) {
372if (LLVM_UNLIKELY(
373divideSignedWouldOverflow(LHS.getSmall(),RHS.getSmall())))
374return -LHS;
375returnDynamicAPInt(divideFloorSigned(LHS.getSmall(),RHS.getSmall()));
376 }
377returnDynamicAPInt(
378floorDiv(detail::SlowDynamicAPInt(LHS),detail::SlowDynamicAPInt(RHS)));
379}
380// The RHS is always expected to be positive, and the result
381/// is always non-negative.
382LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntmod(constDynamicAPInt &LHS,
383constDynamicAPInt &RHS) {
384if (LLVM_LIKELY(LHS.isSmall() &&RHS.isSmall()))
385returnDynamicAPInt(mod(LHS.getSmall(),RHS.getSmall()));
386returnDynamicAPInt(
387mod(detail::SlowDynamicAPInt(LHS),detail::SlowDynamicAPInt(RHS)));
388}
389
390LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntgcd(constDynamicAPInt &A,
391constDynamicAPInt &B) {
392assert(A >= 0 &&B >= 0 &&"operands must be non-negative!");
393if (LLVM_LIKELY(A.isSmall() &&B.isSmall()))
394returnDynamicAPInt(std::gcd(A.getSmall(),B.getSmall()));
395returnDynamicAPInt(
396gcd(detail::SlowDynamicAPInt(A),detail::SlowDynamicAPInt(B)));
397}
398
399/// Returns the least common multiple of A and B.
400LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntlcm(constDynamicAPInt &A,
401constDynamicAPInt &B) {
402DynamicAPIntX =abs(A);
403DynamicAPIntY =abs(B);
404return (X *Y) /gcd(X,Y);
405}
406
407/// This operation cannot overflow.
408LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt
409DynamicAPInt::operator%(constDynamicAPInt &O) const{
410if (LLVM_LIKELY(isSmall() && O.isSmall()))
411returnDynamicAPInt(getSmall() % O.getSmall());
412returnDynamicAPInt(detail::SlowDynamicAPInt(*this) %
413detail::SlowDynamicAPInt(O));
414}
415
416LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntDynamicAPInt::operator-() const{
417if (LLVM_LIKELY(isSmall())) {
418if (LLVM_LIKELY(getSmall() != std::numeric_limits<int64_t>::min()))
419returnDynamicAPInt(-getSmall());
420returnDynamicAPInt(-detail::SlowDynamicAPInt(*this));
421 }
422returnDynamicAPInt(-detail::SlowDynamicAPInt(*this));
423}
424
425/// ---------------------------------------------------------------------------
426/// Assignment operators, preincrement, predecrement.
427/// ---------------------------------------------------------------------------
428LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &
429DynamicAPInt::operator+=(constDynamicAPInt &O) {
430if (LLVM_LIKELY(isSmall() && O.isSmall())) {
431 int64_t Result = getSmall();
432bool Overflow =AddOverflow(getSmall(), O.getSmall(), Result);
433if (LLVM_LIKELY(!Overflow)) {
434 getSmall() = Result;
435return *this;
436 }
437// Note: this return is not strictly required but
438// removing it leads to a performance regression.
439return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) +
440detail::SlowDynamicAPInt(O));
441 }
442return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) +
443detail::SlowDynamicAPInt(O));
444}
445LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &
446DynamicAPInt::operator-=(constDynamicAPInt &O) {
447if (LLVM_LIKELY(isSmall() && O.isSmall())) {
448 int64_t Result = getSmall();
449bool Overflow =SubOverflow(getSmall(), O.getSmall(), Result);
450if (LLVM_LIKELY(!Overflow)) {
451 getSmall() = Result;
452return *this;
453 }
454// Note: this return is not strictly required but
455// removing it leads to a performance regression.
456return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) -
457detail::SlowDynamicAPInt(O));
458 }
459return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) -
460detail::SlowDynamicAPInt(O));
461}
462LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &
463DynamicAPInt::operator*=(constDynamicAPInt &O) {
464if (LLVM_LIKELY(isSmall() && O.isSmall())) {
465 int64_t Result = getSmall();
466bool Overflow =MulOverflow(getSmall(), O.getSmall(), Result);
467if (LLVM_LIKELY(!Overflow)) {
468 getSmall() = Result;
469return *this;
470 }
471// Note: this return is not strictly required but
472// removing it leads to a performance regression.
473return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) *
474detail::SlowDynamicAPInt(O));
475 }
476return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) *
477detail::SlowDynamicAPInt(O));
478}
479LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &
480DynamicAPInt::operator/=(constDynamicAPInt &O) {
481if (LLVM_LIKELY(isSmall() && O.isSmall())) {
482// Division overflows only occur when negating the minimal possible value.
483if (LLVM_UNLIKELY(divideSignedWouldOverflow(getSmall(), O.getSmall())))
484return *this = -*this;
485 getSmall() /= O.getSmall();
486return *this;
487 }
488return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) /
489detail::SlowDynamicAPInt(O));
490}
491
492// Division overflows only occur when the divisor is -1.
493LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &
494DynamicAPInt::divByPositiveInPlace(constDynamicAPInt &O) {
495assert(O > 0);
496if (LLVM_LIKELY(isSmall() && O.isSmall())) {
497 getSmall() /= O.getSmall();
498return *this;
499 }
500return *this =DynamicAPInt(detail::SlowDynamicAPInt(*this) /
501detail::SlowDynamicAPInt(O));
502}
503
504LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &
505DynamicAPInt::operator%=(constDynamicAPInt &O) {
506return *this = *this % O;
507}
508LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &DynamicAPInt::operator++() {
509return *this += 1;
510}
511LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &DynamicAPInt::operator--() {
512return *this -= 1;
513}
514
515/// ----------------------------------------------------------------------------
516/// Convenience operator overloads for int64_t.
517/// ----------------------------------------------------------------------------
518LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator+=(DynamicAPInt &A,
519 int64_tB) {
520returnA =A +B;
521}
522LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator-=(DynamicAPInt &A,
523 int64_tB) {
524returnA =A -B;
525}
526LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator*=(DynamicAPInt &A,
527 int64_tB) {
528returnA =A *B;
529}
530LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator/=(DynamicAPInt &A,
531 int64_tB) {
532returnA =A /B;
533}
534LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPInt &operator%=(DynamicAPInt &A,
535 int64_tB) {
536returnA =A %B;
537}
538LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator+(constDynamicAPInt &A,
539 int64_tB) {
540returnA +DynamicAPInt(B);
541}
542LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator-(constDynamicAPInt &A,
543 int64_tB) {
544returnA -DynamicAPInt(B);
545}
546LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator*(constDynamicAPInt &A,
547 int64_tB) {
548returnA *DynamicAPInt(B);
549}
550LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator/(constDynamicAPInt &A,
551 int64_tB) {
552returnA /DynamicAPInt(B);
553}
554LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator%(constDynamicAPInt &A,
555 int64_tB) {
556returnA %DynamicAPInt(B);
557}
558LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator+(int64_tA,
559constDynamicAPInt &B) {
560returnDynamicAPInt(A) +B;
561}
562LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator-(int64_tA,
563constDynamicAPInt &B) {
564returnDynamicAPInt(A) -B;
565}
566LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator*(int64_tA,
567constDynamicAPInt &B) {
568returnDynamicAPInt(A) *B;
569}
570LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator/(int64_tA,
571constDynamicAPInt &B) {
572returnDynamicAPInt(A) /B;
573}
574LLVM_ATTRIBUTE_ALWAYS_INLINEDynamicAPIntoperator%(int64_tA,
575constDynamicAPInt &B) {
576returnDynamicAPInt(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.
581LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator==(constDynamicAPInt &A, int64_tB) {
582if (LLVM_LIKELY(A.isSmall()))
583returnA.getSmall() ==B;
584returnA.getLarge() ==B;
585}
586LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator!=(constDynamicAPInt &A, int64_tB) {
587if (LLVM_LIKELY(A.isSmall()))
588returnA.getSmall() !=B;
589returnA.getLarge() !=B;
590}
591LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator>(constDynamicAPInt &A, int64_tB) {
592if (LLVM_LIKELY(A.isSmall()))
593returnA.getSmall() >B;
594returnA.getLarge() >B;
595}
596LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator<(constDynamicAPInt &A, int64_tB) {
597if (LLVM_LIKELY(A.isSmall()))
598returnA.getSmall() <B;
599returnA.getLarge() <B;
600}
601LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator<=(constDynamicAPInt &A, int64_tB) {
602if (LLVM_LIKELY(A.isSmall()))
603returnA.getSmall() <=B;
604returnA.getLarge() <=B;
605}
606LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator>=(constDynamicAPInt &A, int64_tB) {
607if (LLVM_LIKELY(A.isSmall()))
608returnA.getSmall() >=B;
609returnA.getLarge() >=B;
610}
611LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator==(int64_tA,constDynamicAPInt &B) {
612if (LLVM_LIKELY(B.isSmall()))
613returnA ==B.getSmall();
614returnA ==B.getLarge();
615}
616LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator!=(int64_tA,constDynamicAPInt &B) {
617if (LLVM_LIKELY(B.isSmall()))
618returnA !=B.getSmall();
619returnA !=B.getLarge();
620}
621LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator>(int64_tA,constDynamicAPInt &B) {
622if (LLVM_LIKELY(B.isSmall()))
623returnA >B.getSmall();
624returnA >B.getLarge();
625}
626LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator<(int64_tA,constDynamicAPInt &B) {
627if (LLVM_LIKELY(B.isSmall()))
628returnA <B.getSmall();
629returnA <B.getLarge();
630}
631LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator<=(int64_tA,constDynamicAPInt &B) {
632if (LLVM_LIKELY(B.isSmall()))
633returnA <=B.getSmall();
634returnA <=B.getLarge();
635}
636LLVM_ATTRIBUTE_ALWAYS_INLINEbooloperator>=(int64_tA,constDynamicAPInt &B) {
637if (LLVM_LIKELY(B.isSmall()))
638returnA >=B.getSmall();
639returnA >=B.getLarge();
640}
641}// namespace llvm
642
643#endif// LLVM_ADT_DYNAMICAPINT_H
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
LLVM_UNLIKELY
#define LLVM_UNLIKELY(EXPR)
Definition:Compiler.h:320
LLVM_ATTRIBUTE_ALWAYS_INLINE
#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:340
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition:Compiler.h:622
LLVM_LIKELY
#define LLVM_LIKELY(EXPR)
Definition:Compiler.h:319
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
MathExtras.h
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
SlowDynamicAPInt.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
llvm::DynamicAPInt
This class provides support for dynamic arbitrary-precision arithmetic.
Definition:DynamicAPInt.h:46
llvm::DynamicAPInt::operator%=
friend DynamicAPInt & operator%=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:534
llvm::DynamicAPInt::print
raw_ostream & print(raw_ostream &OS) const
Definition:DynamicAPInt.cpp:29
llvm::DynamicAPInt::operator>=
friend bool operator>=(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:606
llvm::DynamicAPInt::operator>
friend bool operator>(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:591
llvm::DynamicAPInt::ceilDiv
friend DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition:DynamicAPInt.h:358
llvm::DynamicAPInt::operator!=
friend bool operator!=(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:586
llvm::DynamicAPInt::operator--
DynamicAPInt & operator--()
Definition:DynamicAPInt.h:511
llvm::DynamicAPInt::operator=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(const DynamicAPInt &O)
Definition:DynamicAPInt.h:129
llvm::DynamicAPInt::abs
friend DynamicAPInt abs(const DynamicAPInt &X)
Definition:DynamicAPInt.h:354
llvm::DynamicAPInt::gcd
friend DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition:DynamicAPInt.h:390
llvm::DynamicAPInt::lcm
friend DynamicAPInt lcm(const DynamicAPInt &A, const DynamicAPInt &B)
Returns the least common multiple of A and B.
Definition:DynamicAPInt.h:400
llvm::DynamicAPInt::operator+
friend DynamicAPInt operator+(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:538
llvm::DynamicAPInt::operator+=
friend DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:518
llvm::DynamicAPInt::DynamicAPInt
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt()
Definition:DynamicAPInt.h:118
llvm::DynamicAPInt::operator/
friend DynamicAPInt operator/(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:550
llvm::DynamicAPInt::operator*=
friend DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:526
llvm::DynamicAPInt::operator%
friend DynamicAPInt operator%(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:554
llvm::DynamicAPInt::operator=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(int X)
Definition:DynamicAPInt.h:137
llvm::DynamicAPInt::ValLarge
detail::SlowDynamicAPInt ValLarge
Definition:DynamicAPInt.h:49
llvm::DynamicAPInt::operator<
friend bool operator<(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:596
llvm::DynamicAPInt::static_assert_layout
void static_assert_layout()
Definition:DynamicAPInt.cpp:21
llvm::DynamicAPInt::divByPositive
DynamicAPInt divByPositive(const DynamicAPInt &O) const
Definition:DynamicAPInt.h:334
llvm::DynamicAPInt::DynamicAPInt
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(const DynamicAPInt &O)
Definition:DynamicAPInt.h:123
llvm::DynamicAPInt::operator/=
friend DynamicAPInt & operator/=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:530
llvm::DynamicAPInt::operator-
DynamicAPInt operator-() const
Definition:DynamicAPInt.h:416
llvm::DynamicAPInt::dump
LLVM_DUMP_METHOD void dump() const
Definition:DynamicAPInt.cpp:35
llvm::DynamicAPInt::hash_value
friend hash_code hash_value(const DynamicAPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
llvm::DynamicAPInt::operator++
DynamicAPInt & operator++()
Definition:DynamicAPInt.h:508
llvm::DynamicAPInt::operator<=
friend bool operator<=(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:601
llvm::DynamicAPInt::mod
friend DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
Definition:DynamicAPInt.h:382
llvm::DynamicAPInt::operator==
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::DynamicAPInt::~DynamicAPInt
LLVM_ATTRIBUTE_ALWAYS_INLINE ~DynamicAPInt()
Definition:DynamicAPInt.h:119
llvm::DynamicAPInt::floorDiv
friend DynamicAPInt floorDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition:DynamicAPInt.h:369
llvm::DynamicAPInt::operator*
friend DynamicAPInt operator*(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:546
llvm::DynamicAPInt::operator-=
friend DynamicAPInt & operator-=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:522
llvm::DynamicAPInt::ValSmall
int64_t ValSmall
Definition:DynamicAPInt.h:48
llvm::DynamicAPInt::DynamicAPInt
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(int64_t Val)
Definition:DynamicAPInt.h:114
llvm::DynamicAPInt::divByPositiveInPlace
DynamicAPInt & divByPositiveInPlace(const DynamicAPInt &O)
Definition:DynamicAPInt.h:494
llvm::detail::SlowDynamicAPInt
A simple class providing dynamic arbitrary-precision arithmetic.
Definition:SlowDynamicAPInt.h:34
llvm::hash_code
An opaque object representing a hash code.
Definition:Hashing.h:75
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
llvm::RISCVFenceField::O
@ O
Definition:RISCVBaseInfo.h:372
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition:APSInt.h:361
llvm::gcd
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition:DynamicAPInt.h:390
llvm::MulOverflow
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:754
llvm::divideSignedWouldOverflow
constexpr bool divideSignedWouldOverflow(U Numerator, V Denominator)
Definition:MathExtras.h:420
llvm::mod
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
Definition:DynamicAPInt.h:382
llvm::hash_value
hash_code hash_value(const FixedPointSemantics &Val)
Definition:APFixedPoint.h:136
llvm::operator*
APInt operator*(APInt a, uint64_t RHS)
Definition:APInt.h:2204
llvm::abs
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition:APFloat.h:1534
llvm::divideFloorSigned
constexpr T divideFloorSigned(U Numerator, V Denominator)
Returns the integer floor(Numerator / Denominator).
Definition:MathExtras.h:443
llvm::operator!=
bool operator!=(uint64_t V1, const APInt &V2)
Definition:APInt.h:2082
llvm::operator>=
bool operator>=(int64_t V1, const APSInt &V2)
Definition:APSInt.h:360
llvm::operator+=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:518
llvm::operator-=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator-=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:522
llvm::floorDiv
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt floorDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition:DynamicAPInt.h:369
llvm::operator==
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
Definition:AddressRanges.h:153
llvm::operator%
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt operator%(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:554
llvm::operator*=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator*=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:526
llvm::operator/=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator/=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:530
llvm::operator>
bool operator>(int64_t V1, const APSInt &V2)
Definition:APSInt.h:362
llvm::ceilDiv
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
Definition:DynamicAPInt.h:358
llvm::int64fromDynamicAPInt
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
llvm::divideCeilSigned
constexpr T divideCeilSigned(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition:MathExtras.h:427
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition:APFixedPoint.h:303
llvm::lcm
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
llvm::operator-
APInt operator-(APInt)
Definition:APInt.h:2157
llvm::dynamicAPIntFromInt64
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt dynamicAPIntFromInt64(int64_t X)
Definition:DynamicAPInt.h:237
llvm::AddOverflow
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:702
llvm::operator+
APInt operator+(APInt a, const APInt &b)
Definition:APInt.h:2162
llvm::SubOverflow
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:728
llvm::operator<=
bool operator<=(int64_t V1, const APSInt &V2)
Definition:APSInt.h:359
llvm::operator%=
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator%=(DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:534
llvm::operator/
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt operator/(const DynamicAPInt &A, int64_t B)
Definition:DynamicAPInt.h:550

Generated on Thu Jul 17 2025 04:08:14 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp