Skip to content

Commit a5c3182

Browse files
committed
mlir/Presburger/MPInt: move into LLVM/ADT
MPInt is an arbitrary-precision integer library that builds on top of APInt, and has a fast-path when the number fits within 64 bits. It was originally written for the Presburger library in MLIR, but seems useful to the LLVM project in general, independently of the Presburger library or MLIR. Hence, move it into LLVM/ADT. This patch is part of a project to move the Presburger library into LLVM.
1 parent 0fb216f commit a5c3182

40 files changed

+1869
-1774
lines changed

llvm/include/llvm/ADT/DynamicAPInt.h

Lines changed: 640 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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

llvm/lib/Support/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ add_llvm_component_library(LLVMSupport
170170
DivisionByConstantInfo.cpp
171171
DAGDeltaAlgorithm.cpp
172172
DJB.cpp
173+
DynamicAPInt.cpp
173174
ELFAttributeParser.cpp
174175
ELFAttributes.cpp
175176
Error.cpp
@@ -223,6 +224,7 @@ add_llvm_component_library(LLVMSupport
223224
SHA1.cpp
224225
SHA256.cpp
225226
Signposts.cpp
227+
SlowDynamicAPInt.cpp
226228
SmallPtrSet.cpp
227229
SmallVector.cpp
228230
SourceMgr.cpp

llvm/lib/Support/DynamicAPInt.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===- DynamicAPInt.cpp - DynamicAPInt Implementation -----------*- 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+
#include "llvm/ADT/DynamicAPInt.h"
9+
#include "llvm/ADT/Hashing.h"
10+
#include "llvm/Support/Debug.h"
11+
#include "llvm/Support/raw_ostream.h"
12+
13+
using namespace llvm;
14+
15+
hash_code llvm::hash_value(const DynamicAPInt &X) {
16+
if (X.isSmall())
17+
return llvm::hash_value(X.getSmall());
18+
return detail::hash_value(X.getLarge());
19+
}
20+
21+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
22+
raw_ostream &DynamicAPInt::print(raw_ostream &OS) const {
23+
if (isSmall())
24+
return OS << ValSmall;
25+
return OS << ValLarge;
26+
}
27+
28+
void DynamicAPInt::dump() const { print(dbgs()); }
29+
#endif

0 commit comments

Comments
 (0)