forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mlir/Presburger/MPInt: move into llvm/ADT (llvm#94953)
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 under the name DynamicAPInt. This patch is part of a project to move the Presburger library into LLVM.
- Loading branch information
Showing
40 changed files
with
1,869 additions
and
1,774 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
//===- SlowDynamicAPInt.h - SlowDynamicAPInt Class --------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This is a simple class to represent arbitrary precision signed integers. | ||
// Unlike APInt, one does not have to specify a fixed maximum size, and the | ||
// integer can take on any arbitrary values. | ||
// | ||
// This class is to be used as a fallback slow path for the DynamicAPInt class, | ||
// and is not intended to be used directly. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_ADT_SLOWDYNAMICAPINT_H | ||
#define LLVM_ADT_SLOWDYNAMICAPINT_H | ||
|
||
#include "llvm/ADT/APInt.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
|
||
namespace llvm::detail { | ||
/// A simple class providing dynamic arbitrary-precision arithmetic. Internally, | ||
/// it stores an APInt, whose width is doubled whenever an overflow occurs at a | ||
/// certain width. The default constructor sets the initial width to 64. | ||
/// SlowDynamicAPInt is primarily intended to be used as a slow fallback path | ||
/// for the upcoming DynamicAPInt class. | ||
class SlowDynamicAPInt { | ||
APInt Val; | ||
|
||
public: | ||
explicit SlowDynamicAPInt(int64_t Val); | ||
SlowDynamicAPInt(); | ||
explicit SlowDynamicAPInt(const APInt &Val); | ||
SlowDynamicAPInt &operator=(int64_t Val); | ||
explicit operator int64_t() const; | ||
SlowDynamicAPInt operator-() const; | ||
bool operator==(const SlowDynamicAPInt &O) const; | ||
bool operator!=(const SlowDynamicAPInt &O) const; | ||
bool operator>(const SlowDynamicAPInt &O) const; | ||
bool operator<(const SlowDynamicAPInt &O) const; | ||
bool operator<=(const SlowDynamicAPInt &O) const; | ||
bool operator>=(const SlowDynamicAPInt &O) const; | ||
SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const; | ||
SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const; | ||
SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const; | ||
SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const; | ||
SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const; | ||
SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O); | ||
SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O); | ||
SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O); | ||
SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O); | ||
SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O); | ||
|
||
SlowDynamicAPInt &operator++(); | ||
SlowDynamicAPInt &operator--(); | ||
|
||
friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X); | ||
friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS, | ||
const SlowDynamicAPInt &RHS); | ||
friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS, | ||
const SlowDynamicAPInt &RHS); | ||
/// The operands must be non-negative for gcd. | ||
friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A, | ||
const SlowDynamicAPInt &B); | ||
|
||
/// Overload to compute a hash_code for a SlowDynamicAPInt value. | ||
friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT | ||
|
||
unsigned getBitWidth() const { return Val.getBitWidth(); } | ||
|
||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||
void print(raw_ostream &OS) const; | ||
LLVM_DUMP_METHOD void dump() const; | ||
#endif | ||
}; | ||
|
||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||
inline raw_ostream &operator<<(raw_ostream &OS, const SlowDynamicAPInt &X) { | ||
X.print(OS); | ||
return OS; | ||
} | ||
#endif | ||
|
||
/// Returns the remainder of dividing LHS by RHS. | ||
/// | ||
/// The RHS is always expected to be positive, and the result | ||
/// is always non-negative. | ||
SlowDynamicAPInt mod(const SlowDynamicAPInt &LHS, const SlowDynamicAPInt &RHS); | ||
|
||
/// Returns the least common multiple of A and B. | ||
SlowDynamicAPInt lcm(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B); | ||
|
||
/// Redeclarations of friend declarations above to | ||
/// make it discoverable by lookups. | ||
SlowDynamicAPInt abs(const SlowDynamicAPInt &X); | ||
SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS, | ||
const SlowDynamicAPInt &RHS); | ||
SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS, | ||
const SlowDynamicAPInt &RHS); | ||
SlowDynamicAPInt gcd(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B); | ||
hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT | ||
|
||
/// --------------------------------------------------------------------------- | ||
/// Convenience operator overloads for int64_t. | ||
/// --------------------------------------------------------------------------- | ||
SlowDynamicAPInt &operator+=(SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt &operator-=(SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt &operator*=(SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt &operator/=(SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt &operator%=(SlowDynamicAPInt &A, int64_t B); | ||
|
||
bool operator==(const SlowDynamicAPInt &A, int64_t B); | ||
bool operator!=(const SlowDynamicAPInt &A, int64_t B); | ||
bool operator>(const SlowDynamicAPInt &A, int64_t B); | ||
bool operator<(const SlowDynamicAPInt &A, int64_t B); | ||
bool operator<=(const SlowDynamicAPInt &A, int64_t B); | ||
bool operator>=(const SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt operator+(const SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt operator-(const SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt operator*(const SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt operator/(const SlowDynamicAPInt &A, int64_t B); | ||
SlowDynamicAPInt operator%(const SlowDynamicAPInt &A, int64_t B); | ||
|
||
bool operator==(int64_t A, const SlowDynamicAPInt &B); | ||
bool operator!=(int64_t A, const SlowDynamicAPInt &B); | ||
bool operator>(int64_t A, const SlowDynamicAPInt &B); | ||
bool operator<(int64_t A, const SlowDynamicAPInt &B); | ||
bool operator<=(int64_t A, const SlowDynamicAPInt &B); | ||
bool operator>=(int64_t A, const SlowDynamicAPInt &B); | ||
SlowDynamicAPInt operator+(int64_t A, const SlowDynamicAPInt &B); | ||
SlowDynamicAPInt operator-(int64_t A, const SlowDynamicAPInt &B); | ||
SlowDynamicAPInt operator*(int64_t A, const SlowDynamicAPInt &B); | ||
SlowDynamicAPInt operator/(int64_t A, const SlowDynamicAPInt &B); | ||
SlowDynamicAPInt operator%(int64_t A, const SlowDynamicAPInt &B); | ||
} // namespace llvm::detail | ||
|
||
#endif // LLVM_ADT_SLOWDYNAMICAPINT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//===- DynamicAPInt.cpp - DynamicAPInt Implementation -----------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
#include "llvm/ADT/DynamicAPInt.h" | ||
#include "llvm/ADT/Hashing.h" | ||
#include "llvm/Support/Debug.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
|
||
using namespace llvm; | ||
|
||
hash_code llvm::hash_value(const DynamicAPInt &X) { | ||
if (X.isSmall()) | ||
return llvm::hash_value(X.getSmall()); | ||
return detail::hash_value(X.getLarge()); | ||
} | ||
|
||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||
raw_ostream &DynamicAPInt::print(raw_ostream &OS) const { | ||
if (isSmall()) | ||
return OS << ValSmall; | ||
return OS << ValLarge; | ||
} | ||
|
||
void DynamicAPInt::dump() const { print(dbgs()); } | ||
#endif |
Oops, something went wrong.