optionally use imath for arbitrary precision integers
authorSebastian Pop <spop@codeaurora.org>
Wed, 12 Feb 2014 17:13:15 +0000 (12 11:13 -0600)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 29 May 2014 09:35:29 +0000 (29 11:35 +0200)
Some projects such as LLVM and Polly prefer not to use any
LGPL licensed libraries such as GMP.  The optional use of
the MIT licensed IMath library allows them to avoid this.

IMath is included as a submodule to ensure that a single
version of IMath is used for any given version of isl.
The public symbols are prefixed with isl_ to avoid conflicts
with other copies of IMath that may independently be used by
the users of isl.

The deprecated isl_int functions are not supported when IMath is used
since they depend on GMP.  We rename them when IMath is used to ensure
that any attempt to use them in an IMath enabled isl results in
a linker error.

The subdir-objects automake option is turned on since this is the
first time we use source files in subdirectories and since this
option will become the default in future versions of automake.

Signed-off-by: David Peixotto <dpeixott@codeaurora.org>
Signed-off-by: Sebastian Pop <spop@codeaurora.org>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
23 files changed:
.gitmodules [new file with mode: 0644]
Makefile.am
basis_reduction_tab.c
configure.ac
doc/user.pod
imath [new submodule]
imath_wrap/gmp_compat.c [new file with mode: 0644]
imath_wrap/gmp_compat.h [new file with mode: 0644]
imath_wrap/imath.c [new file with mode: 0644]
imath_wrap/imath.h [new file with mode: 0644]
imath_wrap/imrat.c [new file with mode: 0644]
imath_wrap/imrat.h [new file with mode: 0644]
imath_wrap/wrap.h [new file with mode: 0644]
isl_hide_deprecated.h [new file with mode: 0644]
isl_imath.c [new file with mode: 0644]
isl_imath.h [new file with mode: 0644]
isl_int.h
isl_int_gmp.h [copied from isl_int.h with 64% similarity]
isl_int_imath.h [new file with mode: 0644]
isl_val_imath.c [new file with mode: 0644]
isl_version.c
m4/ax_detect_gmp.m4
m4/ax_detect_imath.m4 [new file with mode: 0644]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..90aadaf
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "imath"]
+       path = imath
+       url = https://github.com/creachadair/imath.git
index 8f73e65..4152d80 100644 (file)
@@ -5,7 +5,7 @@ SUBDIRS = . $(MAYBE_INTERFACE) doc
 DIST_SUBDIRS = $(MAYBE_INTERFACE) doc
 
 ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = nostdinc
+AUTOMAKE_OPTIONS = nostdinc subdir-objects
 
 lib_LTLIBRARIES = libisl.la
 noinst_PROGRAMS = isl_test isl_polyhedron_sample isl_pip \
@@ -14,21 +14,52 @@ noinst_PROGRAMS = isl_test isl_polyhedron_sample isl_pip \
        isl_closure isl_bound isl_codegen
 TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh
 
+if IMATH_FOR_MP
+
+MP_SRC = \
+       isl_hide_deprecated.h \
+       isl_imath.c \
+       isl_imath.h \
+       isl_int_imath.h \
+       isl_val_imath.c \
+       imath_wrap/gmp_compat.h \
+       imath_wrap/imath.h \
+       imath_wrap/imrat.h \
+       imath_wrap/wrap.h \
+       imath_wrap/gmp_compat.c \
+       imath_wrap/imath.c \
+       imath_wrap/imrat.c
+
+DEPRECATED_SRC =
+MP_INCLUDE_H =
+endif
+
+if GMP_FOR_MP
 if NEED_GET_MEMORY_FUNCTIONS
 GET_MEMORY_FUNCTIONS=mp_get_memory_functions.c
 endif
 
-AM_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ @GMP_CPPFLAGS@
+MP_SRC = \
+       $(GET_MEMORY_FUNCTIONS) \
+       isl_int_gmp.h \
+       isl_gmp.c \
+       isl_val_gmp.c
+
+DEPRECATED_SRC = isl_ast_int.c
+MP_INCLUDE_H = include/isl/val_gmp.h
+endif
+
+AM_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ @MP_CPPFLAGS@
 AM_CFLAGS = @WARNING_FLAGS@
 
 libisl_la_SOURCES = \
-       $(GET_MEMORY_FUNCTIONS) \
+       $(MP_SRC) \
+       $(DEPRECATED_SRC) \
        isl_aff.c \
        isl_aff_private.h \
        isl_affine_hull.c \
        isl_arg.c \
        isl_ast.c \
-       isl_ast_int.c \
        isl_ast_private.h \
        isl_ast_build.c \
        isl_ast_build_private.h \
@@ -64,7 +95,6 @@ libisl_la_SOURCES = \
        isl_farkas.c \
        isl_flow.c \
        isl_fold.c \
-       isl_gmp.c \
        isl_hash.c \
        isl_id_to_ast_expr.c \
        isl_id_to_pw_aff.c \
@@ -126,41 +156,40 @@ libisl_la_SOURCES = \
        isl_union_map.c \
        isl_union_map_private.h \
        isl_val.c \
-       isl_val_gmp.c \
        isl_val_private.h \
        isl_vec_private.h \
        isl_vec.c \
        isl_version.c \
        isl_vertices_private.h \
        isl_vertices.c
-libisl_la_LIBADD = @GMP_LIBS@
+libisl_la_LIBADD = @MP_LIBS@
 libisl_la_LDFLAGS = -version-info @versioninfo@ \
-       @GMP_LDFLAGS@
+       @MP_LDFLAGS@
 
-isl_test_LDFLAGS = @GMP_LDFLAGS@
-isl_test_LDADD = libisl.la @GMP_LIBS@
+isl_test_LDFLAGS = @MP_LDFLAGS@
+isl_test_LDADD = libisl.la @MP_LIBS@
 
 isl_polyhedron_sample_LDADD = libisl.la
 isl_polyhedron_sample_SOURCES = \
        polyhedron_sample.c
 
-isl_pip_LDFLAGS = @GMP_LDFLAGS@
-isl_pip_LDADD = libisl.la @GMP_LIBS@
+isl_pip_LDFLAGS = @MP_LDFLAGS@
+isl_pip_LDADD = libisl.la @MP_LIBS@
 isl_pip_SOURCES = \
        pip.c
 
-isl_codegen_LDFLAGS = @GMP_LDFLAGS@
-isl_codegen_LDADD = libisl.la @GMP_LIBS@
+isl_codegen_LDFLAGS = @MP_LDFLAGS@
+isl_codegen_LDADD = libisl.la @MP_LIBS@
 isl_codegen_SOURCES = \
        codegen.c
 
-isl_bound_LDFLAGS = @GMP_LDFLAGS@
-isl_bound_LDADD = libisl.la @GMP_LIBS@
+isl_bound_LDFLAGS = @MP_LDFLAGS@
+isl_bound_LDADD = libisl.la @MP_LIBS@
 isl_bound_SOURCES = \
        bound.c
 
-isl_polyhedron_minimize_LDFLAGS = @GMP_LDFLAGS@
-isl_polyhedron_minimize_LDADD = libisl.la @GMP_LIBS@
+isl_polyhedron_minimize_LDFLAGS = @MP_LDFLAGS@
+isl_polyhedron_minimize_LDADD = libisl.la @MP_LIBS@
 isl_polyhedron_minimize_SOURCES = \
        polyhedron_minimize.c
 
@@ -183,6 +212,7 @@ isl_closure_SOURCES = \
 nodist_pkginclude_HEADERS = \
        include/isl/stdint.h
 pkginclude_HEADERS = \
+       $(MP_INCLUDE_H) \
        include/isl/aff.h \
        include/isl/aff_type.h \
        include/isl/arg.h \
@@ -224,7 +254,6 @@ pkginclude_HEADERS = \
        include/isl/union_set.h \
        include/isl/union_set_type.h \
        include/isl/val.h \
-       include/isl/val_gmp.h \
        include/isl/vec.h \
        include/isl/version.h \
        include/isl/vertices.h
@@ -267,6 +296,12 @@ EXTRA_DIST = \
        doc/mypod2latex \
        doc/manual.tex \
        doc/user.pod \
+       imath/gmp_compat.c \
+       imath/gmp_compat.h \
+       imath/imath.c \
+       imath/imath.h \
+       imath/imrat.c \
+       imath/imrat.h \
        interface/all.h \
        interface/isl.py.top \
        test_inputs
index 73e7074..112d423 100644 (file)
@@ -11,6 +11,7 @@
 #include <isl_map_private.h>
 #include <isl_seq.h>
 #include "isl_tab.h"
+#include <isl_int.h>
 #include <isl_config.h>
 
 struct tab_lp {
@@ -31,27 +32,49 @@ struct tab_lp {
        int              is_fixed;
 };
 
+#ifdef USE_GMP_FOR_MP
+#define GBR_type                           mpq_t
+#define GBR_init(v)                        mpq_init(v)
+#define GBR_clear(v)                       mpq_clear(v)
+#define GBR_set(a,b)                       mpq_set(a,b)
+#define GBR_set_ui(a,b)                            mpq_set_ui(a,b,1)
+#define GBR_mul(a,b,c)                     mpq_mul(a,b,c)
+#define GBR_lt(a,b)                        (mpq_cmp(a,b) < 0)
+#define GBR_is_zero(a)                     (mpq_sgn(a) == 0)
+#define GBR_numref(a)                      mpq_numref(a)
+#define GBR_denref(a)                      mpq_denref(a)
+#define GBR_floor(a,b)                     mpz_fdiv_q(a,GBR_numref(b),GBR_denref(b))
+#define GBR_ceil(a,b)                      mpz_cdiv_q(a,GBR_numref(b),GBR_denref(b))
+#endif /* USE_GMP_FOR_MP */
+
+#ifdef USE_IMATH_FOR_MP
+#include <imrat.h>
+
+#define GBR_type                           mp_rat
+#define GBR_init(v)                        v = mp_rat_alloc()
+#define GBR_clear(v)                       mp_rat_free(v)
+#define GBR_set(a,b)                       mp_rat_copy(b,a)
+#define GBR_set_ui(a,b)                            mp_rat_set_uvalue(a,b,1)
+#define GBR_mul(a,b,c)                     mp_rat_mul(b,c,a)
+#define GBR_lt(a,b)                        (mp_rat_compare(a,b) < 0)
+#define GBR_is_zero(a)                     (mp_rat_compare_zero(a) == 0)
+#define GBR_numref(a)                      mp_rat_numer_ref(a)
+#define GBR_denref(a)                      mp_rat_denom_ref(a)
+#define GBR_floor(a,b)                     impz_fdiv_q(a,GBR_numref(b),GBR_denref(b))
+#define GBR_ceil(a,b)                      impz_cdiv_q(a,GBR_numref(b),GBR_denref(b))
+#endif /* USE_IMATH_FOR_MP */
+
 static struct tab_lp *init_lp(struct isl_tab *tab);
 static void set_lp_obj(struct tab_lp *lp, isl_int *row, int dim);
 static int solve_lp(struct tab_lp *lp);
-static void get_obj_val(struct tab_lp* lp, mpq_t *F);
+static void get_obj_val(struct tab_lp* lp, GBR_type *F);
 static void delete_lp(struct tab_lp *lp);
 static int add_lp_row(struct tab_lp *lp, isl_int *row, int dim);
-static void get_alpha(struct tab_lp* lp, int row, mpq_t *alpha);
+static void get_alpha(struct tab_lp* lp, int row, GBR_type *alpha);
 static int del_lp_row(struct tab_lp *lp) WARN_UNUSED;
 static int cut_lp_to_hyperplane(struct tab_lp *lp, isl_int *row);
 
 #define GBR_LP                             struct tab_lp
-#define GBR_type                           mpq_t
-#define GBR_init(v)                        mpq_init(v)
-#define GBR_clear(v)                       mpq_clear(v)
-#define GBR_set(a,b)                       mpq_set(a,b)
-#define GBR_set_ui(a,b)                            mpq_set_ui(a,b,1)
-#define GBR_mul(a,b,c)                     mpq_mul(a,b,c)
-#define GBR_lt(a,b)                        (mpq_cmp(a,b) < 0)
-#define GBR_is_zero(a)                     (mpq_sgn(a) == 0)
-#define GBR_floor(a,b)                     mpz_fdiv_q(a,mpq_numref(b),mpq_denref(b))
-#define GBR_ceil(a,b)                      mpz_cdiv_q(a,mpq_numref(b),mpq_denref(b))
 #define GBR_lp_init(P)                     init_lp(P)
 #define GBR_lp_set_obj(lp, obj, dim)       set_lp_obj(lp, obj, dim)
 #define GBR_lp_solve(lp)                   solve_lp(lp)
@@ -194,10 +217,10 @@ static int cut_lp_to_hyperplane(struct tab_lp *lp, isl_int *row)
        return lp->tab->empty;
 }
 
-static void get_obj_val(struct tab_lp* lp, mpq_t *F)
+static void get_obj_val(struct tab_lp* lp, GBR_type *F)
 {
-       isl_int_neg(mpq_numref(*F), lp->opt);
-       isl_int_set(mpq_denref(*F), lp->opt_denom);
+       isl_int_neg(GBR_numref(*F), lp->opt);
+       isl_int_set(GBR_denref(*F), lp->opt_denom);
 }
 
 static void delete_lp(struct tab_lp *lp)
@@ -230,11 +253,11 @@ static int add_lp_row(struct tab_lp *lp, isl_int *row, int dim)
        return lp->neq++;
 }
 
-static void get_alpha(struct tab_lp* lp, int row, mpq_t *alpha)
+static void get_alpha(struct tab_lp* lp, int row, GBR_type *alpha)
 {
        row += lp->con_offset;
-       isl_int_neg(mpq_numref(*alpha), lp->tab->dual->el[1 + row]);
-       isl_int_set(mpq_denref(*alpha), lp->tab->dual->el[0]);
+       isl_int_neg(GBR_numref(*alpha), lp->tab->dual->el[1 + row]);
+       isl_int_set(GBR_denref(*alpha), lp->tab->dual->el[0]);
 }
 
 static int del_lp_row(struct tab_lp *lp)
index 1349095..c5d374d 100644 (file)
@@ -35,11 +35,32 @@ AM_CONDITIONAL(GENERATE_DOC, test -n "$PERL" -a -n "$PDFLATEX" -a -n "$POD2HTML"
 
 AX_CREATE_STDINT_H(include/isl/stdint.h)
 
-AC_SUBST(GMP_CPPFLAGS)
-AC_SUBST(GMP_LDFLAGS)
-AC_SUBST(GMP_LIBS)
-AX_DETECT_GMP
+AC_ARG_WITH([int],
+           [AS_HELP_STRING([--with-int=gmp|imath],
+                           [Which package to use to represent
+                               multi-precision integers [default=gmp]])],
+           [], [with_int=gmp])
+case "$with_int" in
+gmp|imath)
+       ;;
+*)
+       AC_MSG_ERROR([bad value ${withval} for --with-int (use gmp or imath)])
+esac
+
+AC_SUBST(MP_CPPFLAGS)
+AC_SUBST(MP_LDFLAGS)
+AC_SUBST(MP_LIBS)
+case "$with_int" in
+gmp)
+       AX_DETECT_GMP
+       ;;
+imath)
+       AX_DETECT_IMATH
+       ;;
+esac
 
+AM_CONDITIONAL(IMATH_FOR_MP, test x$with_int = ximath)
+AM_CONDITIONAL(GMP_FOR_MP, test x$with_int = xgmp)
 AC_CHECK_DECLS(ffs,[],[],[#include <strings.h>])
 AC_CHECK_DECLS(__builtin_ffs,[],[],[])
 
@@ -170,9 +191,9 @@ AX_SET_WARNING_FLAGS
 
 AC_SUBST(WARNING_FLAGS)
 
-PACKAGE_CFLAGS="$GMP_CPPFLAGS"
-PACKAGE_LDFLAGS="$GMP_LDFLAGS"
-PACKAGE_LIBS="-lisl -lgmp"
+PACKAGE_CFLAGS="$MP_CPPFLAGS"
+PACKAGE_LDFLAGS="$MP_LDFLAGS"
+PACKAGE_LIBS="-lisl $MP_LIBS"
 AX_CREATE_PKGCONFIG_INFO
 
 AX_DETECT_GIT_HEAD
index c8fece2..9ea7c26 100644 (file)
@@ -5,7 +5,7 @@ sets and relations of integer points bounded by affine constraints.
 The descriptions of the sets and relations may involve
 both parameters and existentially quantified variables.
 All computations are performed in exact integer arithmetic
-using C<GMP>.
+using C<GMP> or C<imath>.
 The C<isl> library offers functionality that is similar
 to that offered by the C<Omega> and C<Omega+> libraries,
 but the underlying algorithms are in most cases completely different.
@@ -234,10 +234,13 @@ SOFTWARE.
 
 =back
 
-Note that C<isl> currently requires C<GMP>, which is released
+Note that by default C<isl> requires C<GMP>, which is released
 under the GNU Lesser General Public License (LGPL).  This means
 that code linked against C<isl> is also linked against LGPL code.
 
+When configuring with C<--with-int=imath>, C<isl> will link against C<imath>, a
+library for exact integer arithmetic released under the MIT license.
+
 =head1 Installation
 
 The source of C<isl> can be obtained either as a tarball
@@ -261,6 +264,16 @@ To obtain updates, you need to pull in the latest changes
 
        git pull
 
+=item 2 Optionally get C<imath> submodule
+
+To build C<isl> with C<imath>, you need to obtain the C<imath>
+submodule by running in the git source tree of C<isl>
+
+       git submodule init
+       git submodule update
+
+This will fetch the required version of C<imath> in a subdirectory of C<isl>.
+
 =item 2 Generate C<configure>
 
        ./autogen.sh
@@ -276,11 +289,12 @@ with the L<Common installation instructions>.
 
 =item 1 Obtain C<GMP>
 
-Building C<isl> requires C<GMP>, including its headers files.
+By default, building C<isl> requires C<GMP>, including its headers files.
 Your distribution may not provide these header files by default
 and you may need to install a package called C<gmp-devel> or something
 similar.  Alternatively, C<GMP> can be built from
 source, available from L<http://gmplib.org/>.
+C<GMP> is not needed if you build C<isl> with C<imath>.
 
 =item 2 Configure
 
@@ -302,6 +316,11 @@ Below we discuss some of the more common options.
 
 Installation prefix for C<isl>
 
+=item C<--with-int=[gmp|imath]>
+
+Select the integer library to be used by C<isl>, the default is C<gmp>.
+Note that C<isl> may run significantly slower if you use C<imath>.
+
 =item C<--with-gmp-prefix>
 
 Installation prefix for C<GMP> (architecture-independent files).
diff --git a/imath b/imath
new file mode 160000 (submodule)
index 0000000..4d707e5
--- /dev/null
+++ b/imath
@@ -0,0 +1 @@
+Subproject commit 4d707e5ef22923ec230b8d5ed8c5879af8b62f03
diff --git a/imath_wrap/gmp_compat.c b/imath_wrap/gmp_compat.c
new file mode 100644 (file)
index 0000000..a116913
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wrap.h"
+#include "../imath/gmp_compat.c"
diff --git a/imath_wrap/gmp_compat.h b/imath_wrap/gmp_compat.h
new file mode 100644 (file)
index 0000000..11a332d
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wrap.h"
+#include "../imath/gmp_compat.h"
diff --git a/imath_wrap/imath.c b/imath_wrap/imath.c
new file mode 100644 (file)
index 0000000..c4e35c1
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wrap.h"
+#include "../imath/imath.c"
diff --git a/imath_wrap/imath.h b/imath_wrap/imath.h
new file mode 100644 (file)
index 0000000..12029ce
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wrap.h"
+#include "../imath/imath.h"
diff --git a/imath_wrap/imrat.c b/imath_wrap/imrat.c
new file mode 100644 (file)
index 0000000..0c7feaa
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wrap.h"
+#include "../imath/imrat.c"
diff --git a/imath_wrap/imrat.h b/imath_wrap/imrat.h
new file mode 100644 (file)
index 0000000..c998390
--- /dev/null
@@ -0,0 +1,2 @@
+#include "wrap.h"
+#include "../imath/imrat.h"
diff --git a/imath_wrap/wrap.h b/imath_wrap/wrap.h
new file mode 100644 (file)
index 0000000..f68e50d
--- /dev/null
@@ -0,0 +1,172 @@
+#ifndef ISL_IMATH_WRAP
+#define ISL_IMATH_WRAP
+
+#define MP_BADARG      ISL_MP_BADARG
+#define MP_FALSE       ISL_MP_FALSE
+#define MP_MEMORY      ISL_MP_MEMORY
+#define MP_MINERR      ISL_MP_MINERR
+#define MP_NEG ISL_MP_NEG
+#define MP_OK  ISL_MP_OK
+#define MP_RANGE       ISL_MP_RANGE
+#define MP_TRUE        ISL_MP_TRUE
+#define MP_TRUNC       ISL_MP_TRUNC
+#define MP_UNDEF       ISL_MP_UNDEF
+#define MP_ZPOS        ISL_MP_ZPOS
+
+#define impq_canonicalize      isl_impq_canonicalize
+#define impq_clear     isl_impq_clear
+#define impq_cmp       isl_impq_cmp
+#define impq_denref    isl_impq_denref
+#define impq_get_str   isl_impq_get_str
+#define impq_init      isl_impq_init
+#define impq_mul       isl_impq_mul
+#define impq_numref    isl_impq_numref
+#define impq_set       isl_impq_set
+#define impq_set_str   isl_impq_set_str
+#define impq_set_ui    isl_impq_set_ui
+#define impq_sgn       isl_impq_sgn
+#define impz_abs       isl_impz_abs
+#define impz_add       isl_impz_add
+#define impz_addmul    isl_impz_addmul
+#define impz_add_ui    isl_impz_add_ui
+#define impz_cdiv_q    isl_impz_cdiv_q
+#define impz_clear     isl_impz_clear
+#define impz_cmp       isl_impz_cmp
+#define impz_cmpabs    isl_impz_cmpabs
+#define impz_cmp_si    isl_impz_cmp_si
+#define impz_divexact  isl_impz_divexact
+#define impz_divexact_ui       isl_impz_divexact_ui
+#define impz_divisible_p       isl_impz_divisible_p
+#define impz_export    isl_impz_export
+#define impz_fdiv_q    isl_impz_fdiv_q
+#define impz_fdiv_q_ui isl_impz_fdiv_q_ui
+#define impz_fdiv_r    isl_impz_fdiv_r
+#define impz_gcd       isl_impz_gcd
+#define impz_get_si    isl_impz_get_si
+#define impz_get_str   isl_impz_get_str
+#define impz_get_ui    isl_impz_get_ui
+#define impz_import    isl_impz_import
+#define impz_init      isl_impz_init
+#define impz_lcm       isl_impz_lcm
+#define impz_mul       isl_impz_mul
+#define impz_mul_2exp  isl_impz_mul_2exp
+#define impz_mul_ui    isl_impz_mul_ui
+#define impz_neg       isl_impz_neg
+#define impz_pow_ui    isl_impz_pow_ui
+#define impz_set       isl_impz_set
+#define impz_set_si    isl_impz_set_si
+#define impz_set_str   isl_impz_set_str
+#define impz_set_ui    isl_impz_set_ui
+#define impz_sgn       isl_impz_sgn
+#define impz_sizeinbase        isl_impz_sizeinbase
+#define impz_sub       isl_impz_sub
+#define impz_submul    isl_impz_submul
+#define impz_sub_ui    isl_impz_sub_ui
+#define impz_swap      isl_impz_swap
+#define impz_tdiv_q    isl_impz_tdiv_q
+#define mp_error_string        isl_mp_error_string
+#define mp_int_abs     isl_mp_int_abs
+#define mp_int_add     isl_mp_int_add
+#define mp_int_add_value       isl_mp_int_add_value
+#define mp_int_alloc   isl_mp_int_alloc
+#define mp_int_binary_len      isl_mp_int_binary_len
+#define mp_int_clear   isl_mp_int_clear
+#define mp_int_compare isl_mp_int_compare
+#define mp_int_compare_unsigned        isl_mp_int_compare_unsigned
+#define mp_int_compare_uvalue  isl_mp_int_compare_uvalue
+#define mp_int_compare_value   isl_mp_int_compare_value
+#define mp_int_compare_zero    isl_mp_int_compare_zero
+#define mp_int_copy    isl_mp_int_copy
+#define mp_int_count_bits      isl_mp_int_count_bits
+#define mp_int_div     isl_mp_int_div
+#define mp_int_divisible_value isl_mp_int_divisible_value
+#define mp_int_div_pow2        isl_mp_int_div_pow2
+#define mp_int_div_value       isl_mp_int_div_value
+#define mp_int_egcd    isl_mp_int_egcd
+#define mp_int_expt    isl_mp_int_expt
+#define mp_int_expt_full       isl_mp_int_expt_full
+#define mp_int_exptmod isl_mp_int_exptmod
+#define mp_int_exptmod_bvalue  isl_mp_int_exptmod_bvalue
+#define mp_int_exptmod_evalue  isl_mp_int_exptmod_evalue
+#define mp_int_exptmod_known   isl_mp_int_exptmod_known
+#define mp_int_expt_value      isl_mp_int_expt_value
+#define mp_int_free    isl_mp_int_free
+#define mp_int_gcd     isl_mp_int_gcd
+#define mp_int_init    isl_mp_int_init
+#define mp_int_init_copy       isl_mp_int_init_copy
+#define mp_int_init_size       isl_mp_int_init_size
+#define mp_int_init_uvalue     isl_mp_int_init_uvalue
+#define mp_int_init_value      isl_mp_int_init_value
+#define mp_int_invmod  isl_mp_int_invmod
+#define mp_int_is_pow2 isl_mp_int_is_pow2
+#define mp_int_lcm     isl_mp_int_lcm
+#define mp_int_mod     isl_mp_int_mod
+#define mp_int_mul     isl_mp_int_mul
+#define mp_int_mul_pow2        isl_mp_int_mul_pow2
+#define mp_int_mul_value       isl_mp_int_mul_value
+#define mp_int_neg     isl_mp_int_neg
+#define mp_int_read_binary     isl_mp_int_read_binary
+#define mp_int_read_cstring    isl_mp_int_read_cstring
+#define mp_int_read_string     isl_mp_int_read_string
+#define mp_int_read_unsigned   isl_mp_int_read_unsigned
+#define mp_int_redux_const     isl_mp_int_redux_const
+#define mp_int_root    isl_mp_int_root
+#define mp_int_set_uvalue      isl_mp_int_set_uvalue
+#define mp_int_set_value       isl_mp_int_set_value
+#define mp_int_sqr     isl_mp_int_sqr
+#define mp_int_string_len      isl_mp_int_string_len
+#define mp_int_sub     isl_mp_int_sub
+#define mp_int_sub_value       isl_mp_int_sub_value
+#define mp_int_swap    isl_mp_int_swap
+#define mp_int_to_binary       isl_mp_int_to_binary
+#define mp_int_to_int  isl_mp_int_to_int
+#define mp_int_to_string       isl_mp_int_to_string
+#define mp_int_to_uint isl_mp_int_to_uint
+#define mp_int_to_unsigned     isl_mp_int_to_unsigned
+#define mp_int_unsigned_len    isl_mp_int_unsigned_len
+#define mp_int_zero    isl_mp_int_zero
+#define mp_rat_abs     isl_mp_rat_abs
+#define mp_rat_add     isl_mp_rat_add
+#define mp_rat_add_int isl_mp_rat_add_int
+#define mp_rat_alloc   isl_mp_rat_alloc
+#define mp_rat_clear   isl_mp_rat_clear
+#define mp_rat_compare isl_mp_rat_compare
+#define mp_rat_compare_unsigned        isl_mp_rat_compare_unsigned
+#define mp_rat_compare_value   isl_mp_rat_compare_value
+#define mp_rat_compare_zero    isl_mp_rat_compare_zero
+#define mp_rat_copy    isl_mp_rat_copy
+#define mp_rat_decimal_len     isl_mp_rat_decimal_len
+#define mp_rat_denom   isl_mp_rat_denom
+#define mp_rat_denom_ref       isl_mp_rat_denom_ref
+#define mp_rat_div     isl_mp_rat_div
+#define mp_rat_div_int isl_mp_rat_div_int
+#define mp_rat_expt    isl_mp_rat_expt
+#define mp_rat_free    isl_mp_rat_free
+#define mp_rat_init    isl_mp_rat_init
+#define mp_rat_init_copy       isl_mp_rat_init_copy
+#define mp_rat_init_size       isl_mp_rat_init_size
+#define mp_rat_is_integer      isl_mp_rat_is_integer
+#define mp_rat_mul     isl_mp_rat_mul
+#define mp_rat_mul_int isl_mp_rat_mul_int
+#define mp_rat_neg     isl_mp_rat_neg
+#define mp_rat_numer   isl_mp_rat_numer
+#define mp_rat_numer_ref       isl_mp_rat_numer_ref
+#define mp_rat_read_cdecimal   isl_mp_rat_read_cdecimal
+#define mp_rat_read_cstring    isl_mp_rat_read_cstring
+#define mp_rat_read_decimal    isl_mp_rat_read_decimal
+#define mp_rat_read_string     isl_mp_rat_read_string
+#define mp_rat_read_ustring    isl_mp_rat_read_ustring
+#define mp_rat_recip   isl_mp_rat_recip
+#define mp_rat_reduce  isl_mp_rat_reduce
+#define mp_rat_set_uvalue      isl_mp_rat_set_uvalue
+#define mp_rat_set_value       isl_mp_rat_set_value
+#define mp_rat_sign    isl_mp_rat_sign
+#define mp_rat_string_len      isl_mp_rat_string_len
+#define mp_rat_sub     isl_mp_rat_sub
+#define mp_rat_sub_int isl_mp_rat_sub_int
+#define mp_rat_to_decimal      isl_mp_rat_to_decimal
+#define mp_rat_to_ints isl_mp_rat_to_ints
+#define mp_rat_to_string       isl_mp_rat_to_string
+#define mp_rat_zero    isl_mp_rat_zero
+
+#endif
diff --git a/isl_hide_deprecated.h b/isl_hide_deprecated.h
new file mode 100644 (file)
index 0000000..006e796
--- /dev/null
@@ -0,0 +1,53 @@
+#define isl_aff_get_constant   isl_gmp_aff_get_constant
+#define isl_aff_get_coefficient        isl_gmp_aff_get_coefficient
+#define isl_aff_get_denominator        isl_gmp_aff_get_denominator
+#define isl_aff_set_constant   isl_gmp_aff_set_constant
+#define isl_aff_set_coefficient        isl_gmp_aff_set_coefficient
+#define isl_aff_set_denominator        isl_gmp_aff_set_denominator
+#define isl_aff_add_constant   isl_gmp_aff_add_constant
+#define isl_aff_add_constant_num       isl_gmp_aff_add_constant_num
+#define isl_aff_add_coefficient        isl_gmp_aff_add_coefficient
+#define isl_aff_mod    isl_gmp_aff_mod
+#define isl_aff_scale  isl_gmp_aff_scale
+#define isl_aff_scale_down     isl_gmp_aff_scale_down
+#define isl_pw_aff_mod isl_gmp_pw_aff_mod
+#define isl_pw_aff_scale       isl_gmp_pw_aff_scale
+#define isl_pw_aff_scale_down  isl_gmp_pw_aff_scale_down
+#define isl_multi_aff_scale    isl_gmp_multi_aff_scale
+#define isl_ast_expr_get_int   isl_gmp_ast_expr_get_int
+#define isl_constraint_get_constant    isl_gmp_constraint_get_constant
+#define isl_constraint_get_coefficient isl_gmp_constraint_get_coefficient
+#define isl_constraint_set_constant    isl_gmp_constraint_set_constant
+#define isl_constraint_set_coefficient isl_gmp_constraint_set_coefficient
+#define isl_basic_set_max      isl_gmp_basic_set_max
+#define isl_set_min    isl_gmp_set_min
+#define isl_set_max    isl_gmp_set_max
+#define isl_gmp_hash   isl_gmp_gmp_hash
+#define isl_basic_map_plain_is_fixed   isl_gmp_basic_map_plain_is_fixed
+#define isl_map_fix    isl_gmp_map_fix
+#define isl_map_plain_is_fixed isl_gmp_map_plain_is_fixed
+#define isl_map_fast_is_fixed  isl_gmp_map_fast_is_fixed
+#define isl_map_fixed_power    isl_gmp_map_fixed_power
+#define isl_mat_get_element    isl_gmp_mat_get_element
+#define isl_mat_set_element    isl_gmp_mat_set_element
+#define isl_point_get_coordinate       isl_gmp_point_get_coordinate
+#define isl_point_set_coordinate       isl_gmp_point_set_coordinate
+#define isl_qpolynomial_rat_cst_on_domain      isl_gmp_qpolynomial_rat_cst_on_domain
+#define isl_qpolynomial_is_cst isl_gmp_qpolynomial_is_cst
+#define isl_qpolynomial_scale  isl_gmp_qpolynomial_scale
+#define isl_term_get_num       isl_gmp_term_get_num
+#define isl_term_get_den       isl_gmp_term_get_den
+#define isl_qpolynomial_fold_scale     isl_gmp_qpolynomial_fold_scale
+#define isl_pw_qpolynomial_fold_fix_dim        isl_gmp_pw_qpolynomial_fold_fix_dim
+#define isl_basic_set_fix      isl_gmp_basic_set_fix
+#define isl_set_lower_bound    isl_gmp_set_lower_bound
+#define isl_set_upper_bound    isl_gmp_set_upper_bound
+#define isl_set_fix    isl_gmp_set_fix
+#define isl_set_plain_is_fixed isl_gmp_set_plain_is_fixed
+#define isl_union_map_fixed_power      isl_gmp_union_map_fixed_power
+#define isl_val_int_from_isl_int       isl_gmp_val_int_from_isl_int
+#define isl_val_get_num_isl_int        isl_gmp_val_get_num_isl_int
+#define isl_vec_get_element    isl_gmp_vec_get_element
+#define isl_vec_set_element    isl_gmp_vec_set_element
+#define isl_vec_set    isl_gmp_vec_set
+#define isl_vec_fdiv_r isl_gmp_vec_fdiv_r
diff --git a/isl_imath.c b/isl_imath.c
new file mode 100644 (file)
index 0000000..959b5e7
--- /dev/null
@@ -0,0 +1,53 @@
+#include <isl_int.h>
+
+uint32_t isl_imath_hash(mp_int v, uint32_t hash)
+{
+       unsigned const char *data = (unsigned char *)v->digits;
+       unsigned const char *end = data + v->used * sizeof(v->digits[0]);
+
+       if (v->sign == 1)
+               isl_hash_byte(hash, 0xFF);
+       for (; data < end; ++data)
+               isl_hash_byte(hash, *data);
+       return hash;
+}
+
+/* Try a standard conversion that fits into a long.
+ */
+int isl_imath_fits_slong_p(mp_int op)
+{
+       unsigned long out;
+       mp_result res = mp_int_to_int(op, &out);
+       return res == MP_OK;
+}
+
+/* Try a standard conversion that fits into an unsigned long.
+ */
+int isl_imath_fits_ulong_p(mp_int op)
+{
+       unsigned long out;
+       mp_result res = mp_int_to_uint(op, &out);
+       return res == MP_OK;
+}
+
+void isl_imath_addmul_ui(mp_int rop, mp_int op1, unsigned long op2)
+{
+       isl_int temp;
+       isl_int_init(temp);
+
+       isl_int_set_ui(temp, op2);
+       isl_int_addmul(rop, op1, temp);
+
+       isl_int_clear(temp);
+}
+
+void isl_imath_submul_ui(mp_int rop, mp_int op1, unsigned long op2)
+{
+       isl_int temp;
+       isl_int_init(temp);
+
+       isl_int_set_ui(temp, op2);
+       isl_int_submul(rop, op1, temp);
+
+       isl_int_clear(temp);
+}
diff --git a/isl_imath.h b/isl_imath.h
new file mode 100644 (file)
index 0000000..d51e03c
--- /dev/null
@@ -0,0 +1,8 @@
+#include <imath.h>
+#include <gmp_compat.h>
+
+uint32_t isl_imath_hash(mp_int v, uint32_t hash);
+int isl_imath_fits_ulong_p(mp_int op);
+int isl_imath_fits_slong_p(mp_int op);
+void isl_imath_addmul_ui(mp_int rop, mp_int op1, unsigned long op2);
+void isl_imath_submul_ui(mp_int rop, mp_int op1, unsigned long op2);
dissimilarity index 75%
index 71198f2..3be0661 100644 (file)
--- a/isl_int.h
+++ b/isl_int.h
-/*
- * Copyright 2008-2009 Katholieke Universiteit Leuven
- *
- * Use of this software is governed by the MIT license
- *
- * Written by Sven Verdoolaege, K.U.Leuven, Departement
- * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
- */
-
-#ifndef ISL_INT_H
-#define ISL_INT_H
-#define ISL_DEPRECATED_INT_H
-
-#include <isl/hash.h>
-#include <isl/printer.h>
-#include <string.h>
-#include <gmp.h>
-#include <isl_config.h>
-
-#ifndef mp_get_memory_functions
-void mp_get_memory_functions(
-               void *(**alloc_func_ptr) (size_t),
-               void *(**realloc_func_ptr) (void *, size_t, size_t),
-               void (**free_func_ptr) (void *, size_t));
-#endif
-
-/* isl_int is the basic integer type.  It currently always corresponds
- * to a gmp mpz_t, but in the future, different types such as long long
- * or cln::cl_I will be supported.
- */
-typedef mpz_t  isl_int;
-
-#define isl_int_init(i)                mpz_init(i)
-#define isl_int_clear(i)       mpz_clear(i)
-
-#define isl_int_set(r,i)       mpz_set(r,i)
-#define isl_int_set_gmp(r,i)   mpz_set(r,i)
-#define isl_int_set_si(r,i)    mpz_set_si(r,i)
-#define isl_int_set_ui(r,i)    mpz_set_ui(r,i)
-#define isl_int_get_gmp(i,g)   mpz_set(g,i)
-#define isl_int_fits_slong(r)  mpz_fits_slong_p(r)
-#define isl_int_get_si(r)      mpz_get_si(r)
-#define isl_int_fits_ulong(r)  mpz_fits_ulong_p(r)
-#define isl_int_get_ui(r)      mpz_get_ui(r)
-#define isl_int_get_d(r)       mpz_get_d(r)
-#define isl_int_get_str(r)     mpz_get_str(0, 10, r)
-typedef void (*isl_int_print_gmp_free_t)(void *, size_t);
-#define isl_int_free_str(s)                                    \
-       do {                                                            \
-               isl_int_print_gmp_free_t gmp_free;                      \
-               mp_get_memory_functions(NULL, NULL, &gmp_free);         \
-               (*gmp_free)(s, strlen(s) + 1);                          \
-       } while (0)
-#define isl_int_abs(r,i)       mpz_abs(r,i)
-#define isl_int_neg(r,i)       mpz_neg(r,i)
-#define isl_int_swap(i,j)      mpz_swap(i,j)
-#define isl_int_swap_or_set(i,j)       mpz_swap(i,j)
-#define isl_int_add_ui(r,i,j)  mpz_add_ui(r,i,j)
-#define isl_int_sub_ui(r,i,j)  mpz_sub_ui(r,i,j)
-
-#define isl_int_add(r,i,j)     mpz_add(r,i,j)
-#define isl_int_sub(r,i,j)     mpz_sub(r,i,j)
-#define isl_int_mul(r,i,j)     mpz_mul(r,i,j)
-#define isl_int_mul_2exp(r,i,j)        mpz_mul_2exp(r,i,j)
-#define isl_int_mul_si(r,i,j)  mpz_mul_si(r,i,j)
-#define isl_int_mul_ui(r,i,j)  mpz_mul_ui(r,i,j)
-#define isl_int_pow_ui(r,i,j)  mpz_pow_ui(r,i,j)
-#define isl_int_addmul(r,i,j)  mpz_addmul(r,i,j)
-#define isl_int_addmul_ui(r,i,j)       mpz_addmul_ui(r,i,j)
-#define isl_int_submul(r,i,j)  mpz_submul(r,i,j)
-#define isl_int_submul_ui(r,i,j)       mpz_submul_ui(r,i,j)
-
-#define isl_int_gcd(r,i,j)     mpz_gcd(r,i,j)
-#define isl_int_lcm(r,i,j)     mpz_lcm(r,i,j)
-#define isl_int_divexact(r,i,j)        mpz_divexact(r,i,j)
-#define isl_int_divexact_ui(r,i,j)     mpz_divexact_ui(r,i,j)
-#define isl_int_tdiv_q(r,i,j)  mpz_tdiv_q(r,i,j)
-#define isl_int_cdiv_q(r,i,j)  mpz_cdiv_q(r,i,j)
-#define isl_int_fdiv_q(r,i,j)  mpz_fdiv_q(r,i,j)
-#define isl_int_fdiv_r(r,i,j)  mpz_fdiv_r(r,i,j)
-#define isl_int_fdiv_q_ui(r,i,j)       mpz_fdiv_q_ui(r,i,j)
-
-#define isl_int_read(r,s)      mpz_set_str(r,s,10)
-#define isl_int_print(out,i,width)                                     \
-       do {                                                            \
-               char *s;                                                \
-               s = mpz_get_str(0, 10, i);                              \
-               fprintf(out, "%*s", width, s);                          \
-               isl_int_free_str(s);                                        \
-       } while (0)
-
-#define isl_int_sgn(i)         mpz_sgn(i)
-#define isl_int_cmp(i,j)       mpz_cmp(i,j)
-#define isl_int_cmp_si(i,si)   mpz_cmp_si(i,si)
-#define isl_int_eq(i,j)                (mpz_cmp(i,j) == 0)
-#define isl_int_ne(i,j)                (mpz_cmp(i,j) != 0)
-#define isl_int_lt(i,j)                (mpz_cmp(i,j) < 0)
-#define isl_int_le(i,j)                (mpz_cmp(i,j) <= 0)
-#define isl_int_gt(i,j)                (mpz_cmp(i,j) > 0)
-#define isl_int_ge(i,j)                (mpz_cmp(i,j) >= 0)
-#define isl_int_abs_eq(i,j)    (mpz_cmpabs(i,j) == 0)
-#define isl_int_abs_ne(i,j)    (mpz_cmpabs(i,j) != 0)
-#define isl_int_abs_lt(i,j)    (mpz_cmpabs(i,j) < 0)
-#define isl_int_abs_gt(i,j)    (mpz_cmpabs(i,j) > 0)
-#define isl_int_abs_ge(i,j)    (mpz_cmpabs(i,j) >= 0)
-
-
-#define isl_int_is_zero(i)     (isl_int_sgn(i) == 0)
-#define isl_int_is_one(i)      (isl_int_cmp_si(i,1) == 0)
-#define isl_int_is_negone(i)   (isl_int_cmp_si(i,-1) == 0)
-#define isl_int_is_pos(i)      (isl_int_sgn(i) > 0)
-#define isl_int_is_neg(i)      (isl_int_sgn(i) < 0)
-#define isl_int_is_nonpos(i)   (isl_int_sgn(i) <= 0)
-#define isl_int_is_nonneg(i)   (isl_int_sgn(i) >= 0)
-#define isl_int_is_divisible_by(i,j)   mpz_divisible_p(i,j)
-
-uint32_t isl_gmp_hash(mpz_t v, uint32_t hash);
-#define isl_int_hash(v,h)      isl_gmp_hash(v,h)
-
-__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
-       isl_int i);
-
-#endif
+/*
+ * Copyright 2008-2009 Katholieke Universiteit Leuven
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege, K.U.Leuven, Departement
+ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
+ */
+
+#ifndef ISL_INT_H
+#define ISL_INT_H
+#define ISL_DEPRECATED_INT_H
+
+#include <isl/hash.h>
+#include <isl/printer.h>
+#include <string.h>
+#include <isl_config.h>
+
+#ifdef USE_GMP_FOR_MP
+#include <isl_int_gmp.h>
+#endif
+
+#ifdef USE_IMATH_FOR_MP
+#include <isl_int_imath.h>
+#endif
+
+#define isl_int_is_zero(i)     (isl_int_sgn(i) == 0)
+#define isl_int_is_one(i)      (isl_int_cmp_si(i,1) == 0)
+#define isl_int_is_negone(i)   (isl_int_cmp_si(i,-1) == 0)
+#define isl_int_is_pos(i)      (isl_int_sgn(i) > 0)
+#define isl_int_is_neg(i)      (isl_int_sgn(i) < 0)
+#define isl_int_is_nonpos(i)   (isl_int_sgn(i) <= 0)
+#define isl_int_is_nonneg(i)   (isl_int_sgn(i) >= 0)
+
+#define isl_int_print(out,i,width)                                     \
+       do {                                                            \
+               char *s;                                                \
+               s = isl_int_get_str(i);                                 \
+               fprintf(out, "%*s", width, s);                          \
+               isl_int_free_str(s);                                        \
+       } while (0)
+
+__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
+       isl_int i);
+
+#endif /* ISL_INT_H */
similarity index 64%
copy from isl_int.h
copy to isl_int_gmp.h
index 71198f2..263b32c 100644 (file)
--- a/isl_int.h
@@ -1,32 +1,10 @@
-/*
- * Copyright 2008-2009 Katholieke Universiteit Leuven
- *
- * Use of this software is governed by the MIT license
- *
- * Written by Sven Verdoolaege, K.U.Leuven, Departement
- * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
- */
-
-#ifndef ISL_INT_H
-#define ISL_INT_H
-#define ISL_DEPRECATED_INT_H
+#ifndef ISL_INT_GMP_H
+#define ISL_INT_GMP_H
 
-#include <isl/hash.h>
-#include <isl/printer.h>
-#include <string.h>
 #include <gmp.h>
-#include <isl_config.h>
-
-#ifndef mp_get_memory_functions
-void mp_get_memory_functions(
-               void *(**alloc_func_ptr) (size_t),
-               void *(**realloc_func_ptr) (void *, size_t, size_t),
-               void (**free_func_ptr) (void *, size_t));
-#endif
 
-/* isl_int is the basic integer type.  It currently always corresponds
- * to a gmp mpz_t, but in the future, different types such as long long
- * or cln::cl_I will be supported.
+/* isl_int is the basic integer type, implemented with GMP's mpz_t.  In the
+ * future, different types such as long long or cln::cl_I will be supported.
  */
 typedef mpz_t  isl_int;
 
@@ -34,23 +12,14 @@ typedef mpz_t       isl_int;
 #define isl_int_clear(i)       mpz_clear(i)
 
 #define isl_int_set(r,i)       mpz_set(r,i)
-#define isl_int_set_gmp(r,i)   mpz_set(r,i)
 #define isl_int_set_si(r,i)    mpz_set_si(r,i)
 #define isl_int_set_ui(r,i)    mpz_set_ui(r,i)
-#define isl_int_get_gmp(i,g)   mpz_set(g,i)
 #define isl_int_fits_slong(r)  mpz_fits_slong_p(r)
 #define isl_int_get_si(r)      mpz_get_si(r)
 #define isl_int_fits_ulong(r)  mpz_fits_ulong_p(r)
 #define isl_int_get_ui(r)      mpz_get_ui(r)
 #define isl_int_get_d(r)       mpz_get_d(r)
 #define isl_int_get_str(r)     mpz_get_str(0, 10, r)
-typedef void (*isl_int_print_gmp_free_t)(void *, size_t);
-#define isl_int_free_str(s)                                    \
-       do {                                                            \
-               isl_int_print_gmp_free_t gmp_free;                      \
-               mp_get_memory_functions(NULL, NULL, &gmp_free);         \
-               (*gmp_free)(s, strlen(s) + 1);                          \
-       } while (0)
 #define isl_int_abs(r,i)       mpz_abs(r,i)
 #define isl_int_neg(r,i)       mpz_neg(r,i)
 #define isl_int_swap(i,j)      mpz_swap(i,j)
@@ -81,14 +50,6 @@ typedef void (*isl_int_print_gmp_free_t)(void *, size_t);
 #define isl_int_fdiv_q_ui(r,i,j)       mpz_fdiv_q_ui(r,i,j)
 
 #define isl_int_read(r,s)      mpz_set_str(r,s,10)
-#define isl_int_print(out,i,width)                                     \
-       do {                                                            \
-               char *s;                                                \
-               s = mpz_get_str(0, 10, i);                              \
-               fprintf(out, "%*s", width, s);                          \
-               isl_int_free_str(s);                                        \
-       } while (0)
-
 #define isl_int_sgn(i)         mpz_sgn(i)
 #define isl_int_cmp(i,j)       mpz_cmp(i,j)
 #define isl_int_cmp_si(i,si)   mpz_cmp_si(i,si)
@@ -103,21 +64,24 @@ typedef void (*isl_int_print_gmp_free_t)(void *, size_t);
 #define isl_int_abs_lt(i,j)    (mpz_cmpabs(i,j) < 0)
 #define isl_int_abs_gt(i,j)    (mpz_cmpabs(i,j) > 0)
 #define isl_int_abs_ge(i,j)    (mpz_cmpabs(i,j) >= 0)
-
-
-#define isl_int_is_zero(i)     (isl_int_sgn(i) == 0)
-#define isl_int_is_one(i)      (isl_int_cmp_si(i,1) == 0)
-#define isl_int_is_negone(i)   (isl_int_cmp_si(i,-1) == 0)
-#define isl_int_is_pos(i)      (isl_int_sgn(i) > 0)
-#define isl_int_is_neg(i)      (isl_int_sgn(i) < 0)
-#define isl_int_is_nonpos(i)   (isl_int_sgn(i) <= 0)
-#define isl_int_is_nonneg(i)   (isl_int_sgn(i) >= 0)
 #define isl_int_is_divisible_by(i,j)   mpz_divisible_p(i,j)
 
 uint32_t isl_gmp_hash(mpz_t v, uint32_t hash);
 #define isl_int_hash(v,h)      isl_gmp_hash(v,h)
 
-__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
-       isl_int i);
-
+#ifndef mp_get_memory_functions
+void mp_get_memory_functions(
+               void *(**alloc_func_ptr) (size_t),
+               void *(**realloc_func_ptr) (void *, size_t, size_t),
+               void (**free_func_ptr) (void *, size_t));
 #endif
+
+typedef void (*isl_int_print_mp_free_t)(void *, size_t);
+#define isl_int_free_str(s)                                    \
+       do {                                                            \
+               isl_int_print_mp_free_t mp_free;                        \
+               mp_get_memory_functions(NULL, NULL, &mp_free);          \
+               (*mp_free)(s, strlen(s) + 1);                           \
+       } while (0)
+
+#endif /* ISL_INT_GMP_H */
diff --git a/isl_int_imath.h b/isl_int_imath.h
new file mode 100644 (file)
index 0000000..523bca8
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef ISL_INT_IMATH_H
+#define ISL_INT_IMATH_H
+
+#include "isl_hide_deprecated.h"
+
+#include <isl_imath.h>
+
+/* isl_int is the basic integer type, implemented with imath's mp_int. */
+typedef mp_int isl_int;
+
+#define isl_int_init(i)                i = mp_int_alloc()
+#define isl_int_clear(i)       mp_int_free(i)
+
+#define isl_int_set(r,i)       impz_set(r,i)
+#define isl_int_set_si(r,i)    impz_set_si(r,i)
+#define isl_int_set_ui(r,i)    impz_set_ui(r,i)
+#define isl_int_fits_slong(r)  isl_imath_fits_slong_p(r)
+#define isl_int_get_si(r)      impz_get_si(r)
+#define isl_int_fits_ulong(r)  isl_imath_fits_ulong_p(r)
+#define isl_int_get_ui(r)      impz_get_ui(r)
+#define isl_int_get_d(r)       impz_get_si(r)
+#define isl_int_get_str(r)     impz_get_str(0, 10, r)
+#define isl_int_abs(r,i)       impz_abs(r,i)
+#define isl_int_neg(r,i)       impz_neg(r,i)
+#define isl_int_swap(i,j)      impz_swap(i,j)
+#define isl_int_swap_or_set(i,j)       impz_swap(i,j)
+#define isl_int_add_ui(r,i,j)  impz_add_ui(r,i,j)
+#define isl_int_sub_ui(r,i,j)  impz_sub_ui(r,i,j)
+
+#define isl_int_add(r,i,j)     impz_add(r,i,j)
+#define isl_int_sub(r,i,j)     impz_sub(r,i,j)
+#define isl_int_mul(r,i,j)     impz_mul(r,i,j)
+#define isl_int_mul_2exp(r,i,j)        impz_mul_2exp(r,i,j)
+#define isl_int_mul_si(r,i,j)  mp_int_mul_value(i,j,r)
+#define isl_int_mul_ui(r,i,j)  impz_mul_ui(r,i,j)
+#define isl_int_pow_ui(r,i,j)  impz_pow_ui(r,i,j)
+#define isl_int_addmul(r,i,j)  impz_addmul(r,i,j)
+#define isl_int_addmul_ui(r,i,j)       isl_imath_addmul_ui(r,i,j)
+#define isl_int_submul(r,i,j)  impz_submul(r,i,j)
+#define isl_int_submul_ui(r,i,j)       isl_imath_submul_ui(r,i,j)
+
+#define isl_int_gcd(r,i,j)     impz_gcd(r,i,j)
+#define isl_int_lcm(r,i,j)     impz_lcm(r,i,j)
+#define isl_int_divexact(r,i,j)        impz_divexact(r,i,j)
+#define isl_int_divexact_ui(r,i,j)     impz_divexact_ui(r,i,j)
+#define isl_int_tdiv_q(r,i,j)  impz_tdiv_q(r,i,j)
+#define isl_int_cdiv_q(r,i,j)  impz_cdiv_q(r,i,j)
+#define isl_int_fdiv_q(r,i,j)  impz_fdiv_q(r,i,j)
+#define isl_int_fdiv_r(r,i,j)  impz_fdiv_r(r,i,j)
+#define isl_int_fdiv_q_ui(r,i,j)       impz_fdiv_q_ui(r,i,j)
+
+#define isl_int_read(r,s)      impz_set_str(r,s,10)
+#define isl_int_sgn(i)         impz_sgn(i)
+#define isl_int_cmp(i,j)       impz_cmp(i,j)
+#define isl_int_cmp_si(i,si)   impz_cmp_si(i,si)
+#define isl_int_eq(i,j)                (impz_cmp(i,j) == 0)
+#define isl_int_ne(i,j)                (impz_cmp(i,j) != 0)
+#define isl_int_lt(i,j)                (impz_cmp(i,j) < 0)
+#define isl_int_le(i,j)                (impz_cmp(i,j) <= 0)
+#define isl_int_gt(i,j)                (impz_cmp(i,j) > 0)
+#define isl_int_ge(i,j)                (impz_cmp(i,j) >= 0)
+#define isl_int_abs_eq(i,j)    (impz_cmpabs(i,j) == 0)
+#define isl_int_abs_ne(i,j)    (impz_cmpabs(i,j) != 0)
+#define isl_int_abs_lt(i,j)    (impz_cmpabs(i,j) < 0)
+#define isl_int_abs_gt(i,j)    (impz_cmpabs(i,j) > 0)
+#define isl_int_abs_ge(i,j)    (impz_cmpabs(i,j) >= 0)
+#define isl_int_is_divisible_by(i,j)   impz_divisible_p(i,j)
+
+uint32_t isl_imath_hash(mp_int v, uint32_t hash);
+#define isl_int_hash(v,h)      isl_imath_hash(v,h)
+
+typedef void (*isl_int_print_mp_free_t)(void *, size_t);
+#define isl_int_free_str(s)    free(s)
+
+#endif /* ISL_INT_IMATH_H */
diff --git a/isl_val_imath.c b/isl_val_imath.c
new file mode 100644 (file)
index 0000000..8f91700
--- /dev/null
@@ -0,0 +1,64 @@
+#include <isl_val_private.h>
+
+/* Return a reference to an isl_val representing the unsigned
+ * integer value stored in the "n" chunks of size "size" at "chunks".
+ * The least significant chunk is assumed to be stored first.
+ */
+__isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n,
+       size_t size, const void *chunks)
+{
+       isl_val *v;
+
+       v = isl_val_alloc(ctx);
+       if (!v)
+               return NULL;
+
+       impz_import(v->n, n, -1, size, 0, 0, chunks);
+       isl_int_set_si(v->d, 1);
+
+       return v;
+}
+
+/* Store a representation of the absolute value of the numerator of "v"
+ * in terms of chunks of size "size" at "chunks".
+ * The least significant chunk is stored first.
+ * The number of chunks in the result can be obtained by calling
+ * isl_val_n_abs_num_chunks.  The user is responsible for allocating
+ * enough memory to store the results.
+ *
+ * In the special case of a zero value, isl_val_n_abs_num_chunks will
+ * return one, while impz_export will not fill in any chunks.  We therefore
+ * do it ourselves.
+ */
+int isl_val_get_abs_num_chunks(__isl_keep isl_val *v, size_t size,
+       void *chunks)
+{
+       if (!v || !chunks)
+               return -1;
+
+       if (!isl_val_is_rat(v))
+               isl_die(isl_val_get_ctx(v), isl_error_invalid,
+                       "expecting rational value", return -1);
+
+       impz_export(chunks, NULL, -1, size, 0, 0, v->n);
+       if (isl_val_is_zero(v))
+               memset(chunks, 0, size);
+
+       return 0;
+}
+
+/* Return the number of chunks of size "size" required to
+ * store the absolute value of the numerator of "v".
+ */
+size_t isl_val_n_abs_num_chunks(__isl_keep isl_val *v, size_t size)
+{
+       if (!v)
+               return 0;
+
+       if (!isl_val_is_rat(v))
+               isl_die(isl_val_get_ctx(v), isl_error_invalid,
+                       "expecting rational value", return 0);
+
+       size *= 8;
+       return (impz_sizeinbase(v->n, 2) + size - 1) / size;
+}
index 1a59f55..a7ddd9d 100644 (file)
@@ -1,6 +1,14 @@
+#include "isl_config.h"
 #include "gitversion.h"
 
 const char *isl_version(void)
 {
-       return GIT_HEAD_ID"\n";
+       return GIT_HEAD_ID
+#ifdef USE_GMP_FOR_MP
+       "-GMP"
+#endif
+#ifdef USE_IMATH_FOR_MP
+       "-IMath"
+#endif
+       "\n";
 }
index 7748ff0..43fa20d 100644 (file)
@@ -1,19 +1,20 @@
 AC_DEFUN([AX_DETECT_GMP], [
+AC_DEFINE([USE_GMP_FOR_MP], [], [use gmp to implement isl_int])
 AX_SUBMODULE(gmp,system|build,system)
 case "$with_gmp" in
 system)
        if test "x$with_gmp_prefix" != "x"; then
                isl_configure_args="$isl_configure_args --with-gmp=$with_gmp_prefix"
-               GMP_CPPFLAGS="-I$with_gmp_prefix/include"
-               GMP_LDFLAGS="-L$with_gmp_prefix/lib"
+               MP_CPPFLAGS="-I$with_gmp_prefix/include"
+               MP_LDFLAGS="-L$with_gmp_prefix/lib"
        fi
-       GMP_LIBS=-lgmp
+       MP_LIBS=-lgmp
        SAVE_CPPFLAGS="$CPPFLAGS"
        SAVE_LDFLAGS="$LDFLAGS"
        SAVE_LIBS="$LIBS"
-       CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS"
-       LDFLAGS="$GMP_LDFLAGS $LDFLAGS"
-       LIBS="$GMP_LIBS $LIBS"
+       CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS"
+       LDFLAGS="$MP_LDFLAGS $LDFLAGS"
+       LIBS="$MP_LIBS $LIBS"
        AC_CHECK_HEADER([gmp.h], [], [AC_ERROR([gmp.h header not found])])
        AC_CHECK_LIB([gmp], [main], [], [AC_ERROR([gmp library not found])])
        AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <gmp.h>]], [[
@@ -26,16 +27,16 @@ system)
        LIBS="$SAVE_LIBS"
        ;;
 build)
-       GMP_CPPFLAGS="-I$gmp_srcdir -I$with_gmp_builddir"
-       GMP_LIBS="$with_gmp_builddir/libgmp.la"
+       MP_CPPFLAGS="-I$gmp_srcdir -I$with_gmp_builddir"
+       MP_LIBS="$with_gmp_builddir/libgmp.la"
        ;;
 esac
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
 SAVE_LIBS="$LIBS"
-CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS"
-LDFLAGS="$GMP_LDFLAGS $LDFLAGS"
-LIBS="$GMP_LIBS $LIBS"
+CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS"
+LDFLAGS="$MP_LDFLAGS $LDFLAGS"
+LIBS="$MP_LIBS $LIBS"
 need_get_memory_functions=false
 AC_CHECK_DECLS(mp_get_memory_functions,[],[
        need_get_memory_functions=true
diff --git a/m4/ax_detect_imath.m4 b/m4/ax_detect_imath.m4
new file mode 100644 (file)
index 0000000..9c30a61
--- /dev/null
@@ -0,0 +1,15 @@
+AC_DEFUN([AX_DETECT_IMATH], [
+AC_DEFINE([USE_IMATH_FOR_MP], [], [use imath to implement isl_int])
+
+MP_CPPFLAGS="-I$srcdir/imath_wrap"
+MP_LDFLAGS=""
+MP_LIBS=""
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS"
+AC_CHECK_HEADER([imath.h], [], [AC_ERROR([imath.h header not found])])
+AC_CHECK_HEADER([gmp_compat.h], [], [AC_ERROR([gmp_compat.h header not found])])
+CPPFLAGS="$SAVE_CPPFLAGS"
+
+AM_CONDITIONAL(NEED_GET_MEMORY_FUNCTIONS, test x = xfalse)
+])