|
| 1 | +//===- SlowDynamicAPInt.h - SlowDynamicAPInt 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. |
| 12 | +// |
| 13 | +// This class is to be used as a fallback slow path for the DynamicAPInt class, |
| 14 | +// and is not intended to be used directly. |
| 15 | +// |
| 16 | +//===----------------------------------------------------------------------===// |
| 17 | + |
| 18 | +#ifndef LLVM_ADT_SLOWDYNAMICAPINT_H |
| 19 | +#define LLVM_ADT_SLOWDYNAMICAPINT_H |
| 20 | + |
| 21 | +#include "llvm/ADT/APInt.h" |
| 22 | +#include "llvm/Support/raw_ostream.h" |
| 23 | + |
| 24 | +namespace llvm::detail { |
| 25 | +/// A simple class providing dynamic arbitrary-precision arithmetic. Internally, |
| 26 | +/// it stores an APInt, whose width is doubled whenever an overflow occurs at a |
| 27 | +/// certain width. The default constructor sets the initial width to 64. |
| 28 | +/// SlowDynamicAPInt is primarily intended to be used as a slow fallback path |
| 29 | +/// for the upcoming DynamicAPInt class. |
| 30 | +class SlowDynamicAPInt { |
| 31 | + APInt Val; |
| 32 | + |
| 33 | +public: |
| 34 | + explicit SlowDynamicAPInt(int64_t Val); |
| 35 | + SlowDynamicAPInt(); |
| 36 | + explicit SlowDynamicAPInt(const APInt &Val); |
| 37 | + SlowDynamicAPInt &operator=(int64_t Val); |
| 38 | + explicit operator int64_t() const; |
| 39 | + SlowDynamicAPInt operator-() const; |
| 40 | + bool operator==(const SlowDynamicAPInt &O) const; |
| 41 | + bool operator!=(const SlowDynamicAPInt &O) const; |
| 42 | + bool operator>(const SlowDynamicAPInt &O) const; |
| 43 | + bool operator<(const SlowDynamicAPInt &O) const; |
| 44 | + bool operator<=(const SlowDynamicAPInt &O) const; |
| 45 | + bool operator>=(const SlowDynamicAPInt &O) const; |
| 46 | + SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const; |
| 47 | + SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const; |
| 48 | + SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const; |
| 49 | + SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const; |
| 50 | + SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const; |
| 51 | + SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O); |
| 52 | + SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O); |
| 53 | + SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O); |
| 54 | + SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O); |
| 55 | + SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O); |
| 56 | + |
| 57 | + SlowDynamicAPInt &operator++(); |
| 58 | + SlowDynamicAPInt &operator--(); |
| 59 | + |
| 60 | + friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X); |
| 61 | + friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS, |
| 62 | + const SlowDynamicAPInt &RHS); |
| 63 | + friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS, |
| 64 | + const SlowDynamicAPInt &RHS); |
| 65 | + /// The operands must be non-negative for gcd. |
| 66 | + friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A, |
| 67 | + const SlowDynamicAPInt &B); |
| 68 | + |
| 69 | + /// Overload to compute a hash_code for a SlowDynamicAPInt value. |
| 70 | + friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT |
| 71 | + |
| 72 | + unsigned getBitWidth() const { return Val.getBitWidth(); } |
| 73 | + |
| 74 | +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
| 75 | + void print(raw_ostream &OS) const; |
| 76 | + LLVM_DUMP_METHOD void dump() const; |
| 77 | +#endif |
| 78 | +}; |
| 79 | + |
| 80 | +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
| 81 | +inline raw_ostream &operator<<(raw_ostream &OS, const SlowDynamicAPInt &X) { |
| 82 | + X.print(OS); |
| 83 | + return OS; |
| 84 | +} |
| 85 | +#endif |
| 86 | + |
| 87 | +/// Returns the remainder of dividing LHS by RHS. |
| 88 | +/// |
| 89 | +/// The RHS is always expected to be positive, and the result |
| 90 | +/// is always non-negative. |
| 91 | +SlowDynamicAPInt mod(const SlowDynamicAPInt &LHS, const SlowDynamicAPInt &RHS); |
| 92 | + |
| 93 | +/// Returns the least common multiple of A and B. |
| 94 | +SlowDynamicAPInt lcm(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B); |
| 95 | + |
| 96 | +/// Redeclarations of friend declarations above to |
| 97 | +/// make it discoverable by lookups. |
| 98 | +SlowDynamicAPInt abs(const SlowDynamicAPInt &X); |
| 99 | +SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS, |
| 100 | + const SlowDynamicAPInt &RHS); |
| 101 | +SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS, |
| 102 | + const SlowDynamicAPInt &RHS); |
| 103 | +SlowDynamicAPInt gcd(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B); |
| 104 | +hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT |
| 105 | + |
| 106 | +/// --------------------------------------------------------------------------- |
| 107 | +/// Convenience operator overloads for int64_t. |
| 108 | +/// --------------------------------------------------------------------------- |
| 109 | +SlowDynamicAPInt &operator+=(SlowDynamicAPInt &A, int64_t B); |
| 110 | +SlowDynamicAPInt &operator-=(SlowDynamicAPInt &A, int64_t B); |
| 111 | +SlowDynamicAPInt &operator*=(SlowDynamicAPInt &A, int64_t B); |
| 112 | +SlowDynamicAPInt &operator/=(SlowDynamicAPInt &A, int64_t B); |
| 113 | +SlowDynamicAPInt &operator%=(SlowDynamicAPInt &A, int64_t B); |
| 114 | + |
| 115 | +bool operator==(const SlowDynamicAPInt &A, int64_t B); |
| 116 | +bool operator!=(const SlowDynamicAPInt &A, int64_t B); |
| 117 | +bool operator>(const SlowDynamicAPInt &A, int64_t B); |
| 118 | +bool operator<(const SlowDynamicAPInt &A, int64_t B); |
| 119 | +bool operator<=(const SlowDynamicAPInt &A, int64_t B); |
| 120 | +bool operator>=(const SlowDynamicAPInt &A, int64_t B); |
| 121 | +SlowDynamicAPInt operator+(const SlowDynamicAPInt &A, int64_t B); |
| 122 | +SlowDynamicAPInt operator-(const SlowDynamicAPInt &A, int64_t B); |
| 123 | +SlowDynamicAPInt operator*(const SlowDynamicAPInt &A, int64_t B); |
| 124 | +SlowDynamicAPInt operator/(const SlowDynamicAPInt &A, int64_t B); |
| 125 | +SlowDynamicAPInt operator%(const SlowDynamicAPInt &A, int64_t B); |
| 126 | + |
| 127 | +bool operator==(int64_t A, const SlowDynamicAPInt &B); |
| 128 | +bool operator!=(int64_t A, const SlowDynamicAPInt &B); |
| 129 | +bool operator>(int64_t A, const SlowDynamicAPInt &B); |
| 130 | +bool operator<(int64_t A, const SlowDynamicAPInt &B); |
| 131 | +bool operator<=(int64_t A, const SlowDynamicAPInt &B); |
| 132 | +bool operator>=(int64_t A, const SlowDynamicAPInt &B); |
| 133 | +SlowDynamicAPInt operator+(int64_t A, const SlowDynamicAPInt &B); |
| 134 | +SlowDynamicAPInt operator-(int64_t A, const SlowDynamicAPInt &B); |
| 135 | +SlowDynamicAPInt operator*(int64_t A, const SlowDynamicAPInt &B); |
| 136 | +SlowDynamicAPInt operator/(int64_t A, const SlowDynamicAPInt &B); |
| 137 | +SlowDynamicAPInt operator%(int64_t A, const SlowDynamicAPInt &B); |
| 138 | +} // namespace llvm::detail |
| 139 | + |
| 140 | +#endif // LLVM_ADT_SLOWDYNAMICAPINT_H |
0 commit comments