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