[Mlir-commits] [llvm] [mlir] mlir/Presburger/MPInt: move into LLVM/ADT (PR #94953)

Arjun P llvmlistbot at llvm.org
Mon Jun 10 05:01:21 PDT 2024


================
@@ -0,0 +1,644 @@
+//===- MPInt.h - MPInt 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 is optimized for small-values
+// by providing fast-paths for the cases when the value stored fits in 64-bits.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_MPINT_H
+#define LLVM_ADT_MPINT_H
+
+#include "llvm/ADT/SlowMPInt.h"
+#include "llvm/Support/raw_ostream.h"
+#include <numeric>
+
+namespace llvm {
+namespace detail {
+/// ---------------------------------------------------------------------------
+/// Some helpers from MLIR/MathExtras.
+/// ---------------------------------------------------------------------------
+LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t ceilDiv(int64_t Numerator,
+                                             int64_t Denominator) {
+  assert(Denominator);
+  if (!Numerator)
+    return 0;
+  // C's integer division rounds towards 0.
+  int64_t X = (Denominator > 0) ? -1 : 1;
+  bool SameSign = (Numerator > 0) == (Denominator > 0);
+  return SameSign ? ((Numerator + X) / Denominator) + 1
+                  : -(-Numerator / Denominator);
+}
+
+LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t floorDiv(int64_t Numerator,
+                                              int64_t Denominator) {
+  assert(Denominator);
+  if (!Numerator)
+    return 0;
+  // C's integer division rounds towards 0.
+  int64_t X = (Denominator > 0) ? -1 : 1;
+  bool SameSign = (Numerator > 0) == (Denominator > 0);
+  return SameSign ? Numerator / Denominator
+                  : -((-Numerator + X) / Denominator) - 1;
+}
+
+/// Returns the remainder of the Euclidean division of LHS by RHS. Result is
+/// always non-negative.
+LLVM_ATTRIBUTE_ALWAYS_INLINE int64_t mod(int64_t Numerator,
+                                         int64_t Denominator) {
+  assert(Denominator >= 1);
+  return Numerator % Denominator < 0 ? Numerator % Denominator + Denominator
+                                     : Numerator % Denominator;
+}
+
+/// If builtin intrinsics for overflow-checked arithmetic are available,
+/// use them. Otherwise, call through to LLVM's overflow-checked arithmetic
+/// functionality. Those functions also have such macro-gated uses of intrinsics
+/// but they are not always_inlined, which is important for us to achieve
+/// high-performance; calling the functions directly would result in a slowdown
+/// of 1.15x.
+LLVM_ATTRIBUTE_ALWAYS_INLINE bool addOverflow(int64_t X, int64_t Y,
+                                              int64_t &Result) {
+#if __has_builtin(__builtin_add_overflow)
+  return __builtin_add_overflow(X, Y, &Result);
+#else
+  return AddOverflow(X, Y, Result);
+#endif
+}
+LLVM_ATTRIBUTE_ALWAYS_INLINE bool subOverflow(int64_t X, int64_t Y,
+                                              int64_t &Result) {
+#if __has_builtin(__builtin_sub_overflow)
+  return __builtin_sub_overflow(X, Y, &Result);
+#else
+  return SubOverflow(X, Y, Result);
+#endif
+}
+LLVM_ATTRIBUTE_ALWAYS_INLINE bool mulOverflow(int64_t X, int64_t Y,
+                                              int64_t &Result) {
+#if __has_builtin(__builtin_mul_overflow)
+  return __builtin_mul_overflow(X, Y, &Result);
+#else
+  return MulOverflow(X, Y, Result);
+#endif
+}
+} // namespace detail
+
+/// This class provides support for multi-precision arithmetic.
+///
+/// Unlike APInt, this extends the precision as necessary to prevent overflows
+/// and supports operations between objects with differing internal precisions.
+///
+/// This is optimized for small-values by providing fast-paths for the cases
+/// when the value stored fits in 64-bits. We annotate all fastpaths by using
+/// the LLVM_LIKELY/LLVM_UNLIKELY annotations. Removing these would result in
+/// a 1.2x performance slowdown.
+///
+/// We always_inline all operations; removing these results in a 1.5x
+/// performance slowdown.
+///
+/// When holdsLarge is true, a SlowMPInt is held in the union. If it is false,
----------------
Superty wrote:

I assume you changed holdsLarge -> HoldsLarge to match ADT style. The change needs to be made in documentation too. 

https://github.com/llvm/llvm-project/pull/94953


More information about the Mlir-commits mailing list