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