LLVM: include/llvm/ADT/DynamicAPInt.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16#ifndef LLVM_ADT_DYNAMICAPINT_H

17#define LLVM_ADT_DYNAMICAPINT_H

18

23#include

24

25namespace llvm {

26

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48class DynamicAPInt {

49 union {

52 };

53

56 ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();

59 }

61 initLarge(const detail::SlowDynamicAPInt &O) {

63

64

65

66

67

68 new (&ValLarge) detail::SlowDynamicAPInt(O);

69 } else {

70

71

72

74 }

75 }

76

78 const detail::SlowDynamicAPInt &Val)

81 return ValLarge.Val.BitWidth == 0;

82 }

84 return !isSmall();

85 }

86

87

90 "getSmall should only be called when the value stored is small!");

92 }

95 "getSmall should only be called when the value stored is small!");

97 }

99 getLarge() const {

101 "getLarge should only be called when the value stored is large!");

103 }

106 "getLarge should only be called when the value stored is large!");

108 }

109 explicit operator detail::SlowDynamicAPInt() const {

110 if (isSmall())

111 return detail::SlowDynamicAPInt(getSmall());

112 return getLarge();

113 }

114

115public:

131 ValLarge.detail::SlowDynamicAPInt::~SlowDynamicAPInt();

132 }

137 initLarge(O.ValLarge);

138 }

141 initSmall(O.ValSmall);

142 return *this;

143 }

144 initLarge(O.ValLarge);

145 return *this;

146 }

148 initSmall(X);

149 return *this;

150 }

152 if (isSmall())

153 return getSmall();

154 return static_cast<int64_t>(getLarge());

155 }

156

176

177

178

181

186

190

191

192

193

199

211

223

225

227

229

230#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

232#endif

233};

234

236 X.print(OS);

237 return OS;

238}

239

240

241

243

244

245

246

248 return int64_t(X);

249}

253

254

255

257 const DynamicAPInt &RHS);

258

259

260

261

262

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

303

304

307 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

308 DynamicAPInt Result;

309 bool Overflow = AddOverflow(getSmall(), O.getSmall(), Result.getSmall());

311 return Result;

314 }

317}

320 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

321 DynamicAPInt Result;

322 bool Overflow = SubOverflow(getSmall(), O.getSmall(), Result.getSmall());

324 return Result;

327 }

330}

333 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

334 DynamicAPInt Result;

335 bool Overflow = MulOverflow(getSmall(), O.getSmall(), Result.getSmall());

337 return Result;

340 }

343}

344

345

354

357 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

358

360 return -*this;

361 return DynamicAPInt(getSmall() / O.getSmall());

362 }

365}

366

368 return DynamicAPInt(X >= 0 ? X : -X);

369}

370

372 const DynamicAPInt &RHS) {

376 return -LHS;

378 }

379 return DynamicAPInt(

381}

383 const DynamicAPInt &RHS) {

387 return -LHS;

389 }

390 return DynamicAPInt(

392}

393

394

396 const DynamicAPInt &RHS) {

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!");

407 return DynamicAPInt(std::gcd(A.getSmall(), B.getSmall()));

408 return DynamicAPInt(

410}

411

412

414 const DynamicAPInt &B) {

415 DynamicAPInt X = abs(A);

416 DynamicAPInt Y = abs(B);

417 return (X * Y) / gcd(X, Y);

418}

419

420

428

431 if (LLVM_LIKELY(getSmall() != std::numeric_limits<int64_t>::min()))

434 }

436}

437

438

439

440

443 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

444 int64_t Result = getSmall();

445 bool Overflow = AddOverflow(getSmall(), O.getSmall(), Result);

447 getSmall() = Result;

448 return *this;

449 }

450

451

454 }

457}

460 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

461 int64_t Result = getSmall();

462 bool Overflow = SubOverflow(getSmall(), O.getSmall(), Result);

464 getSmall() = Result;

465 return *this;

466 }

467

468

471 }

474}

477 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

478 int64_t Result = getSmall();

479 bool Overflow = MulOverflow(getSmall(), O.getSmall(), Result);

481 getSmall() = Result;

482 return *this;

483 }

484

485

488 }

491}

494 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

495

497 return *this = -*this;

498 getSmall() /= O.getSmall();

499 return *this;

500 }

503}

504

505

509 if (LLVM_LIKELY(isSmall() && O.isSmall())) {

510 getSmall() /= O.getSmall();

511 return *this;

512 }

515}

516

519 return *this = *this % O;

520}

522 return *this += 1;

523}

525 return *this -= 1;

526}

527

528

529

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

593

596 return A.getSmall() == B;

597 return A.getLarge() == B;

598}

601 return A.getSmall() != B;

602 return A.getLarge() != B;

603}

606 return A.getSmall() > B;

607 return A.getLarge() > B;

608}

611 return A.getSmall() < B;

612 return A.getLarge() < B;

613}

616 return A.getSmall() <= B;

617 return A.getLarge() <= B;

618}

621 return A.getSmall() >= B;

622 return A.getLarge() >= B;

623}

626 return A == B.getSmall();

627 return A == B.getLarge();

628}

631 return A != B.getSmall();

632 return A != B.getLarge();

633}

636 return A > B.getSmall();

637 return A > B.getLarge();

638}

641 return A < B.getSmall();

642 return A < B.getLarge();

643}

646 return A <= B.getSmall();

647 return A <= B.getLarge();

648}

651 return A >= B.getSmall();

652 return A >= B.getLarge();

653}

654}

655

656#endif

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< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_UNLIKELY(EXPR)

#define LLVM_ATTRIBUTE_ALWAYS_INLINE

LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

#define LLVM_LIKELY(EXPR)

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

Class for arbitrary precision integers.

unsigned getBitWidth() const

Return the number of bits in the APInt.

int64_t getSExtValue() const

Get sign extended value.

This class provides support for dynamic arbitrary-precision arithmetic.

Definition DynamicAPInt.h:48

LLVM_ABI raw_ostream & print(raw_ostream &OS) const

DynamicAPInt & operator%=(const DynamicAPInt &O)

Definition DynamicAPInt.h:518

friend DynamicAPInt ceilDiv(const DynamicAPInt &LHS, const DynamicAPInt &RHS)

Definition DynamicAPInt.h:371

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

DynamicAPInt & operator/=(const DynamicAPInt &O)

Definition DynamicAPInt.h:493

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

DynamicAPInt operator/(const DynamicAPInt &O) const

Definition DynamicAPInt.h:356

LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt()

Definition DynamicAPInt.h:128

DynamicAPInt operator%(const DynamicAPInt &O) const

This operation cannot overflow.

Definition DynamicAPInt.h:422

LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator=(int X)

Definition DynamicAPInt.h:147

detail::SlowDynamicAPInt ValLarge

Definition DynamicAPInt.h:51

DynamicAPInt & operator*=(const DynamicAPInt &O)

Definition DynamicAPInt.h:476

bool operator==(const DynamicAPInt &O) const

We define the operations here in the header to facilitate inlining.

Definition DynamicAPInt.h:265

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

bool operator<=(const DynamicAPInt &O) const

Definition DynamicAPInt.h:289

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

bool operator<(const DynamicAPInt &O) const

Definition DynamicAPInt.h:283

bool operator>=(const DynamicAPInt &O) const

Definition DynamicAPInt.h:295

LLVM_DUMP_METHOD void dump() const

DynamicAPInt & operator+=(const DynamicAPInt &O)

Definition DynamicAPInt.h:442

DynamicAPInt operator+(const DynamicAPInt &O) const

Definition DynamicAPInt.h:306

DynamicAPInt & operator-=(const DynamicAPInt &O)

Definition DynamicAPInt.h:459

DynamicAPInt & operator++()

Definition DynamicAPInt.h:521

DynamicAPInt operator*(const DynamicAPInt &O) const

Definition DynamicAPInt.h:332

bool operator!=(const DynamicAPInt &O) const

Definition DynamicAPInt.h:271

friend DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)

is always non-negative.

Definition DynamicAPInt.h:395

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

int64_t ValSmall

Definition DynamicAPInt.h:50

LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt(int64_t Val)

Definition DynamicAPInt.h:116

DynamicAPInt & divByPositiveInPlace(const DynamicAPInt &O)

Definition DynamicAPInt.h:507

bool operator>(const DynamicAPInt &O) const

Definition DynamicAPInt.h:277

A simple class providing dynamic arbitrary-precision arithmetic.

An opaque object representing a hash code.

This class implements an extremely fast bulk output stream that can only output to a stream.

This is an optimization pass for GlobalISel generic memory operations.

bool operator<(int64_t V1, const APSInt &V2)

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...

constexpr bool divideSignedWouldOverflow(U Numerator, V Denominator)

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)

APInt operator*(APInt a, uint64_t RHS)

APFloat abs(APFloat X)

Returns the absolute value of the argument.

constexpr T divideFloorSigned(U Numerator, V Denominator)

Returns the integer floor(Numerator / Denominator).

bool operator!=(uint64_t V1, const APInt &V2)

bool operator>=(int64_t V1, const APSInt &V2)

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)

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).

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

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

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 ...

APInt operator+(APInt a, const APInt &b)

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...

bool operator<=(int64_t V1, const APSInt &V2)

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