diff -Nru isl-0.12.2/aclocal.m4 isl-0.15/aclocal.m4 --- isl-0.12.2/aclocal.m4 2014-01-12 11:45:16.000000000 +0000 +++ isl-0.15/aclocal.m4 2015-06-11 10:47:02.000000000 +0000 @@ -1,8 +1,7 @@ -# generated automatically by aclocal 1.11.6 -*- Autoconf -*- +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -12,33 +11,31 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.6], [], +m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -54,24 +51,22 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.6])dnl +[AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -90,7 +85,7 @@ # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -116,22 +111,19 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -150,16 +142,14 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, -# 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 12 -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -169,7 +159,7 @@ # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -182,12 +172,13 @@ AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -195,8 +186,8 @@ # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -236,16 +227,16 @@ : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -254,8 +245,8 @@ test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -263,7 +254,7 @@ fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -311,7 +302,7 @@ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -321,9 +312,13 @@ # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' @@ -338,20 +333,18 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -364,7 +357,7 @@ # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -376,21 +369,19 @@ continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` @@ -408,7 +399,7 @@ # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will +# is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], @@ -418,18 +409,21 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -442,7 +436,7 @@ # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -471,31 +465,40 @@ # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -506,34 +509,78 @@ [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -555,15 +602,12 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, -# Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -577,16 +621,14 @@ install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -602,14 +644,12 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -627,7 +667,7 @@ _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -654,15 +694,12 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -670,11 +707,10 @@ $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -687,54 +723,22 @@ esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, -# Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 1 - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -744,7 +748,7 @@ # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ @@ -758,24 +762,82 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Check to make sure that the build environment is sane. -*- Autoconf -*- +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -786,32 +848,40 @@ esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -821,31 +891,50 @@ AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2009, 2011 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT -# (`yes' being less verbose, `no' or empty being verbose). +# ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], -[ --enable-silent-rules less verbose build output (undo: `make V=1') - --disable-silent-rules verbose build output (undo: `make V=0')]) -case $enable_silent_rules in -yes) AM_DEFAULT_VERBOSITY=0;; -no) AM_DEFAULT_VERBOSITY=1;; -*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl -dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} @@ -863,7 +952,7 @@ am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then - dnl Using `$V' instead of `$(V)' breaks IRIX make. + dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else @@ -880,44 +969,40 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -931,18 +1016,16 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -952,76 +1035,114 @@ # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR @@ -1033,6 +1154,8 @@ m4_include([m4/ax_create_pkgconfig_info.m4]) m4_include([m4/ax_create_stdint_h.m4]) m4_include([m4/ax_detect_git_head.m4]) +m4_include([m4/ax_detect_gmp.m4]) +m4_include([m4/ax_detect_imath.m4]) m4_include([m4/ax_gcc_archflag.m4]) m4_include([m4/ax_gcc_warn_unused_result.m4]) m4_include([m4/ax_gcc_x86_cpuid.m4]) diff -Nru isl-0.12.2/AUTHORS isl-0.15/AUTHORS --- isl-0.12.2/AUTHORS 2013-05-28 07:39:07.000000000 +0000 +++ isl-0.15/AUTHORS 2015-06-10 18:25:32.000000000 +0000 @@ -16,8 +16,12 @@ 91893 Orsay France 2011-2012 consultant for Leiden Institute of Advanced Computer Science -2012 Ecole Normale Superieure - 45 rue d’Ulm, 75230 Paris +2012-2014 Ecole Normale Superieure + 45 rue d'Ulm, 75230 Paris + France +2014 INRIA Rocquencourt + Domaine de Voluceau - Rocquencourt, B.P. 105 + 78153 Le Chesnay France Contributions by @@ -25,11 +29,16 @@ Mythri Alle Riyadh Baghdadi Serge Belyshev +Ray Donnelly +Johannes Doerfert Tobias Grosser +Alexandre Isoard Andreas Kloeckner +Michael Kruse Sebastian Pop Louis-Noel Pouchet Uday Kumar Reddy +Andreas Simbuerger Sven van Haastregt The merge sort implementation was written by Jeffrey Stedfast. diff -Nru isl-0.12.2/basis_reduction_tab.c isl-0.15/basis_reduction_tab.c --- isl-0.12.2/basis_reduction_tab.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/basis_reduction_tab.c 2015-06-11 10:46:17.000000000 +0000 @@ -9,8 +9,10 @@ #include #include -#include +#include #include "isl_tab.h" +#include +#include struct tab_lp { struct isl_ctx *ctx; @@ -30,27 +32,49 @@ 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 + +#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) @@ -157,8 +181,11 @@ isl_vec_free(sample); } isl_int_divexact_ui(lp->opt_denom, lp->opt_denom, 2); - if (res != isl_lp_ok) + if (res < 0) return -1; + if (res != isl_lp_ok) + isl_die(lp->ctx, isl_error_internal, + "unexpected missing (bounded) solution", return -1); return 0; } @@ -193,10 +220,10 @@ 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) @@ -229,11 +256,11 @@ 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) diff -Nru isl-0.12.2/basis_reduction_templ.c isl-0.15/basis_reduction_templ.c --- isl-0.12.2/basis_reduction_templ.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/basis_reduction_templ.c 2015-05-27 08:56:13.000000000 +0000 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "isl_basis_reduction.h" @@ -50,7 +51,6 @@ unsigned dim; struct isl_ctx *ctx; struct isl_mat *B; - int unbounded; int i; GBR_LP *lp = NULL; GBR_type F_old, alpha, F_new; @@ -132,8 +132,8 @@ GBR_lp_set_obj(lp, B->row[1+i]+1, dim); ctx->stats->gbr_solved_lps++; - unbounded = GBR_lp_solve(lp); - isl_assert(ctx, !unbounded, goto error); + if (GBR_lp_solve(lp) < 0) + goto error; GBR_lp_get_obj_val(lp, &F[i]); if (GBR_lt(F[i], one)) { @@ -150,8 +150,8 @@ if (i+1 == tab->n_zero) { GBR_lp_set_obj(lp, B->row[1+i+1]+1, dim); ctx->stats->gbr_solved_lps++; - unbounded = GBR_lp_solve(lp); - isl_assert(ctx, !unbounded, goto error); + if (GBR_lp_solve(lp) < 0) + goto error; GBR_lp_get_obj_val(lp, &F_new); fixed = GBR_lp_is_fixed(lp); GBR_set_ui(alpha, 0); @@ -165,8 +165,8 @@ row = GBR_lp_add_row(lp, B->row[1+i]+1, dim); GBR_lp_set_obj(lp, B->row[1+i+1]+1, dim); ctx->stats->gbr_solved_lps++; - unbounded = GBR_lp_solve(lp); - isl_assert(ctx, !unbounded, goto error); + if (GBR_lp_solve(lp) < 0) + goto error; GBR_lp_get_obj_val(lp, &F_new); fixed = GBR_lp_is_fixed(lp); @@ -195,8 +195,8 @@ tmp, B->row[1+i]+1, dim); GBR_lp_set_obj(lp, b_tmp->el, dim); ctx->stats->gbr_solved_lps++; - unbounded = GBR_lp_solve(lp); - isl_assert(ctx, !unbounded, goto error); + if (GBR_lp_solve(lp) < 0) + goto error; GBR_lp_get_obj_val(lp, &mu_F[j]); mu_fixed[j] = GBR_lp_is_fixed(lp); if (i > 0) diff -Nru isl-0.12.2/bound.c isl-0.15/bound.c --- isl-0.12.2/bound.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/bound.c 2015-06-02 09:28:08.000000000 +0000 @@ -1,8 +1,11 @@ #include #include +#include #include #include #include +#include +#include struct bound_options { struct isl_options *isl; @@ -55,7 +58,7 @@ isl_pw_qpolynomial_fold *bound; }; -static int verify_point(__isl_take isl_point *pnt, void *user) +static isl_stat verify_point(__isl_take isl_point *pnt, void *user) { int i; unsigned nvar; @@ -64,8 +67,8 @@ isl_int t; isl_ctx *ctx; isl_pw_qpolynomial_fold *pwf; - isl_qpolynomial *bound = NULL; - isl_qpolynomial *opt = NULL; + isl_val *bound = NULL; + isl_val *opt = NULL; isl_set *dom = NULL; isl_printer *p; const char *minmax; @@ -117,13 +120,12 @@ opt = isl_pw_qpolynomial_fold_min(isl_pw_qpolynomial_fold_copy(pwf)); nvar = isl_set_dim(dom, isl_dim_set); - opt = isl_qpolynomial_project_domain_on_params(opt); if (vpb->exact && bounded) - ok = isl_qpolynomial_plain_is_equal(opt, bound); + ok = isl_val_eq(opt, bound); else if (sign > 0) - ok = isl_qpolynomial_le_cst(opt, bound); + ok = isl_val_le(opt, bound); else - ok = isl_qpolynomial_le_cst(bound, opt); + ok = isl_val_le(bound, opt); if (ok < 0) goto error; @@ -137,11 +139,11 @@ p = isl_printer_print_isl_int(p, t); } p = isl_printer_print_str(p, ") = "); - p = isl_printer_print_qpolynomial(p, bound); + p = isl_printer_print_val(p, bound); p = isl_printer_print_str(p, ", "); p = isl_printer_print_str(p, bounded ? "opt" : "sample"); p = isl_printer_print_str(p, " = "); - p = isl_printer_print_qpolynomial(p, opt); + p = isl_printer_print_val(p, opt); if (ok) p = isl_printer_print_str(p, ". OK"); else @@ -158,8 +160,8 @@ } isl_pw_qpolynomial_fold_free(pwf); - isl_qpolynomial_free(bound); - isl_qpolynomial_free(opt); + isl_val_free(bound); + isl_val_free(opt); isl_point_free(pnt); isl_set_free(dom); @@ -173,7 +175,7 @@ if (vpb->options->continue_on_error) ok = 1; - return (vpb->n >= 1 && ok) ? 0 : -1; + return (vpb->n >= 1 && ok) ? isl_stat_ok : isl_stat_error; } static int check_solution(__isl_take isl_pw_qpolynomial_fold *pwf, @@ -240,7 +242,7 @@ isl_ctx *ctx; isl_pw_qpolynomial_fold *copy; isl_pw_qpolynomial_fold *pwf; - struct isl_stream *s; + isl_stream *s; struct isl_obj obj; struct bound_options *options; int exact; diff -Nru isl-0.12.2/cat.c isl-0.15/cat.c --- isl-0.12.2/cat.c 2013-01-08 11:20:43.000000000 +0000 +++ isl-0.15/cat.c 2015-06-02 09:28:08.000000000 +0000 @@ -13,15 +13,24 @@ {0} }; +struct isl_arg_choice cat_yaml_style[] = { + { "block", ISL_YAML_STYLE_BLOCK }, + { "flow", ISL_YAML_STYLE_FLOW }, + { 0 } +}; + struct cat_options { struct isl_options *isl; unsigned format; + unsigned yaml_style; }; ISL_ARGS_START(struct cat_options, cat_options_args) ISL_ARG_CHILD(struct cat_options, isl, "isl", &isl_options_args, "isl options") ISL_ARG_CHOICE(struct cat_options, format, 0, "format", \ cat_format, ISL_FORMAT_ISL, "output format") +ISL_ARG_CHOICE(struct cat_options, yaml_style, 0, "yaml-style", \ + cat_yaml_style, ISL_YAML_STYLE_BLOCK, "output YAML style") ISL_ARGS_END ISL_ARG_DEF(cat_options, struct cat_options, cat_options_args) @@ -29,7 +38,7 @@ int main(int argc, char **argv) { struct isl_ctx *ctx; - struct isl_stream *s; + isl_stream *s; struct isl_obj obj; struct cat_options *options; isl_printer *p; @@ -46,6 +55,7 @@ p = isl_printer_to_file(ctx, stdout); p = isl_printer_set_output_format(p, options->format); + p = isl_printer_set_yaml_style(p, options->yaml_style); p = obj.type->print(p, obj.v); p = isl_printer_end_line(p); isl_printer_free(p); diff -Nru isl-0.12.2/ChangeLog isl-0.15/ChangeLog --- isl-0.12.2/ChangeLog 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/ChangeLog 2015-06-11 10:46:00.000000000 +0000 @@ -1,3 +1,38 @@ +version: 0.15 +date: Thu Jun 11 12:45:33 CEST 2015 +changes: + - improve coalescing + - add isl_union_access_info_compute_flow + - add mark nodes in AST + - add isl_union_pw_aff and isl_multi_union_pw_aff + - add schedule trees + - deprecate band forests + - deprecate separation_class AST generation option + - introduce isl_bool and isl_stat types +--- +version: 0.14.1 +date: Thu Apr 9 12:57:23 CEST 2015 +changes: + - fix bug in affine expression normalization + - fix handling of conditional validity constraints +--- +version: 0.14 +date: Sat Oct 25 16:08:47 CEST 2014 +changes: + - support IMath as an optional replacement for GMP + - minor AST generator improvements +--- +version: 0.13 +date: Mon Apr 14 11:08:45 CEST 2014 +changes: + - deprecate isl_int + - improved support for multi piecewise quasi-affine expressions + - allow the user to impose a bound on the number of low-level operations + - add isl_id_to_ast_expr and isl_id_to_pw_aff + - add isl_schedule_constraints + - hide internal structure of isl_vec + - remove support for piplib +--- version: 0.12.2 date: Sun Jan 12 12:09:46 CET 2014 changes: diff -Nru isl-0.12.2/closure.c isl-0.15/closure.c --- isl-0.12.2/closure.c 2013-01-08 11:20:43.000000000 +0000 +++ isl-0.15/closure.c 2015-06-02 09:28:08.000000000 +0000 @@ -7,6 +7,7 @@ struct isl_ctx *ctx; struct isl_map *map; struct isl_options *options; + isl_printer *p; int exact; options = isl_options_new_with_defaults(); @@ -15,19 +16,23 @@ ctx = isl_ctx_alloc_with_options(&isl_options_args, options); + p = isl_printer_to_file(ctx, stdout); + map = isl_map_read_from_file(ctx, stdin); map = isl_map_transitive_closure(map, &exact); if (!exact) - printf("# NOT exact\n"); - isl_map_print(map, stdout, 0, ISL_FORMAT_ISL); - printf("\n"); + p = isl_printer_print_str(p, "# NOT exact\n"); + p = isl_printer_print_map(p, map); + p = isl_printer_end_line(p); map = isl_map_compute_divs(map); map = isl_map_coalesce(map); - printf("# coalesced\n"); - isl_map_print(map, stdout, 0, ISL_FORMAT_ISL); - printf("\n"); + p = isl_printer_print_str(p, "# coalesced\n"); + p = isl_printer_print_map(p, map); + p = isl_printer_end_line(p); isl_map_free(map); + isl_printer_free(p); + isl_ctx_free(ctx); return 0; diff -Nru isl-0.12.2/codegen.c isl-0.15/codegen.c --- isl-0.12.2/codegen.c 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/codegen.c 2015-06-02 09:28:08.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012,2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -8,19 +8,26 @@ */ /* This program prints an AST that scans the domain elements of - * the domain of a given schedule in the order of their image(s). + * the domain of a given schedule in the order specified by + * the schedule tree or by their image(s) in the schedule map. * - * The input consists of three sets/relations. - * - a schedule + * The input consists of either a schedule tree or + * a sequence of three sets/relations. + * - a schedule map * - a context * - a relation describing AST generation options */ #include +#include #include #include #include #include +#include +#include +#include +#include struct options { struct isl_options *isl; @@ -36,7 +43,8 @@ "globally set the separate option") ISL_ARGS_END -ISL_ARG_DEF(options, struct options, options_args) +ISL_ARG_DEF(cg_options, struct options, options_args) +ISL_ARG_CTX_DEF(cg_options, struct options, options_args) /* Return a universal, 1-dimensional set with the given name. */ @@ -100,32 +108,130 @@ return build; } -int main(int argc, char **argv) +/* Construct an AST in case the schedule is specified by a union map. + * + * We read the context and the options from "s" and construct the AST. + */ +static __isl_give isl_ast_node *construct_ast_from_union_map( + __isl_take isl_union_map *schedule, __isl_keep isl_stream *s) { - isl_ctx *ctx; isl_set *context; - isl_union_map *schedule; isl_union_map *options_map; isl_ast_build *build; isl_ast_node *tree; struct options *options; - isl_printer *p; - - options = options_new_with_defaults(); - assert(options); - argc = options_parse(options, argc, argv, ISL_ARG_ALL); - ctx = isl_ctx_alloc_with_options(&options_args, options); + options = isl_ctx_peek_cg_options(isl_stream_get_ctx(s)); - schedule = isl_union_map_read_from_file(ctx, stdin); - context = isl_set_read_from_file(ctx, stdin); - options_map = isl_union_map_read_from_file(ctx, stdin); + context = isl_stream_read_set(s); + options_map = isl_stream_read_union_map(s); build = isl_ast_build_from_context(context); build = set_options(build, options_map, options, schedule); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); + return tree; +} + +/* If "node" is a band node, then replace the AST build options + * by "options". + */ +static __isl_give isl_schedule_node *node_set_options( + __isl_take isl_schedule_node *node, void *user) +{ + enum isl_ast_loop_type *type = user; + int i, n; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_band) + return node; + + n = isl_schedule_node_band_n_member(node); + for (i = 0; i < n; ++i) + node = isl_schedule_node_band_member_set_ast_loop_type(node, + i, *type); + return node; +} + +/* Replace the AST build options on all band nodes if requested + * by the user. + */ +static __isl_give isl_schedule *schedule_set_options( + __isl_take isl_schedule *schedule, struct options *options) +{ + enum isl_ast_loop_type type; + + if (!options->separate && !options->atomic) + return schedule; + + type = options->separate ? isl_ast_loop_separate : isl_ast_loop_atomic; + schedule = isl_schedule_map_schedule_node_bottom_up(schedule, + &node_set_options, &type); + + return schedule; +} + +/* Construct an AST in case the schedule is specified by a schedule tree. + */ +static __isl_give isl_ast_node *construct_ast_from_schedule( + __isl_take isl_schedule *schedule) +{ + isl_ast_build *build; + isl_ast_node *tree; + struct options *options; + + options = isl_ctx_peek_cg_options(isl_schedule_get_ctx(schedule)); + + build = isl_ast_build_alloc(isl_schedule_get_ctx(schedule)); + schedule = schedule_set_options(schedule, options); + tree = isl_ast_build_node_from_schedule(build, schedule); + isl_ast_build_free(build); + + return tree; +} + +/* Read an object from stdin. + * If it is a (union) map, then assume an input specified by + * schedule map, context and options and construct an AST from + * those elements + * If it is a schedule object, then construct the AST from the schedule. + */ +int main(int argc, char **argv) +{ + isl_ctx *ctx; + isl_stream *s; + isl_ast_node *tree = NULL; + struct options *options; + isl_printer *p; + struct isl_obj obj; + int r = EXIT_SUCCESS; + + options = cg_options_new_with_defaults(); + assert(options); + argc = cg_options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&options_args, options); + + s = isl_stream_new_file(ctx, stdin); + obj = isl_stream_read_obj(s); + if (obj.v == NULL) { + r = EXIT_FAILURE; + } else if (obj.type == isl_obj_map) { + isl_union_map *umap; + + umap = isl_union_map_from_map(obj.v); + tree = construct_ast_from_union_map(umap, s); + } else if (obj.type == isl_obj_union_map) { + tree = construct_ast_from_union_map(obj.v, s); + } else if (obj.type == isl_obj_schedule) { + tree = construct_ast_from_schedule(obj.v); + } else { + obj.type->free(obj.v); + isl_die(ctx, isl_error_invalid, "unknown input", + r = EXIT_FAILURE); + } + isl_stream_free(s); + p = isl_printer_to_file(ctx, stdout); p = isl_printer_set_output_format(p, ISL_FORMAT_C); p = isl_printer_print_ast_node(p, tree); @@ -134,5 +240,5 @@ isl_ast_node_free(tree); isl_ctx_free(ctx); - return 0; + return r; } diff -Nru isl-0.12.2/codegen_test.sh.in isl-0.15/codegen_test.sh.in --- isl-0.12.2/codegen_test.sh.in 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/codegen_test.sh.in 2015-06-02 09:28:08.000000000 +0000 @@ -5,8 +5,17 @@ failed=0 +for i in $srcdir/test_inputs/codegen/*.st \ + $srcdir/test_inputs/codegen/cloog/*.st; do + echo $i; + base=`basename $i .st` + test=test-$base.c + dir=`dirname $i` + ref=$dir/$base.c + (./isl_codegen$EXEEXT < $i > $test && + diff -uw $ref $test && rm $test) || failed=1 +done for i in $srcdir/test_inputs/codegen/*.in \ - $srcdir/test_inputs/codegen/cloog/*.in \ $srcdir/test_inputs/codegen/omega/*.in \ $srcdir/test_inputs/codegen/pldi2012/*.in; do echo $i; diff -Nru isl-0.12.2/configure isl-0.15/configure --- isl-0.12.2/configure 2014-01-12 11:45:17.000000000 +0000 +++ isl-0.15/configure 2015-06-11 10:47:03.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for isl 0.12.2. +# Generated by GNU Autoconf 2.69 for isl 0.15. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='isl' PACKAGE_TARNAME='isl' -PACKAGE_VERSION='0.12.2' -PACKAGE_STRING='isl 0.12.2' +PACKAGE_VERSION='0.15' +PACKAGE_STRING='isl 0.15' PACKAGE_BUGREPORT='isl-development@googlegroups.com' PACKAGE_URL='' @@ -648,16 +648,15 @@ CLANG_LIBS CLANG_LDFLAGS CLANG_CXXFLAGS -HAVE_PIPLIB_FALSE -HAVE_PIPLIB_TRUE -PIPLIB_LIBS -PIPLIB_LDFLAGS -PIPLIB_CPPFLAGS +GMP_FOR_MP_FALSE +GMP_FOR_MP_TRUE +IMATH_FOR_MP_FALSE +IMATH_FOR_MP_TRUE NEED_GET_MEMORY_FUNCTIONS_FALSE NEED_GET_MEMORY_FUNCTIONS_TRUE -GMP_LIBS -GMP_LDFLAGS -GMP_CPPFLAGS +MP_LIBS +MP_LDFLAGS +MP_CPPFLAGS GENERATE_DOC_FALSE GENERATE_DOC_TRUE POD2HTML @@ -798,14 +797,11 @@ with_gnu_ld with_sysroot enable_libtool_lock +with_int with_gmp with_gmp_prefix with_gmp_exec_prefix with_gmp_builddir -with_piplib -with_piplib_prefix -with_piplib_exec_prefix -with_piplib_builddir with_clang with_clang_prefix with_clang_exec_prefix @@ -1363,7 +1359,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures isl 0.12.2 to adapt to many kinds of systems. +\`configure' configures isl 0.15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1433,7 +1429,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of isl 0.12.2:";; + short | recursive ) echo "Configuration of isl 0.15:";; esac cat <<\_ACEOF @@ -1441,10 +1437,12 @@ --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: `make V=1') - --disable-silent-rules verbose build output (undo: `make V=0') - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build --enable-portable-binary disable compiler optimizations that would produce unportable binaries @@ -1464,19 +1462,13 @@ --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). + --with-int=gmp|imath Which package to use to represent multi-precision + integers [default=gmp] --with-gmp=system|build Which gmp to use [default=system] --with-gmp-prefix=DIR Prefix of gmp installation --with-gmp-exec-prefix=DIR Exec prefix of gmp installation --with-gmp-builddir=DIR Location of gmp builddir - --with-piplib=no|system|build - Which piplib to use [default=no] - --with-piplib-prefix=DIR - Prefix of piplib installation - --with-piplib-exec-prefix=DIR - Exec prefix of piplib installation - --with-piplib-builddir=DIR - Location of piplib builddir --with-clang=system|no Which clang to use [default=no] --with-clang-prefix=DIR Prefix of clang installation --with-clang-exec-prefix=DIR @@ -1561,7 +1553,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -isl configure 0.12.2 +isl configure 0.15 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2331,63 +2323,6 @@ } # ac_fn_c_check_decl -# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES -# ---------------------------------------------------- -# Tries to find if the field MEMBER exists in type AGGR, after including -# INCLUDES, setting cache variable VAR accordingly. -ac_fn_c_check_member () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -$as_echo_n "checking for $2.$3... " >&6; } -if eval \${$4+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - eval "$4=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$4 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_member - # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using @@ -2482,7 +2417,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by isl $as_me 0.12.2, which was +It was created by isl $as_me 0.15, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2860,7 +2795,7 @@ -am__api_version='1.11' +am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2957,9 +2892,6 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -2970,32 +2902,40 @@ esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -3007,6 +2947,16 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -3029,12 +2979,12 @@ esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -3046,10 +2996,10 @@ esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -3188,12 +3138,6 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -3276,6 +3220,45 @@ fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -3298,7 +3281,7 @@ # Define the identity of the package. PACKAGE='isl' - VERSION='0.12.2' + VERSION='0.15' cat >>confdefs.h <<_ACEOF @@ -3326,27 +3309,79 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi -case $enable_silent_rules in -yes) AM_DEFAULT_VERBOSITY=0;; -no) AM_DEFAULT_VERBOSITY=1;; -*) AM_DEFAULT_VERBOSITY=0;; +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 @@ -3378,7 +3413,7 @@ AM_BACKSLASH='\' -versioninfo=12:2:2 +versioninfo=15:0:0 if test "x$prefix" != "xNONE"; then prefix_wd=`cd $prefix && pwd` @@ -4180,6 +4215,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" @@ -4199,7 +4293,7 @@ _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -4255,8 +4349,8 @@ # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -4291,16 +4385,16 @@ : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -4309,8 +4403,8 @@ test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -4318,7 +4412,7 @@ fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -4640,8 +4734,8 @@ # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're @@ -4676,16 +4770,16 @@ : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -4694,8 +4788,8 @@ test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else @@ -4703,7 +4797,7 @@ fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -17158,6 +17252,30 @@ +# Check whether --with-int was given. +if test "${with_int+set}" = set; then : + withval=$with_int; +else + with_int=gmp +fi + +case "$with_int" in +gmp|imath) + ;; +*) + as_fn_error $? "bad value ${withval} for --with-int (use gmp or imath)" "$LINENO" 5 +esac + + + + +case "$with_int" in +gmp) + + +$as_echo "#define USE_GMP_FOR_MP /**/" >>confdefs.h + + # Check whether --with-gmp was given. @@ -17245,24 +17363,20 @@ $as_echo "$with_gmp" >&6; } - - - - 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_fn_c_check_header_mongrel "$LINENO" "gmp.h" "ac_cv_header_gmp_h" "$ac_includes_default" if test "x$ac_cv_header_gmp_h" = xyes; then : @@ -17339,16 +17453,16 @@ 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_fn_c_check_decl "$LINENO" "mp_get_memory_functions" "ac_cv_have_decl_mp_get_memory_functions" "#include " @@ -17369,43 +17483,6 @@ fi -if test "$cross_compiling" = yes; then : - need_normalized_gcdext=true -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ - - mpz_t x,y,g,a,b; - mpz_init(x); - mpz_init(y); - mpz_init(g); - mpz_init(a); - mpz_init(b); - mpz_set_si(x, -1); - mpz_set_si(y, 9); - mpz_gcdext(g, a, b, x, y); - if (mpz_get_si(a) == -1 && mpz_get_si(b) == 0) - return 0; - else - return 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - need_normalized_gcdext=false -else - need_normalized_gcdext=true -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" LIBS="$SAVE_LIBS" @@ -17417,220 +17494,88 @@ NEED_GET_MEMORY_FUNCTIONS_FALSE= fi -if test $need_normalized_gcdext = true; then -$as_echo "#define GMP_NORMALIZE_GCDEXT /**/" >>confdefs.h + ;; +imath) -fi -ac_fn_c_check_decl "$LINENO" "ffs" "ac_cv_have_decl_ffs" "#include -" -if test "x$ac_cv_have_decl_ffs" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_FFS $ac_have_decl -_ACEOF +$as_echo "#define USE_IMATH_FOR_MP /**/" >>confdefs.h -ac_fn_c_check_decl "$LINENO" "__builtin_ffs" "ac_cv_have_decl___builtin_ffs" "$ac_includes_default" -if test "x$ac_cv_have_decl___builtin_ffs" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL___BUILTIN_FFS $ac_have_decl -_ACEOF +MP_CPPFLAGS="-I$srcdir/imath_wrap" +MP_LDFLAGS="" +MP_LIBS="" +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$MP_CPPFLAGS $CPPFLAGS" +ac_fn_c_check_header_mongrel "$LINENO" "imath.h" "ac_cv_header_imath_h" "$ac_includes_default" +if test "x$ac_cv_header_imath_h" = xyes; then : +else + as_fn_error $? "imath.h header not found" "$LINENO" 5 +fi +ac_fn_c_check_header_mongrel "$LINENO" "gmp_compat.h" "ac_cv_header_gmp_compat_h" "$ac_includes_default" +if test "x$ac_cv_header_gmp_compat_h" = xyes; then : -# Check whether --with-piplib was given. -if test "${with_piplib+set}" = set; then : - withval=$with_piplib; +else + as_fn_error $? "gmp_compat.h header not found" "$LINENO" 5 fi -case "system" in -no|system|build) - -# Check whether --with-piplib_prefix was given. -if test "${with_piplib_prefix+set}" = set; then : - withval=$with_piplib_prefix; -fi +CPPFLAGS="$SAVE_CPPFLAGS" -# Check whether --with-piplib_exec_prefix was given. -if test "${with_piplib_exec_prefix+set}" = set; then : - withval=$with_piplib_exec_prefix; + if test x = xfalse; then + NEED_GET_MEMORY_FUNCTIONS_TRUE= + NEED_GET_MEMORY_FUNCTIONS_FALSE='#' +else + NEED_GET_MEMORY_FUNCTIONS_TRUE='#' + NEED_GET_MEMORY_FUNCTIONS_FALSE= fi -esac -# Check whether --with-piplib_builddir was given. -if test "${with_piplib_builddir+set}" = set; then : - withval=$with_piplib_builddir; -fi - -if test "x$with_piplib_prefix" != "x" -a "x$with_piplib_exec_prefix" = "x"; then - with_piplib_exec_prefix=$with_piplib_prefix -fi -if test "x$with_piplib_prefix" != "x" -o "x$with_piplib_exec_prefix" != "x"; then - if test "x$with_piplib" != "x" -a "x$with_piplib" != "xyes" -a "x$with_piplib" != "xsystem"; then - as_fn_error $? "Setting $with_piplib_prefix implies use of system piplib" "$LINENO" 5 - fi - with_piplib="system" -fi -if test "x$with_piplib_builddir" != "x"; then - if test "x$with_piplib" != "x" -a "x$with_piplib" != "xyes" -a "x$with_piplib" != "xbuild"; then - as_fn_error $? "Setting $with_piplib_builddir implies use of build piplib" "$LINENO" 5 - fi - with_piplib="build" - piplib_srcdir=`echo @abs_srcdir@ | $with_piplib_builddir/config.status --file=-` - { $as_echo "$as_me:${as_lineno-$LINENO}: piplib sources in $piplib_srcdir" >&5 -$as_echo "$as_me: piplib sources in $piplib_srcdir" >&6;} -fi -if test "x$with_piplib_exec_prefix" != "x"; then - export PKG_CONFIG_PATH="$with_piplib_exec_prefix/lib/pkgconfig${PKG_CONFIG_PATH+:$PKG_CONFIG_PATH}" -fi -case "$with_piplib" in -no|system|build) - ;; -*) - case "no" in - bundled) - if test -d $srcdir/.git -a \ - -d $srcdir/piplib -a \ - ! -d $srcdir/piplib/.git; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: git repo detected, but submodule piplib not initialized" >&5 -$as_echo "$as_me: WARNING: git repo detected, but submodule piplib not initialized" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You may want to run" >&5 -$as_echo "$as_me: WARNING: You may want to run" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: git submodule init" >&5 -$as_echo "$as_me: WARNING: git submodule init" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: git submodule update" >&5 -$as_echo "$as_me: WARNING: git submodule update" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: sh autogen.sh" >&5 -$as_echo "$as_me: WARNING: sh autogen.sh" >&2;} - fi - if test -f $srcdir/piplib/configure; then - with_piplib="bundled" - else - with_piplib="no" - fi - ;; - *) - with_piplib="no" - ;; - esac ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which piplib to use" >&5 -$as_echo_n "checking which piplib to use... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_piplib" >&5 -$as_echo "$with_piplib" >&6; } - - -have_piplib=false - - - -case "$with_piplib" in - build) - PIPLIB_CPPFLAGS="-I$piplib_srcdir/include" - PIPLIB_LIBS="$with_piplib_builddir/libpiplibMP.la" - ;; - system) - PIPLIB_LIBS="-lpiplibMP" - if test "x$with_piplib_prefix" != "x"; then - PIPLIB_CPPFLAGS="-I$with_piplib_prefix/include" - PIPLIB_LDFLAGS="-L$with_piplib_prefix/lib" - fi - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$PIPLIB_CPPFLAGS $CPPFLAGS" - LDFLAGS="$PIPLIB_LDFLAGS $LDFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pip_solve in -lpiplibMP" >&5 -$as_echo_n "checking for pip_solve in -lpiplibMP... " >&6; } -if ${ac_cv_lib_piplibMP_pip_solve+:} false; then : - $as_echo_n "(cached) " >&6 + if test x$with_int = ximath; then + IMATH_FOR_MP_TRUE= + IMATH_FOR_MP_FALSE='#' else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpiplibMP $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + IMATH_FOR_MP_TRUE='#' + IMATH_FOR_MP_FALSE= +fi -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pip_solve (); -int -main () -{ -return pip_solve (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_piplibMP_pip_solve=yes + if test x$with_int = xgmp; then + GMP_FOR_MP_TRUE= + GMP_FOR_MP_FALSE='#' else - ac_cv_lib_piplibMP_pip_solve=no + GMP_FOR_MP_TRUE='#' + GMP_FOR_MP_FALSE= fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_piplibMP_pip_solve" >&5 -$as_echo "$ac_cv_lib_piplibMP_pip_solve" >&6; } -if test "x$ac_cv_lib_piplibMP_pip_solve" = xyes; then : - ac_fn_c_check_member "$LINENO" "PipOptions" "Urs_parms" "ac_cv_member_PipOptions_Urs_parms" "#include +ac_fn_c_check_decl "$LINENO" "ffs" "ac_cv_have_decl_ffs" "#include " -if test "x$ac_cv_member_PipOptions_Urs_parms" = xyes; then : - +if test "x$ac_cv_have_decl_ffs" = xyes; then : + ac_have_decl=1 else - - as_fn_error $? "Piplib too old; please install version 1.3.6 or newer" "$LINENO" 5 - + ac_have_decl=0 fi +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FFS $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "__builtin_ffs" "ac_cv_have_decl___builtin_ffs" "$ac_includes_default" +if test "x$ac_cv_have_decl___builtin_ffs" = xyes; then : + ac_have_decl=1 else - - as_fn_error $? "Piplib not found" "$LINENO" 5 - + ac_have_decl=0 fi - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - ;; - no) - ;; - *) - as_fn_error $? "unsupported" "$LINENO" 5 - ;; -esac -if test "$with_piplib" != "no"; then - -$as_echo "#define ISL_PIPLIB /**/" >>confdefs.h - - have_piplib=true -fi - if test x$have_piplib = xtrue; then - HAVE_PIPLIB_TRUE= - HAVE_PIPLIB_FALSE='#' -else - HAVE_PIPLIB_TRUE='#' - HAVE_PIPLIB_FALSE= -fi +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL___BUILTIN_FFS $ac_have_decl +_ACEOF @@ -17840,6 +17785,10 @@ components="$components option" fi CLANG_LIBS=`$llvm_config --libs $components` + systemlibs=`$llvm_config --system-libs 2> /dev/null | tail -1` + if test $? -eq 0; then + CLANG_LIBS="$CLANG_LIBS $systemlibs" + fi CLANG_PREFIX=`$llvm_config --prefix` cat >>confdefs.h <<_ACEOF @@ -17950,6 +17899,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include +int +main () +{ + + using namespace clang; + DiagnosticsEngine *Diags; + new driver::Driver("", "", "", *Diags); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define DRIVER_CTOR_TAKES_DEFAULTIMAGENAME /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ #include _ACEOF @@ -17987,6 +17957,28 @@ { using namespace clang; + std::shared_ptr TO; + DiagnosticsEngine *Diags; + TargetInfo::CreateTargetInfo(*Diags, TO); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define CREATETARGETINFO_TAKES_SHARED_PTR /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + using namespace clang; TargetOptions *TO; DiagnosticsEngine *Diags; TargetInfo::CreateTargetInfo(*Diags, TO); @@ -18046,6 +18038,79 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getNumParams" >/dev/null 2>&1; then : + +$as_echo "#define getNumArgs getNumParams" >>confdefs.h + + +$as_echo "#define getArgType getParamType" >>confdefs.h + +fi +rm -f conftest* + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getReturnType" >/dev/null 2>&1; then : + +else + +$as_echo "#define getReturnType getResultType" >>confdefs.h + +fi +rm -f conftest* + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + using namespace clang; + CompilerInstance *Clang; + Clang->createPreprocessor(TU_Complete); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +$as_echo "#define CREATEPREPROCESSOR_TAKES_TUKIND /**/" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "setMainFileID" >/dev/null 2>&1; then : + +$as_echo "#define HAVE_SETMAINFILEID /**/" >>confdefs.h + +fi +rm -f conftest* + + ac_fn_cxx_check_header_mongrel "$LINENO" "llvm/ADT/OwningPtr.h" "ac_cv_header_llvm_ADT_OwningPtr_h" "$ac_includes_default" +if test "x$ac_cv_header_llvm_ADT_OwningPtr_h" = xyes; then : + +$as_echo "#define HAVE_ADT_OWNINGPTR_H /**/" >>confdefs.h + +fi + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -18148,9 +18213,9 @@ -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" # we need the expanded forms... test "x$prefix" = xNONE && prefix=$ac_default_prefix @@ -18340,10 +18405,15 @@ - if test -f $srcdir/.git/HEAD; then + if test -f $srcdir/.git; then + gitdir=`GIT_DIR=$srcdir/.git git rev-parse --git-dir` + GIT_HEAD="$gitdir/index" + GIT_REPO="$gitdir" + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` + elif test -f $srcdir/.git/HEAD; then GIT_HEAD="$srcdir/.git/index" GIT_REPO="$srcdir/.git" - GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe` + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` elif test -f $srcdir/GIT_HEAD_ID; then GIT_HEAD_ID=`cat $srcdir/GIT_HEAD_ID` else @@ -18360,7 +18430,7 @@ if test -z "$GIT_REPO" ; then GIT_HEAD_VERSION="$GIT_HEAD_ID" else - GIT_HEAD_VERSION="\`GIT_DIR=$GIT_REPO git describe\`" + GIT_HEAD_VERSION="\`GIT_DIR=$GIT_REPO git describe --always\`" fi echo '#define GIT_HEAD_ID "'$GIT_HEAD_ID'"' > gitversion.h @@ -18368,8 +18438,6 @@ ac_config_headers="$ac_config_headers isl_config.h" -ac_config_headers="$ac_config_headers include/isl/config.h" - ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files doc/Makefile" @@ -18494,6 +18562,14 @@ LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -18522,8 +18598,16 @@ as_fn_error $? "conditional \"NEED_GET_MEMORY_FUNCTIONS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${HAVE_PIPLIB_TRUE}" && test -z "${HAVE_PIPLIB_FALSE}"; then - as_fn_error $? "conditional \"HAVE_PIPLIB\" was never defined. +if test -z "${NEED_GET_MEMORY_FUNCTIONS_TRUE}" && test -z "${NEED_GET_MEMORY_FUNCTIONS_FALSE}"; then + as_fn_error $? "conditional \"NEED_GET_MEMORY_FUNCTIONS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IMATH_FOR_MP_TRUE}" && test -z "${IMATH_FOR_MP_FALSE}"; then + as_fn_error $? "conditional \"IMATH_FOR_MP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GMP_FOR_MP_TRUE}" && test -z "${GMP_FOR_MP_FALSE}"; then + as_fn_error $? "conditional \"GMP_FOR_MP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_CLANG_TRUE}" && test -z "${HAVE_CLANG_FALSE}"; then @@ -18927,7 +19011,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by isl $as_me 0.12.2, which was +This file was extended by isl $as_me 0.15, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18993,7 +19077,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -isl config.status 0.12.2 +isl config.status 0.15 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -19543,7 +19627,6 @@ "$ac_stdint_h") CONFIG_COMMANDS="$CONFIG_COMMANDS $ac_stdint_h" ;; "$ax_create_pkgconfig_generate") CONFIG_COMMANDS="$CONFIG_COMMANDS $ax_create_pkgconfig_generate" ;; "isl_config.h") CONFIG_HEADERS="$CONFIG_HEADERS isl_config.h" ;; - "include/isl/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/isl/config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "interface/Makefile") CONFIG_FILES="$CONFIG_FILES interface/Makefile" ;; @@ -20146,7 +20229,7 @@ case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -20159,7 +20242,7 @@ # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -20193,21 +20276,19 @@ continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || diff -Nru isl-0.12.2/configure.ac isl-0.15/configure.ac --- isl-0.12.2/configure.ac 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/configure.ac 2015-06-11 10:46:17.000000000 +0000 @@ -1,10 +1,10 @@ -AC_INIT([isl], [0.12.2], [isl-development@googlegroups.com]) +AC_INIT([isl], [0.15], [isl-development@googlegroups.com]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_SUBST(versioninfo) -versioninfo=12:2:2 +versioninfo=15:0:0 if test "x$prefix" != "xNONE"; then prefix_wd=`cd $prefix && pwd` @@ -35,120 +35,34 @@ AX_CREATE_STDINT_H(include/isl/stdint.h) -AX_SUBMODULE(gmp,system|build,system) - -AC_SUBST(GMP_CPPFLAGS) -AC_SUBST(GMP_LDFLAGS) -AC_SUBST(GMP_LIBS) -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" - fi - GMP_LIBS=-lgmp - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - SAVE_LIBS="$LIBS" - CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" - LDFLAGS="$GMP_LDFLAGS $LDFLAGS" - LIBS="$GMP_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 ]], [[ - mpz_t n, d; - if (mpz_divisible_p(n, d)) - mpz_divexact_ui(n, n, 4); - ]])], [], [AC_ERROR([gmp library too old])]) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - LIBS="$SAVE_LIBS" - ;; -build) - GMP_CPPFLAGS="-I$gmp_srcdir -I$with_gmp_builddir" - GMP_LIBS="$with_gmp_builddir/libgmp.la" +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 -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" -SAVE_LIBS="$LIBS" -CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" -LDFLAGS="$GMP_LDFLAGS $LDFLAGS" -LIBS="$GMP_LIBS $LIBS" -need_get_memory_functions=false -AC_CHECK_DECLS(mp_get_memory_functions,[],[ - need_get_memory_functions=true -],[#include ]) -AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ - mpz_t x,y,g,a,b; - mpz_init(x); - mpz_init(y); - mpz_init(g); - mpz_init(a); - mpz_init(b); - mpz_set_si(x, -1); - mpz_set_si(y, 9); - mpz_gcdext(g, a, b, x, y); - if (mpz_get_si(a) == -1 && mpz_get_si(b) == 0) - return 0; - else - return 1; -]])], [need_normalized_gcdext=false], [need_normalized_gcdext=true], -[need_normalized_gcdext=true]) -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" -LIBS="$SAVE_LIBS" -AM_CONDITIONAL(NEED_GET_MEMORY_FUNCTIONS, test x$need_get_memory_functions = xtrue) -if test $need_normalized_gcdext = true; then -AC_DEFINE([GMP_NORMALIZE_GCDEXT], [], - [result of mpz_gcdext needs to be normalized]) -fi -AC_CHECK_DECLS(ffs,[],[],[#include ]) -AC_CHECK_DECLS(__builtin_ffs,[],[],[]) - -AX_SUBMODULE(piplib,no|system|build,no) -have_piplib=false -AC_SUBST(PIPLIB_CPPFLAGS) -AC_SUBST(PIPLIB_LDFLAGS) -AC_SUBST(PIPLIB_LIBS) -case "$with_piplib" in - build) - PIPLIB_CPPFLAGS="-I$piplib_srcdir/include" - PIPLIB_LIBS="$with_piplib_builddir/libpiplibMP.la" - ;; - system) - PIPLIB_LIBS="-lpiplibMP" - if test "x$with_piplib_prefix" != "x"; then - PIPLIB_CPPFLAGS="-I$with_piplib_prefix/include" - PIPLIB_LDFLAGS="-L$with_piplib_prefix/lib" - fi - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$PIPLIB_CPPFLAGS $CPPFLAGS" - LDFLAGS="$PIPLIB_LDFLAGS $LDFLAGS" - AC_CHECK_LIB(piplibMP, pip_solve,[ - AC_CHECK_MEMBER(PipOptions.Urs_parms, [], [ - AC_MSG_ERROR([Piplib too old; please install version 1.3.6 or newer]) - ],[#include ]) - ],[ - AC_MSG_ERROR([Piplib not found]) - ]) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - ;; - no) +AC_SUBST(MP_CPPFLAGS) +AC_SUBST(MP_LDFLAGS) +AC_SUBST(MP_LIBS) +case "$with_int" in +gmp) + AX_DETECT_GMP ;; - *) - AC_MSG_ERROR(unsupported) +imath) + AX_DETECT_IMATH ;; esac -if test "$with_piplib" != "no"; then - AC_DEFINE(ISL_PIPLIB,,piplib is available) - have_piplib=true -fi -AM_CONDITIONAL(HAVE_PIPLIB, test x$have_piplib = xtrue) + +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 ]) +AC_CHECK_DECLS(__builtin_ffs,[],[],[]) AC_SUBST(CLANG_CXXFLAGS) AC_SUBST(CLANG_LDFLAGS) @@ -177,6 +91,10 @@ components="$components option" fi CLANG_LIBS=`$llvm_config --libs $components` + systemlibs=`$llvm_config --system-libs 2> /dev/null | tail -1` + if test $? -eq 0; then + CLANG_LIBS="$CLANG_LIBS $systemlibs" + fi CLANG_PREFIX=`$llvm_config --prefix` AC_DEFINE_UNQUOTED(CLANG_PREFIX, ["$CLANG_PREFIX"], [Clang installation prefix]) @@ -208,6 +126,12 @@ AC_EGREP_HEADER([ IsProduction], [clang/Driver/Driver.h], [AC_DEFINE([HAVE_ISPRODUCTION], [], [Define if Driver constructor takes IsProduction argument])]) + AC_TRY_COMPILE([#include ], [ + using namespace clang; + DiagnosticsEngine *Diags; + new driver::Driver("", "", "", *Diags); + ], [AC_DEFINE([DRIVER_CTOR_TAKES_DEFAULTIMAGENAME], [], + [Define if Driver constructor takes default image name])]) AC_EGREP_HEADER([void HandleTopLevelDecl\(], [clang/AST/ASTConsumer.h], [AC_DEFINE([HandleTopLevelDeclReturn], [void], [Return type of HandleTopLevelDeclReturn]) @@ -222,6 +146,13 @@ [Define if clang/Basic/DiagnosticOptions.h exists])]) AC_TRY_COMPILE([#include ], [ using namespace clang; + std::shared_ptr TO; + DiagnosticsEngine *Diags; + TargetInfo::CreateTargetInfo(*Diags, TO); + ], [AC_DEFINE([CREATETARGETINFO_TAKES_SHARED_PTR], [], + [Define if TargetInfo::CreateTargetInfo takes shared_ptr])]) + AC_TRY_COMPILE([#include ], [ + using namespace clang; TargetOptions *TO; DiagnosticsEngine *Diags; TargetInfo::CreateTargetInfo(*Diags, TO); @@ -240,6 +171,29 @@ HSO.AddPath("", frontend::Angled, false, false); ], [AC_DEFINE([ADDPATH_TAKES_4_ARGUMENTS], [], [Define if HeaderSearchOptions::AddPath takes 4 arguments])]) + AC_EGREP_HEADER([getNumParams], + [clang/AST/CanonicalType.h], + [AC_DEFINE([getNumArgs], [getNumParams], + [Define to getNumParams for newer versions of clang]) + AC_DEFINE([getArgType], [getParamType], + [Define to getParamType for newer versions of clang])]) + AC_EGREP_HEADER([getReturnType], + [clang/AST/CanonicalType.h], [], + [AC_DEFINE([getReturnType], [getResultType], + [Define to getResultType for older versions of clang])]) + AC_TRY_COMPILE([#include ], [ + using namespace clang; + CompilerInstance *Clang; + Clang->createPreprocessor(TU_Complete); + ], [AC_DEFINE([CREATEPREPROCESSOR_TAKES_TUKIND], [], + [Define if CompilerInstance::createPreprocessor takes + TranslationUnitKind])]) + AC_EGREP_HEADER([setMainFileID], [clang/Basic/SourceManager.h], + [AC_DEFINE([HAVE_SETMAINFILEID], [], + [Define if SourceManager has a setMainFileID method])]) + AC_CHECK_HEADER([llvm/ADT/OwningPtr.h], + [AC_DEFINE([HAVE_ADT_OWNINGPTR_H], [], + [Define if llvm/ADT/OwningPtr.h exists])]) AC_LANG_POP CPPFLAGS="$SAVE_CPPFLAGS" @@ -256,9 +210,9 @@ 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 @@ -266,7 +220,6 @@ AH_BOTTOM([#include ]) AC_CONFIG_HEADERS(isl_config.h) -AC_CONFIG_HEADERS(include/isl/config.h) AC_CONFIG_FILES(Makefile) AC_CONFIG_FILES(doc/Makefile) if test $with_clang = system; then diff -Nru isl-0.12.2/debian/changelog isl-0.15/debian/changelog --- isl-0.12.2/debian/changelog 2014-02-13 14:09:34.000000000 +0000 +++ isl-0.15/debian/changelog 2015-11-30 10:35:51.000000000 +0000 @@ -1,3 +1,52 @@ +isl (0.15-3~14.04) trusty; urgency=medium + + * PPA upload. + + -- Matthias Klose Mon, 30 Nov 2015 11:34:44 +0100 + +isl (0.15-3) unstable; urgency=medium + + * Upload to unstable. + + -- Matthias Klose Tue, 17 Nov 2015 00:20:09 +0100 + +isl (0.15-2) experimental; urgency=medium + + * libisl-dbg: Fix dependency on libisl. + + -- Matthias Klose Mon, 27 Jul 2015 19:25:08 +0200 + +isl (0.15-1) experimental; urgency=medium + + * New upstream release. + + -- Matthias Klose Sat, 25 Jul 2015 18:18:18 +0200 + +isl (0.14-2) unstable; urgency=medium + + * Upload to unstable. + + -- Matthias Klose Fri, 24 Apr 2015 14:36:08 +0200 + +isl (0.14-1) experimental; urgency=medium + + * New upstream release. + + -- Matthias Klose Tue, 11 Nov 2014 12:24:42 +0100 + +isl (0.13-1) experimental; urgency=medium + + * New upstream release. + + -- Matthias Klose Wed, 25 Jun 2014 16:24:52 +0200 + +isl (0.12.2-2) unstable; urgency=medium + + * Make the python pretty printer file compatible with python3. + * Let the python pretty printer load the library by the soname. + + -- Matthias Klose Wed, 25 Jun 2014 15:35:38 +0200 + isl (0.12.2-1) unstable; urgency=medium * New upstream release. diff -Nru isl-0.12.2/debian/control isl-0.15/debian/control --- isl-0.12.2/debian/control 2014-02-13 14:04:57.000000000 +0000 +++ isl-0.15/debian/control 2015-07-27 17:25:04.000000000 +0000 @@ -2,9 +2,9 @@ Priority: optional Maintainer: Debian GCC Maintainers Uploaders: Matthias Klose -Build-Depends: debhelper (>= 7.0.50~), dh-autoreconf, automake1.11, +Build-Depends: debhelper (>= 7.0.50~), dh-autoreconf, libgmp-dev -Standards-Version: 3.9.5 +Standards-Version: 3.9.6 Section: libs Homepage: http://freecode.com/projects/isl @@ -12,7 +12,7 @@ Section: libdevel Architecture: any Multi-Arch: same -Depends: libisl10 (= ${binary:Version}), ${misc:Depends} +Depends: libisl15 (= ${binary:Version}), ${misc:Depends} Description: manipulating sets and relations of integer points bounded by linear constraints isl is a library for manipulating sets and relations of integer points bounded by linear constraints. Supported operations on sets include @@ -28,7 +28,7 @@ Priority: extra Architecture: any Multi-Arch: same -Depends: libisl10 (= ${binary:Version}), ${misc:Depends} +Depends: libisl15 (= ${binary:Version}), ${misc:Depends} Replaces: libisl-dev (<< 0.08) Description: manipulating sets and relations of integer points bounded by linear constraints isl is a library for manipulating sets and relations of integer points @@ -40,13 +40,12 @@ . This package contains debug files. -Package: libisl10 +Package: libisl15 Section: libs Architecture: any Multi-Arch: same Pre-Depends: multiarch-support Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: libcloog-isl4 (<< 0.18.1) Description: manipulating sets and relations of integer points bounded by linear constraints isl is a library for manipulating sets and relations of integer points bounded by linear constraints. Supported operations on sets include diff -Nru isl-0.12.2/debian/copyright isl-0.15/debian/copyright --- isl-0.12.2/debian/copyright 2013-01-13 02:31:03.000000000 +0000 +++ isl-0.15/debian/copyright 2014-11-11 11:53:16.000000000 +0000 @@ -30,7 +30,7 @@ Files: interface/python.* Copyright: Copyright 2011 Sven Verdoolaege. All rights reserved. -License: 2-clause BSD +License: BSD-2-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -97,7 +97,7 @@ from Young Ryu and Brian Reiser's modifications of 'apalike.bst'. Files: debian/* -Copyright: 2011 Matthias Klose +Copyright: 2011-2014 Matthias Klose License: LGPL-2.1+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff -Nru isl-0.12.2/debian/.debhelper/generated/libisl15/triggers isl-0.15/debian/.debhelper/generated/libisl15/triggers --- isl-0.12.2/debian/.debhelper/generated/libisl15/triggers 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/debian/.debhelper/generated/libisl15/triggers 2015-11-16 23:23:05.000000000 +0000 @@ -0,0 +1,2 @@ +# Triggers added by dh_makeshlibs +activate-noawait ldconfig diff -Nru isl-0.12.2/debian/libisl10.install isl-0.15/debian/libisl10.install --- isl-0.12.2/debian/libisl10.install 2011-12-15 16:41:36.000000000 +0000 +++ isl-0.15/debian/libisl10.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*/lib*.so.*[0-9] diff -Nru isl-0.12.2/debian/libisl10.symbols isl-0.15/debian/libisl10.symbols --- isl-0.12.2/debian/libisl10.symbols 2014-02-13 14:09:17.000000000 +0000 +++ isl-0.15/debian/libisl10.symbols 1970-01-01 00:00:00.000000000 +0000 @@ -1,2944 +0,0 @@ -libisl.so.10 #PACKAGE# #MINVER# - isl_access_info_add_source@Base 0.10 - isl_access_info_alloc@Base 0.10 - isl_access_info_compute_flow@Base 0.10 - isl_access_info_free@Base 0.10 - isl_access_info_get_ctx@Base 0.10 - isl_access_info_set_restrict@Base 0.10 - isl_aff_add@Base 0.10 - isl_aff_add_coefficient@Base 0.10 - isl_aff_add_coefficient_si@Base 0.10 - isl_aff_add_coefficient_val@Base 0.12.1 - isl_aff_add_constant@Base 0.10 - isl_aff_add_constant_num@Base 0.11 - isl_aff_add_constant_num_si@Base 0.11 - isl_aff_add_constant_si@Base 0.10 - isl_aff_add_constant_val@Base 0.12.1 - isl_aff_add_dims@Base 0.10 - isl_aff_add_on_domain@Base 0.10 - isl_aff_align_divs@Base 0.10 - isl_aff_align_params@Base 0.10 - isl_aff_alloc@Base 0.10 - isl_aff_alloc_vec@Base 0.10 - isl_aff_ceil@Base 0.10 - isl_aff_check_match_domain_space@Base 0.12.1 - isl_aff_copy@Base 0.10 - isl_aff_cow@Base 0.10 - isl_aff_dim@Base 0.10 - isl_aff_div@Base 0.11 - isl_aff_drop_dims@Base 0.10 - isl_aff_dump@Base 0.10 - isl_aff_dup@Base 0.10 - isl_aff_expand_divs@Base 0.10 - isl_aff_floor@Base 0.10 - isl_aff_free@Base 0.10 - isl_aff_ge_basic_set@Base 0.10 - isl_aff_get_coefficient@Base 0.10 - isl_aff_get_coefficient_val@Base 0.12.1 - isl_aff_get_constant@Base 0.10 - isl_aff_get_constant_val@Base 0.12.1 - isl_aff_get_ctx@Base 0.10 - isl_aff_get_denominator@Base 0.10 - isl_aff_get_denominator_val@Base 0.12.1 - isl_aff_get_dim@Base 0.10 - isl_aff_get_dim_name@Base 0.10 - isl_aff_get_div@Base 0.10 - isl_aff_get_domain_local_space@Base 0.10 - isl_aff_get_domain_space@Base 0.10 - isl_aff_get_local_space@Base 0.10 - isl_aff_get_space@Base 0.10 - isl_aff_gist@Base 0.10 - isl_aff_gist_params@Base 0.10 - isl_aff_insert_dims@Base 0.10 - isl_aff_involves_dims@Base 0.10 - isl_aff_is_cst@Base 0.10 - isl_aff_is_empty@Base 0.10 - isl_aff_le_basic_set@Base 0.10 - isl_aff_lift@Base 0.10 - isl_aff_list_add@Base 0.10 - isl_aff_list_alloc@Base 0.10 - isl_aff_list_concat@Base 0.10 - isl_aff_list_copy@Base 0.10 - isl_aff_list_cow@Base 0.11 - isl_aff_list_drop@Base 0.11 - isl_aff_list_dump@Base 0.10 - isl_aff_list_dup@Base 0.10 - isl_aff_list_foreach@Base 0.10 - isl_aff_list_foreach_scc@Base 0.12.1 - isl_aff_list_free@Base 0.10 - isl_aff_list_from_aff@Base 0.10 - isl_aff_list_get_aff@Base 0.10 - isl_aff_list_get_ctx@Base 0.10 - isl_aff_list_insert@Base 0.11 - isl_aff_list_n_aff@Base 0.10 - isl_aff_list_set_aff@Base 0.11 - isl_aff_list_sort@Base 0.12.1 - isl_aff_mod@Base 0.10 - isl_aff_mod_val@Base 0.12.1 - isl_aff_mul@Base 0.10 - isl_aff_neg@Base 0.10 - isl_aff_neg_basic_set@Base 0.11 - isl_aff_nonneg_basic_set@Base 0.10 - isl_aff_normalize@Base 0.10 - isl_aff_plain_is_equal@Base 0.10 - isl_aff_plain_is_zero@Base 0.10 - isl_aff_project_domain_on_params@Base 0.10 - isl_aff_pullback_multi_aff@Base 0.11 - isl_aff_read_from_str@Base 0.10 - isl_aff_realign_domain@Base 0.10 - isl_aff_remove_unused_divs@Base 0.10 - isl_aff_reset_domain_space@Base 0.10 - isl_aff_reset_space_and_domain@Base 0.10 - isl_aff_scale@Base 0.10 - isl_aff_scale_down@Base 0.10 - isl_aff_scale_down_ui@Base 0.10 - isl_aff_scale_down_val@Base 0.12.1 - isl_aff_scale_val@Base 0.12.1 - isl_aff_set_coefficient@Base 0.10 - isl_aff_set_coefficient_si@Base 0.10 - isl_aff_set_coefficient_val@Base 0.12.1 - isl_aff_set_constant@Base 0.10 - isl_aff_set_constant_si@Base 0.10 - isl_aff_set_constant_val@Base 0.12.1 - isl_aff_set_denominator@Base 0.10 - isl_aff_set_dim_id@Base 0.10 - isl_aff_set_dim_name@Base 0.10 - isl_aff_sub@Base 0.10 - isl_aff_substitute@Base 0.10 - isl_aff_to_str@Base 0.10 - isl_aff_var_on_domain@Base 0.11 - isl_aff_zero_basic_set@Base 0.10 - isl_aff_zero_on_domain@Base 0.10 - isl_args_free@Base 0.10 - isl_args_parse@Base 0.10 - isl_args_set_defaults@Base 0.10 - isl_ast_build_aff_is_nonneg@Base 0.11 - isl_ast_build_align_params@Base 0.11 - isl_ast_build_ast_from_schedule@Base 0.11 - isl_ast_build_call_from_executed@Base 0.11 - isl_ast_build_call_from_pw_multi_aff@Base 0.11 - isl_ast_build_clear_local_info@Base 0.11 - isl_ast_build_compute_gist@Base 0.11 - isl_ast_build_compute_gist_aff@Base 0.11 - isl_ast_build_compute_gist_basic_set@Base 0.11 - isl_ast_build_compute_gist_map_domain@Base 0.11 - isl_ast_build_compute_gist_pw_aff@Base 0.11 - isl_ast_build_compute_gist_pw_multi_aff@Base 0.11 - isl_ast_build_copy@Base 0.11 - isl_ast_build_cow@Base 0.11 - isl_ast_build_detect_strides@Base 0.11 - isl_ast_build_dump@Base 0.11 - isl_ast_build_dup@Base 0.11 - isl_ast_build_eliminate@Base 0.11 - isl_ast_build_eliminate_divs@Base 0.11 - isl_ast_build_eliminate_inner@Base 0.11 - isl_ast_build_expr_from_basic_set@Base 0.11 - isl_ast_build_expr_from_pw_aff@Base 0.11 - isl_ast_build_expr_from_pw_aff_internal@Base 0.11 - isl_ast_build_expr_from_set@Base 0.11 - isl_ast_build_free@Base 0.11 - isl_ast_build_from_context@Base 0.11 - isl_ast_build_get_ctx@Base 0.11 - isl_ast_build_get_depth@Base 0.11 - isl_ast_build_get_domain@Base 0.11 - isl_ast_build_get_iterator_id@Base 0.11 - isl_ast_build_get_offset@Base 0.11 - isl_ast_build_get_option_domain@Base 0.11 - isl_ast_build_get_schedule@Base 0.11 - isl_ast_build_get_schedule_map@Base 0.11 - isl_ast_build_get_schedule_map_multi_aff@Base 0.11 - isl_ast_build_get_schedule_space@Base 0.11 - isl_ast_build_get_separation_class@Base 0.11 - isl_ast_build_get_space@Base 0.11 - isl_ast_build_get_stride@Base 0.11 - isl_ast_build_get_stride_constraint@Base 0.11 - isl_ast_build_get_stride_expansion@Base 0.11 - isl_ast_build_has_affine_value@Base 0.11 - isl_ast_build_has_stride@Base 0.11 - isl_ast_build_has_value@Base 0.11 - isl_ast_build_include_stride@Base 0.11 - isl_ast_build_increase_depth@Base 0.11 - isl_ast_build_insert_dim@Base 0.11 - isl_ast_build_map_to_iterator@Base 0.11 - isl_ast_build_need_schedule_map@Base 0.11 - isl_ast_build_options_involve_depth@Base 0.11 - isl_ast_build_product@Base 0.11 - isl_ast_build_restrict@Base 0.11 - isl_ast_build_restrict_generated@Base 0.11 - isl_ast_build_restrict_pending@Base 0.11 - isl_ast_build_scale_down@Base 0.11 - isl_ast_build_set_after_each_for@Base 0.11 - isl_ast_build_set_at_each_domain@Base 0.11 - isl_ast_build_set_before_each_for@Base 0.11 - isl_ast_build_set_create_leaf@Base 0.11 - isl_ast_build_set_enforced@Base 0.11 - isl_ast_build_set_executed@Base 0.11 - isl_ast_build_set_iterators@Base 0.11 - isl_ast_build_set_loop_bounds@Base 0.11 - isl_ast_build_set_options@Base 0.11 - isl_ast_build_set_single_valued@Base 0.11.2 - isl_ast_build_substitute_values_union_map_domain@Base 0.12.1 - isl_ast_expr_add@Base 0.11 - isl_ast_expr_alloc_binary@Base 0.11 - isl_ast_expr_alloc_int_si@Base 0.12.1 - isl_ast_expr_alloc_op@Base 0.11 - isl_ast_expr_and@Base 0.11 - isl_ast_expr_copy@Base 0.11 - isl_ast_expr_cow@Base 0.11 - isl_ast_expr_div@Base 0.11 - isl_ast_expr_dump@Base 0.11 - isl_ast_expr_dup@Base 0.11 - isl_ast_expr_free@Base 0.11 - isl_ast_expr_from_aff@Base 0.11 - isl_ast_expr_from_id@Base 0.11 - isl_ast_expr_from_val@Base 0.12.1 - isl_ast_expr_get_ctx@Base 0.11 - isl_ast_expr_get_id@Base 0.11 - isl_ast_expr_get_int@Base 0.11 - isl_ast_expr_get_op_arg@Base 0.11 - isl_ast_expr_get_op_n_arg@Base 0.11 - isl_ast_expr_get_op_type@Base 0.11 - isl_ast_expr_get_type@Base 0.11 - isl_ast_expr_get_val@Base 0.12.1 - isl_ast_expr_list_add@Base 0.11 - isl_ast_expr_list_alloc@Base 0.11 - isl_ast_expr_list_concat@Base 0.11 - isl_ast_expr_list_copy@Base 0.11 - isl_ast_expr_list_cow@Base 0.11 - isl_ast_expr_list_drop@Base 0.11 - isl_ast_expr_list_dump@Base 0.11 - isl_ast_expr_list_dup@Base 0.11 - isl_ast_expr_list_foreach@Base 0.11 - isl_ast_expr_list_foreach_scc@Base 0.12.1 - isl_ast_expr_list_free@Base 0.11 - isl_ast_expr_list_from_ast_expr@Base 0.11 - isl_ast_expr_list_get_ast_expr@Base 0.11 - isl_ast_expr_list_get_ctx@Base 0.11 - isl_ast_expr_list_insert@Base 0.11 - isl_ast_expr_list_n_ast_expr@Base 0.11 - isl_ast_expr_list_set_ast_expr@Base 0.11 - isl_ast_expr_list_sort@Base 0.12.1 - isl_ast_expr_mul@Base 0.11 - isl_ast_expr_neg@Base 0.11 - isl_ast_expr_or@Base 0.11 - isl_ast_expr_set_op_arg@Base 0.11 - isl_ast_expr_sub@Base 0.11 - isl_ast_expr_to_str@Base 0.11 - isl_ast_graft_add_guard@Base 0.11 - isl_ast_graft_alloc@Base 0.11 - isl_ast_graft_alloc_domain@Base 0.11 - isl_ast_graft_alloc_level@Base 0.11 - isl_ast_graft_dump@Base 0.11 - isl_ast_graft_enforce@Base 0.11 - isl_ast_graft_free@Base 0.11 - isl_ast_graft_get_ctx@Base 0.11 - isl_ast_graft_get_enforced@Base 0.11 - isl_ast_graft_get_guard@Base 0.11 - isl_ast_graft_get_node@Base 0.11 - isl_ast_graft_insert_for@Base 0.11 - isl_ast_graft_list_add@Base 0.11 - isl_ast_graft_list_alloc@Base 0.11 - isl_ast_graft_list_concat@Base 0.11 - isl_ast_graft_list_copy@Base 0.11 - isl_ast_graft_list_cow@Base 0.11 - isl_ast_graft_list_drop@Base 0.11 - isl_ast_graft_list_dump@Base 0.11 - isl_ast_graft_list_dup@Base 0.11 - isl_ast_graft_list_foreach@Base 0.11 - isl_ast_graft_list_foreach_scc@Base 0.12.1 - isl_ast_graft_list_free@Base 0.11 - isl_ast_graft_list_from_ast_graft@Base 0.11 - isl_ast_graft_list_fuse@Base 0.11 - isl_ast_graft_list_get_ast_graft@Base 0.11 - isl_ast_graft_list_get_ctx@Base 0.11 - isl_ast_graft_list_insert@Base 0.11 - isl_ast_graft_list_merge@Base 0.11 - isl_ast_graft_list_n_ast_graft@Base 0.11 - isl_ast_graft_list_preimage_multi_aff@Base 0.11 - isl_ast_graft_list_set_ast_graft@Base 0.11 - isl_ast_graft_list_sort@Base 0.11 - isl_ast_graft_list_sort_guard@Base 0.12.1 - isl_ast_graft_list_unembed@Base 0.11 - isl_ast_graft_preimage_multi_aff@Base 0.11 - isl_ast_graft_set_enforced@Base 0.11 - isl_ast_graft_to_str@Base 0.11 - isl_ast_graft_unembed@Base 0.11 - isl_ast_node_alloc@Base 0.11 - isl_ast_node_alloc_block@Base 0.11 - isl_ast_node_alloc_for@Base 0.11 - isl_ast_node_alloc_if@Base 0.11 - isl_ast_node_alloc_user@Base 0.11 - isl_ast_node_block_get_children@Base 0.11 - isl_ast_node_copy@Base 0.11 - isl_ast_node_cow@Base 0.11 - isl_ast_node_dump@Base 0.11 - isl_ast_node_dup@Base 0.11 - isl_ast_node_for_get_body@Base 0.11 - isl_ast_node_for_get_cond@Base 0.11 - isl_ast_node_for_get_inc@Base 0.11 - isl_ast_node_for_get_init@Base 0.11 - isl_ast_node_for_get_iterator@Base 0.11 - isl_ast_node_for_is_degenerate@Base 0.11 - isl_ast_node_for_mark_degenerate@Base 0.11 - isl_ast_node_for_print@Base 0.11 - isl_ast_node_for_set_body@Base 0.11 - isl_ast_node_foreach_ast_op_type@Base 0.11 - isl_ast_node_free@Base 0.11 - isl_ast_node_from_ast_node_list@Base 0.11 - isl_ast_node_from_graft_list@Base 0.11 - isl_ast_node_get_annotation@Base 0.11 - isl_ast_node_get_ctx@Base 0.11 - isl_ast_node_get_type@Base 0.11 - isl_ast_node_if_get_cond@Base 0.11 - isl_ast_node_if_get_else@Base 0.11 - isl_ast_node_if_get_then@Base 0.11 - isl_ast_node_if_has_else@Base 0.11 - isl_ast_node_if_print@Base 0.11 - isl_ast_node_if_set_then@Base 0.11 - isl_ast_node_list_add@Base 0.11 - isl_ast_node_list_alloc@Base 0.11 - isl_ast_node_list_concat@Base 0.11 - isl_ast_node_list_copy@Base 0.11 - isl_ast_node_list_cow@Base 0.11 - isl_ast_node_list_drop@Base 0.11 - isl_ast_node_list_dump@Base 0.11 - isl_ast_node_list_dup@Base 0.11 - isl_ast_node_list_foreach@Base 0.11 - isl_ast_node_list_foreach_scc@Base 0.12.1 - isl_ast_node_list_free@Base 0.11 - isl_ast_node_list_from_ast_node@Base 0.11 - isl_ast_node_list_get_ast_node@Base 0.11 - isl_ast_node_list_get_ctx@Base 0.11 - isl_ast_node_list_insert@Base 0.11 - isl_ast_node_list_n_ast_node@Base 0.11 - isl_ast_node_list_print@Base 0.11 - isl_ast_node_list_set_ast_node@Base 0.11 - isl_ast_node_list_sort@Base 0.12.1 - isl_ast_node_print@Base 0.11 - isl_ast_node_print_macros@Base 0.11 - isl_ast_node_set_annotation@Base 0.11 - isl_ast_node_to_str@Base 0.11 - isl_ast_node_user_get_expr@Base 0.11 - isl_ast_op_type_print_macro@Base 0.11 - isl_ast_print_options_alloc@Base 0.11 - isl_ast_print_options_copy@Base 0.11 - isl_ast_print_options_cow@Base 0.11 - isl_ast_print_options_dup@Base 0.11 - isl_ast_print_options_free@Base 0.11 - isl_ast_print_options_get_ctx@Base 0.11 - isl_ast_print_options_set_print_for@Base 0.11 - isl_ast_print_options_set_print_user@Base 0.11 - isl_band_alloc@Base 0.10 - isl_band_copy@Base 0.10 - isl_band_dump@Base 0.10 - isl_band_dup@Base 0.10 - isl_band_free@Base 0.10 - isl_band_get_children@Base 0.10 - isl_band_get_ctx@Base 0.10 - isl_band_get_partial_schedule@Base 0.10 - isl_band_get_partial_schedule_union_pw_multi_aff@Base 0.10 - isl_band_get_prefix_schedule@Base 0.10 - isl_band_get_suffix_schedule@Base 0.10 - isl_band_get_suffix_schedule_union_pw_multi_aff@Base 0.10 - isl_band_has_children@Base 0.10 - isl_band_list_add@Base 0.10 - isl_band_list_alloc@Base 0.10 - isl_band_list_concat@Base 0.10 - isl_band_list_copy@Base 0.10 - isl_band_list_cow@Base 0.11 - isl_band_list_drop@Base 0.11 - isl_band_list_dump@Base 0.10 - isl_band_list_dup@Base 0.10 - isl_band_list_foreach@Base 0.10 - isl_band_list_foreach_band@Base 0.10 - isl_band_list_foreach_scc@Base 0.12.1 - isl_band_list_free@Base 0.10 - isl_band_list_from_band@Base 0.10 - isl_band_list_get_band@Base 0.10 - isl_band_list_get_ctx@Base 0.10 - isl_band_list_get_suffix_schedule@Base 0.10 - isl_band_list_get_suffix_schedule_union_pw_multi_aff@Base 0.10 - isl_band_list_insert@Base 0.11 - isl_band_list_n_band@Base 0.10 - isl_band_list_set_band@Base 0.11 - isl_band_list_sort@Base 0.12.1 - isl_band_member_is_zero_distance@Base 0.10 - isl_band_n_member@Base 0.10 - isl_band_split@Base 0.12.1 - isl_band_tile@Base 0.10 - isl_band_to_str@Base 0.10 - isl_basic_map_add@Base 0.10 - isl_basic_map_add_constraint@Base 0.10 - isl_basic_map_add_constraints_dim_map@Base 0.10 - isl_basic_map_add_div_constraint@Base 0.12.2 - isl_basic_map_add_div_constraints@Base 0.10 - isl_basic_map_add_div_constraints_var@Base 0.10 - isl_basic_map_add_eq@Base 0.10 - isl_basic_map_add_ineq@Base 0.10 - isl_basic_map_affine_hull@Base 0.10 - isl_basic_map_align_divs@Base 0.10 - isl_basic_map_align_params@Base 0.11 - isl_basic_map_alloc@Base 0.10 - isl_basic_map_alloc_div@Base 0.10 - isl_basic_map_alloc_equality@Base 0.10 - isl_basic_map_alloc_inequality@Base 0.10 - isl_basic_map_alloc_space@Base 0.10 - isl_basic_map_apply_domain@Base 0.10 - isl_basic_map_apply_range@Base 0.10 - isl_basic_map_can_curry@Base 0.10 - isl_basic_map_can_uncurry@Base 0.11 - isl_basic_map_can_zip@Base 0.10 - isl_basic_map_compatible_domain@Base 0.10 - isl_basic_map_compatible_range@Base 0.10 - isl_basic_map_compute_divs@Base 0.10 - isl_basic_map_constraint@Base 0.10 - isl_basic_map_constraint_is_redundant@Base 0.10 - isl_basic_map_contains@Base 0.10 - isl_basic_map_contains_point@Base 0.10 - isl_basic_map_copy@Base 0.10 - isl_basic_map_cow@Base 0.10 - isl_basic_map_curry@Base 0.10 - isl_basic_map_deltas@Base 0.10 - isl_basic_map_deltas_map@Base 0.10 - isl_basic_map_detect_equalities@Base 0.10 - isl_basic_map_dim@Base 0.10 - isl_basic_map_dim_has_lower_bound@Base 0.10 - isl_basic_map_dim_has_upper_bound@Base 0.10 - isl_basic_map_dim_is_bounded@Base 0.10 - isl_basic_map_divs_known@Base 0.10 - isl_basic_map_domain@Base 0.10 - isl_basic_map_domain_map@Base 0.10 - isl_basic_map_domain_product@Base 0.10 - isl_basic_map_drop@Base 0.10 - isl_basic_map_drop_constraints_involving_dims@Base 0.11 - isl_basic_map_drop_constraints_not_involving_dims@Base 0.11 - isl_basic_map_drop_equality@Base 0.10 - isl_basic_map_drop_inequality@Base 0.10 - isl_basic_map_drop_inputs@Base 0.10 - isl_basic_map_drop_redundant_divs@Base 0.10 - isl_basic_map_dump@Base 0.10 - isl_basic_map_dup@Base 0.10 - isl_basic_map_eliminate@Base 0.10 - isl_basic_map_eliminate_vars@Base 0.10 - isl_basic_map_empty@Base 0.10 - isl_basic_map_empty_like@Base 0.10 - isl_basic_map_empty_like_map@Base 0.10 - isl_basic_map_equal@Base 0.10 - isl_basic_map_equalities_matrix@Base 0.10 - isl_basic_map_equate@Base 0.10 - isl_basic_map_extend@Base 0.10 - isl_basic_map_extend_constraints@Base 0.10 - isl_basic_map_extend_space@Base 0.10 - isl_basic_map_fast_is_empty@Base 0.10 - isl_basic_map_finalize@Base 0.10 - isl_basic_map_fix@Base 0.10 - isl_basic_map_fix_input_si@Base 0.10 - isl_basic_map_fix_si@Base 0.10 - isl_basic_map_fix_val@Base 0.12.1 - isl_basic_map_flat_product@Base 0.10 - isl_basic_map_flat_range_product@Base 0.10 - isl_basic_map_flatten@Base 0.10 - isl_basic_map_flatten_domain@Base 0.10 - isl_basic_map_flatten_range@Base 0.10 - isl_basic_map_floordiv@Base 0.10 - isl_basic_map_foreach_constraint@Base 0.10 - isl_basic_map_foreach_lexopt@Base 0.10 - isl_basic_map_free@Base 0.10 - isl_basic_map_free_div@Base 0.10 - isl_basic_map_free_equality@Base 0.10 - isl_basic_map_free_inequality@Base 0.10 - isl_basic_map_from_aff@Base 0.10 - isl_basic_map_from_aff_list@Base 0.10 - isl_basic_map_from_basic_set@Base 0.10 - isl_basic_map_from_constraint@Base 0.10 - isl_basic_map_from_constraint_matrices@Base 0.10 - isl_basic_map_from_domain@Base 0.10 - isl_basic_map_from_domain_and_range@Base 0.10 - isl_basic_map_from_local_space@Base 0.10 - isl_basic_map_from_multi_aff@Base 0.10 - isl_basic_map_from_qpolynomial@Base 0.10 - isl_basic_map_from_range@Base 0.10 - isl_basic_map_gauss@Base 0.10 - isl_basic_map_get_ctx@Base 0.10 - isl_basic_map_get_dim@Base 0.10 - isl_basic_map_get_dim_name@Base 0.10 - isl_basic_map_get_div@Base 0.10 - isl_basic_map_get_divs@Base 0.10 - isl_basic_map_get_hash@Base 0.10 - isl_basic_map_get_local_space@Base 0.10 - isl_basic_map_get_space@Base 0.10 - isl_basic_map_get_tuple_name@Base 0.10 - isl_basic_map_gist@Base 0.10 - isl_basic_map_has_defining_equality@Base 0.10 - isl_basic_map_has_dim_id@Base 0.10 - isl_basic_map_has_rational@Base 0.11 - isl_basic_map_identity@Base 0.10 - isl_basic_map_identity_like@Base 0.10 - isl_basic_map_image_is_bounded@Base 0.10 - isl_basic_map_implicit_equalities@Base 0.10 - isl_basic_map_inequalities_matrix@Base 0.10 - isl_basic_map_inequality_to_equality@Base 0.10 - isl_basic_map_insert_dims@Base 0.11 - isl_basic_map_intersect@Base 0.10 - isl_basic_map_intersect_domain@Base 0.10 - isl_basic_map_intersect_range@Base 0.10 - isl_basic_map_involves_dims@Base 0.10 - isl_basic_map_is_div_constraint@Base 0.10 - isl_basic_map_is_empty@Base 0.10 - isl_basic_map_is_equal@Base 0.10 - isl_basic_map_is_rational@Base 0.10 - isl_basic_map_is_set@Base 0.10 - isl_basic_map_is_single_valued@Base 0.10 - isl_basic_map_is_strict_subset@Base 0.10 - isl_basic_map_is_subset@Base 0.10 - isl_basic_map_is_universe@Base 0.10 - isl_basic_map_less_at@Base 0.10 - isl_basic_map_less_or_equal_at@Base 0.10 - isl_basic_map_lexmax@Base 0.10 - isl_basic_map_lexmin@Base 0.10 - isl_basic_map_lexmin_pw_multi_aff@Base 0.10 - isl_basic_map_lexopt@Base 0.10 - isl_basic_map_lexopt_pw_multi_aff@Base 0.10 - isl_basic_map_lower_bound_si@Base 0.10 - isl_basic_map_may_be_set@Base 0.10 - isl_basic_map_more_at@Base 0.10 - isl_basic_map_more_or_equal_at@Base 0.10 - isl_basic_map_move_dims@Base 0.10 - isl_basic_map_n_div@Base 0.10 - isl_basic_map_n_in@Base 0.10 - isl_basic_map_n_out@Base 0.10 - isl_basic_map_n_param@Base 0.10 - isl_basic_map_nat_universe@Base 0.10 - isl_basic_map_neg@Base 0.10 - isl_basic_map_normalize@Base 0.10 - isl_basic_map_normalize_constraints@Base 0.10 - isl_basic_map_offset@Base 0.10 - isl_basic_map_order_divs@Base 0.10 - isl_basic_map_order_ge@Base 0.11 - isl_basic_map_order_gt@Base 0.12.1 - isl_basic_map_overlying_set@Base 0.10 - isl_basic_map_partial_lexmax@Base 0.10 - isl_basic_map_partial_lexmax_pw_multi_aff@Base 0.10 - isl_basic_map_partial_lexmin@Base 0.10 - isl_basic_map_partial_lexmin_pw_multi_aff@Base 0.10 - isl_basic_map_partial_lexopt_pw_multi_aff@Base 0.10 - isl_basic_map_plain_cmp@Base 0.10 - isl_basic_map_plain_get_val_if_fixed@Base 0.12.1 - isl_basic_map_plain_is_disjoint@Base 0.10 - isl_basic_map_plain_is_empty@Base 0.10 - isl_basic_map_plain_is_equal@Base 0.10 - isl_basic_map_plain_is_fixed@Base 0.10 - isl_basic_map_plain_is_single_valued@Base 0.10 - isl_basic_map_plain_is_singleton@Base 0.10 - isl_basic_map_preimage_multi_aff@Base 0.12.1 - isl_basic_map_print@Base 0.10 - isl_basic_map_print_internal@Base 0.10 - isl_basic_map_product@Base 0.10 - isl_basic_map_project_out@Base 0.10 - isl_basic_map_range@Base 0.10 - isl_basic_map_range_map@Base 0.10 - isl_basic_map_range_product@Base 0.10 - isl_basic_map_read_from_file@Base 0.10 - isl_basic_map_read_from_str@Base 0.10 - isl_basic_map_realign@Base 0.10 - isl_basic_map_remove_dims@Base 0.10 - isl_basic_map_remove_divs@Base 0.10 - isl_basic_map_remove_divs_involving_dims@Base 0.10 - isl_basic_map_remove_redundancies@Base 0.10 - isl_basic_map_remove_unknown_divs@Base 0.10 - isl_basic_map_reset@Base 0.10 - isl_basic_map_reset_space@Base 0.10 - isl_basic_map_reverse@Base 0.10 - isl_basic_map_sample@Base 0.10 - isl_basic_map_set_dim_name@Base 0.10 - isl_basic_map_set_rational@Base 0.10 - isl_basic_map_set_to_empty@Base 0.10 - isl_basic_map_set_tuple_name@Base 0.10 - isl_basic_map_simplify@Base 0.10 - isl_basic_map_solve_lp@Base 0.10 - isl_basic_map_sort_divs@Base 0.10 - isl_basic_map_sum@Base 0.10 - isl_basic_map_swap_div@Base 0.10 - isl_basic_map_to_str@Base 0.10 - isl_basic_map_total_dim@Base 0.10 - isl_basic_map_uncurry@Base 0.11 - isl_basic_map_underlying_set@Base 0.10 - isl_basic_map_union@Base 0.10 - isl_basic_map_universe@Base 0.10 - isl_basic_map_universe_like@Base 0.10 - isl_basic_map_update_from_tab@Base 0.10 - isl_basic_map_upper_bound_si@Base 0.11 - isl_basic_map_wrap@Base 0.10 - isl_basic_map_zip@Base 0.10 - isl_basic_set_add@Base 0.10 - isl_basic_set_add_constraint@Base 0.10 - isl_basic_set_add_constraints@Base 0.10 - isl_basic_set_add_constraints_dim_map@Base 0.10 - isl_basic_set_add_dims@Base 0.11 - isl_basic_set_add_div_constraints@Base 0.11 - isl_basic_set_add_div_constraints_var@Base 0.10 - isl_basic_set_add_eq@Base 0.10 - isl_basic_set_add_ineq@Base 0.10 - isl_basic_set_affine_hull@Base 0.10 - isl_basic_set_align_divs@Base 0.10 - isl_basic_set_align_params@Base 0.11 - isl_basic_set_alloc@Base 0.10 - isl_basic_set_alloc_div@Base 0.10 - isl_basic_set_alloc_equality@Base 0.10 - isl_basic_set_alloc_inequality@Base 0.10 - isl_basic_set_alloc_space@Base 0.10 - isl_basic_set_apply@Base 0.10 - isl_basic_set_box_from_points@Base 0.10 - isl_basic_set_coefficients@Base 0.10 - isl_basic_set_compare_at@Base 0.10 - isl_basic_set_compute_divs@Base 0.10 - isl_basic_set_compute_vertices@Base 0.10 - isl_basic_set_constraint@Base 0.10 - isl_basic_set_constraint_is_redundant@Base 0.10 - isl_basic_set_contains@Base 0.10 - isl_basic_set_copy@Base 0.10 - isl_basic_set_count_upto@Base 0.10 - isl_basic_set_cow@Base 0.10 - isl_basic_set_detect_equalities@Base 0.10 - isl_basic_set_dim@Base 0.10 - isl_basic_set_dim_is_unique@Base 0.10 - isl_basic_set_dim_residue_class@Base 0.10 - isl_basic_set_dims_get_sign@Base 0.10 - isl_basic_set_drop@Base 0.10 - isl_basic_set_drop_constraint@Base 0.10 - isl_basic_set_drop_constraints_involving@Base 0.10 - isl_basic_set_drop_constraints_involving_dims@Base 0.11 - isl_basic_set_drop_constraints_not_involving_dims@Base 0.11 - isl_basic_set_drop_dims@Base 0.10 - isl_basic_set_drop_equality@Base 0.10 - isl_basic_set_drop_inequality@Base 0.10 - isl_basic_set_drop_redundant_divs@Base 0.10 - isl_basic_set_dump@Base 0.10 - isl_basic_set_dup@Base 0.10 - isl_basic_set_eliminate@Base 0.11 - isl_basic_set_eliminate_vars@Base 0.10 - isl_basic_set_empty@Base 0.10 - isl_basic_set_empty_like@Base 0.10 - isl_basic_set_equalities_matrix@Base 0.10 - isl_basic_set_expand_divs@Base 0.10 - isl_basic_set_extend@Base 0.10 - isl_basic_set_extend_constraints@Base 0.10 - isl_basic_set_extend_space@Base 0.10 - isl_basic_set_factorizer@Base 0.10 - isl_basic_set_fast_is_empty@Base 0.10 - isl_basic_set_finalize@Base 0.10 - isl_basic_set_fix@Base 0.10 - isl_basic_set_fix_dim_si@Base 0.10 - isl_basic_set_fix_si@Base 0.10 - isl_basic_set_fix_val@Base 0.12.1 - isl_basic_set_flat_product@Base 0.10 - isl_basic_set_flatten@Base 0.10 - isl_basic_set_follows_at@Base 0.10 - isl_basic_set_foreach_bound_pair@Base 0.10 - isl_basic_set_foreach_constraint@Base 0.10 - isl_basic_set_foreach_lexopt@Base 0.10 - isl_basic_set_free@Base 0.10 - isl_basic_set_free_div@Base 0.10 - isl_basic_set_free_equality@Base 0.10 - isl_basic_set_free_inequality@Base 0.10 - isl_basic_set_from_basic_map@Base 0.10 - isl_basic_set_from_constraint@Base 0.10 - isl_basic_set_from_constraint_matrices@Base 0.10 - isl_basic_set_from_local_space@Base 0.10 - isl_basic_set_from_params@Base 0.11 - isl_basic_set_from_point@Base 0.10 - isl_basic_set_from_underlying_set@Base 0.10 - isl_basic_set_from_vec@Base 0.10 - isl_basic_set_full_compression@Base 0.10 - isl_basic_set_gauss@Base 0.10 - isl_basic_set_get_ctx@Base 0.10 - isl_basic_set_get_dim@Base 0.10 - isl_basic_set_get_dim_id@Base 0.10 - isl_basic_set_get_dim_name@Base 0.10 - isl_basic_set_get_div@Base 0.10 - isl_basic_set_get_divs@Base 0.12.1 - isl_basic_set_get_hash@Base 0.10 - isl_basic_set_get_local_space@Base 0.10 - isl_basic_set_get_space@Base 0.10 - isl_basic_set_get_tuple_name@Base 0.10 - isl_basic_set_gist@Base 0.10 - isl_basic_set_has_defining_equality@Base 0.10 - isl_basic_set_has_defining_inequalities@Base 0.10 - isl_basic_set_implicit_equalities@Base 0.10 - isl_basic_set_inequalities_matrix@Base 0.10 - isl_basic_set_insert_dims@Base 0.11 - isl_basic_set_intersect@Base 0.10 - isl_basic_set_intersect_params@Base 0.10 - isl_basic_set_interval@Base 0.10 - isl_basic_set_involves_dims@Base 0.10 - isl_basic_set_is_bounded@Base 0.10 - isl_basic_set_is_box@Base 0.10 - isl_basic_set_is_div_constraint@Base 0.10 - isl_basic_set_is_empty@Base 0.10 - isl_basic_set_is_equal@Base 0.10 - isl_basic_set_is_params@Base 0.10 - isl_basic_set_is_rational@Base 0.10 - isl_basic_set_is_subset@Base 0.10 - isl_basic_set_is_universe@Base 0.10 - isl_basic_set_is_wrapping@Base 0.10 - isl_basic_set_lexmax@Base 0.10 - isl_basic_set_lexmin@Base 0.10 - isl_basic_set_lift@Base 0.10 - isl_basic_set_lineality_space@Base 0.10 - isl_basic_set_list_add@Base 0.10 - isl_basic_set_list_alloc@Base 0.10 - isl_basic_set_list_concat@Base 0.10 - isl_basic_set_list_copy@Base 0.10 - isl_basic_set_list_cow@Base 0.11 - isl_basic_set_list_drop@Base 0.11 - isl_basic_set_list_dump@Base 0.10 - isl_basic_set_list_dup@Base 0.10 - isl_basic_set_list_foreach@Base 0.10 - isl_basic_set_list_foreach_scc@Base 0.12.1 - isl_basic_set_list_free@Base 0.10 - isl_basic_set_list_from_basic_set@Base 0.10 - isl_basic_set_list_get_basic_set@Base 0.10 - isl_basic_set_list_get_ctx@Base 0.10 - isl_basic_set_list_insert@Base 0.11 - isl_basic_set_list_n_basic_set@Base 0.10 - isl_basic_set_list_product@Base 0.10 - isl_basic_set_list_set_basic_set@Base 0.11 - isl_basic_set_list_sort@Base 0.12.1 - isl_basic_set_lower_bound_dim@Base 0.10 - isl_basic_set_max@Base 0.10 - isl_basic_set_max_lp_val@Base 0.12.1 - isl_basic_set_max_val@Base 0.12.1 - isl_basic_set_min_lp_val@Base 0.12.1 - isl_basic_set_move_dims@Base 0.10 - isl_basic_set_multiplicative_call@Base 0.10 - isl_basic_set_n_constraint@Base 0.10 - isl_basic_set_n_dim@Base 0.10 - isl_basic_set_n_param@Base 0.10 - isl_basic_set_nat_universe@Base 0.10 - isl_basic_set_neg@Base 0.10 - isl_basic_set_normalize@Base 0.10 - isl_basic_set_normalize_constraints@Base 0.10 - isl_basic_set_offset@Base 0.10 - isl_basic_set_opt@Base 0.10 - isl_basic_set_opt_val@Base 0.12.1 - isl_basic_set_order_divs@Base 0.10 - isl_basic_set_parameter_compression@Base 0.10 - isl_basic_set_params@Base 0.10 - isl_basic_set_partial_lexmax@Base 0.10 - isl_basic_set_partial_lexmax_pw_multi_aff@Base 0.10 - isl_basic_set_partial_lexmin@Base 0.10 - isl_basic_set_partial_lexmin_pw_multi_aff@Base 0.10 - isl_basic_set_plain_cmp@Base 0.10 - isl_basic_set_plain_dim_has_fixed_lower_bound@Base 0.10 - isl_basic_set_plain_dim_is_fixed@Base 0.10 - isl_basic_set_plain_is_disjoint@Base 0.10 - isl_basic_set_plain_is_empty@Base 0.10 - isl_basic_set_plain_is_equal@Base 0.10 - isl_basic_set_positive_orthant@Base 0.10 - isl_basic_set_preimage@Base 0.10 - isl_basic_set_preimage_multi_aff@Base 0.11 - isl_basic_set_print@Base 0.10 - isl_basic_set_print_internal@Base 0.10 - isl_basic_set_project_out@Base 0.10 - isl_basic_set_read_from_file@Base 0.10 - isl_basic_set_read_from_str@Base 0.10 - isl_basic_set_recession_cone@Base 0.10 - isl_basic_set_reduced_basis@Base 0.10 - isl_basic_set_remove_dims@Base 0.10 - isl_basic_set_remove_divs@Base 0.10 - isl_basic_set_remove_divs_involving_dims@Base 0.11 - isl_basic_set_remove_equalities@Base 0.10 - isl_basic_set_remove_redundancies@Base 0.10 - isl_basic_set_remove_unknown_divs@Base 0.11 - isl_basic_set_reset_space@Base 0.10 - isl_basic_set_sample@Base 0.10 - isl_basic_set_sample_bounded@Base 0.10 - isl_basic_set_sample_point@Base 0.10 - isl_basic_set_sample_vec@Base 0.10 - isl_basic_set_sample_with_cone@Base 0.10 - isl_basic_set_scan@Base 0.10 - isl_basic_set_set_dim_name@Base 0.10 - isl_basic_set_set_integral@Base 0.10 - isl_basic_set_set_rational@Base 0.10 - isl_basic_set_set_to_empty@Base 0.10 - isl_basic_set_set_tuple_name@Base 0.10 - isl_basic_set_simplify@Base 0.10 - isl_basic_set_size@Base 0.10 - isl_basic_set_solutions@Base 0.10 - isl_basic_set_solve_ilp@Base 0.10 - isl_basic_set_solve_lp@Base 0.10 - isl_basic_set_sort_constraints@Base 0.10 - isl_basic_set_substitute@Base 0.10 - isl_basic_set_to_str@Base 0.10 - isl_basic_set_total_dim@Base 0.10 - isl_basic_set_transform_dims@Base 0.10 - isl_basic_set_underlying_set@Base 0.10 - isl_basic_set_union@Base 0.10 - isl_basic_set_universe@Base 0.10 - isl_basic_set_universe_like@Base 0.10 - isl_basic_set_universe_like_set@Base 0.10 - isl_basic_set_unwrap@Base 0.10 - isl_basic_set_update_from_tab@Base 0.10 - isl_basic_set_variable_compression@Base 0.10 - isl_basic_set_vars_get_sign@Base 0.10 - isl_blk_alloc@Base 0.10 - isl_blk_clear_cache@Base 0.10 - isl_blk_empty@Base 0.10 - isl_blk_extend@Base 0.10 - isl_blk_free@Base 0.10 - isl_blk_is_error@Base 0.10 - isl_cell_foreach_simplex@Base 0.10 - isl_cell_foreach_vertex@Base 0.10 - isl_cell_free@Base 0.10 - isl_cell_get_ctx@Base 0.10 - isl_cell_get_domain@Base 0.10 - isl_closure_choice@Base 0.10 - isl_constraint_alloc@Base 0.10 - isl_constraint_alloc_vec@Base 0.10 - isl_constraint_copy@Base 0.10 - isl_constraint_cow@Base 0.10 - isl_constraint_dim@Base 0.10 - isl_constraint_dump@Base 0.10 - isl_constraint_dup@Base 0.10 - isl_constraint_free@Base 0.10 - isl_constraint_get_aff@Base 0.10 - isl_constraint_get_bound@Base 0.10 - isl_constraint_get_coefficient@Base 0.10 - isl_constraint_get_coefficient_val@Base 0.12.1 - isl_constraint_get_constant@Base 0.10 - isl_constraint_get_constant_val@Base 0.12.1 - isl_constraint_get_ctx@Base 0.10 - isl_constraint_get_dim@Base 0.10 - isl_constraint_get_dim_name@Base 0.10 - isl_constraint_get_div@Base 0.10 - isl_constraint_get_local_space@Base 0.10 - isl_constraint_get_space@Base 0.10 - isl_constraint_involves_dims@Base 0.10 - isl_constraint_is_div_constraint@Base 0.10 - isl_constraint_is_equal@Base 0.10 - isl_constraint_is_equality@Base 0.10 - isl_constraint_is_lower_bound@Base 0.10 - isl_constraint_is_upper_bound@Base 0.10 - isl_constraint_list_add@Base 0.11 - isl_constraint_list_alloc@Base 0.11 - isl_constraint_list_concat@Base 0.11 - isl_constraint_list_copy@Base 0.11 - isl_constraint_list_cow@Base 0.11 - isl_constraint_list_drop@Base 0.11 - isl_constraint_list_dump@Base 0.11 - isl_constraint_list_dup@Base 0.11 - isl_constraint_list_foreach@Base 0.11 - isl_constraint_list_foreach_scc@Base 0.12.1 - isl_constraint_list_free@Base 0.11 - isl_constraint_list_from_constraint@Base 0.11 - isl_constraint_list_get_constraint@Base 0.11 - isl_constraint_list_get_ctx@Base 0.11 - isl_constraint_list_insert@Base 0.11 - isl_constraint_list_n_constraint@Base 0.11 - isl_constraint_list_set_constraint@Base 0.11 - isl_constraint_list_sort@Base 0.12.1 - isl_constraint_negate@Base 0.10 - isl_constraint_set_coefficient@Base 0.10 - isl_constraint_set_coefficient_si@Base 0.10 - isl_constraint_set_coefficient_val@Base 0.12.1 - isl_constraint_set_constant@Base 0.10 - isl_constraint_set_constant_si@Base 0.10 - isl_constraint_set_constant_val@Base 0.12.1 - isl_constraint_to_str@Base 0.10 - isl_context_gbr_op@Base 0.10 - isl_context_lex_op@Base 0.10 - isl_ctx_abort@Base 0.10 - isl_ctx_aborted@Base 0.10 - isl_ctx_alloc@Base 0.10 - isl_ctx_alloc_with_options@Base 0.10 - isl_ctx_deref@Base 0.10 - isl_ctx_free@Base 0.10 - isl_ctx_last_error@Base 0.10 - isl_ctx_options@Base 0.10 - isl_ctx_parse_options@Base 0.10 - isl_ctx_peek_isl_options@Base 0.10 - isl_ctx_peek_options@Base 0.10 - isl_ctx_ref@Base 0.10 - isl_ctx_reset_error@Base 0.10 - isl_ctx_resume@Base 0.10 - isl_ctx_set_error@Base 0.10 - isl_dim_add@Base 0.10 - isl_dim_align_params@Base 0.10 - isl_dim_alloc@Base 0.10 - isl_dim_copy@Base 0.10 - isl_dim_domain@Base 0.10 - isl_dim_drop@Base 0.10 - isl_dim_find_dim_by_id@Base 0.10 - isl_dim_free@Base 0.10 - isl_dim_from_domain@Base 0.10 - isl_dim_from_range@Base 0.10 - isl_dim_get_ctx@Base 0.10 - isl_dim_get_dim_id@Base 0.10 - isl_dim_get_name@Base 0.10 - isl_dim_get_tuple_id@Base 0.10 - isl_dim_get_tuple_name@Base 0.10 - isl_dim_has_dim_id@Base 0.10 - isl_dim_has_tuple_id@Base 0.10 - isl_dim_insert@Base 0.10 - isl_dim_is_wrapping@Base 0.10 - isl_dim_join@Base 0.10 - isl_dim_map_alloc@Base 0.10 - isl_dim_map_dim@Base 0.10 - isl_dim_map_dim_range@Base 0.10 - isl_dim_map_div@Base 0.10 - isl_dim_map_dump@Base 0.10 - isl_dim_map_extend@Base 0.10 - isl_dim_map_from_reordering@Base 0.10 - isl_dim_map_from_set@Base 0.10 - isl_dim_map_range@Base 0.10 - isl_dim_move@Base 0.10 - isl_dim_range@Base 0.10 - isl_dim_reset_tuple_id@Base 0.10 - isl_dim_reverse@Base 0.10 - isl_dim_set_alloc@Base 0.10 - isl_dim_set_dim_id@Base 0.10 - isl_dim_set_name@Base 0.10 - isl_dim_set_tuple_id@Base 0.10 - isl_dim_set_tuple_name@Base 0.10 - isl_dim_size@Base 0.10 - isl_dim_unwrap@Base 0.10 - isl_dim_wrap@Base 0.10 - isl_dim_zip@Base 0.10 - isl_equality_alloc@Base 0.10 - isl_equality_from_aff@Base 0.10 - isl_factorizer_dump@Base 0.10 - isl_factorizer_free@Base 0.10 - isl_factorizer_groups@Base 0.10 - isl_factorizer_identity@Base 0.10 - isl_flow_foreach@Base 0.10 - isl_flow_free@Base 0.10 - isl_flow_get_ctx@Base 0.10 - isl_flow_get_no_source@Base 0.10 - isl_fold_type_negate@Base 0.10 - isl_gbr_choice@Base 0.10 - isl_gmp_gcdext@Base 0.12.1 - isl_gmp_hash@Base 0.10 - isl_handle_error@Base 0.10 - isl_hash_id@Base 0.10 - isl_hash_mem@Base 0.10 - isl_hash_string@Base 0.10 - isl_hash_table_alloc@Base 0.10 - isl_hash_table_clear@Base 0.10 - isl_hash_table_find@Base 0.10 - isl_hash_table_foreach@Base 0.10 - isl_hash_table_free@Base 0.10 - isl_hash_table_init@Base 0.10 - isl_hash_table_remove@Base 0.10 - isl_hmap_map_basic_set_alloc@Base 0.10 - isl_hmap_map_basic_set_free@Base 0.10 - isl_hmap_map_basic_set_get@Base 0.10 - isl_hmap_map_basic_set_has@Base 0.10 - isl_hmap_map_basic_set_set@Base 0.10 - isl_id_alloc@Base 0.10 - isl_id_copy@Base 0.10 - isl_id_dump@Base 0.10 - isl_id_free@Base 0.10 - isl_id_get_ctx@Base 0.10 - isl_id_get_name@Base 0.10 - isl_id_get_user@Base 0.10 - isl_id_list_add@Base 0.11 - isl_id_list_alloc@Base 0.11 - isl_id_list_concat@Base 0.11 - isl_id_list_copy@Base 0.11 - isl_id_list_cow@Base 0.11 - isl_id_list_drop@Base 0.11 - isl_id_list_dump@Base 0.11 - isl_id_list_dup@Base 0.11 - isl_id_list_foreach@Base 0.11 - isl_id_list_foreach_scc@Base 0.12.1 - isl_id_list_free@Base 0.11 - isl_id_list_from_id@Base 0.11 - isl_id_list_get_ctx@Base 0.11 - isl_id_list_get_id@Base 0.11 - isl_id_list_insert@Base 0.11 - isl_id_list_n_id@Base 0.11 - isl_id_list_set_id@Base 0.11 - isl_id_list_sort@Base 0.12.1 - isl_id_none@Base 0.10 - isl_id_set_free_user@Base 0.11 - isl_id_to_str@Base 0.10 - isl_ilp_solver_choice@Base 0.10 - isl_inequality_alloc@Base 0.10 - isl_inequality_from_aff@Base 0.10 - isl_inequality_negate@Base 0.10 - isl_int_obj_add@Base 0.10 - isl_int_obj_alloc@Base 0.10 - isl_int_obj_copy@Base 0.10 - isl_int_obj_cow@Base 0.10 - isl_int_obj_dup@Base 0.10 - isl_int_obj_free@Base 0.10 - isl_int_obj_get_int@Base 0.10 - isl_int_obj_mul@Base 0.10 - isl_int_obj_sub@Base 0.10 - isl_local_space_add_dims@Base 0.10 - isl_local_space_add_div@Base 0.10 - isl_local_space_alloc@Base 0.10 - isl_local_space_alloc_div@Base 0.10 - isl_local_space_copy@Base 0.10 - isl_local_space_cow@Base 0.10 - isl_local_space_dim@Base 0.10 - isl_local_space_divs_known@Base 0.10 - isl_local_space_domain@Base 0.10 - isl_local_space_drop_dims@Base 0.10 - isl_local_space_dump@Base 0.10 - isl_local_space_dup@Base 0.10 - isl_local_space_free@Base 0.10 - isl_local_space_from_dim@Base 0.10 - isl_local_space_from_domain@Base 0.10 - isl_local_space_from_space@Base 0.10 - isl_local_space_get_active@Base 0.10 - isl_local_space_get_ctx@Base 0.10 - isl_local_space_get_dim@Base 0.10 - isl_local_space_get_dim_id@Base 0.11 - isl_local_space_get_dim_name@Base 0.10 - isl_local_space_get_div@Base 0.10 - isl_local_space_get_space@Base 0.10 - isl_local_space_has_dim_id@Base 0.11 - isl_local_space_has_dim_name@Base 0.10 - isl_local_space_insert_dims@Base 0.10 - isl_local_space_intersect@Base 0.10 - isl_local_space_is_div_constraint@Base 0.10 - isl_local_space_is_equal@Base 0.10 - isl_local_space_is_named_or_nested@Base 0.10 - isl_local_space_is_set@Base 0.10 - isl_local_space_lift@Base 0.10 - isl_local_space_lifting@Base 0.10 - isl_local_space_offset@Base 0.10 - isl_local_space_preimage_multi_aff@Base 0.11 - isl_local_space_range@Base 0.10 - isl_local_space_realign@Base 0.10 - isl_local_space_replace_divs@Base 0.10 - isl_local_space_reset_space@Base 0.10 - isl_local_space_set_dim_id@Base 0.10 - isl_local_space_set_dim_name@Base 0.10 - isl_local_space_substitute@Base 0.10 - isl_local_space_substitute_equalities@Base 0.10 - isl_local_space_substitute_seq@Base 0.11 - isl_local_space_swap_div@Base 0.11 - isl_local_space_to_str@Base 0.10 - isl_lp_solver_choice@Base 0.10 - isl_map_add_basic_map@Base 0.10 - isl_map_add_constraint@Base 0.10 - isl_map_add_dims@Base 0.10 - isl_map_affine_hull@Base 0.10 - isl_map_align_divs@Base 0.10 - isl_map_align_params@Base 0.10 - isl_map_align_params_map_map_and@Base 0.10 - isl_map_align_params_map_map_and_test@Base 0.10 - isl_map_alloc@Base 0.10 - isl_map_alloc_space@Base 0.10 - isl_map_apply_domain@Base 0.10 - isl_map_apply_pw_qpolynomial_fold@Base 0.10 - isl_map_apply_range@Base 0.10 - isl_map_can_curry@Base 0.10 - isl_map_can_uncurry@Base 0.11 - isl_map_can_zip@Base 0.10 - isl_map_coalesce@Base 0.10 - isl_map_compatible_domain@Base 0.10 - isl_map_compatible_range@Base 0.10 - isl_map_complement@Base 0.10 - isl_map_compute_divs@Base 0.10 - isl_map_contains_point@Base 0.10 - isl_map_convex_hull@Base 0.10 - isl_map_copy@Base 0.10 - isl_map_copy_basic_map@Base 0.10 - isl_map_cow@Base 0.10 - isl_map_curry@Base 0.10 - isl_map_deltas@Base 0.10 - isl_map_deltas_map@Base 0.10 - isl_map_detect_equalities@Base 0.10 - isl_map_dim@Base 0.10 - isl_map_dim_is_bounded@Base 0.10 - isl_map_dim_max@Base 0.10 - isl_map_domain@Base 0.10 - isl_map_domain_map@Base 0.10 - isl_map_domain_product@Base 0.10 - isl_map_drop@Base 0.10 - isl_map_drop_basic_map@Base 0.10 - isl_map_drop_constraints_involving_dims@Base 0.11 - isl_map_drop_inputs@Base 0.10 - isl_map_drop_redundant_divs@Base 0.10 - isl_map_dump@Base 0.10 - isl_map_dup@Base 0.10 - isl_map_eliminate@Base 0.10 - isl_map_empty@Base 0.10 - isl_map_empty_like@Base 0.10 - isl_map_empty_like_basic_map@Base 0.10 - isl_map_equate@Base 0.10 - isl_map_extend@Base 0.10 - isl_map_fast_is_empty@Base 0.10 - isl_map_fast_is_equal@Base 0.10 - isl_map_fast_is_fixed@Base 0.10 - isl_map_finalize@Base 0.10 - isl_map_find_dim_by_id@Base 0.10 - isl_map_find_dim_by_name@Base 0.10 - isl_map_fix@Base 0.10 - isl_map_fix_input_si@Base 0.10 - isl_map_fix_si@Base 0.10 - isl_map_fix_val@Base 0.12.1 - isl_map_fixed_power@Base 0.10 - isl_map_fixed_power_val@Base 0.12.1 - isl_map_flat_domain_product@Base 0.10 - isl_map_flat_product@Base 0.10 - isl_map_flat_range_product@Base 0.10 - isl_map_flatten@Base 0.10 - isl_map_flatten_domain@Base 0.10 - isl_map_flatten_range@Base 0.10 - isl_map_floordiv@Base 0.10 - isl_map_floordiv_val@Base 0.12.1 - isl_map_foreach_basic_map@Base 0.10 - isl_map_free@Base 0.10 - isl_map_from_aff@Base 0.10 - isl_map_from_basic_map@Base 0.10 - isl_map_from_domain@Base 0.10 - isl_map_from_domain_and_range@Base 0.10 - isl_map_from_multi_aff@Base 0.10 - isl_map_from_pw_aff@Base 0.10 - isl_map_from_pw_multi_aff@Base 0.10 - isl_map_from_range@Base 0.10 - isl_map_from_set@Base 0.10 - isl_map_from_union_map@Base 0.10 - isl_map_get_ctx@Base 0.10 - isl_map_get_dim@Base 0.10 - isl_map_get_dim_id@Base 0.10 - isl_map_get_dim_name@Base 0.10 - isl_map_get_hash@Base 0.10 - isl_map_get_space@Base 0.10 - isl_map_get_tuple_id@Base 0.10 - isl_map_get_tuple_name@Base 0.10 - isl_map_gist@Base 0.10 - isl_map_gist_basic_map@Base 0.10 - isl_map_gist_domain@Base 0.10 - isl_map_gist_params@Base 0.10 - isl_map_gist_range@Base 0.10 - isl_map_grow@Base 0.10 - isl_map_has_dim_id@Base 0.10 - isl_map_has_dim_name@Base 0.11 - isl_map_has_equal_space@Base 0.10 - isl_map_has_rational@Base 0.11 - isl_map_has_tuple_id@Base 0.10 - isl_map_has_tuple_name@Base 0.11 - isl_map_identity@Base 0.10 - isl_map_identity_like@Base 0.10 - isl_map_identity_like_basic_map@Base 0.10 - isl_map_implicit_equalities@Base 0.10 - isl_map_inline_foreach_basic_map@Base 0.10 - isl_map_insert_dims@Base 0.10 - isl_map_intersect@Base 0.10 - isl_map_intersect_domain@Base 0.10 - isl_map_intersect_params@Base 0.10 - isl_map_intersect_range@Base 0.10 - isl_map_involves_dims@Base 0.10 - isl_map_is_bijective@Base 0.10 - isl_map_is_disjoint@Base 0.11 - isl_map_is_empty@Base 0.10 - isl_map_is_equal@Base 0.10 - isl_map_is_injective@Base 0.10 - isl_map_is_params@Base 0.10 - isl_map_is_set@Base 0.10 - isl_map_is_single_valued@Base 0.10 - isl_map_is_strict_subset@Base 0.10 - isl_map_is_subset@Base 0.10 - isl_map_is_transitively_closed@Base 0.10 - isl_map_is_translation@Base 0.10 - isl_map_lex_ge@Base 0.10 - isl_map_lex_ge_first@Base 0.10 - isl_map_lex_ge_map@Base 0.10 - isl_map_lex_gt@Base 0.10 - isl_map_lex_gt_first@Base 0.10 - isl_map_lex_gt_map@Base 0.10 - isl_map_lex_le@Base 0.10 - isl_map_lex_le_first@Base 0.10 - isl_map_lex_le_map@Base 0.10 - isl_map_lex_lt@Base 0.10 - isl_map_lex_lt_first@Base 0.10 - isl_map_lex_lt_map@Base 0.10 - isl_map_lexmax@Base 0.10 - isl_map_lexmax_pw_multi_aff@Base 0.11 - isl_map_lexmin@Base 0.10 - isl_map_lexmin_pw_multi_aff@Base 0.11 - isl_map_lexopt@Base 0.10 - isl_map_lexopt_pw_multi_aff@Base 0.11 - isl_map_lower_bound@Base 0.10 - isl_map_lower_bound_si@Base 0.10 - isl_map_make_disjoint@Base 0.10 - isl_map_may_be_set@Base 0.10 - isl_map_move_dims@Base 0.10 - isl_map_n_in@Base 0.10 - isl_map_n_out@Base 0.10 - isl_map_n_param@Base 0.10 - isl_map_nat_universe@Base 0.10 - isl_map_neg@Base 0.10 - isl_map_normalize@Base 0.10 - isl_map_oppose@Base 0.10 - isl_map_order_divs@Base 0.10 - isl_map_order_gt@Base 0.10 - isl_map_order_lt@Base 0.10 - isl_map_params@Base 0.10 - isl_map_partial_lexmax@Base 0.10 - isl_map_partial_lexmin@Base 0.10 - isl_map_plain_get_val_if_fixed@Base 0.12.1 - isl_map_plain_input_is_fixed@Base 0.10 - isl_map_plain_is_disjoint@Base 0.10 - isl_map_plain_is_empty@Base 0.10 - isl_map_plain_is_equal@Base 0.10 - isl_map_plain_is_fixed@Base 0.10 - isl_map_plain_is_injective@Base 0.10 - isl_map_plain_is_single_valued@Base 0.10 - isl_map_plain_is_singleton@Base 0.10 - isl_map_plain_is_universe@Base 0.10 - isl_map_polyhedral_hull@Base 0.10 - isl_map_power@Base 0.10 - isl_map_preimage_domain_multi_aff@Base 0.12.1 - isl_map_preimage_multi_aff@Base 0.12.1 - isl_map_print@Base 0.10 - isl_map_print_internal@Base 0.10 - isl_map_product@Base 0.10 - isl_map_project_out@Base 0.10 - isl_map_range@Base 0.10 - isl_map_range_map@Base 0.10 - isl_map_range_product@Base 0.10 - isl_map_reaching_path_lengths@Base 0.10 - isl_map_read_from_file@Base 0.10 - isl_map_read_from_str@Base 0.10 - isl_map_realign@Base 0.10 - isl_map_remove_dims@Base 0.10 - isl_map_remove_divs@Base 0.10 - isl_map_remove_divs_involving_dims@Base 0.10 - isl_map_remove_empty_parts@Base 0.10 - isl_map_remove_inputs@Base 0.10 - isl_map_remove_redundancies@Base 0.10 - isl_map_remove_unknown_divs@Base 0.10 - isl_map_reset@Base 0.10 - isl_map_reset_space@Base 0.10 - isl_map_reset_tuple_id@Base 0.10 - isl_map_reverse@Base 0.10 - isl_map_sample@Base 0.10 - isl_map_set_dim_id@Base 0.10 - isl_map_set_dim_name@Base 0.10 - isl_map_set_rational@Base 0.10 - isl_map_set_tuple_id@Base 0.10 - isl_map_set_tuple_name@Base 0.10 - isl_map_simple_hull@Base 0.10 - isl_map_solve_lp@Base 0.10 - isl_map_sort_divs@Base 0.10 - isl_map_subtract@Base 0.10 - isl_map_subtract_domain@Base 0.10 - isl_map_subtract_range@Base 0.10 - isl_map_sum@Base 0.10 - isl_map_to_str@Base 0.10 - isl_map_transitive_closure@Base 0.10 - isl_map_uncurry@Base 0.11 - isl_map_underlying_set@Base 0.10 - isl_map_union@Base 0.10 - isl_map_union_disjoint@Base 0.10 - isl_map_universe@Base 0.10 - isl_map_unshifted_simple_hull@Base 0.11 - isl_map_upper_bound@Base 0.10 - isl_map_upper_bound_si@Base 0.10 - isl_map_wrap@Base 0.10 - isl_map_zip@Base 0.10 - isl_mat_add_rows@Base 0.10 - isl_mat_add_zero_cols@Base 0.10 - isl_mat_add_zero_rows@Base 0.10 - isl_mat_aff_direct_sum@Base 0.10 - isl_mat_alloc@Base 0.10 - isl_mat_cmp_div@Base 0.11 - isl_mat_col_add@Base 0.10 - isl_mat_col_combine@Base 0.10 - isl_mat_col_mul@Base 0.10 - isl_mat_col_scale@Base 0.10 - isl_mat_col_submul@Base 0.10 - isl_mat_cols@Base 0.10 - isl_mat_concat@Base 0.10 - isl_mat_copy@Base 0.10 - isl_mat_cow@Base 0.10 - isl_mat_diag@Base 0.10 - isl_mat_diagonal@Base 0.10 - isl_mat_drop_cols@Base 0.10 - isl_mat_drop_rows@Base 0.10 - isl_mat_dump@Base 0.10 - isl_mat_dup@Base 0.10 - isl_mat_extend@Base 0.10 - isl_mat_free@Base 0.10 - isl_mat_from_row_vec@Base 0.10 - isl_mat_gcd@Base 0.10 - isl_mat_get_ctx@Base 0.10 - isl_mat_get_element@Base 0.10 - isl_mat_get_element_val@Base 0.12.1 - isl_mat_identity@Base 0.10 - isl_mat_initial_non_zero_cols@Base 0.10 - isl_mat_insert_cols@Base 0.10 - isl_mat_insert_rows@Base 0.10 - isl_mat_insert_zero_cols@Base 0.10 - isl_mat_insert_zero_rows@Base 0.10 - isl_mat_inverse_product@Base 0.10 - isl_mat_is_equal@Base 0.10 - isl_mat_left_hermite@Base 0.10 - isl_mat_lin_to_aff@Base 0.10 - isl_mat_move_cols@Base 0.10 - isl_mat_normalize@Base 0.10 - isl_mat_normalize_row@Base 0.10 - isl_mat_parameter_compression@Base 0.10 - isl_mat_parameter_compression_ext@Base 0.12.1 - isl_mat_print_internal@Base 0.10 - isl_mat_product@Base 0.10 - isl_mat_right_inverse@Base 0.10 - isl_mat_right_kernel@Base 0.10 - isl_mat_rows@Base 0.10 - isl_mat_scale_down@Base 0.10 - isl_mat_scale_down_row@Base 0.10 - isl_mat_set_element@Base 0.10 - isl_mat_set_element_si@Base 0.10 - isl_mat_set_element_val@Base 0.12.1 - isl_mat_sub_alloc6@Base 0.10 - isl_mat_sub_alloc@Base 0.10 - isl_mat_sub_copy@Base 0.10 - isl_mat_sub_neg@Base 0.10 - isl_mat_swap_cols@Base 0.10 - isl_mat_swap_rows@Base 0.10 - isl_mat_transpose@Base 0.10 - isl_mat_unimodular_complete@Base 0.10 - isl_mat_variable_compression@Base 0.10 - isl_mat_vec_concat@Base 0.10 - isl_mat_vec_inverse_product@Base 0.10 - isl_mat_vec_product@Base 0.10 - isl_memrchr@Base 0.10 - isl_merge_divs@Base 0.10 - isl_morph_alloc@Base 0.10 - isl_morph_basic_set@Base 0.10 - isl_morph_compose@Base 0.10 - isl_morph_copy@Base 0.10 - isl_morph_cow@Base 0.10 - isl_morph_dom_dim@Base 0.10 - isl_morph_dom_params@Base 0.10 - isl_morph_dump@Base 0.10 - isl_morph_dup@Base 0.10 - isl_morph_empty@Base 0.10 - isl_morph_free@Base 0.10 - isl_morph_get_ran_space@Base 0.10 - isl_morph_identity@Base 0.10 - isl_morph_inverse@Base 0.10 - isl_morph_print_internal@Base 0.10 - isl_morph_ran_dim@Base 0.10 - isl_morph_ran_params@Base 0.10 - isl_morph_remove_dom_dims@Base 0.10 - isl_morph_remove_ran_dims@Base 0.10 - isl_morph_set@Base 0.10 - isl_morph_vec@Base 0.10 - isl_morph_vertices@Base 0.10 - isl_multi_aff_add@Base 0.10 - isl_multi_aff_add_dims@Base 0.11 - isl_multi_aff_add_on_domain@Base 0.10 - isl_multi_aff_align_divs@Base 0.10 - isl_multi_aff_align_params@Base 0.10 - isl_multi_aff_alloc@Base 0.10 - isl_multi_aff_copy@Base 0.10 - isl_multi_aff_cow@Base 0.10 - isl_multi_aff_dim@Base 0.10 - isl_multi_aff_drop_dims@Base 0.10 - isl_multi_aff_dump@Base 0.10 - isl_multi_aff_dup@Base 0.10 - isl_multi_aff_flat_range_product@Base 0.10 - isl_multi_aff_flatten_range@Base 0.11 - isl_multi_aff_free@Base 0.10 - isl_multi_aff_from_aff@Base 0.11 - isl_multi_aff_from_aff_list@Base 0.10 - isl_multi_aff_get_aff@Base 0.10 - isl_multi_aff_get_ctx@Base 0.10 - isl_multi_aff_get_domain_space@Base 0.10 - isl_multi_aff_get_space@Base 0.10 - isl_multi_aff_get_tuple_name@Base 0.10 - isl_multi_aff_gist@Base 0.10 - isl_multi_aff_gist_aligned@Base 0.10 - isl_multi_aff_gist_params@Base 0.10 - isl_multi_aff_identity@Base 0.11 - isl_multi_aff_insert_dims@Base 0.11 - isl_multi_aff_is_empty@Base 0.10 - isl_multi_aff_lex_ge_set@Base 0.11 - isl_multi_aff_lex_le_set@Base 0.11 - isl_multi_aff_lift@Base 0.10 - isl_multi_aff_plain_is_equal@Base 0.10 - isl_multi_aff_product@Base 0.11 - isl_multi_aff_pullback_multi_aff@Base 0.11 - isl_multi_aff_range_product@Base 0.11 - isl_multi_aff_range_splice@Base 0.11 - isl_multi_aff_read_from_str@Base 0.10 - isl_multi_aff_realign_domain@Base 0.10 - isl_multi_aff_reset_domain_space@Base 0.10 - isl_multi_aff_reset_space@Base 0.10 - isl_multi_aff_reset_space_and_domain@Base 0.10 - isl_multi_aff_scale@Base 0.10 - isl_multi_aff_scale_multi_val@Base 0.12.1 - isl_multi_aff_scale_val@Base 0.12.1 - isl_multi_aff_set_aff@Base 0.10 - isl_multi_aff_set_dim_name@Base 0.10 - isl_multi_aff_set_tuple_id@Base 0.10 - isl_multi_aff_set_tuple_name@Base 0.11 - isl_multi_aff_splice@Base 0.11 - isl_multi_aff_sub@Base 0.12.1 - isl_multi_aff_substitute@Base 0.10 - isl_multi_aff_to_str@Base 0.10 - isl_multi_aff_zero@Base 0.10 - isl_multi_pw_aff_add_dims@Base 0.11 - isl_multi_pw_aff_align_params@Base 0.11 - isl_multi_pw_aff_alloc@Base 0.11 - isl_multi_pw_aff_copy@Base 0.11 - isl_multi_pw_aff_cow@Base 0.11 - isl_multi_pw_aff_dim@Base 0.11 - isl_multi_pw_aff_drop_dims@Base 0.11 - isl_multi_pw_aff_dump@Base 0.11 - isl_multi_pw_aff_dup@Base 0.11 - isl_multi_pw_aff_flat_range_product@Base 0.11 - isl_multi_pw_aff_flatten_range@Base 0.11 - isl_multi_pw_aff_free@Base 0.11 - isl_multi_pw_aff_from_pw_aff@Base 0.11 - isl_multi_pw_aff_from_pw_aff_list@Base 0.11 - isl_multi_pw_aff_get_ctx@Base 0.11 - isl_multi_pw_aff_get_domain_space@Base 0.11 - isl_multi_pw_aff_get_pw_aff@Base 0.11 - isl_multi_pw_aff_get_space@Base 0.11 - isl_multi_pw_aff_get_tuple_name@Base 0.11 - isl_multi_pw_aff_gist@Base 0.11 - isl_multi_pw_aff_gist_aligned@Base 0.11 - isl_multi_pw_aff_gist_params@Base 0.11 - isl_multi_pw_aff_identity@Base 0.11 - isl_multi_pw_aff_insert_dims@Base 0.11 - isl_multi_pw_aff_range_product@Base 0.11 - isl_multi_pw_aff_range_splice@Base 0.11 - isl_multi_pw_aff_realign_domain@Base 0.11 - isl_multi_pw_aff_reset_domain_space@Base 0.11 - isl_multi_pw_aff_reset_space@Base 0.11 - isl_multi_pw_aff_reset_space_and_domain@Base 0.11 - isl_multi_pw_aff_scale_multi_val@Base 0.12.1 - isl_multi_pw_aff_scale_val@Base 0.12.1 - isl_multi_pw_aff_set_dim_name@Base 0.11 - isl_multi_pw_aff_set_pw_aff@Base 0.11 - isl_multi_pw_aff_set_tuple_id@Base 0.11 - isl_multi_pw_aff_set_tuple_name@Base 0.11 - isl_multi_pw_aff_splice@Base 0.11 - isl_multi_pw_aff_to_str@Base 0.11 - isl_multi_pw_aff_zero@Base 0.11 - isl_multi_val_add_dims@Base 0.12.1 - isl_multi_val_add_val@Base 0.12.1 - isl_multi_val_align_params@Base 0.12.1 - isl_multi_val_alloc@Base 0.12.1 - isl_multi_val_copy@Base 0.12.1 - isl_multi_val_cow@Base 0.12.1 - isl_multi_val_dim@Base 0.12.1 - isl_multi_val_drop_dims@Base 0.12.1 - isl_multi_val_dup@Base 0.12.1 - isl_multi_val_flat_range_product@Base 0.12.1 - isl_multi_val_flatten_range@Base 0.12.1 - isl_multi_val_free@Base 0.12.1 - isl_multi_val_from_val_list@Base 0.12.1 - isl_multi_val_get_ctx@Base 0.12.1 - isl_multi_val_get_domain_space@Base 0.12.1 - isl_multi_val_get_space@Base 0.12.1 - isl_multi_val_get_tuple_name@Base 0.12.1 - isl_multi_val_get_val@Base 0.12.1 - isl_multi_val_insert_dims@Base 0.12.1 - isl_multi_val_mod_val@Base 0.12.1 - isl_multi_val_range_product@Base 0.12.1 - isl_multi_val_range_splice@Base 0.12.1 - isl_multi_val_realign_domain@Base 0.12.1 - isl_multi_val_reset_domain_space@Base 0.12.1 - isl_multi_val_reset_space@Base 0.12.1 - isl_multi_val_reset_space_and_domain@Base 0.12.1 - isl_multi_val_scale_multi_val@Base 0.12.1 - isl_multi_val_scale_val@Base 0.12.1 - isl_multi_val_set_dim_name@Base 0.12.1 - isl_multi_val_set_tuple_id@Base 0.12.1 - isl_multi_val_set_tuple_name@Base 0.12.1 - isl_multi_val_set_val@Base 0.12.1 - isl_multi_val_splice@Base 0.12.1 - isl_multi_val_zero@Base 0.12.1 - isl_obj_int_vtable@Base 0.10 - isl_obj_map_vtable@Base 0.10 - isl_obj_none_vtable@Base 0.10 - isl_obj_pw_qpolynomial_fold_vtable@Base 0.10 - isl_obj_pw_qpolynomial_vtable@Base 0.10 - isl_obj_set_vtable@Base 0.10 - isl_obj_union_map_vtable@Base 0.10 - isl_obj_union_pw_qpolynomial_fold_vtable@Base 0.10 - isl_obj_union_pw_qpolynomial_vtable@Base 0.10 - isl_obj_union_set_vtable@Base 0.10 - isl_obj_val_vtable@Base 0.12.1 - isl_options_args@Base 0.10 - isl_options_argsLIST@Base 0.10 - isl_options_free@Base 0.10 - isl_options_get_ast_build_allow_else@Base 0.11 - isl_options_get_ast_build_allow_or@Base 0.12.1 - isl_options_get_ast_build_atomic_upper_bound@Base 0.11 - isl_options_get_ast_build_exploit_nested_bounds@Base 0.11 - isl_options_get_ast_build_group_coscheduled@Base 0.11 - isl_options_get_ast_build_prefer_pdiv@Base 0.11 - isl_options_get_ast_build_scale_strides@Base 0.11 - isl_options_get_ast_build_separation_bounds@Base 0.11 - isl_options_get_ast_iterator_type@Base 0.11 - isl_options_get_bound@Base 0.10 - isl_options_get_coalesce_bounded_wrapping@Base 0.10 - isl_options_get_gbr_only_first@Base 0.10 - isl_options_get_on_error@Base 0.10 - isl_options_get_schedule_algorithm@Base 0.10 - isl_options_get_schedule_fuse@Base 0.10 - isl_options_get_schedule_max_coefficient@Base 0.10 - isl_options_get_schedule_max_constant_term@Base 0.10 - isl_options_get_schedule_maximize_band_depth@Base 0.10 - isl_options_get_schedule_outer_zero_distance@Base 0.10 - isl_options_get_schedule_separate_components@Base 0.10 - isl_options_get_schedule_split_scaled@Base 0.10 - isl_options_get_tile_scale_tile_loops@Base 0.10 - isl_options_get_tile_shift_point_loops@Base 0.12.1 - isl_options_new_with_defaults@Base 0.10 - isl_options_parse@Base 0.10 - isl_options_set_ast_build_allow_else@Base 0.11 - isl_options_set_ast_build_allow_or@Base 0.12.1 - isl_options_set_ast_build_atomic_upper_bound@Base 0.11 - isl_options_set_ast_build_exploit_nested_bounds@Base 0.11 - isl_options_set_ast_build_group_coscheduled@Base 0.11 - isl_options_set_ast_build_prefer_pdiv@Base 0.11 - isl_options_set_ast_build_scale_strides@Base 0.11 - isl_options_set_ast_build_separation_bounds@Base 0.11 - isl_options_set_ast_iterator_type@Base 0.11 - isl_options_set_bound@Base 0.10 - isl_options_set_coalesce_bounded_wrapping@Base 0.10 - isl_options_set_gbr_only_first@Base 0.10 - isl_options_set_on_error@Base 0.10 - isl_options_set_schedule_algorithm@Base 0.10 - isl_options_set_schedule_fuse@Base 0.10 - isl_options_set_schedule_max_coefficient@Base 0.10 - isl_options_set_schedule_max_constant_term@Base 0.10 - isl_options_set_schedule_maximize_band_depth@Base 0.10 - isl_options_set_schedule_outer_zero_distance@Base 0.10 - isl_options_set_schedule_separate_components@Base 0.10 - isl_options_set_schedule_split_scaled@Base 0.10 - isl_options_set_tile_scale_tile_loops@Base 0.10 - isl_options_set_tile_shift_point_loops@Base 0.12.1 - isl_parameter_alignment_reordering@Base 0.10 - isl_pip_basic_map_lexopt@Base 0.10 - isl_pip_basic_set_sample@Base 0.10 - isl_pip_context_choice@Base 0.10 - isl_pip_solve_lp@Base 0.10 - isl_pip_solver_choice@Base 0.10 - isl_point_add_ui@Base 0.10 - isl_point_alloc@Base 0.10 - isl_point_copy@Base 0.10 - isl_point_cow@Base 0.10 - isl_point_dump@Base 0.11 - isl_point_dup@Base 0.10 - isl_point_free@Base 0.10 - isl_point_get_coordinate@Base 0.10 - isl_point_get_coordinate_val@Base 0.12.1 - isl_point_get_ctx@Base 0.10 - isl_point_get_dim@Base 0.10 - isl_point_get_space@Base 0.10 - isl_point_is_void@Base 0.10 - isl_point_set_coordinate@Base 0.10 - isl_point_set_coordinate_val@Base 0.12.1 - isl_point_sub_ui@Base 0.10 - isl_point_to_str@Base 0.11 - isl_point_void@Base 0.10 - isl_point_zero@Base 0.10 - isl_printer_end_line@Base 0.10 - isl_printer_flush@Base 0.10 - isl_printer_free@Base 0.10 - isl_printer_get_ctx@Base 0.10 - isl_printer_get_file@Base 0.10 - isl_printer_get_output_format@Base 0.10 - isl_printer_get_str@Base 0.10 - isl_printer_indent@Base 0.10 - isl_printer_print_aff@Base 0.10 - isl_printer_print_aff_list@Base 0.10 - isl_printer_print_ast_expr@Base 0.11 - isl_printer_print_ast_expr_list@Base 0.11 - isl_printer_print_ast_graft@Base 0.11 - isl_printer_print_ast_graft_list@Base 0.11 - isl_printer_print_ast_node@Base 0.11 - isl_printer_print_ast_node_list@Base 0.11 - isl_printer_print_band@Base 0.10 - isl_printer_print_band_list@Base 0.10 - isl_printer_print_basic_map@Base 0.10 - isl_printer_print_basic_set@Base 0.10 - isl_printer_print_basic_set_list@Base 0.10 - isl_printer_print_constraint@Base 0.10 - isl_printer_print_constraint_list@Base 0.11 - isl_printer_print_double@Base 0.11 - isl_printer_print_id@Base 0.10 - isl_printer_print_id_list@Base 0.11 - isl_printer_print_int@Base 0.10 - isl_printer_print_isl_int@Base 0.10 - isl_printer_print_local_space@Base 0.10 - isl_printer_print_map@Base 0.10 - isl_printer_print_multi_aff@Base 0.10 - isl_printer_print_multi_pw_aff@Base 0.11 - isl_printer_print_point@Base 0.10 - isl_printer_print_pw_aff@Base 0.10 - isl_printer_print_pw_aff_list@Base 0.10 - isl_printer_print_pw_multi_aff@Base 0.10 - isl_printer_print_pw_qpolynomial@Base 0.10 - isl_printer_print_pw_qpolynomial_fold@Base 0.10 - isl_printer_print_qpolynomial@Base 0.10 - isl_printer_print_qpolynomial_fold@Base 0.10 - isl_printer_print_schedule@Base 0.10 - isl_printer_print_set@Base 0.10 - isl_printer_print_set_list@Base 0.10 - isl_printer_print_space@Base 0.10 - isl_printer_print_str@Base 0.10 - isl_printer_print_union_map@Base 0.10 - isl_printer_print_union_pw_multi_aff@Base 0.10 - isl_printer_print_union_pw_qpolynomial@Base 0.10 - isl_printer_print_union_pw_qpolynomial_fold@Base 0.10 - isl_printer_print_union_set@Base 0.10 - isl_printer_print_val@Base 0.12.1 - isl_printer_print_val_list@Base 0.12.1 - isl_printer_print_vec@Base 0.10 - isl_printer_set_indent@Base 0.10 - isl_printer_set_isl_int_width@Base 0.10 - isl_printer_set_output_format@Base 0.10 - isl_printer_set_prefix@Base 0.10 - isl_printer_set_suffix@Base 0.10 - isl_printer_start_line@Base 0.10 - isl_printer_to_file@Base 0.10 - isl_printer_to_str@Base 0.10 - isl_pw_aff_add@Base 0.10 - isl_pw_aff_add_dims@Base 0.10 - isl_pw_aff_add_disjoint@Base 0.10 - isl_pw_aff_add_piece@Base 0.10 - isl_pw_aff_align_params@Base 0.10 - isl_pw_aff_alloc@Base 0.10 - isl_pw_aff_alloc_size@Base 0.10 - isl_pw_aff_ceil@Base 0.10 - isl_pw_aff_check_match_domain_space@Base 0.12.1 - isl_pw_aff_coalesce@Base 0.10 - isl_pw_aff_cond@Base 0.10 - isl_pw_aff_copy@Base 0.10 - isl_pw_aff_cow@Base 0.10 - isl_pw_aff_dim@Base 0.10 - isl_pw_aff_div@Base 0.11 - isl_pw_aff_domain@Base 0.10 - isl_pw_aff_drop_dims@Base 0.10 - isl_pw_aff_dump@Base 0.10 - isl_pw_aff_dup@Base 0.10 - isl_pw_aff_empty@Base 0.10 - isl_pw_aff_eq_set@Base 0.10 - isl_pw_aff_fix_dim@Base 0.10 - isl_pw_aff_fix_val@Base 0.12.1 - isl_pw_aff_floor@Base 0.10 - isl_pw_aff_foreach_piece@Base 0.10 - isl_pw_aff_free@Base 0.10 - isl_pw_aff_from_aff@Base 0.10 - isl_pw_aff_ge_set@Base 0.10 - isl_pw_aff_get_ctx@Base 0.10 - isl_pw_aff_get_dim@Base 0.10 - isl_pw_aff_get_dim_id@Base 0.10 - isl_pw_aff_get_dim_name@Base 0.10 - isl_pw_aff_get_domain_space@Base 0.10 - isl_pw_aff_get_space@Base 0.10 - isl_pw_aff_get_tuple_id@Base 0.10 - isl_pw_aff_get_tuple_name@Base 0.10 - isl_pw_aff_gist@Base 0.10 - isl_pw_aff_gist_params@Base 0.10 - isl_pw_aff_gt_set@Base 0.10 - isl_pw_aff_has_dim_id@Base 0.10 - isl_pw_aff_has_equal_space@Base 0.10 - isl_pw_aff_has_tuple_id@Base 0.10 - isl_pw_aff_has_tuple_name@Base 0.11 - isl_pw_aff_insert_dims@Base 0.10 - isl_pw_aff_intersect_domain@Base 0.10 - isl_pw_aff_intersect_params@Base 0.10 - isl_pw_aff_involves_dims@Base 0.10 - isl_pw_aff_is_cst@Base 0.10 - isl_pw_aff_is_empty@Base 0.10 - isl_pw_aff_le_set@Base 0.10 - isl_pw_aff_list_add@Base 0.10 - isl_pw_aff_list_alloc@Base 0.10 - isl_pw_aff_list_concat@Base 0.10 - isl_pw_aff_list_copy@Base 0.10 - isl_pw_aff_list_cow@Base 0.11 - isl_pw_aff_list_drop@Base 0.11 - isl_pw_aff_list_dump@Base 0.10 - isl_pw_aff_list_dup@Base 0.10 - isl_pw_aff_list_eq_set@Base 0.10 - isl_pw_aff_list_foreach@Base 0.10 - isl_pw_aff_list_foreach_scc@Base 0.12.1 - isl_pw_aff_list_free@Base 0.10 - isl_pw_aff_list_from_pw_aff@Base 0.10 - isl_pw_aff_list_ge_set@Base 0.10 - isl_pw_aff_list_get_ctx@Base 0.10 - isl_pw_aff_list_get_pw_aff@Base 0.10 - isl_pw_aff_list_gt_set@Base 0.10 - isl_pw_aff_list_insert@Base 0.11 - isl_pw_aff_list_le_set@Base 0.10 - isl_pw_aff_list_lt_set@Base 0.10 - isl_pw_aff_list_max@Base 0.10 - isl_pw_aff_list_min@Base 0.10 - isl_pw_aff_list_n_pw_aff@Base 0.10 - isl_pw_aff_list_ne_set@Base 0.10 - isl_pw_aff_list_set_pw_aff@Base 0.11 - isl_pw_aff_list_set_rational@Base 0.11 - isl_pw_aff_list_sort@Base 0.12.1 - isl_pw_aff_lt_set@Base 0.10 - isl_pw_aff_max@Base 0.10 - isl_pw_aff_min@Base 0.10 - isl_pw_aff_mod@Base 0.10 - isl_pw_aff_mod_val@Base 0.12.1 - isl_pw_aff_mul@Base 0.10 - isl_pw_aff_mul_isl_int@Base 0.10 - isl_pw_aff_n_piece@Base 0.10 - isl_pw_aff_ne_set@Base 0.10 - isl_pw_aff_neg@Base 0.10 - isl_pw_aff_non_zero_set@Base 0.10 - isl_pw_aff_nonneg_set@Base 0.10 - isl_pw_aff_normalize@Base 0.10 - isl_pw_aff_plain_is_equal@Base 0.10 - isl_pw_aff_project_domain_on_params@Base 0.10 - isl_pw_aff_project_out@Base 0.10 - isl_pw_aff_pullback_multi_aff@Base 0.11 - isl_pw_aff_pullback_pw_multi_aff@Base 0.11 - isl_pw_aff_read_from_str@Base 0.10 - isl_pw_aff_realign_domain@Base 0.10 - isl_pw_aff_reset_domain_space@Base 0.10 - isl_pw_aff_reset_space@Base 0.10 - isl_pw_aff_scale@Base 0.10 - isl_pw_aff_scale_down@Base 0.10 - isl_pw_aff_scale_down_val@Base 0.12.1 - isl_pw_aff_scale_val@Base 0.12.1 - isl_pw_aff_set_dim_id@Base 0.10 - isl_pw_aff_set_dim_name@Base 0.10 - isl_pw_aff_set_rational@Base 0.11 - isl_pw_aff_set_tuple_id@Base 0.10 - isl_pw_aff_split_dims@Base 0.10 - isl_pw_aff_sub@Base 0.10 - isl_pw_aff_tdiv_q@Base 0.11 - isl_pw_aff_tdiv_r@Base 0.11 - isl_pw_aff_to_str@Base 0.10 - isl_pw_aff_union_add@Base 0.10 - isl_pw_aff_union_max@Base 0.10 - isl_pw_aff_union_min@Base 0.10 - isl_pw_aff_union_opt@Base 0.10 - isl_pw_aff_var_on_domain@Base 0.11 - isl_pw_aff_zero_on_domain@Base 0.11 - isl_pw_aff_zero_set@Base 0.10 - isl_pw_multi_aff_add@Base 0.10 - isl_pw_multi_aff_add_disjoint@Base 0.10 - isl_pw_multi_aff_add_piece@Base 0.10 - isl_pw_multi_aff_align_params@Base 0.10 - isl_pw_multi_aff_alloc@Base 0.10 - isl_pw_multi_aff_alloc_size@Base 0.10 - isl_pw_multi_aff_coalesce@Base 0.10 - isl_pw_multi_aff_copy@Base 0.10 - isl_pw_multi_aff_cow@Base 0.10 - isl_pw_multi_aff_dim@Base 0.10 - isl_pw_multi_aff_domain@Base 0.10 - isl_pw_multi_aff_drop_dims@Base 0.10 - isl_pw_multi_aff_dump@Base 0.10 - isl_pw_multi_aff_dup@Base 0.10 - isl_pw_multi_aff_empty@Base 0.10 - isl_pw_multi_aff_fix_dim@Base 0.10 - isl_pw_multi_aff_fix_val@Base 0.12.1 - isl_pw_multi_aff_flat_range_product@Base 0.10 - isl_pw_multi_aff_foreach_piece@Base 0.10 - isl_pw_multi_aff_free@Base 0.10 - isl_pw_multi_aff_from_domain@Base 0.10 - isl_pw_multi_aff_from_map@Base 0.10 - isl_pw_multi_aff_from_multi_aff@Base 0.10 - isl_pw_multi_aff_from_set@Base 0.10 - isl_pw_multi_aff_get_ctx@Base 0.10 - isl_pw_multi_aff_get_dim_id@Base 0.10 - isl_pw_multi_aff_get_dim_name@Base 0.10 - isl_pw_multi_aff_get_domain_space@Base 0.10 - isl_pw_multi_aff_get_pw_aff@Base 0.10 - isl_pw_multi_aff_get_space@Base 0.10 - isl_pw_multi_aff_get_tuple_id@Base 0.10 - isl_pw_multi_aff_get_tuple_name@Base 0.10 - isl_pw_multi_aff_gist@Base 0.10 - isl_pw_multi_aff_gist_params@Base 0.10 - isl_pw_multi_aff_has_dim_id@Base 0.10 - isl_pw_multi_aff_has_equal_space@Base 0.10 - isl_pw_multi_aff_has_tuple_id@Base 0.10 - isl_pw_multi_aff_has_tuple_name@Base 0.11 - isl_pw_multi_aff_identity@Base 0.11 - isl_pw_multi_aff_intersect_domain@Base 0.10 - isl_pw_multi_aff_intersect_params@Base 0.10 - isl_pw_multi_aff_is_empty@Base 0.10 - isl_pw_multi_aff_mul_isl_int@Base 0.10 - isl_pw_multi_aff_n_piece@Base 0.10 - isl_pw_multi_aff_normalize@Base 0.10 - isl_pw_multi_aff_plain_is_equal@Base 0.10 - isl_pw_multi_aff_product@Base 0.11 - isl_pw_multi_aff_project_domain_on_params@Base 0.10 - isl_pw_multi_aff_project_out@Base 0.10 - isl_pw_multi_aff_pullback_multi_aff@Base 0.11 - isl_pw_multi_aff_pullback_pw_multi_aff@Base 0.11 - isl_pw_multi_aff_range_product@Base 0.11 - isl_pw_multi_aff_read_from_str@Base 0.10 - isl_pw_multi_aff_realign_domain@Base 0.10 - isl_pw_multi_aff_reset_domain_space@Base 0.10 - isl_pw_multi_aff_reset_space@Base 0.10 - isl_pw_multi_aff_scale@Base 0.10 - isl_pw_multi_aff_scale_multi_val@Base 0.12.1 - isl_pw_multi_aff_scale_val@Base 0.12.1 - isl_pw_multi_aff_set_dim_id@Base 0.10 - isl_pw_multi_aff_set_dim_name@Base 0.10 - isl_pw_multi_aff_set_pw_aff@Base 0.11 - isl_pw_multi_aff_set_tuple_id@Base 0.10 - isl_pw_multi_aff_split_dims@Base 0.10 - isl_pw_multi_aff_sub@Base 0.12.1 - isl_pw_multi_aff_substitute@Base 0.10 - isl_pw_multi_aff_to_str@Base 0.10 - isl_pw_multi_aff_union_add@Base 0.10 - isl_pw_multi_aff_union_lexmax@Base 0.11 - isl_pw_multi_aff_union_lexmin@Base 0.11 - isl_pw_qpolynomial_add@Base 0.10 - isl_pw_qpolynomial_add_dims@Base 0.10 - isl_pw_qpolynomial_add_disjoint@Base 0.10 - isl_pw_qpolynomial_add_piece@Base 0.10 - isl_pw_qpolynomial_align_params@Base 0.10 - isl_pw_qpolynomial_alloc@Base 0.10 - isl_pw_qpolynomial_alloc_size@Base 0.10 - isl_pw_qpolynomial_bound@Base 0.10 - isl_pw_qpolynomial_coalesce@Base 0.10 - isl_pw_qpolynomial_copy@Base 0.10 - isl_pw_qpolynomial_cow@Base 0.10 - isl_pw_qpolynomial_dim@Base 0.10 - isl_pw_qpolynomial_domain@Base 0.10 - isl_pw_qpolynomial_drop_dims@Base 0.10 - isl_pw_qpolynomial_dump@Base 0.10 - isl_pw_qpolynomial_dup@Base 0.10 - isl_pw_qpolynomial_eval@Base 0.10 - isl_pw_qpolynomial_fix_dim@Base 0.10 - isl_pw_qpolynomial_fix_val@Base 0.12.1 - isl_pw_qpolynomial_fold_add@Base 0.10 - isl_pw_qpolynomial_fold_add_disjoint@Base 0.10 - isl_pw_qpolynomial_fold_add_piece@Base 0.10 - isl_pw_qpolynomial_fold_align_params@Base 0.10 - isl_pw_qpolynomial_fold_alloc@Base 0.10 - isl_pw_qpolynomial_fold_alloc_size@Base 0.10 - isl_pw_qpolynomial_fold_bound@Base 0.10 - isl_pw_qpolynomial_fold_coalesce@Base 0.10 - isl_pw_qpolynomial_fold_copy@Base 0.10 - isl_pw_qpolynomial_fold_covers@Base 0.10 - isl_pw_qpolynomial_fold_cow@Base 0.10 - isl_pw_qpolynomial_fold_dim@Base 0.10 - isl_pw_qpolynomial_fold_domain@Base 0.10 - isl_pw_qpolynomial_fold_drop_dims@Base 0.10 - isl_pw_qpolynomial_fold_dump@Base 0.10 - isl_pw_qpolynomial_fold_dup@Base 0.10 - isl_pw_qpolynomial_fold_eval@Base 0.10 - isl_pw_qpolynomial_fold_fix_dim@Base 0.10 - isl_pw_qpolynomial_fold_fix_val@Base 0.12.1 - isl_pw_qpolynomial_fold_fold@Base 0.10 - isl_pw_qpolynomial_fold_foreach_lifted_piece@Base 0.10 - isl_pw_qpolynomial_fold_foreach_piece@Base 0.10 - isl_pw_qpolynomial_fold_free@Base 0.10 - isl_pw_qpolynomial_fold_from_pw_qpolynomial@Base 0.10 - isl_pw_qpolynomial_fold_get_ctx@Base 0.10 - isl_pw_qpolynomial_fold_get_dim@Base 0.10 - isl_pw_qpolynomial_fold_get_dim_id@Base 0.10 - isl_pw_qpolynomial_fold_get_dim_name@Base 0.10 - isl_pw_qpolynomial_fold_get_domain_space@Base 0.10 - isl_pw_qpolynomial_fold_get_space@Base 0.10 - isl_pw_qpolynomial_fold_get_tuple_id@Base 0.10 - isl_pw_qpolynomial_fold_get_tuple_name@Base 0.10 - isl_pw_qpolynomial_fold_gist@Base 0.10 - isl_pw_qpolynomial_fold_gist_params@Base 0.10 - isl_pw_qpolynomial_fold_has_dim_id@Base 0.10 - isl_pw_qpolynomial_fold_has_equal_space@Base 0.10 - isl_pw_qpolynomial_fold_has_tuple_id@Base 0.10 - isl_pw_qpolynomial_fold_has_tuple_name@Base 0.11 - isl_pw_qpolynomial_fold_insert_dims@Base 0.10 - isl_pw_qpolynomial_fold_intersect_domain@Base 0.10 - isl_pw_qpolynomial_fold_intersect_params@Base 0.10 - isl_pw_qpolynomial_fold_involves_dims@Base 0.10 - isl_pw_qpolynomial_fold_is_zero@Base 0.10 - isl_pw_qpolynomial_fold_max@Base 0.10 - isl_pw_qpolynomial_fold_min@Base 0.10 - isl_pw_qpolynomial_fold_morph_domain@Base 0.10 - isl_pw_qpolynomial_fold_move_dims@Base 0.10 - isl_pw_qpolynomial_fold_mul_isl_int@Base 0.10 - isl_pw_qpolynomial_fold_n_piece@Base 0.10 - isl_pw_qpolynomial_fold_normalize@Base 0.10 - isl_pw_qpolynomial_fold_opt@Base 0.10 - isl_pw_qpolynomial_fold_plain_is_equal@Base 0.10 - isl_pw_qpolynomial_fold_print@Base 0.10 - isl_pw_qpolynomial_fold_project_domain_on_params@Base 0.10 - isl_pw_qpolynomial_fold_project_out@Base 0.10 - isl_pw_qpolynomial_fold_realign_domain@Base 0.10 - isl_pw_qpolynomial_fold_reset_domain_space@Base 0.10 - isl_pw_qpolynomial_fold_reset_space@Base 0.10 - isl_pw_qpolynomial_fold_scale@Base 0.10 - isl_pw_qpolynomial_fold_scale_val@Base 0.12.1 - isl_pw_qpolynomial_fold_set_dim_id@Base 0.10 - isl_pw_qpolynomial_fold_set_dim_name@Base 0.10 - isl_pw_qpolynomial_fold_set_tuple_id@Base 0.10 - isl_pw_qpolynomial_fold_size@Base 0.10 - isl_pw_qpolynomial_fold_split_dims@Base 0.10 - isl_pw_qpolynomial_fold_to_str@Base 0.10 - isl_pw_qpolynomial_fold_zero@Base 0.10 - isl_pw_qpolynomial_foreach_lifted_piece@Base 0.10 - isl_pw_qpolynomial_foreach_piece@Base 0.10 - isl_pw_qpolynomial_free@Base 0.10 - isl_pw_qpolynomial_from_pw_aff@Base 0.10 - isl_pw_qpolynomial_from_qpolynomial@Base 0.10 - isl_pw_qpolynomial_get_ctx@Base 0.10 - isl_pw_qpolynomial_get_dim@Base 0.10 - isl_pw_qpolynomial_get_dim_id@Base 0.10 - isl_pw_qpolynomial_get_dim_name@Base 0.10 - isl_pw_qpolynomial_get_domain_space@Base 0.10 - isl_pw_qpolynomial_get_space@Base 0.10 - isl_pw_qpolynomial_get_tuple_id@Base 0.10 - isl_pw_qpolynomial_get_tuple_name@Base 0.10 - isl_pw_qpolynomial_gist@Base 0.10 - isl_pw_qpolynomial_gist_params@Base 0.10 - isl_pw_qpolynomial_has_dim_id@Base 0.10 - isl_pw_qpolynomial_has_equal_space@Base 0.10 - isl_pw_qpolynomial_has_tuple_id@Base 0.10 - isl_pw_qpolynomial_has_tuple_name@Base 0.11 - isl_pw_qpolynomial_insert_dims@Base 0.10 - isl_pw_qpolynomial_intersect_domain@Base 0.10 - isl_pw_qpolynomial_intersect_params@Base 0.10 - isl_pw_qpolynomial_involves_dims@Base 0.10 - isl_pw_qpolynomial_is_one@Base 0.10 - isl_pw_qpolynomial_is_zero@Base 0.10 - isl_pw_qpolynomial_max@Base 0.10 - isl_pw_qpolynomial_min@Base 0.10 - isl_pw_qpolynomial_morph_domain@Base 0.10 - isl_pw_qpolynomial_move_dims@Base 0.10 - isl_pw_qpolynomial_mul@Base 0.10 - isl_pw_qpolynomial_mul_isl_int@Base 0.10 - isl_pw_qpolynomial_n_piece@Base 0.10 - isl_pw_qpolynomial_neg@Base 0.10 - isl_pw_qpolynomial_normalize@Base 0.10 - isl_pw_qpolynomial_opt@Base 0.10 - isl_pw_qpolynomial_plain_is_equal@Base 0.10 - isl_pw_qpolynomial_pow@Base 0.10 - isl_pw_qpolynomial_print@Base 0.10 - isl_pw_qpolynomial_project_domain_on_params@Base 0.10 - isl_pw_qpolynomial_project_out@Base 0.10 - isl_pw_qpolynomial_read_from_file@Base 0.10 - isl_pw_qpolynomial_read_from_str@Base 0.10 - isl_pw_qpolynomial_realign_domain@Base 0.10 - isl_pw_qpolynomial_reset_domain_space@Base 0.10 - isl_pw_qpolynomial_reset_space@Base 0.10 - isl_pw_qpolynomial_scale@Base 0.10 - isl_pw_qpolynomial_scale_val@Base 0.12.1 - isl_pw_qpolynomial_set_dim_id@Base 0.10 - isl_pw_qpolynomial_set_dim_name@Base 0.10 - isl_pw_qpolynomial_set_tuple_id@Base 0.10 - isl_pw_qpolynomial_split_dims@Base 0.10 - isl_pw_qpolynomial_split_periods@Base 0.10 - isl_pw_qpolynomial_sub@Base 0.10 - isl_pw_qpolynomial_to_polynomial@Base 0.10 - isl_pw_qpolynomial_to_str@Base 0.10 - isl_pw_qpolynomial_zero@Base 0.10 - isl_qpolynomial_add@Base 0.10 - isl_qpolynomial_add_dims@Base 0.10 - isl_qpolynomial_add_isl_int@Base 0.10 - isl_qpolynomial_add_on_domain@Base 0.10 - isl_qpolynomial_align_params@Base 0.10 - isl_qpolynomial_alloc@Base 0.10 - isl_qpolynomial_as_polynomial_on_domain@Base 0.10 - isl_qpolynomial_bound_on_domain_bernstein@Base 0.10 - isl_qpolynomial_bound_on_domain_range@Base 0.10 - isl_qpolynomial_coeff@Base 0.10 - isl_qpolynomial_copy@Base 0.10 - isl_qpolynomial_cow@Base 0.10 - isl_qpolynomial_cst_on_domain@Base 0.10 - isl_qpolynomial_degree@Base 0.10 - isl_qpolynomial_dim@Base 0.10 - isl_qpolynomial_drop_dims@Base 0.10 - isl_qpolynomial_dump@Base 0.10 - isl_qpolynomial_dup@Base 0.10 - isl_qpolynomial_eval@Base 0.10 - isl_qpolynomial_extract_affine@Base 0.10 - isl_qpolynomial_fold_add_on_domain@Base 0.10 - isl_qpolynomial_fold_add_qpolynomial@Base 0.10 - isl_qpolynomial_fold_alloc@Base 0.10 - isl_qpolynomial_fold_copy@Base 0.10 - isl_qpolynomial_fold_cow@Base 0.10 - isl_qpolynomial_fold_drop_dims@Base 0.10 - isl_qpolynomial_fold_dump@Base 0.10 - isl_qpolynomial_fold_dup@Base 0.10 - isl_qpolynomial_fold_empty@Base 0.10 - isl_qpolynomial_fold_eval@Base 0.10 - isl_qpolynomial_fold_fold@Base 0.10 - isl_qpolynomial_fold_fold_on_domain@Base 0.10 - isl_qpolynomial_fold_foreach_qpolynomial@Base 0.10 - isl_qpolynomial_fold_free@Base 0.10 - isl_qpolynomial_fold_get_ctx@Base 0.10 - isl_qpolynomial_fold_get_dim@Base 0.10 - isl_qpolynomial_fold_get_domain_space@Base 0.10 - isl_qpolynomial_fold_get_space@Base 0.10 - isl_qpolynomial_fold_get_type@Base 0.10 - isl_qpolynomial_fold_gist@Base 0.10 - isl_qpolynomial_fold_gist_params@Base 0.10 - isl_qpolynomial_fold_insert_dims@Base 0.10 - isl_qpolynomial_fold_involves_dims@Base 0.10 - isl_qpolynomial_fold_is_empty@Base 0.10 - isl_qpolynomial_fold_lift@Base 0.10 - isl_qpolynomial_fold_morph_domain@Base 0.10 - isl_qpolynomial_fold_move_dims@Base 0.10 - isl_qpolynomial_fold_mul_isl_int@Base 0.10 - isl_qpolynomial_fold_opt_on_domain@Base 0.10 - isl_qpolynomial_fold_plain_is_equal@Base 0.10 - isl_qpolynomial_fold_print@Base 0.10 - isl_qpolynomial_fold_realign_domain@Base 0.10 - isl_qpolynomial_fold_reset_domain_space@Base 0.10 - isl_qpolynomial_fold_reset_space_and_domain@Base 0.10 - isl_qpolynomial_fold_scale@Base 0.10 - isl_qpolynomial_fold_scale_val@Base 0.12.1 - isl_qpolynomial_fold_set_dim_name@Base 0.10 - isl_qpolynomial_fold_substitute@Base 0.10 - isl_qpolynomial_fold_substitute_equalities@Base 0.10 - isl_qpolynomial_fold_to_str@Base 0.10 - isl_qpolynomial_foreach_term@Base 0.10 - isl_qpolynomial_free@Base 0.10 - isl_qpolynomial_from_aff@Base 0.10 - isl_qpolynomial_from_affine@Base 0.10 - isl_qpolynomial_from_constraint@Base 0.10 - isl_qpolynomial_from_term@Base 0.10 - isl_qpolynomial_get_constant_val@Base 0.12.1 - isl_qpolynomial_get_ctx@Base 0.10 - isl_qpolynomial_get_den@Base 0.10 - isl_qpolynomial_get_dim@Base 0.10 - isl_qpolynomial_get_domain_space@Base 0.10 - isl_qpolynomial_get_space@Base 0.10 - isl_qpolynomial_gist@Base 0.10 - isl_qpolynomial_gist_params@Base 0.10 - isl_qpolynomial_homogenize@Base 0.10 - isl_qpolynomial_infty_on_domain@Base 0.10 - isl_qpolynomial_insert_dims@Base 0.10 - isl_qpolynomial_involves_dims@Base 0.10 - isl_qpolynomial_is_affine@Base 0.10 - isl_qpolynomial_is_cst@Base 0.10 - isl_qpolynomial_is_infty@Base 0.10 - isl_qpolynomial_is_nan@Base 0.10 - isl_qpolynomial_is_neginfty@Base 0.10 - isl_qpolynomial_is_one@Base 0.10 - isl_qpolynomial_is_zero@Base 0.10 - isl_qpolynomial_le_cst@Base 0.10 - isl_qpolynomial_lift@Base 0.10 - isl_qpolynomial_max_cst@Base 0.10 - isl_qpolynomial_min_cst@Base 0.10 - isl_qpolynomial_morph_domain@Base 0.10 - isl_qpolynomial_move_dims@Base 0.10 - isl_qpolynomial_mul@Base 0.10 - isl_qpolynomial_mul_isl_int@Base 0.10 - isl_qpolynomial_nan_on_domain@Base 0.10 - isl_qpolynomial_neg@Base 0.10 - isl_qpolynomial_neginfty_on_domain@Base 0.10 - isl_qpolynomial_one_on_domain@Base 0.10 - isl_qpolynomial_opt_on_domain@Base 0.10 - isl_qpolynomial_plain_is_equal@Base 0.10 - isl_qpolynomial_pow@Base 0.10 - isl_qpolynomial_print@Base 0.10 - isl_qpolynomial_project_domain_on_params@Base 0.10 - isl_qpolynomial_rat_cst_on_domain@Base 0.10 - isl_qpolynomial_realign_domain@Base 0.10 - isl_qpolynomial_reset_domain_space@Base 0.10 - isl_qpolynomial_reset_space_and_domain@Base 0.10 - isl_qpolynomial_scale@Base 0.10 - isl_qpolynomial_scale_val@Base 0.12.1 - isl_qpolynomial_set_dim_name@Base 0.10 - isl_qpolynomial_sgn@Base 0.10 - isl_qpolynomial_sub@Base 0.10 - isl_qpolynomial_substitute@Base 0.10 - isl_qpolynomial_substitute_equalities@Base 0.10 - isl_qpolynomial_terms_of_sign@Base 0.10 - isl_qpolynomial_to_str@Base 0.10 - isl_qpolynomial_val_on_domain@Base 0.12.1 - isl_qpolynomial_var_on_domain@Base 0.10 - isl_qpolynomial_var_pow_on_domain@Base 0.10 - isl_qpolynomial_zero_on_domain@Base 0.10 - isl_reordering_alloc@Base 0.10 - isl_reordering_copy@Base 0.10 - isl_reordering_cow@Base 0.10 - isl_reordering_dump@Base 0.10 - isl_reordering_dup@Base 0.10 - isl_reordering_extend@Base 0.10 - isl_reordering_extend_space@Base 0.10 - isl_reordering_free@Base 0.10 - isl_restriction_empty@Base 0.10 - isl_restriction_free@Base 0.10 - isl_restriction_get_ctx@Base 0.10 - isl_restriction_input@Base 0.10 - isl_restriction_none@Base 0.10 - isl_restriction_output@Base 0.10 - isl_schedule_dump@Base 0.10 - isl_schedule_foreach_band@Base 0.10 - isl_schedule_free@Base 0.10 - isl_schedule_get_band_forest@Base 0.10 - isl_schedule_get_ctx@Base 0.10 - isl_schedule_get_map@Base 0.10 - isl_seq_abs_max@Base 0.10 - isl_seq_abs_min_non_zero@Base 0.10 - isl_seq_addmul@Base 0.10 - isl_seq_cdiv_q@Base 0.10 - isl_seq_clr@Base 0.10 - isl_seq_cmp@Base 0.10 - isl_seq_combine@Base 0.10 - isl_seq_cpy@Base 0.10 - isl_seq_dump@Base 0.10 - isl_seq_elim@Base 0.10 - isl_seq_eq@Base 0.10 - isl_seq_fdiv_q@Base 0.10 - isl_seq_fdiv_r@Base 0.10 - isl_seq_first_non_zero@Base 0.10 - isl_seq_gcd@Base 0.10 - isl_seq_get_hash@Base 0.10 - isl_seq_get_hash_bits@Base 0.10 - isl_seq_hash@Base 0.10 - isl_seq_inner_product@Base 0.10 - isl_seq_is_neg@Base 0.10 - isl_seq_last_non_zero@Base 0.10 - isl_seq_lcm@Base 0.10 - isl_seq_neg@Base 0.10 - isl_seq_normalize@Base 0.10 - isl_seq_preimage@Base 0.11 - isl_seq_scale@Base 0.10 - isl_seq_scale_down@Base 0.10 - isl_seq_set@Base 0.10 - isl_seq_set_si@Base 0.10 - isl_seq_submul@Base 0.10 - isl_seq_substitute@Base 0.11 - isl_seq_swp_or_cpy@Base 0.10 - isl_set_add_basic_set@Base 0.10 - isl_set_add_constraint@Base 0.10 - isl_set_add_dims@Base 0.10 - isl_set_affine_hull@Base 0.10 - isl_set_align_divs@Base 0.10 - isl_set_align_params@Base 0.10 - isl_set_alloc@Base 0.10 - isl_set_alloc_space@Base 0.10 - isl_set_apply@Base 0.10 - isl_set_apply_pw_qpolynomial_fold@Base 0.10 - isl_set_bounded_simple_hull@Base 0.10 - isl_set_box_from_points@Base 0.10 - isl_set_coalesce@Base 0.10 - isl_set_coefficients@Base 0.10 - isl_set_complement@Base 0.10 - isl_set_compute_divs@Base 0.10 - isl_set_contains_point@Base 0.10 - isl_set_convex_hull@Base 0.10 - isl_set_copy@Base 0.10 - isl_set_copy_basic_set@Base 0.10 - isl_set_count@Base 0.10 - isl_set_count_upto@Base 0.10 - isl_set_count_val@Base 0.12.1 - isl_set_cow@Base 0.10 - isl_set_detect_equalities@Base 0.10 - isl_set_dim@Base 0.10 - isl_set_dim_has_any_lower_bound@Base 0.11 - isl_set_dim_has_any_upper_bound@Base 0.11 - isl_set_dim_has_lower_bound@Base 0.10 - isl_set_dim_has_upper_bound@Base 0.10 - isl_set_dim_is_bounded@Base 0.10 - isl_set_dim_is_unique@Base 0.10 - isl_set_dim_max@Base 0.10 - isl_set_dim_min@Base 0.10 - isl_set_dim_residue_class@Base 0.10 - isl_set_dim_residue_class_val@Base 0.12.1 - isl_set_drop@Base 0.10 - isl_set_drop_basic_set@Base 0.10 - isl_set_drop_constraints_involving_dims@Base 0.11 - isl_set_drop_dims@Base 0.10 - isl_set_drop_redundant_divs@Base 0.10 - isl_set_dump@Base 0.10 - isl_set_dup@Base 0.10 - isl_set_eliminate@Base 0.10 - isl_set_eliminate_dims@Base 0.10 - isl_set_empty@Base 0.10 - isl_set_empty_like@Base 0.10 - isl_set_equate@Base 0.10 - isl_set_extend@Base 0.10 - isl_set_fast_dim_is_fixed@Base 0.10 - isl_set_fast_is_disjoint@Base 0.10 - isl_set_fast_is_empty@Base 0.10 - isl_set_fast_is_equal@Base 0.10 - isl_set_fast_is_universe@Base 0.10 - isl_set_finalize@Base 0.10 - isl_set_find_dim_by_id@Base 0.10 - isl_set_find_dim_by_name@Base 0.10 - isl_set_fix@Base 0.10 - isl_set_fix_dim_si@Base 0.10 - isl_set_fix_si@Base 0.10 - isl_set_fix_val@Base 0.12.1 - isl_set_flat_product@Base 0.10 - isl_set_flatten@Base 0.10 - isl_set_flatten_map@Base 0.10 - isl_set_follows_at@Base 0.10 - isl_set_foreach_basic_set@Base 0.10 - isl_set_foreach_orthant@Base 0.10 - isl_set_foreach_point@Base 0.10 - isl_set_free@Base 0.10 - isl_set_from_basic_set@Base 0.10 - isl_set_from_map@Base 0.10 - isl_set_from_params@Base 0.10 - isl_set_from_point@Base 0.10 - isl_set_from_pw_aff@Base 0.10 - isl_set_from_pw_multi_aff@Base 0.10 - isl_set_from_underlying_set@Base 0.10 - isl_set_from_union_set@Base 0.10 - isl_set_get_ctx@Base 0.10 - isl_set_get_dim@Base 0.10 - isl_set_get_dim_id@Base 0.10 - isl_set_get_dim_name@Base 0.10 - isl_set_get_hash@Base 0.10 - isl_set_get_space@Base 0.10 - isl_set_get_tuple_id@Base 0.10 - isl_set_get_tuple_name@Base 0.10 - isl_set_gist@Base 0.10 - isl_set_gist_basic_set@Base 0.10 - isl_set_gist_params@Base 0.10 - isl_set_gist_params_basic_set@Base 0.10 - isl_set_grow@Base 0.10 - isl_set_has_dim_id@Base 0.10 - isl_set_has_dim_name@Base 0.10 - isl_set_has_equal_space@Base 0.10 - isl_set_has_rational@Base 0.11 - isl_set_has_tuple_id@Base 0.10 - isl_set_has_tuple_name@Base 0.10 - isl_set_identity@Base 0.10 - isl_set_indicator_function@Base 0.10 - isl_set_insert_dims@Base 0.10 - isl_set_intersect@Base 0.10 - isl_set_intersect_params@Base 0.10 - isl_set_involves_dims@Base 0.10 - isl_set_is_bounded@Base 0.10 - isl_set_is_box@Base 0.10 - isl_set_is_disjoint@Base 0.11 - isl_set_is_empty@Base 0.10 - isl_set_is_equal@Base 0.10 - isl_set_is_params@Base 0.10 - isl_set_is_singleton@Base 0.10 - isl_set_is_strict_subset@Base 0.10 - isl_set_is_subset@Base 0.10 - isl_set_is_wrapping@Base 0.10 - isl_set_lex_ge_set@Base 0.10 - isl_set_lex_gt_set@Base 0.10 - isl_set_lex_le_set@Base 0.10 - isl_set_lex_lt_set@Base 0.10 - isl_set_lexmax@Base 0.10 - isl_set_lexmax_pw_multi_aff@Base 0.12.1 - isl_set_lexmin@Base 0.10 - isl_set_lexmin_pw_multi_aff@Base 0.12.1 - isl_set_lift@Base 0.10 - isl_set_lifting@Base 0.10 - isl_set_list_add@Base 0.10 - isl_set_list_alloc@Base 0.10 - isl_set_list_concat@Base 0.10 - isl_set_list_copy@Base 0.10 - isl_set_list_cow@Base 0.11 - isl_set_list_drop@Base 0.11 - isl_set_list_dump@Base 0.10 - isl_set_list_dup@Base 0.10 - isl_set_list_foreach@Base 0.10 - isl_set_list_foreach_scc@Base 0.12.1 - isl_set_list_free@Base 0.10 - isl_set_list_from_set@Base 0.10 - isl_set_list_get_ctx@Base 0.10 - isl_set_list_get_set@Base 0.10 - isl_set_list_insert@Base 0.11 - isl_set_list_n_set@Base 0.10 - isl_set_list_set_set@Base 0.11 - isl_set_list_sort@Base 0.12.1 - isl_set_lower_bound@Base 0.10 - isl_set_lower_bound_dim@Base 0.10 - isl_set_lower_bound_si@Base 0.10 - isl_set_lower_bound_val@Base 0.12.1 - isl_set_make_disjoint@Base 0.10 - isl_set_max@Base 0.10 - isl_set_max_val@Base 0.12.1 - isl_set_min@Base 0.10 - isl_set_min_val@Base 0.12.1 - isl_set_move_dims@Base 0.10 - isl_set_n_basic_set@Base 0.10 - isl_set_n_dim@Base 0.10 - isl_set_n_param@Base 0.10 - isl_set_nat_universe@Base 0.10 - isl_set_neg@Base 0.10 - isl_set_normalize@Base 0.10 - isl_set_opt@Base 0.10 - isl_set_opt_val@Base 0.12.1 - isl_set_params@Base 0.10 - isl_set_partial_lexmax@Base 0.10 - isl_set_partial_lexmin@Base 0.10 - isl_set_plain_cmp@Base 0.10 - isl_set_plain_dim_has_fixed_lower_bound@Base 0.10 - isl_set_plain_dim_is_fixed@Base 0.10 - isl_set_plain_get_val_if_fixed@Base 0.12.1 - isl_set_plain_is_disjoint@Base 0.10 - isl_set_plain_is_empty@Base 0.10 - isl_set_plain_is_equal@Base 0.10 - isl_set_plain_is_fixed@Base 0.10 - isl_set_plain_is_universe@Base 0.10 - isl_set_polyhedral_hull@Base 0.10 - isl_set_preimage@Base 0.10 - isl_set_preimage_multi_aff@Base 0.11 - isl_set_preimage_pw_multi_aff@Base 0.11 - isl_set_print@Base 0.10 - isl_set_print_internal@Base 0.10 - isl_set_product@Base 0.10 - isl_set_project_out@Base 0.10 - isl_set_read_from_file@Base 0.10 - isl_set_read_from_str@Base 0.10 - isl_set_realign@Base 0.10 - isl_set_recession_cone@Base 0.10 - isl_set_remove_dims@Base 0.10 - isl_set_remove_divs@Base 0.10 - isl_set_remove_divs_involving_dims@Base 0.10 - isl_set_remove_empty_parts@Base 0.10 - isl_set_remove_redundancies@Base 0.10 - isl_set_remove_unknown_divs@Base 0.10 - isl_set_reset_space@Base 0.10 - isl_set_reset_tuple_id@Base 0.10 - isl_set_sample@Base 0.10 - isl_set_sample_point@Base 0.10 - isl_set_scan@Base 0.10 - isl_set_set_dim_id@Base 0.10 - isl_set_set_dim_name@Base 0.10 - isl_set_set_rational@Base 0.10 - isl_set_set_tuple_id@Base 0.10 - isl_set_set_tuple_name@Base 0.10 - isl_set_simple_hull@Base 0.10 - isl_set_size@Base 0.10 - isl_set_solutions@Base 0.10 - isl_set_solve_lp@Base 0.10 - isl_set_split_dims@Base 0.10 - isl_set_substitute@Base 0.10 - isl_set_subtract@Base 0.10 - isl_set_sum@Base 0.10 - isl_set_to_str@Base 0.10 - isl_set_to_underlying_set@Base 0.10 - isl_set_union@Base 0.10 - isl_set_union_disjoint@Base 0.10 - isl_set_universe@Base 0.10 - isl_set_universe_like@Base 0.10 - isl_set_unshifted_simple_hull@Base 0.11 - isl_set_unwrap@Base 0.10 - isl_set_upper_bound@Base 0.10 - isl_set_upper_bound_si@Base 0.10 - isl_set_upper_bound_val@Base 0.12.1 - isl_set_wrap_facet@Base 0.10 - isl_sort@Base 0.11 - isl_space_add_dims@Base 0.10 - isl_space_align_params@Base 0.10 - isl_space_alloc@Base 0.10 - isl_space_as_set_space@Base 0.10 - isl_space_can_curry@Base 0.10 - isl_space_can_uncurry@Base 0.11 - isl_space_can_zip@Base 0.10 - isl_space_compatible@Base 0.10 - isl_space_copy@Base 0.10 - isl_space_cow@Base 0.10 - isl_space_curry@Base 0.10 - isl_space_dim@Base 0.10 - isl_space_domain@Base 0.10 - isl_space_domain_product@Base 0.10 - isl_space_drop_dims@Base 0.10 - isl_space_drop_inputs@Base 0.10 - isl_space_drop_outputs@Base 0.10 - isl_space_dump@Base 0.10 - isl_space_dup@Base 0.10 - isl_space_extend@Base 0.10 - isl_space_extend_domain_with_range@Base 0.10 - isl_space_find_dim_by_id@Base 0.10 - isl_space_find_dim_by_name@Base 0.10 - isl_space_flatten@Base 0.10 - isl_space_flatten_domain@Base 0.10 - isl_space_flatten_range@Base 0.10 - isl_space_free@Base 0.10 - isl_space_from_domain@Base 0.10 - isl_space_from_range@Base 0.10 - isl_space_get_ctx@Base 0.10 - isl_space_get_dim_id@Base 0.10 - isl_space_get_dim_name@Base 0.10 - isl_space_get_hash@Base 0.10 - isl_space_get_tuple_id@Base 0.10 - isl_space_get_tuple_name@Base 0.10 - isl_space_has_dim_id@Base 0.10 - isl_space_has_dim_name@Base 0.10 - isl_space_has_named_params@Base 0.10 - isl_space_has_tuple_id@Base 0.10 - isl_space_has_tuple_name@Base 0.10 - isl_space_insert_dims@Base 0.10 - isl_space_is_domain@Base 0.10 - isl_space_is_domain_internal@Base 0.11 - isl_space_is_equal@Base 0.10 - isl_space_is_map@Base 0.11 - isl_space_is_named_or_nested@Base 0.10 - isl_space_is_params@Base 0.10 - isl_space_is_range@Base 0.11 - isl_space_is_range_internal@Base 0.11 - isl_space_is_set@Base 0.10 - isl_space_is_wrapping@Base 0.10 - isl_space_join@Base 0.10 - isl_space_lift@Base 0.10 - isl_space_map_from_domain_and_range@Base 0.10 - isl_space_map_from_set@Base 0.10 - isl_space_match@Base 0.10 - isl_space_may_be_set@Base 0.10 - isl_space_move_dims@Base 0.10 - isl_space_offset@Base 0.10 - isl_space_params@Base 0.10 - isl_space_params_alloc@Base 0.10 - isl_space_product@Base 0.10 - isl_space_range@Base 0.10 - isl_space_range_product@Base 0.10 - isl_space_replace@Base 0.10 - isl_space_reset@Base 0.10 - isl_space_reset_dim_id@Base 0.10 - isl_space_reset_tuple_id@Base 0.10 - isl_space_reverse@Base 0.10 - isl_space_set_alloc@Base 0.10 - isl_space_set_dim_id@Base 0.10 - isl_space_set_dim_name@Base 0.10 - isl_space_set_from_params@Base 0.10 - isl_space_set_tuple_id@Base 0.10 - isl_space_set_tuple_name@Base 0.10 - isl_space_to_str@Base 0.10 - isl_space_tuple_match@Base 0.10 - isl_space_uncurry@Base 0.11 - isl_space_underlying@Base 0.10 - isl_space_unwrap@Base 0.10 - isl_space_wrap@Base 0.10 - isl_space_zip@Base 0.10 - isl_stream_eat@Base 0.10 - isl_stream_eat_if_available@Base 0.10 - isl_stream_error@Base 0.10 - isl_stream_flush_tokens@Base 0.10 - isl_stream_free@Base 0.10 - isl_stream_is_empty@Base 0.10 - isl_stream_new_file@Base 0.10 - isl_stream_new_str@Base 0.10 - isl_stream_next_token@Base 0.10 - isl_stream_next_token_is@Base 0.10 - isl_stream_next_token_on_same_line@Base 0.10 - isl_stream_push_token@Base 0.10 - isl_stream_read_aff@Base 0.10 - isl_stream_read_ident_if_available@Base 0.10 - isl_stream_read_map@Base 0.10 - isl_stream_read_multi_aff@Base 0.10 - isl_stream_read_obj@Base 0.10 - isl_stream_read_pw_aff@Base 0.10 - isl_stream_read_pw_multi_aff@Base 0.10 - isl_stream_read_pw_qpolynomial@Base 0.10 - isl_stream_read_set@Base 0.10 - isl_stream_read_union_map@Base 0.10 - isl_stream_read_union_pw_multi_aff@Base 0.12.1 - isl_stream_read_union_pw_qpolynomial@Base 0.10 - isl_stream_read_union_set@Base 0.10 - isl_stream_read_val@Base 0.12.1 - isl_stream_register_keyword@Base 0.10 - isl_stream_skip_line@Base 0.10 - isl_tab_add_div@Base 0.10 - isl_tab_add_eq@Base 0.10 - isl_tab_add_ineq@Base 0.10 - isl_tab_add_row@Base 0.10 - isl_tab_add_sample@Base 0.10 - isl_tab_add_valid_eq@Base 0.10 - isl_tab_alloc@Base 0.10 - isl_tab_allocate_con@Base 0.10 - isl_tab_allocate_var@Base 0.10 - isl_tab_basic_map_partial_lexopt@Base 0.10 - isl_tab_basic_set_non_neg_lexmin@Base 0.10 - isl_tab_basic_set_non_trivial_lexmin@Base 0.10 - isl_tab_compute_reduced_basis@Base 0.10 - isl_tab_cone_is_bounded@Base 0.10 - isl_tab_detect_equalities@Base 0.10 - isl_tab_detect_implicit_equalities@Base 0.10 - isl_tab_detect_redundant@Base 0.10 - isl_tab_drop_sample@Base 0.10 - isl_tab_dump@Base 0.10 - isl_tab_dup@Base 0.10 - isl_tab_extend@Base 0.10 - isl_tab_extend_cons@Base 0.10 - isl_tab_extend_vars@Base 0.10 - isl_tab_free@Base 0.10 - isl_tab_freeze_constraint@Base 0.10 - isl_tab_from_basic_map@Base 0.10 - isl_tab_from_basic_set@Base 0.10 - isl_tab_from_recession_cone@Base 0.10 - isl_tab_get_ctx@Base 0.12.1 - isl_tab_get_sample_value@Base 0.10 - isl_tab_ineq_type@Base 0.10 - isl_tab_init_samples@Base 0.10 - isl_tab_is_equality@Base 0.10 - isl_tab_is_redundant@Base 0.10 - isl_tab_kill_col@Base 0.10 - isl_tab_make_equalities_explicit@Base 0.11.2 - isl_tab_mark_empty@Base 0.10 - isl_tab_mark_redundant@Base 0.10 - isl_tab_min@Base 0.10 - isl_tab_min_at_most_neg_one@Base 0.10 - isl_tab_peek_bset@Base 0.10 - isl_tab_pivot@Base 0.10 - isl_tab_product@Base 0.10 - isl_tab_push@Base 0.10 - isl_tab_push_basis@Base 0.10 - isl_tab_push_callback@Base 0.10 - isl_tab_push_var@Base 0.10 - isl_tab_relax@Base 0.10 - isl_tab_rollback@Base 0.10 - isl_tab_row_is_redundant@Base 0.10 - isl_tab_sample@Base 0.10 - isl_tab_sample_is_integer@Base 0.10 - isl_tab_save_samples@Base 0.10 - isl_tab_select_facet@Base 0.10 - isl_tab_set_initial_basis_with_cone@Base 0.10 - isl_tab_sign_of_max@Base 0.10 - isl_tab_snap@Base 0.10 - isl_tab_solve_lp@Base 0.10 - isl_tab_track_bmap@Base 0.10 - isl_tab_track_bset@Base 0.10 - isl_tab_unrestrict@Base 0.12.1 - isl_tab_var_from_row@Base 0.10 - isl_tarjan_graph_free@Base 0.11 - isl_tarjan_graph_init@Base 0.11 - isl_term_alloc@Base 0.10 - isl_term_copy@Base 0.10 - isl_term_cow@Base 0.10 - isl_term_dim@Base 0.10 - isl_term_dup@Base 0.10 - isl_term_free@Base 0.10 - isl_term_get_coefficient_val@Base 0.12.1 - isl_term_get_ctx@Base 0.10 - isl_term_get_den@Base 0.10 - isl_term_get_div@Base 0.10 - isl_term_get_exp@Base 0.10 - isl_term_get_num@Base 0.10 - isl_token_free@Base 0.10 - isl_token_get_str@Base 0.12.1 - isl_token_get_type@Base 0.12.1 - isl_token_get_val@Base 0.12.1 - isl_token_new@Base 0.10 - isl_union_map_add_map@Base 0.10 - isl_union_map_affine_hull@Base 0.10 - isl_union_map_align_params@Base 0.10 - isl_union_map_apply_domain@Base 0.10 - isl_union_map_apply_range@Base 0.10 - isl_union_map_apply_union_pw_qpolynomial_fold@Base 0.10 - isl_union_map_coalesce@Base 0.10 - isl_union_map_compute_divs@Base 0.10 - isl_union_map_compute_flow@Base 0.10 - isl_union_map_contains@Base 0.10 - isl_union_map_copy@Base 0.10 - isl_union_map_cow@Base 0.10 - isl_union_map_curry@Base 0.10 - isl_union_map_deltas@Base 0.10 - isl_union_map_deltas_map@Base 0.10 - isl_union_map_detect_equalities@Base 0.10 - isl_union_map_domain@Base 0.10 - isl_union_map_domain_map@Base 0.10 - isl_union_map_domain_product@Base 0.11 - isl_union_map_dump@Base 0.10 - isl_union_map_dup@Base 0.10 - isl_union_map_empty@Base 0.10 - isl_union_map_extract_map@Base 0.10 - isl_union_map_fixed_power@Base 0.10 - isl_union_map_fixed_power_val@Base 0.12.1 - isl_union_map_flat_range_product@Base 0.10 - isl_union_map_foreach_map@Base 0.10 - isl_union_map_free@Base 0.10 - isl_union_map_from_basic_map@Base 0.11 - isl_union_map_from_domain@Base 0.10 - isl_union_map_from_domain_and_range@Base 0.10 - isl_union_map_from_map@Base 0.10 - isl_union_map_from_range@Base 0.10 - isl_union_map_from_union_pw_multi_aff@Base 0.10 - isl_union_map_get_ctx@Base 0.10 - isl_union_map_get_dim@Base 0.10 - isl_union_map_get_space@Base 0.10 - isl_union_map_gist@Base 0.10 - isl_union_map_gist_domain@Base 0.10 - isl_union_map_gist_params@Base 0.10 - isl_union_map_gist_range@Base 0.10 - isl_union_map_intersect@Base 0.10 - isl_union_map_intersect_domain@Base 0.10 - isl_union_map_intersect_params@Base 0.10 - isl_union_map_intersect_range@Base 0.10 - isl_union_map_is_bijective@Base 0.10 - isl_union_map_is_empty@Base 0.10 - isl_union_map_is_equal@Base 0.10 - isl_union_map_is_injective@Base 0.10 - isl_union_map_is_single_valued@Base 0.10 - isl_union_map_is_strict_subset@Base 0.10 - isl_union_map_is_subset@Base 0.10 - isl_union_map_is_transitively_closed@Base 0.10 - isl_union_map_lex_ge_union_map@Base 0.10 - isl_union_map_lex_gt_union_map@Base 0.10 - isl_union_map_lex_le_union_map@Base 0.10 - isl_union_map_lex_lt_union_map@Base 0.10 - isl_union_map_lexmax@Base 0.10 - isl_union_map_lexmin@Base 0.10 - isl_union_map_n_map@Base 0.10 - isl_union_map_params@Base 0.10 - isl_union_map_plain_is_injective@Base 0.10 - isl_union_map_polyhedral_hull@Base 0.10 - isl_union_map_power@Base 0.10 - isl_union_map_preimage_domain_multi_aff@Base 0.12.1 - isl_union_map_product@Base 0.10 - isl_union_map_range@Base 0.10 - isl_union_map_range_map@Base 0.10 - isl_union_map_range_product@Base 0.10 - isl_union_map_read_from_file@Base 0.10 - isl_union_map_read_from_str@Base 0.10 - isl_union_map_reverse@Base 0.10 - isl_union_map_sample@Base 0.10 - isl_union_map_simple_hull@Base 0.10 - isl_union_map_subtract@Base 0.10 - isl_union_map_subtract_domain@Base 0.11 - isl_union_map_subtract_range@Base 0.11 - isl_union_map_to_str@Base 0.10 - isl_union_map_transitive_closure@Base 0.10 - isl_union_map_uncurry@Base 0.11 - isl_union_map_union@Base 0.10 - isl_union_map_universe@Base 0.10 - isl_union_map_wrap@Base 0.10 - isl_union_map_zip@Base 0.10 - isl_union_pw_multi_aff_add@Base 0.10 - isl_union_pw_multi_aff_add_pw_multi_aff@Base 0.10 - isl_union_pw_multi_aff_align_params@Base 0.10 - isl_union_pw_multi_aff_coalesce@Base 0.10 - isl_union_pw_multi_aff_copy@Base 0.10 - isl_union_pw_multi_aff_cow@Base 0.10 - isl_union_pw_multi_aff_domain@Base 0.10 - isl_union_pw_multi_aff_dump@Base 0.10 - isl_union_pw_multi_aff_dup@Base 0.10 - isl_union_pw_multi_aff_empty@Base 0.10 - isl_union_pw_multi_aff_extract_pw_multi_aff@Base 0.10 - isl_union_pw_multi_aff_flat_range_product@Base 0.10 - isl_union_pw_multi_aff_foreach_pw_multi_aff@Base 0.10 - isl_union_pw_multi_aff_free@Base 0.10 - isl_union_pw_multi_aff_from_domain@Base 0.10 - isl_union_pw_multi_aff_from_pw_multi_aff@Base 0.10 - isl_union_pw_multi_aff_from_union_map@Base 0.12.1 - isl_union_pw_multi_aff_from_union_set@Base 0.12.1 - isl_union_pw_multi_aff_get_ctx@Base 0.10 - isl_union_pw_multi_aff_get_space@Base 0.10 - isl_union_pw_multi_aff_gist@Base 0.10 - isl_union_pw_multi_aff_gist_params@Base 0.10 - isl_union_pw_multi_aff_intersect_domain@Base 0.10 - isl_union_pw_multi_aff_intersect_params@Base 0.10 - isl_union_pw_multi_aff_mul_isl_int@Base 0.10 - isl_union_pw_multi_aff_plain_is_equal@Base 0.10 - isl_union_pw_multi_aff_read_from_str@Base 0.12.1 - isl_union_pw_multi_aff_scale_multi_val@Base 0.12.1 - isl_union_pw_multi_aff_scale_val@Base 0.12.1 - isl_union_pw_multi_aff_sub@Base 0.12.1 - isl_union_pw_multi_aff_to_str@Base 0.10 - isl_union_pw_qpolynomial_add@Base 0.10 - isl_union_pw_qpolynomial_add_pw_qpolynomial@Base 0.10 - isl_union_pw_qpolynomial_align_params@Base 0.10 - isl_union_pw_qpolynomial_bound@Base 0.10 - isl_union_pw_qpolynomial_coalesce@Base 0.10 - isl_union_pw_qpolynomial_copy@Base 0.10 - isl_union_pw_qpolynomial_cow@Base 0.10 - isl_union_pw_qpolynomial_domain@Base 0.10 - isl_union_pw_qpolynomial_dump@Base 0.10 - isl_union_pw_qpolynomial_dup@Base 0.10 - isl_union_pw_qpolynomial_eval@Base 0.10 - isl_union_pw_qpolynomial_extract_pw_qpolynomial@Base 0.10 - isl_union_pw_qpolynomial_fold_add@Base 0.10 - isl_union_pw_qpolynomial_fold_add_pw_qpolynomial_fold@Base 0.10 - isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial@Base 0.10 - isl_union_pw_qpolynomial_fold_align_params@Base 0.10 - isl_union_pw_qpolynomial_fold_coalesce@Base 0.10 - isl_union_pw_qpolynomial_fold_copy@Base 0.10 - isl_union_pw_qpolynomial_fold_cow@Base 0.10 - isl_union_pw_qpolynomial_fold_domain@Base 0.10 - isl_union_pw_qpolynomial_fold_dump@Base 0.10 - isl_union_pw_qpolynomial_fold_dup@Base 0.10 - isl_union_pw_qpolynomial_fold_eval@Base 0.10 - isl_union_pw_qpolynomial_fold_extract_pw_qpolynomial_fold@Base 0.10 - isl_union_pw_qpolynomial_fold_fold@Base 0.10 - isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold@Base 0.10 - isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold@Base 0.10 - isl_union_pw_qpolynomial_fold_free@Base 0.10 - isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold@Base 0.10 - isl_union_pw_qpolynomial_fold_get_ctx@Base 0.10 - isl_union_pw_qpolynomial_fold_get_dim@Base 0.10 - isl_union_pw_qpolynomial_fold_get_space@Base 0.10 - isl_union_pw_qpolynomial_fold_get_type@Base 0.10 - isl_union_pw_qpolynomial_fold_gist@Base 0.10 - isl_union_pw_qpolynomial_fold_gist_params@Base 0.10 - isl_union_pw_qpolynomial_fold_intersect_domain@Base 0.10 - isl_union_pw_qpolynomial_fold_intersect_params@Base 0.10 - isl_union_pw_qpolynomial_fold_mul_isl_int@Base 0.10 - isl_union_pw_qpolynomial_fold_plain_is_equal@Base 0.10 - isl_union_pw_qpolynomial_fold_scale_val@Base 0.12.1 - isl_union_pw_qpolynomial_fold_to_str@Base 0.10 - isl_union_pw_qpolynomial_fold_zero@Base 0.10 - isl_union_pw_qpolynomial_foreach_pw_qpolynomial@Base 0.10 - isl_union_pw_qpolynomial_free@Base 0.10 - isl_union_pw_qpolynomial_from_pw_qpolynomial@Base 0.10 - isl_union_pw_qpolynomial_get_ctx@Base 0.10 - isl_union_pw_qpolynomial_get_dim@Base 0.10 - isl_union_pw_qpolynomial_get_space@Base 0.10 - isl_union_pw_qpolynomial_gist@Base 0.10 - isl_union_pw_qpolynomial_gist_params@Base 0.10 - isl_union_pw_qpolynomial_intersect_domain@Base 0.10 - isl_union_pw_qpolynomial_intersect_params@Base 0.10 - isl_union_pw_qpolynomial_mul@Base 0.10 - isl_union_pw_qpolynomial_mul_isl_int@Base 0.10 - isl_union_pw_qpolynomial_neg@Base 0.10 - isl_union_pw_qpolynomial_plain_is_equal@Base 0.10 - isl_union_pw_qpolynomial_read_from_str@Base 0.10 - isl_union_pw_qpolynomial_scale_val@Base 0.12.1 - isl_union_pw_qpolynomial_sub@Base 0.10 - isl_union_pw_qpolynomial_to_polynomial@Base 0.10 - isl_union_pw_qpolynomial_to_str@Base 0.10 - isl_union_pw_qpolynomial_zero@Base 0.10 - isl_union_set_add_set@Base 0.10 - isl_union_set_affine_hull@Base 0.10 - isl_union_set_align_params@Base 0.10 - isl_union_set_apply@Base 0.10 - isl_union_set_apply_union_pw_qpolynomial_fold@Base 0.10 - isl_union_set_coalesce@Base 0.10 - isl_union_set_coefficients@Base 0.10 - isl_union_set_compute_divs@Base 0.10 - isl_union_set_compute_schedule@Base 0.10 - isl_union_set_contains@Base 0.10 - isl_union_set_copy@Base 0.10 - isl_union_set_detect_equalities@Base 0.10 - isl_union_set_dump@Base 0.10 - isl_union_set_empty@Base 0.10 - isl_union_set_extract_set@Base 0.10 - isl_union_set_foreach_point@Base 0.10 - isl_union_set_foreach_set@Base 0.10 - isl_union_set_free@Base 0.10 - isl_union_set_from_basic_set@Base 0.11 - isl_union_set_from_set@Base 0.10 - isl_union_set_get_ctx@Base 0.10 - isl_union_set_get_dim@Base 0.10 - isl_union_set_get_space@Base 0.10 - isl_union_set_gist@Base 0.10 - isl_union_set_gist_params@Base 0.10 - isl_union_set_identity@Base 0.10 - isl_union_set_intersect@Base 0.10 - isl_union_set_intersect_params@Base 0.10 - isl_union_set_is_empty@Base 0.10 - isl_union_set_is_equal@Base 0.10 - isl_union_set_is_params@Base 0.10 - isl_union_set_is_strict_subset@Base 0.10 - isl_union_set_is_subset@Base 0.10 - isl_union_set_lex_ge_union_set@Base 0.10 - isl_union_set_lex_gt_union_set@Base 0.10 - isl_union_set_lex_le_union_set@Base 0.10 - isl_union_set_lex_lt_union_set@Base 0.10 - isl_union_set_lexmax@Base 0.10 - isl_union_set_lexmin@Base 0.10 - isl_union_set_lift@Base 0.10 - isl_union_set_n_set@Base 0.10 - isl_union_set_params@Base 0.10 - isl_union_set_polyhedral_hull@Base 0.10 - isl_union_set_product@Base 0.10 - isl_union_set_read_from_file@Base 0.10 - isl_union_set_read_from_str@Base 0.10 - isl_union_set_sample@Base 0.10 - isl_union_set_simple_hull@Base 0.10 - isl_union_set_solutions@Base 0.10 - isl_union_set_subtract@Base 0.10 - isl_union_set_to_str@Base 0.10 - isl_union_set_union@Base 0.10 - isl_union_set_universe@Base 0.10 - isl_union_set_unwrap@Base 0.10 - isl_upoly_add_isl_int@Base 0.10 - isl_upoly_alloc_rec@Base 0.10 - isl_upoly_as_cst@Base 0.10 - isl_upoly_as_rec@Base 0.10 - isl_upoly_cmp@Base 0.10 - isl_upoly_coeff@Base 0.10 - isl_upoly_copy@Base 0.10 - isl_upoly_cow@Base 0.10 - isl_upoly_cst_add_isl_int@Base 0.10 - isl_upoly_cst_alloc@Base 0.10 - isl_upoly_cst_mul_isl_int@Base 0.10 - isl_upoly_degree@Base 0.10 - isl_upoly_drop@Base 0.10 - isl_upoly_dup@Base 0.10 - isl_upoly_dup_cst@Base 0.10 - isl_upoly_dup_rec@Base 0.10 - isl_upoly_eval@Base 0.10 - isl_upoly_foreach_term@Base 0.10 - isl_upoly_free@Base 0.10 - isl_upoly_from_affine@Base 0.10 - isl_upoly_homogenize@Base 0.10 - isl_upoly_infty@Base 0.10 - isl_upoly_is_affine@Base 0.10 - isl_upoly_is_cst@Base 0.10 - isl_upoly_is_equal@Base 0.10 - isl_upoly_is_infty@Base 0.10 - isl_upoly_is_nan@Base 0.10 - isl_upoly_is_neginfty@Base 0.10 - isl_upoly_is_negone@Base 0.10 - isl_upoly_is_one@Base 0.10 - isl_upoly_is_zero@Base 0.10 - isl_upoly_mul@Base 0.10 - isl_upoly_mul_cst@Base 0.10 - isl_upoly_mul_isl_int@Base 0.10 - isl_upoly_mul_rec@Base 0.10 - isl_upoly_nan@Base 0.10 - isl_upoly_neginfty@Base 0.10 - isl_upoly_one@Base 0.10 - isl_upoly_pow@Base 0.10 - isl_upoly_rat_cst@Base 0.10 - isl_upoly_sgn@Base 0.10 - isl_upoly_subs@Base 0.10 - isl_upoly_sum@Base 0.10 - isl_upoly_sum_cst@Base 0.10 - isl_upoly_update_affine@Base 0.10 - isl_upoly_var_pow@Base 0.10 - isl_upoly_zero@Base 0.10 - isl_val_2exp@Base 0.12.1 - isl_val_abs@Base 0.12.1 - isl_val_add@Base 0.12.1 - isl_val_add_ui@Base 0.12.1 - isl_val_alloc@Base 0.12.1 - isl_val_ceil@Base 0.12.1 - isl_val_check_match_domain_space@Base 0.12.1 - isl_val_cmp_si@Base 0.12.1 - isl_val_copy@Base 0.12.1 - isl_val_cow@Base 0.12.1 - isl_val_div@Base 0.12.1 - isl_val_drop_dims@Base 0.12.1 - isl_val_dump@Base 0.12.1 - isl_val_dup@Base 0.12.1 - isl_val_eq@Base 0.12.1 - isl_val_floor@Base 0.12.1 - isl_val_free@Base 0.12.1 - isl_val_from_gmp@Base 0.12.1 - isl_val_gcd@Base 0.12.1 - isl_val_gcdext@Base 0.12.1 - isl_val_ge@Base 0.12.1 - isl_val_get_abs_num_chunks@Base 0.12.1 - isl_val_get_ctx@Base 0.12.1 - isl_val_get_d@Base 0.12.1 - isl_val_get_den_gmp@Base 0.12.1 - isl_val_get_den_si@Base 0.12.1 - isl_val_get_num_gmp@Base 0.12.1 - isl_val_get_num_isl_int@Base 0.12.1 - isl_val_get_num_si@Base 0.12.1 - isl_val_gt@Base 0.12.1 - isl_val_infty@Base 0.12.1 - isl_val_insert_dims@Base 0.12.1 - isl_val_int_from_chunks@Base 0.12.1 - isl_val_int_from_gmp@Base 0.12.1 - isl_val_int_from_isl_int@Base 0.12.1 - isl_val_int_from_si@Base 0.12.1 - isl_val_int_from_ui@Base 0.12.1 - isl_val_is_divisible_by@Base 0.12.1 - isl_val_is_infty@Base 0.12.1 - isl_val_is_int@Base 0.12.1 - isl_val_is_nan@Base 0.12.1 - isl_val_is_neg@Base 0.12.1 - isl_val_is_neginfty@Base 0.12.1 - isl_val_is_negone@Base 0.12.1 - isl_val_is_nonneg@Base 0.12.1 - isl_val_is_nonpos@Base 0.12.1 - isl_val_is_one@Base 0.12.1 - isl_val_is_pos@Base 0.12.1 - isl_val_is_rat@Base 0.12.1 - isl_val_is_zero@Base 0.12.1 - isl_val_le@Base 0.12.1 - isl_val_list_add@Base 0.12.1 - isl_val_list_alloc@Base 0.12.1 - isl_val_list_concat@Base 0.12.1 - isl_val_list_copy@Base 0.12.1 - isl_val_list_cow@Base 0.12.1 - isl_val_list_drop@Base 0.12.1 - isl_val_list_dump@Base 0.12.1 - isl_val_list_dup@Base 0.12.1 - isl_val_list_foreach@Base 0.12.1 - isl_val_list_foreach_scc@Base 0.12.1 - isl_val_list_free@Base 0.12.1 - isl_val_list_from_val@Base 0.12.1 - isl_val_list_get_ctx@Base 0.12.1 - isl_val_list_get_val@Base 0.12.1 - isl_val_list_insert@Base 0.12.1 - isl_val_list_n_val@Base 0.12.1 - isl_val_list_set_val@Base 0.12.1 - isl_val_list_sort@Base 0.12.1 - isl_val_lt@Base 0.12.1 - isl_val_max@Base 0.12.1 - isl_val_min@Base 0.12.1 - isl_val_mod@Base 0.12.1 - isl_val_mul@Base 0.12.1 - isl_val_mul_ui@Base 0.12.1 - isl_val_n_abs_num_chunks@Base 0.12.1 - isl_val_nan@Base 0.12.1 - isl_val_ne@Base 0.12.1 - isl_val_neg@Base 0.12.1 - isl_val_neginfty@Base 0.12.1 - isl_val_normalize@Base 0.12.1 - isl_val_one@Base 0.12.1 - isl_val_rat_from_isl_int@Base 0.12.1 - isl_val_read_from_str@Base 0.12.1 - isl_val_realign_domain@Base 0.12.1 - isl_val_reset_domain_space@Base 0.12.1 - isl_val_scale_val@Base 0.12.1 - isl_val_set_dim_name@Base 0.12.1 - isl_val_set_nan@Base 0.12.1 - isl_val_set_si@Base 0.12.1 - isl_val_set_zero@Base 0.12.1 - isl_val_sgn@Base 0.12.1 - isl_val_sub@Base 0.12.1 - isl_val_sub_ui@Base 0.12.1 - isl_val_to_str@Base 0.12.1 - isl_val_trunc@Base 0.12.1 - isl_val_zero@Base 0.12.1 - isl_val_zero_on_domain@Base 0.12.1 - isl_vec_add@Base 0.10 - isl_vec_alloc@Base 0.10 - isl_vec_ceil@Base 0.10 - isl_vec_clr@Base 0.10 - isl_vec_cmp_element@Base 0.12.1 - isl_vec_concat@Base 0.11 - isl_vec_copy@Base 0.10 - isl_vec_cow@Base 0.10 - isl_vec_drop_els@Base 0.10 - isl_vec_dump@Base 0.10 - isl_vec_dup@Base 0.10 - isl_vec_extend@Base 0.10 - isl_vec_fdiv_r@Base 0.11 - isl_vec_free@Base 0.10 - isl_vec_get_ctx@Base 0.10 - isl_vec_get_element@Base 0.10 - isl_vec_get_element_val@Base 0.12.1 - isl_vec_insert_els@Base 0.10 - isl_vec_insert_zero_els@Base 0.10 - isl_vec_is_equal@Base 0.10 - isl_vec_lcm@Base 0.10 - isl_vec_mat_product@Base 0.10 - isl_vec_neg@Base 0.10 - isl_vec_normalize@Base 0.10 - isl_vec_read_from_file@Base 0.10 - isl_vec_scale@Base 0.10 - isl_vec_set@Base 0.10 - isl_vec_set_element@Base 0.10 - isl_vec_set_element_si@Base 0.10 - isl_vec_set_element_val@Base 0.12.1 - isl_vec_set_si@Base 0.10 - isl_vec_set_val@Base 0.12.1 - isl_vec_size@Base 0.10 - isl_vec_sort@Base 0.10 - isl_vec_zero_extend@Base 0.10 - isl_version@Base 0.10 - isl_vertex_free@Base 0.10 - isl_vertex_get_ctx@Base 0.10 - isl_vertex_get_domain@Base 0.10 - isl_vertex_get_expr@Base 0.10 - isl_vertex_get_id@Base 0.10 - isl_vertices_copy@Base 0.10 - isl_vertices_foreach_cell@Base 0.10 - isl_vertices_foreach_disjoint_cell@Base 0.10 - isl_vertices_foreach_vertex@Base 0.10 - isl_vertices_free@Base 0.10 - isl_vertices_get_ctx@Base 0.10 - isl_vertices_get_n_vertices@Base 0.10 diff -Nru isl-0.12.2/debian/libisl15.install isl-0.15/debian/libisl15.install --- isl-0.12.2/debian/libisl15.install 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/debian/libisl15.install 2011-12-15 16:41:36.000000000 +0000 @@ -0,0 +1 @@ +usr/lib/*/lib*.so.*[0-9] diff -Nru isl-0.12.2/debian/libisl15.symbols isl-0.15/debian/libisl15.symbols --- isl-0.12.2/debian/libisl15.symbols 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/debian/libisl15.symbols 2015-07-25 16:40:59.000000000 +0000 @@ -0,0 +1,3792 @@ +libisl.so.15 #PACKAGE# #MINVER# + isl_access_info_add_source@Base 0.10 + isl_access_info_alloc@Base 0.10 + isl_access_info_compute_flow@Base 0.10 + isl_access_info_free@Base 0.10 + isl_access_info_get_ctx@Base 0.10 + isl_access_info_set_restrict@Base 0.10 + isl_aff_add@Base 0.10 + isl_aff_add_coefficient@Base 0.10 + isl_aff_add_coefficient_si@Base 0.10 + isl_aff_add_coefficient_val@Base 0.12.1 + isl_aff_add_constant@Base 0.10 + isl_aff_add_constant_num@Base 0.11 + isl_aff_add_constant_num_si@Base 0.11 + isl_aff_add_constant_si@Base 0.10 + isl_aff_add_constant_val@Base 0.12.1 + isl_aff_add_dims@Base 0.10 + isl_aff_add_on_domain@Base 0.10 + isl_aff_align_divs@Base 0.10 + isl_aff_align_params@Base 0.10 + isl_aff_alloc@Base 0.10 + isl_aff_alloc_vec@Base 0.10 + isl_aff_ceil@Base 0.10 + isl_aff_check_match_domain_space@Base 0.12.1 + isl_aff_coefficient_sgn@Base 0.15 + isl_aff_copy@Base 0.10 + isl_aff_cow@Base 0.10 + isl_aff_dim@Base 0.10 + isl_aff_div@Base 0.11 + isl_aff_drop_dims@Base 0.10 + isl_aff_dump@Base 0.10 + isl_aff_dup@Base 0.10 + isl_aff_expand_divs@Base 0.10 + isl_aff_find_dim_by_name@Base 0.15 + isl_aff_floor@Base 0.10 + isl_aff_free@Base 0.10 + isl_aff_ge_basic_set@Base 0.10 + isl_aff_get_coefficient@Base 0.10 + isl_aff_get_coefficient_val@Base 0.12.1 + isl_aff_get_constant@Base 0.10 + isl_aff_get_constant_val@Base 0.12.1 + isl_aff_get_ctx@Base 0.10 + isl_aff_get_denominator@Base 0.10 + isl_aff_get_denominator_val@Base 0.12.1 + isl_aff_get_dim_name@Base 0.10 + isl_aff_get_div@Base 0.10 + isl_aff_get_domain_local_space@Base 0.10 + isl_aff_get_domain_space@Base 0.10 + isl_aff_get_local_space@Base 0.10 + isl_aff_get_space@Base 0.10 + isl_aff_gist@Base 0.10 + isl_aff_gist_params@Base 0.10 + isl_aff_insert_dims@Base 0.10 + isl_aff_involves_dims@Base 0.10 + isl_aff_is_cst@Base 0.10 + isl_aff_is_empty@Base 0.10 + isl_aff_is_nan@Base 0.13 + isl_aff_le_basic_set@Base 0.10 + isl_aff_lift@Base 0.10 + isl_aff_list_add@Base 0.10 + isl_aff_list_alloc@Base 0.10 + isl_aff_list_concat@Base 0.10 + isl_aff_list_copy@Base 0.10 + isl_aff_list_cow@Base 0.11 + isl_aff_list_drop@Base 0.11 + isl_aff_list_dump@Base 0.10 + isl_aff_list_dup@Base 0.10 + isl_aff_list_foreach@Base 0.10 + isl_aff_list_foreach_scc@Base 0.12.1 + isl_aff_list_free@Base 0.10 + isl_aff_list_from_aff@Base 0.10 + isl_aff_list_get_aff@Base 0.10 + isl_aff_list_get_ctx@Base 0.10 + isl_aff_list_insert@Base 0.11 + isl_aff_list_n_aff@Base 0.10 + isl_aff_list_set_aff@Base 0.11 + isl_aff_list_sort@Base 0.12.1 + isl_aff_matching_params@Base 0.13 + isl_aff_mod@Base 0.10 + isl_aff_mod_val@Base 0.12.1 + isl_aff_move_dims@Base 0.13 + isl_aff_mul@Base 0.10 + isl_aff_nan_on_domain@Base 0.13 + isl_aff_neg@Base 0.10 + isl_aff_neg_basic_set@Base 0.11 + isl_aff_nonneg_basic_set@Base 0.10 + isl_aff_normalize@Base 0.10 + isl_aff_plain_cmp@Base 0.13 + isl_aff_plain_is_equal@Base 0.10 + isl_aff_plain_is_zero@Base 0.10 + isl_aff_project_domain_on_params@Base 0.10 + isl_aff_pullback_aff@Base 0.13 + isl_aff_pullback_multi_aff@Base 0.11 + isl_aff_read_from_str@Base 0.10 + isl_aff_realign_domain@Base 0.10 + isl_aff_remove_unused_divs@Base 0.10 + isl_aff_reset_domain_space@Base 0.10 + isl_aff_reset_space_and_domain@Base 0.10 + isl_aff_scale@Base 0.10 + isl_aff_scale_down@Base 0.10 + isl_aff_scale_down_ui@Base 0.10 + isl_aff_scale_down_val@Base 0.12.1 + isl_aff_scale_val@Base 0.12.1 + isl_aff_set_coefficient@Base 0.10 + isl_aff_set_coefficient_si@Base 0.10 + isl_aff_set_coefficient_val@Base 0.12.1 + isl_aff_set_constant@Base 0.10 + isl_aff_set_constant_si@Base 0.10 + isl_aff_set_constant_val@Base 0.12.1 + isl_aff_set_denominator@Base 0.10 + isl_aff_set_dim_id@Base 0.10 + isl_aff_set_dim_name@Base 0.10 + isl_aff_set_tuple_id@Base 0.13 + isl_aff_sub@Base 0.10 + isl_aff_substitute@Base 0.10 + isl_aff_substitute_equalities@Base 0.15 + isl_aff_to_str@Base 0.10 + isl_aff_val_on_domain@Base 0.13 + isl_aff_var_on_domain@Base 0.11 + isl_aff_zero_basic_set@Base 0.10 + isl_aff_zero_on_domain@Base 0.10 + isl_args_free@Base 0.10 + isl_args_parse@Base 0.10 + isl_args_set_defaults@Base 0.10 + isl_ast_build_access_from_multi_pw_aff@Base 0.13 + isl_ast_build_access_from_pw_multi_aff@Base 0.13 + isl_ast_build_aff_is_nonneg@Base 0.11 + isl_ast_build_align_params@Base 0.11 + isl_ast_build_alloc@Base 0.15 + isl_ast_build_ast_from_schedule@Base 0.11 + isl_ast_build_call_from_executed@Base 0.11 + isl_ast_build_call_from_multi_pw_aff@Base 0.13 + isl_ast_build_call_from_pw_multi_aff@Base 0.11 + isl_ast_build_clear_local_info@Base 0.11 + isl_ast_build_compute_gist@Base 0.11 + isl_ast_build_compute_gist_aff@Base 0.11 + isl_ast_build_compute_gist_basic_set@Base 0.11 + isl_ast_build_compute_gist_map_domain@Base 0.11 + isl_ast_build_compute_gist_pw_aff@Base 0.11 + isl_ast_build_compute_gist_pw_multi_aff@Base 0.11 + isl_ast_build_copy@Base 0.11 + isl_ast_build_cow@Base 0.11 + isl_ast_build_detect_strides@Base 0.11 + isl_ast_build_dim@Base 0.14 + isl_ast_build_dump@Base 0.11 + isl_ast_build_dup@Base 0.11 + isl_ast_build_eliminate@Base 0.11 + isl_ast_build_eliminate_divs@Base 0.11 + isl_ast_build_eliminate_inner@Base 0.11 + isl_ast_build_expr_from_basic_set@Base 0.11 + isl_ast_build_expr_from_pw_aff@Base 0.11 + isl_ast_build_expr_from_pw_aff_internal@Base 0.11 + isl_ast_build_expr_from_set@Base 0.11 + isl_ast_build_expr_from_set_internal@Base 0.15 + isl_ast_build_extract_isolated@Base 0.15 + isl_ast_build_free@Base 0.11 + isl_ast_build_from_context@Base 0.11 + isl_ast_build_get_ctx@Base 0.11 + isl_ast_build_get_depth@Base 0.11 + isl_ast_build_get_domain@Base 0.11 + isl_ast_build_get_generated@Base 0.14 + isl_ast_build_get_internal2input@Base 0.15 + isl_ast_build_get_isolated@Base 0.15 + isl_ast_build_get_iterator_id@Base 0.11 + isl_ast_build_get_loop_type@Base 0.15 + isl_ast_build_get_offset@Base 0.11 + isl_ast_build_get_option_domain@Base 0.11 + isl_ast_build_get_pending@Base 0.14 + isl_ast_build_get_schedule@Base 0.11 + isl_ast_build_get_schedule_map@Base 0.11 + isl_ast_build_get_schedule_map_multi_aff@Base 0.11 + isl_ast_build_get_schedule_node@Base 0.15 + isl_ast_build_get_schedule_space@Base 0.11 + isl_ast_build_get_separation_class@Base 0.11 + isl_ast_build_get_space@Base 0.11 + isl_ast_build_get_stride@Base 0.11 + isl_ast_build_get_stride_constraint@Base 0.11 + isl_ast_build_get_stride_expansion@Base 0.11 + isl_ast_build_has_affine_value@Base 0.11 + isl_ast_build_has_isolated@Base 0.15 + isl_ast_build_has_schedule_node@Base 0.15 + isl_ast_build_has_stride@Base 0.11 + isl_ast_build_has_value@Base 0.11 + isl_ast_build_include_stride@Base 0.11 + isl_ast_build_increase_depth@Base 0.11 + isl_ast_build_insert_dim@Base 0.11 + isl_ast_build_map_to_iterator@Base 0.11 + isl_ast_build_need_schedule_map@Base 0.11 + isl_ast_build_node_from_schedule@Base 0.15 + isl_ast_build_node_from_schedule_map@Base 0.15 + isl_ast_build_options_involve_depth@Base 0.11 + isl_ast_build_product@Base 0.11 + isl_ast_build_replace_pending_by_guard@Base 0.14 + isl_ast_build_reset_schedule_node@Base 0.15 + isl_ast_build_restrict@Base 0.11 + isl_ast_build_restrict_generated@Base 0.11 + isl_ast_build_restrict_pending@Base 0.11 + isl_ast_build_scale_down@Base 0.11 + isl_ast_build_set_after_each_for@Base 0.11 + isl_ast_build_set_after_each_mark@Base 0.15 + isl_ast_build_set_at_each_domain@Base 0.11 + isl_ast_build_set_before_each_for@Base 0.11 + isl_ast_build_set_before_each_mark@Base 0.15 + isl_ast_build_set_create_leaf@Base 0.11 + isl_ast_build_set_executed@Base 0.11 + isl_ast_build_set_iterators@Base 0.11 + isl_ast_build_set_loop_bounds@Base 0.11 + isl_ast_build_set_options@Base 0.11 + isl_ast_build_set_schedule_node@Base 0.15 + isl_ast_build_set_single_valued@Base 0.11.2 + isl_ast_build_specialize@Base 0.14 + isl_ast_build_substitute_values_union_map_domain@Base 0.12.1 + isl_ast_expr_access@Base 0.13 + isl_ast_expr_add@Base 0.11 + isl_ast_expr_address_of@Base 0.14 + isl_ast_expr_alloc_binary@Base 0.11 + isl_ast_expr_alloc_int_si@Base 0.12.1 + isl_ast_expr_alloc_op@Base 0.11 + isl_ast_expr_alloc_unary@Base 0.14 + isl_ast_expr_and@Base 0.11 + isl_ast_expr_and_then@Base 0.15 + isl_ast_expr_call@Base 0.15 + isl_ast_expr_copy@Base 0.11 + isl_ast_expr_cow@Base 0.11 + isl_ast_expr_div@Base 0.11 + isl_ast_expr_dump@Base 0.11 + isl_ast_expr_dup@Base 0.11 + isl_ast_expr_eq@Base 0.14 + isl_ast_expr_free@Base 0.11 + isl_ast_expr_from_aff@Base 0.11 + isl_ast_expr_from_id@Base 0.11 + isl_ast_expr_from_val@Base 0.12.1 + isl_ast_expr_ge@Base 0.14 + isl_ast_expr_get_ctx@Base 0.11 + isl_ast_expr_get_id@Base 0.11 + isl_ast_expr_get_int@Base 0.11 + isl_ast_expr_get_op_arg@Base 0.11 + isl_ast_expr_get_op_n_arg@Base 0.11 + isl_ast_expr_get_op_type@Base 0.11 + isl_ast_expr_get_type@Base 0.11 + isl_ast_expr_get_val@Base 0.12.1 + isl_ast_expr_gt@Base 0.14 + isl_ast_expr_is_equal@Base 0.13 + isl_ast_expr_le@Base 0.14 + isl_ast_expr_list_add@Base 0.11 + isl_ast_expr_list_alloc@Base 0.11 + isl_ast_expr_list_concat@Base 0.11 + isl_ast_expr_list_copy@Base 0.11 + isl_ast_expr_list_cow@Base 0.11 + isl_ast_expr_list_drop@Base 0.11 + isl_ast_expr_list_dump@Base 0.11 + isl_ast_expr_list_dup@Base 0.11 + isl_ast_expr_list_foreach@Base 0.11 + isl_ast_expr_list_foreach_scc@Base 0.12.1 + isl_ast_expr_list_free@Base 0.11 + isl_ast_expr_list_from_ast_expr@Base 0.11 + isl_ast_expr_list_get_ast_expr@Base 0.11 + isl_ast_expr_list_get_ctx@Base 0.11 + isl_ast_expr_list_insert@Base 0.11 + isl_ast_expr_list_n_ast_expr@Base 0.11 + isl_ast_expr_list_set_ast_expr@Base 0.11 + isl_ast_expr_list_sort@Base 0.12.1 + isl_ast_expr_lt@Base 0.14 + isl_ast_expr_mul@Base 0.11 + isl_ast_expr_neg@Base 0.11 + isl_ast_expr_or@Base 0.11 + isl_ast_expr_or_else@Base 0.15 + isl_ast_expr_pdiv_q@Base 0.15 + isl_ast_expr_pdiv_r@Base 0.15 + isl_ast_expr_set_op_arg@Base 0.11 + isl_ast_expr_sub@Base 0.11 + isl_ast_expr_substitute_ids@Base 0.13 + isl_ast_expr_to_str@Base 0.11 + isl_ast_graft_add_guard@Base 0.11 + isl_ast_graft_alloc@Base 0.11 + isl_ast_graft_alloc_domain@Base 0.11 + isl_ast_graft_alloc_from_children@Base 0.14 + isl_ast_graft_dump@Base 0.11 + isl_ast_graft_enforce@Base 0.11 + isl_ast_graft_free@Base 0.11 + isl_ast_graft_get_ctx@Base 0.11 + isl_ast_graft_get_enforced@Base 0.11 + isl_ast_graft_get_guard@Base 0.11 + isl_ast_graft_get_node@Base 0.11 + isl_ast_graft_insert_for@Base 0.11 + isl_ast_graft_insert_mark@Base 0.15 + isl_ast_graft_list_add@Base 0.11 + isl_ast_graft_list_alloc@Base 0.11 + isl_ast_graft_list_concat@Base 0.11 + isl_ast_graft_list_copy@Base 0.11 + isl_ast_graft_list_cow@Base 0.11 + isl_ast_graft_list_drop@Base 0.11 + isl_ast_graft_list_dump@Base 0.11 + isl_ast_graft_list_dup@Base 0.11 + isl_ast_graft_list_extract_hoistable_guard@Base 0.14 + isl_ast_graft_list_extract_shared_enforced@Base 0.14 + isl_ast_graft_list_foreach@Base 0.11 + isl_ast_graft_list_foreach_scc@Base 0.12.1 + isl_ast_graft_list_free@Base 0.11 + isl_ast_graft_list_from_ast_graft@Base 0.11 + isl_ast_graft_list_fuse@Base 0.11 + isl_ast_graft_list_get_ast_graft@Base 0.11 + isl_ast_graft_list_get_ctx@Base 0.11 + isl_ast_graft_list_gist_guards@Base 0.14 + isl_ast_graft_list_insert@Base 0.11 + isl_ast_graft_list_insert_pending_guard_nodes@Base 0.15 + isl_ast_graft_list_merge@Base 0.11 + isl_ast_graft_list_n_ast_graft@Base 0.11 + isl_ast_graft_list_preimage_multi_aff@Base 0.11 + isl_ast_graft_list_set_ast_graft@Base 0.11 + isl_ast_graft_list_sort@Base 0.11 + isl_ast_graft_list_sort_guard@Base 0.12.1 + isl_ast_graft_list_unembed@Base 0.11 + isl_ast_graft_preimage_multi_aff@Base 0.11 + isl_ast_graft_set_enforced@Base 0.11 + isl_ast_graft_to_str@Base 0.11 + isl_ast_graft_unembed@Base 0.11 + isl_ast_node_alloc@Base 0.11 + isl_ast_node_alloc_block@Base 0.11 + isl_ast_node_alloc_for@Base 0.11 + isl_ast_node_alloc_if@Base 0.11 + isl_ast_node_alloc_mark@Base 0.15 + isl_ast_node_alloc_user@Base 0.11 + isl_ast_node_block_get_children@Base 0.11 + isl_ast_node_copy@Base 0.11 + isl_ast_node_cow@Base 0.11 + isl_ast_node_dump@Base 0.11 + isl_ast_node_dup@Base 0.11 + isl_ast_node_for_get_body@Base 0.11 + isl_ast_node_for_get_cond@Base 0.11 + isl_ast_node_for_get_inc@Base 0.11 + isl_ast_node_for_get_init@Base 0.11 + isl_ast_node_for_get_iterator@Base 0.11 + isl_ast_node_for_is_degenerate@Base 0.11 + isl_ast_node_for_mark_degenerate@Base 0.11 + isl_ast_node_for_print@Base 0.11 + isl_ast_node_for_set_body@Base 0.11 + isl_ast_node_foreach_ast_op_type@Base 0.11 + isl_ast_node_free@Base 0.11 + isl_ast_node_from_ast_node_list@Base 0.11 + isl_ast_node_from_graft_list@Base 0.11 + isl_ast_node_get_annotation@Base 0.11 + isl_ast_node_get_ctx@Base 0.11 + isl_ast_node_get_type@Base 0.11 + isl_ast_node_if_get_cond@Base 0.11 + isl_ast_node_if_get_else@Base 0.11 + isl_ast_node_if_get_then@Base 0.11 + isl_ast_node_if_has_else@Base 0.11 + isl_ast_node_if_print@Base 0.11 + isl_ast_node_if_set_then@Base 0.11 + isl_ast_node_list_add@Base 0.11 + isl_ast_node_list_alloc@Base 0.11 + isl_ast_node_list_concat@Base 0.11 + isl_ast_node_list_copy@Base 0.11 + isl_ast_node_list_cow@Base 0.11 + isl_ast_node_list_drop@Base 0.11 + isl_ast_node_list_dump@Base 0.11 + isl_ast_node_list_dup@Base 0.11 + isl_ast_node_list_foreach@Base 0.11 + isl_ast_node_list_foreach_scc@Base 0.12.1 + isl_ast_node_list_free@Base 0.11 + isl_ast_node_list_from_ast_node@Base 0.11 + isl_ast_node_list_get_ast_node@Base 0.11 + isl_ast_node_list_get_ctx@Base 0.11 + isl_ast_node_list_insert@Base 0.11 + isl_ast_node_list_n_ast_node@Base 0.11 + isl_ast_node_list_print@Base 0.11 + isl_ast_node_list_set_ast_node@Base 0.11 + isl_ast_node_list_sort@Base 0.12.1 + isl_ast_node_mark_get_id@Base 0.15 + isl_ast_node_mark_get_node@Base 0.15 + isl_ast_node_print@Base 0.11 + isl_ast_node_print_macros@Base 0.11 + isl_ast_node_set_annotation@Base 0.11 + isl_ast_node_to_str@Base 0.11 + isl_ast_node_user_get_expr@Base 0.11 + isl_ast_op_type_print_macro@Base 0.11 + isl_ast_print_options_alloc@Base 0.11 + isl_ast_print_options_copy@Base 0.11 + isl_ast_print_options_cow@Base 0.11 + isl_ast_print_options_dup@Base 0.11 + isl_ast_print_options_free@Base 0.11 + isl_ast_print_options_get_ctx@Base 0.11 + isl_ast_print_options_set_print_for@Base 0.11 + isl_ast_print_options_set_print_user@Base 0.11 + isl_band_alloc@Base 0.10 + isl_band_copy@Base 0.10 + isl_band_dump@Base 0.10 + isl_band_dup@Base 0.10 + isl_band_free@Base 0.10 + isl_band_get_children@Base 0.10 + isl_band_get_ctx@Base 0.10 + isl_band_get_partial_schedule@Base 0.10 + isl_band_get_partial_schedule_union_pw_multi_aff@Base 0.10 + isl_band_get_prefix_schedule@Base 0.10 + isl_band_get_suffix_schedule@Base 0.10 + isl_band_get_suffix_schedule_union_pw_multi_aff@Base 0.10 + isl_band_has_children@Base 0.10 + isl_band_list_add@Base 0.10 + isl_band_list_alloc@Base 0.10 + isl_band_list_concat@Base 0.10 + isl_band_list_copy@Base 0.10 + isl_band_list_cow@Base 0.11 + isl_band_list_drop@Base 0.11 + isl_band_list_dump@Base 0.10 + isl_band_list_dup@Base 0.10 + isl_band_list_foreach@Base 0.10 + isl_band_list_foreach_band@Base 0.10 + isl_band_list_foreach_scc@Base 0.12.1 + isl_band_list_free@Base 0.10 + isl_band_list_from_band@Base 0.10 + isl_band_list_get_band@Base 0.10 + isl_band_list_get_ctx@Base 0.10 + isl_band_list_get_suffix_schedule@Base 0.10 + isl_band_list_get_suffix_schedule_union_pw_multi_aff@Base 0.10 + isl_band_list_insert@Base 0.11 + isl_band_list_n_band@Base 0.10 + isl_band_list_set_band@Base 0.11 + isl_band_list_sort@Base 0.12.1 + isl_band_member_is_coincident@Base 0.13 + isl_band_n_member@Base 0.10 + isl_band_split@Base 0.12.1 + isl_band_tile@Base 0.10 + isl_band_to_str@Base 0.10 + isl_basic_map_add_constraint@Base 0.10 + isl_basic_map_add_constraints_dim_map@Base 0.10 + isl_basic_map_add_dims@Base 0.15 + isl_basic_map_add_div_constraint@Base 0.12.2 + isl_basic_map_add_div_constraints@Base 0.10 + isl_basic_map_add_div_constraints_var@Base 0.10 + isl_basic_map_add_eq@Base 0.10 + isl_basic_map_add_ineq@Base 0.10 + isl_basic_map_add_known_div_constraints@Base 0.14 + isl_basic_map_affine_hull@Base 0.10 + isl_basic_map_align_divs@Base 0.10 + isl_basic_map_align_params@Base 0.11 + isl_basic_map_alloc@Base 0.10 + isl_basic_map_alloc_div@Base 0.10 + isl_basic_map_alloc_equality@Base 0.10 + isl_basic_map_alloc_inequality@Base 0.10 + isl_basic_map_alloc_space@Base 0.10 + isl_basic_map_apply_domain@Base 0.10 + isl_basic_map_apply_range@Base 0.10 + isl_basic_map_can_curry@Base 0.10 + isl_basic_map_can_uncurry@Base 0.11 + isl_basic_map_can_zip@Base 0.10 + isl_basic_map_compatible_domain@Base 0.10 + isl_basic_map_compatible_range@Base 0.10 + isl_basic_map_compute_divs@Base 0.10 + isl_basic_map_constraint@Base 0.10 + isl_basic_map_constraint_is_redundant@Base 0.10 + isl_basic_map_contains@Base 0.10 + isl_basic_map_contains_point@Base 0.10 + isl_basic_map_copy@Base 0.10 + isl_basic_map_cow@Base 0.10 + isl_basic_map_curry@Base 0.10 + isl_basic_map_deltas@Base 0.10 + isl_basic_map_deltas_map@Base 0.10 + isl_basic_map_detect_equalities@Base 0.10 + isl_basic_map_detect_inequality_pairs@Base 0.15 + isl_basic_map_dim@Base 0.10 + isl_basic_map_dim_has_lower_bound@Base 0.10 + isl_basic_map_dim_has_upper_bound@Base 0.10 + isl_basic_map_dim_is_bounded@Base 0.10 + isl_basic_map_divs_known@Base 0.10 + isl_basic_map_domain@Base 0.10 + isl_basic_map_domain_map@Base 0.10 + isl_basic_map_domain_product@Base 0.10 + isl_basic_map_drop@Base 0.10 + isl_basic_map_drop_constraints_involving_dims@Base 0.11 + isl_basic_map_drop_constraints_not_involving_dims@Base 0.11 + isl_basic_map_drop_equality@Base 0.10 + isl_basic_map_drop_inequality@Base 0.10 + isl_basic_map_drop_inputs@Base 0.10 + isl_basic_map_drop_redundant_divs@Base 0.10 + isl_basic_map_dump@Base 0.10 + isl_basic_map_dup@Base 0.10 + isl_basic_map_eliminate@Base 0.10 + isl_basic_map_eliminate_vars@Base 0.10 + isl_basic_map_empty@Base 0.10 + isl_basic_map_equal@Base 0.10 + isl_basic_map_equalities_matrix@Base 0.10 + isl_basic_map_equate@Base 0.10 + isl_basic_map_extend@Base 0.10 + isl_basic_map_extend_constraints@Base 0.10 + isl_basic_map_extend_space@Base 0.10 + isl_basic_map_finalize@Base 0.10 + isl_basic_map_find_dim_by_name@Base 0.15 + isl_basic_map_fix@Base 0.10 + isl_basic_map_fix_input_si@Base 0.10 + isl_basic_map_fix_si@Base 0.10 + isl_basic_map_fix_val@Base 0.12.1 + isl_basic_map_flat_product@Base 0.10 + isl_basic_map_flat_range_product@Base 0.10 + isl_basic_map_flatten@Base 0.10 + isl_basic_map_flatten_domain@Base 0.10 + isl_basic_map_flatten_range@Base 0.10 + isl_basic_map_floordiv@Base 0.10 + isl_basic_map_foreach_constraint@Base 0.10 + isl_basic_map_foreach_lexopt@Base 0.10 + isl_basic_map_free@Base 0.10 + isl_basic_map_free_div@Base 0.10 + isl_basic_map_free_equality@Base 0.10 + isl_basic_map_free_inequality@Base 0.10 + isl_basic_map_from_aff@Base 0.10 + isl_basic_map_from_aff_list@Base 0.10 + isl_basic_map_from_basic_set@Base 0.10 + isl_basic_map_from_constraint@Base 0.10 + isl_basic_map_from_constraint_matrices@Base 0.10 + isl_basic_map_from_domain@Base 0.10 + isl_basic_map_from_domain_and_range@Base 0.10 + isl_basic_map_from_local_space@Base 0.10 + isl_basic_map_from_multi_aff@Base 0.10 + isl_basic_map_from_qpolynomial@Base 0.10 + isl_basic_map_from_range@Base 0.10 + isl_basic_map_gauss@Base 0.10 + isl_basic_map_get_constraint_list@Base 0.14 + isl_basic_map_get_ctx@Base 0.10 + isl_basic_map_get_dim_name@Base 0.10 + isl_basic_map_get_div@Base 0.10 + isl_basic_map_get_divs@Base 0.10 + isl_basic_map_get_hash@Base 0.10 + isl_basic_map_get_local_space@Base 0.10 + isl_basic_map_get_space@Base 0.10 + isl_basic_map_get_tuple_name@Base 0.10 + isl_basic_map_gist@Base 0.10 + isl_basic_map_gist_domain@Base 0.15 + isl_basic_map_has_defining_equality@Base 0.10 + isl_basic_map_has_dim_id@Base 0.10 + isl_basic_map_has_rational@Base 0.11 + isl_basic_map_identity@Base 0.10 + isl_basic_map_image_is_bounded@Base 0.10 + isl_basic_map_implicit_equalities@Base 0.10 + isl_basic_map_inequalities_matrix@Base 0.10 + isl_basic_map_inequality_to_equality@Base 0.10 + isl_basic_map_insert_dims@Base 0.11 + isl_basic_map_intersect@Base 0.10 + isl_basic_map_intersect_domain@Base 0.10 + isl_basic_map_intersect_range@Base 0.10 + isl_basic_map_involves_dims@Base 0.10 + isl_basic_map_is_disjoint@Base 0.13 + isl_basic_map_is_div_constraint@Base 0.10 + isl_basic_map_is_empty@Base 0.10 + isl_basic_map_is_equal@Base 0.10 + isl_basic_map_is_rational@Base 0.10 + isl_basic_map_is_set@Base 0.10 + isl_basic_map_is_single_valued@Base 0.10 + isl_basic_map_is_strict_subset@Base 0.10 + isl_basic_map_is_subset@Base 0.10 + isl_basic_map_is_universe@Base 0.10 + isl_basic_map_less_at@Base 0.10 + isl_basic_map_less_or_equal_at@Base 0.10 + isl_basic_map_lexmax@Base 0.10 + isl_basic_map_lexmin@Base 0.10 + isl_basic_map_lexmin_pw_multi_aff@Base 0.10 + isl_basic_map_lexopt@Base 0.10 + isl_basic_map_lexopt_pw_multi_aff@Base 0.10 + isl_basic_map_list_add@Base 0.15 + isl_basic_map_list_align_divs_to_basic_map@Base 0.15 + isl_basic_map_list_alloc@Base 0.15 + isl_basic_map_list_concat@Base 0.15 + isl_basic_map_list_copy@Base 0.15 + isl_basic_map_list_cow@Base 0.15 + isl_basic_map_list_drop@Base 0.15 + isl_basic_map_list_dump@Base 0.15 + isl_basic_map_list_dup@Base 0.15 + isl_basic_map_list_foreach@Base 0.15 + isl_basic_map_list_foreach_scc@Base 0.15 + isl_basic_map_list_free@Base 0.15 + isl_basic_map_list_from_basic_map@Base 0.15 + isl_basic_map_list_get_basic_map@Base 0.15 + isl_basic_map_list_get_ctx@Base 0.15 + isl_basic_map_list_insert@Base 0.15 + isl_basic_map_list_intersect@Base 0.15 + isl_basic_map_list_n_basic_map@Base 0.15 + isl_basic_map_list_set_basic_map@Base 0.15 + isl_basic_map_list_sort@Base 0.15 + isl_basic_map_list_underlying_set@Base 0.15 + isl_basic_map_lower_bound_si@Base 0.10 + isl_basic_map_may_be_set@Base 0.10 + isl_basic_map_more_at@Base 0.10 + isl_basic_map_more_or_equal_at@Base 0.10 + isl_basic_map_move_dims@Base 0.10 + isl_basic_map_n_constraint@Base 0.14 + isl_basic_map_n_div@Base 0.10 + isl_basic_map_n_in@Base 0.10 + isl_basic_map_n_out@Base 0.10 + isl_basic_map_n_param@Base 0.10 + isl_basic_map_nat_universe@Base 0.10 + isl_basic_map_neg@Base 0.10 + isl_basic_map_normalize@Base 0.10 + isl_basic_map_normalize_constraints@Base 0.10 + isl_basic_map_offset@Base 0.10 + isl_basic_map_order_divs@Base 0.10 + isl_basic_map_order_ge@Base 0.11 + isl_basic_map_order_gt@Base 0.12.1 + isl_basic_map_output_defining_equality@Base 0.14 + isl_basic_map_overlying_set@Base 0.10 + isl_basic_map_partial_lexmax@Base 0.10 + isl_basic_map_partial_lexmax_pw_multi_aff@Base 0.10 + isl_basic_map_partial_lexmin@Base 0.10 + isl_basic_map_partial_lexmin_pw_multi_aff@Base 0.10 + isl_basic_map_partial_lexopt_pw_multi_aff@Base 0.10 + isl_basic_map_plain_affine_hull@Base 0.15 + isl_basic_map_plain_cmp@Base 0.10 + isl_basic_map_plain_get_val_if_fixed@Base 0.12.1 + isl_basic_map_plain_is_disjoint@Base 0.10 + isl_basic_map_plain_is_empty@Base 0.10 + isl_basic_map_plain_is_equal@Base 0.10 + isl_basic_map_plain_is_fixed@Base 0.10 + isl_basic_map_plain_is_single_valued@Base 0.10 + isl_basic_map_plain_is_singleton@Base 0.10 + isl_basic_map_preimage_domain_multi_aff@Base 0.13 + isl_basic_map_preimage_multi_aff@Base 0.12.1 + isl_basic_map_preimage_range_multi_aff@Base 0.13 + isl_basic_map_print_internal@Base 0.10 + isl_basic_map_product@Base 0.10 + isl_basic_map_project_out@Base 0.10 + isl_basic_map_range@Base 0.10 + isl_basic_map_range_map@Base 0.10 + isl_basic_map_range_product@Base 0.10 + isl_basic_map_read_from_file@Base 0.10 + isl_basic_map_read_from_str@Base 0.10 + isl_basic_map_realign@Base 0.10 + isl_basic_map_reduce_coefficients@Base 0.15 + isl_basic_map_remove_dims@Base 0.10 + isl_basic_map_remove_divs@Base 0.10 + isl_basic_map_remove_divs_involving_dims@Base 0.10 + isl_basic_map_remove_duplicate_constraints@Base 0.14 + isl_basic_map_remove_redundancies@Base 0.10 + isl_basic_map_remove_unknown_divs@Base 0.10 + isl_basic_map_reset@Base 0.10 + isl_basic_map_reset_space@Base 0.10 + isl_basic_map_reverse@Base 0.10 + isl_basic_map_sample@Base 0.10 + isl_basic_map_set_dim_name@Base 0.10 + isl_basic_map_set_rational@Base 0.10 + isl_basic_map_set_to_empty@Base 0.10 + isl_basic_map_set_tuple_id@Base 0.13 + isl_basic_map_set_tuple_name@Base 0.10 + isl_basic_map_shift_div@Base 0.15 + isl_basic_map_simplify@Base 0.10 + isl_basic_map_solve_lp@Base 0.10 + isl_basic_map_sort_divs@Base 0.10 + isl_basic_map_sum@Base 0.10 + isl_basic_map_swap_div@Base 0.10 + isl_basic_map_to_str@Base 0.10 + isl_basic_map_total_dim@Base 0.10 + isl_basic_map_uncurry@Base 0.11 + isl_basic_map_underlying_set@Base 0.10 + isl_basic_map_union@Base 0.10 + isl_basic_map_universe@Base 0.10 + isl_basic_map_update_from_tab@Base 0.10 + isl_basic_map_upper_bound_si@Base 0.11 + isl_basic_map_wrap@Base 0.10 + isl_basic_map_zip@Base 0.10 + isl_basic_set_add@Base 0.10 + isl_basic_set_add_constraint@Base 0.10 + isl_basic_set_add_constraints@Base 0.10 + isl_basic_set_add_constraints_dim_map@Base 0.10 + isl_basic_set_add_dims@Base 0.11 + isl_basic_set_add_div_constraints@Base 0.11 + isl_basic_set_add_div_constraints_var@Base 0.10 + isl_basic_set_add_eq@Base 0.10 + isl_basic_set_add_ineq@Base 0.10 + isl_basic_set_affine_hull@Base 0.10 + isl_basic_set_align_divs@Base 0.10 + isl_basic_set_align_params@Base 0.11 + isl_basic_set_alloc@Base 0.10 + isl_basic_set_alloc_div@Base 0.10 + isl_basic_set_alloc_equality@Base 0.10 + isl_basic_set_alloc_inequality@Base 0.10 + isl_basic_set_alloc_space@Base 0.10 + isl_basic_set_apply@Base 0.10 + isl_basic_set_box_from_points@Base 0.10 + isl_basic_set_coefficients@Base 0.10 + isl_basic_set_compare_at@Base 0.10 + isl_basic_set_compute_divs@Base 0.10 + isl_basic_set_compute_vertices@Base 0.10 + isl_basic_set_constraint@Base 0.10 + isl_basic_set_constraint_is_redundant@Base 0.10 + isl_basic_set_contains@Base 0.10 + isl_basic_set_copy@Base 0.10 + isl_basic_set_count_upto@Base 0.10 + isl_basic_set_cow@Base 0.10 + isl_basic_set_detect_equalities@Base 0.10 + isl_basic_set_dim@Base 0.10 + isl_basic_set_dim_is_unique@Base 0.10 + isl_basic_set_dim_residue_class@Base 0.10 + isl_basic_set_dims_get_sign@Base 0.10 + isl_basic_set_drop@Base 0.10 + isl_basic_set_drop_constraint@Base 0.10 + isl_basic_set_drop_constraints_involving@Base 0.10 + isl_basic_set_drop_constraints_involving_dims@Base 0.11 + isl_basic_set_drop_constraints_not_involving_dims@Base 0.11 + isl_basic_set_drop_dims@Base 0.10 + isl_basic_set_drop_equality@Base 0.10 + isl_basic_set_drop_inequality@Base 0.10 + isl_basic_set_drop_redundant_divs@Base 0.10 + isl_basic_set_dump@Base 0.10 + isl_basic_set_dup@Base 0.10 + isl_basic_set_eliminate@Base 0.11 + isl_basic_set_eliminate_vars@Base 0.10 + isl_basic_set_empty@Base 0.10 + isl_basic_set_equalities_matrix@Base 0.10 + isl_basic_set_expand_divs@Base 0.10 + isl_basic_set_extend@Base 0.10 + isl_basic_set_extend_constraints@Base 0.10 + isl_basic_set_extend_space@Base 0.10 + isl_basic_set_factorizer@Base 0.10 + isl_basic_set_finalize@Base 0.10 + isl_basic_set_fix@Base 0.10 + isl_basic_set_fix_dim_si@Base 0.10 + isl_basic_set_fix_si@Base 0.10 + isl_basic_set_fix_val@Base 0.12.1 + isl_basic_set_flat_product@Base 0.10 + isl_basic_set_flatten@Base 0.10 + isl_basic_set_follows_at@Base 0.10 + isl_basic_set_foreach_bound_pair@Base 0.10 + isl_basic_set_foreach_constraint@Base 0.10 + isl_basic_set_foreach_lexopt@Base 0.10 + isl_basic_set_free@Base 0.10 + isl_basic_set_free_div@Base 0.10 + isl_basic_set_free_equality@Base 0.10 + isl_basic_set_free_inequality@Base 0.10 + isl_basic_set_from_constraint@Base 0.10 + isl_basic_set_from_constraint_matrices@Base 0.10 + isl_basic_set_from_local_space@Base 0.10 + isl_basic_set_from_params@Base 0.11 + isl_basic_set_from_point@Base 0.10 + isl_basic_set_from_underlying_set@Base 0.10 + isl_basic_set_from_vec@Base 0.10 + isl_basic_set_full_compression@Base 0.10 + isl_basic_set_gauss@Base 0.10 + isl_basic_set_get_constraint_list@Base 0.14 + isl_basic_set_get_ctx@Base 0.10 + isl_basic_set_get_dim_id@Base 0.10 + isl_basic_set_get_dim_name@Base 0.10 + isl_basic_set_get_div@Base 0.10 + isl_basic_set_get_divs@Base 0.12.1 + isl_basic_set_get_hash@Base 0.10 + isl_basic_set_get_local_space@Base 0.10 + isl_basic_set_get_space@Base 0.10 + isl_basic_set_get_tuple_name@Base 0.10 + isl_basic_set_gist@Base 0.10 + isl_basic_set_has_defining_equality@Base 0.10 + isl_basic_set_has_defining_inequalities@Base 0.10 + isl_basic_set_implicit_equalities@Base 0.10 + isl_basic_set_inequalities_matrix@Base 0.10 + isl_basic_set_insert_dims@Base 0.11 + isl_basic_set_intersect@Base 0.10 + isl_basic_set_intersect_params@Base 0.10 + isl_basic_set_interval@Base 0.10 + isl_basic_set_involves_dims@Base 0.10 + isl_basic_set_is_bounded@Base 0.10 + isl_basic_set_is_box@Base 0.10 + isl_basic_set_is_disjoint@Base 0.13 + isl_basic_set_is_div_constraint@Base 0.10 + isl_basic_set_is_empty@Base 0.10 + isl_basic_set_is_equal@Base 0.10 + isl_basic_set_is_params@Base 0.10 + isl_basic_set_is_rational@Base 0.10 + isl_basic_set_is_subset@Base 0.10 + isl_basic_set_is_universe@Base 0.10 + isl_basic_set_is_wrapping@Base 0.10 + isl_basic_set_lexmax@Base 0.10 + isl_basic_set_lexmin@Base 0.10 + isl_basic_set_lift@Base 0.10 + isl_basic_set_lineality_space@Base 0.10 + isl_basic_set_list_add@Base 0.10 + isl_basic_set_list_alloc@Base 0.10 + isl_basic_set_list_concat@Base 0.10 + isl_basic_set_list_copy@Base 0.10 + isl_basic_set_list_cow@Base 0.11 + isl_basic_set_list_drop@Base 0.11 + isl_basic_set_list_dump@Base 0.10 + isl_basic_set_list_dup@Base 0.10 + isl_basic_set_list_foreach@Base 0.10 + isl_basic_set_list_foreach_scc@Base 0.12.1 + isl_basic_set_list_free@Base 0.10 + isl_basic_set_list_from_basic_set@Base 0.10 + isl_basic_set_list_get_basic_set@Base 0.10 + isl_basic_set_list_get_ctx@Base 0.10 + isl_basic_set_list_insert@Base 0.11 + isl_basic_set_list_intersect@Base 0.14 + isl_basic_set_list_n_basic_set@Base 0.10 + isl_basic_set_list_product@Base 0.10 + isl_basic_set_list_set_basic_set@Base 0.11 + isl_basic_set_list_sort@Base 0.12.1 + isl_basic_set_lower_bound_dim@Base 0.10 + isl_basic_set_max@Base 0.10 + isl_basic_set_max_lp_val@Base 0.12.1 + isl_basic_set_max_val@Base 0.12.1 + isl_basic_set_min_lp_val@Base 0.12.1 + isl_basic_set_move_dims@Base 0.10 + isl_basic_set_multiplicative_call@Base 0.10 + isl_basic_set_n_constraint@Base 0.10 + isl_basic_set_n_dim@Base 0.10 + isl_basic_set_n_param@Base 0.10 + isl_basic_set_nat_universe@Base 0.10 + isl_basic_set_neg@Base 0.10 + isl_basic_set_normalize@Base 0.10 + isl_basic_set_normalize_constraints@Base 0.10 + isl_basic_set_offset@Base 0.10 + isl_basic_set_opt@Base 0.10 + isl_basic_set_opt_val@Base 0.12.1 + isl_basic_set_order_divs@Base 0.10 + isl_basic_set_parameter_compression@Base 0.10 + isl_basic_set_params@Base 0.10 + isl_basic_set_partial_lexmax@Base 0.10 + isl_basic_set_partial_lexmax_pw_multi_aff@Base 0.10 + isl_basic_set_partial_lexmin@Base 0.10 + isl_basic_set_partial_lexmin_pw_multi_aff@Base 0.10 + isl_basic_set_plain_cmp@Base 0.10 + isl_basic_set_plain_dim_has_fixed_lower_bound@Base 0.10 + isl_basic_set_plain_dim_is_fixed@Base 0.10 + isl_basic_set_plain_is_disjoint@Base 0.10 + isl_basic_set_plain_is_empty@Base 0.10 + isl_basic_set_plain_is_equal@Base 0.10 + isl_basic_set_positive_orthant@Base 0.10 + isl_basic_set_preimage@Base 0.10 + isl_basic_set_preimage_multi_aff@Base 0.11 + isl_basic_set_print_internal@Base 0.10 + isl_basic_set_project_out@Base 0.10 + isl_basic_set_read_from_file@Base 0.10 + isl_basic_set_read_from_str@Base 0.10 + isl_basic_set_recession_cone@Base 0.10 + isl_basic_set_reduced_basis@Base 0.10 + isl_basic_set_remove_dims@Base 0.10 + isl_basic_set_remove_divs@Base 0.10 + isl_basic_set_remove_divs_involving_dims@Base 0.11 + isl_basic_set_remove_equalities@Base 0.10 + isl_basic_set_remove_redundancies@Base 0.10 + isl_basic_set_remove_unknown_divs@Base 0.11 + isl_basic_set_reset_space@Base 0.10 + isl_basic_set_sample@Base 0.10 + isl_basic_set_sample_bounded@Base 0.10 + isl_basic_set_sample_point@Base 0.10 + isl_basic_set_sample_vec@Base 0.10 + isl_basic_set_sample_with_cone@Base 0.10 + isl_basic_set_scan@Base 0.10 + isl_basic_set_set_dim_name@Base 0.10 + isl_basic_set_set_integral@Base 0.10 + isl_basic_set_set_rational@Base 0.10 + isl_basic_set_set_to_empty@Base 0.10 + isl_basic_set_set_tuple_id@Base 0.13 + isl_basic_set_set_tuple_name@Base 0.10 + isl_basic_set_simplify@Base 0.10 + isl_basic_set_size@Base 0.10 + isl_basic_set_solutions@Base 0.10 + isl_basic_set_solve_ilp@Base 0.10 + isl_basic_set_solve_lp@Base 0.10 + isl_basic_set_sort_constraints@Base 0.10 + isl_basic_set_substitute@Base 0.10 + isl_basic_set_to_str@Base 0.10 + isl_basic_set_total_dim@Base 0.10 + isl_basic_set_transform_dims@Base 0.10 + isl_basic_set_underlying_set@Base 0.10 + isl_basic_set_union@Base 0.10 + isl_basic_set_universe@Base 0.10 + isl_basic_set_unwrap@Base 0.10 + isl_basic_set_update_from_tab@Base 0.10 + isl_basic_set_variable_compression@Base 0.10 + isl_basic_set_vars_get_sign@Base 0.10 + isl_blk_alloc@Base 0.10 + isl_blk_clear_cache@Base 0.10 + isl_blk_empty@Base 0.10 + isl_blk_extend@Base 0.10 + isl_blk_free@Base 0.10 + isl_blk_is_error@Base 0.10 + isl_calloc_or_die@Base 0.13 + isl_cell_foreach_simplex@Base 0.10 + isl_cell_foreach_vertex@Base 0.10 + isl_cell_free@Base 0.10 + isl_cell_get_ctx@Base 0.10 + isl_cell_get_domain@Base 0.10 + isl_closure_choice@Base 0.10 + isl_constraint_alloc@Base 0.10 + isl_constraint_alloc_equality@Base 0.15 + isl_constraint_alloc_inequality@Base 0.15 + isl_constraint_alloc_vec@Base 0.10 + isl_constraint_cmp_last_non_zero@Base 0.14 + isl_constraint_copy@Base 0.10 + isl_constraint_cow@Base 0.10 + isl_constraint_dim@Base 0.10 + isl_constraint_dump@Base 0.10 + isl_constraint_dup@Base 0.10 + isl_constraint_free@Base 0.10 + isl_constraint_get_aff@Base 0.10 + isl_constraint_get_bound@Base 0.10 + isl_constraint_get_coefficient@Base 0.10 + isl_constraint_get_coefficient_val@Base 0.12.1 + isl_constraint_get_constant@Base 0.10 + isl_constraint_get_constant_val@Base 0.12.1 + isl_constraint_get_ctx@Base 0.10 + isl_constraint_get_dim_name@Base 0.10 + isl_constraint_get_div@Base 0.10 + isl_constraint_get_local_space@Base 0.10 + isl_constraint_get_space@Base 0.10 + isl_constraint_involves_dims@Base 0.10 + isl_constraint_is_div_constraint@Base 0.10 + isl_constraint_is_equal@Base 0.10 + isl_constraint_is_equality@Base 0.10 + isl_constraint_is_lower_bound@Base 0.10 + isl_constraint_is_upper_bound@Base 0.10 + isl_constraint_list_add@Base 0.11 + isl_constraint_list_alloc@Base 0.11 + isl_constraint_list_concat@Base 0.11 + isl_constraint_list_copy@Base 0.11 + isl_constraint_list_cow@Base 0.11 + isl_constraint_list_drop@Base 0.11 + isl_constraint_list_dump@Base 0.11 + isl_constraint_list_dup@Base 0.11 + isl_constraint_list_foreach@Base 0.11 + isl_constraint_list_foreach_scc@Base 0.12.1 + isl_constraint_list_free@Base 0.11 + isl_constraint_list_from_constraint@Base 0.11 + isl_constraint_list_get_constraint@Base 0.11 + isl_constraint_list_get_ctx@Base 0.11 + isl_constraint_list_insert@Base 0.11 + isl_constraint_list_n_constraint@Base 0.11 + isl_constraint_list_set_constraint@Base 0.11 + isl_constraint_list_sort@Base 0.12.1 + isl_constraint_negate@Base 0.10 + isl_constraint_plain_cmp@Base 0.14 + isl_constraint_set_coefficient@Base 0.10 + isl_constraint_set_coefficient_si@Base 0.10 + isl_constraint_set_coefficient_val@Base 0.12.1 + isl_constraint_set_constant@Base 0.10 + isl_constraint_set_constant_si@Base 0.10 + isl_constraint_set_constant_val@Base 0.12.1 + isl_constraint_to_str@Base 0.10 + isl_context_gbr_op@Base 0.10 + isl_context_lex_op@Base 0.10 + isl_ctx_abort@Base 0.10 + isl_ctx_aborted@Base 0.10 + isl_ctx_alloc@Base 0.10 + isl_ctx_alloc_with_options@Base 0.10 + isl_ctx_deref@Base 0.10 + isl_ctx_free@Base 0.10 + isl_ctx_get_max_operations@Base 0.13 + isl_ctx_last_error@Base 0.10 + isl_ctx_next_operation@Base 0.13 + isl_ctx_options@Base 0.10 + isl_ctx_parse_options@Base 0.10 + isl_ctx_peek_isl_options@Base 0.10 + isl_ctx_peek_options@Base 0.10 + isl_ctx_ref@Base 0.10 + isl_ctx_reset_error@Base 0.10 + isl_ctx_reset_operations@Base 0.13 + isl_ctx_resume@Base 0.10 + isl_ctx_set_error@Base 0.10 + isl_ctx_set_max_operations@Base 0.13 + isl_dim_map_alloc@Base 0.10 + isl_dim_map_dim@Base 0.10 + isl_dim_map_dim_range@Base 0.10 + isl_dim_map_div@Base 0.10 + isl_dim_map_dump@Base 0.10 + isl_dim_map_extend@Base 0.10 + isl_dim_map_from_reordering@Base 0.10 + isl_dim_map_range@Base 0.10 + isl_equality_alloc@Base 0.10 + isl_equality_from_aff@Base 0.10 + isl_factorizer_dump@Base 0.10 + isl_factorizer_free@Base 0.10 + isl_factorizer_groups@Base 0.10 + isl_factorizer_identity@Base 0.10 + isl_flow_foreach@Base 0.10 + isl_flow_free@Base 0.10 + isl_flow_get_ctx@Base 0.10 + isl_flow_get_no_source@Base 0.10 + isl_fold_type_negate@Base 0.10 + isl_gbr_choice@Base 0.10 + isl_gmp_hash@Base 0.10 + isl_handle_error@Base 0.10 + isl_hash_id@Base 0.10 + isl_hash_mem@Base 0.10 + isl_hash_string@Base 0.10 + isl_hash_table_alloc@Base 0.10 + isl_hash_table_clear@Base 0.10 + isl_hash_table_find@Base 0.10 + isl_hash_table_foreach@Base 0.10 + isl_hash_table_free@Base 0.10 + isl_hash_table_init@Base 0.10 + isl_hash_table_remove@Base 0.10 + isl_id_alloc@Base 0.10 + isl_id_cmp@Base 0.13 + isl_id_copy@Base 0.10 + isl_id_dump@Base 0.10 + isl_id_free@Base 0.10 + isl_id_get_ctx@Base 0.10 + isl_id_get_hash@Base 0.13 + isl_id_get_name@Base 0.10 + isl_id_get_user@Base 0.10 + isl_id_list_add@Base 0.11 + isl_id_list_alloc@Base 0.11 + isl_id_list_concat@Base 0.11 + isl_id_list_copy@Base 0.11 + isl_id_list_cow@Base 0.11 + isl_id_list_drop@Base 0.11 + isl_id_list_dump@Base 0.11 + isl_id_list_dup@Base 0.11 + isl_id_list_foreach@Base 0.11 + isl_id_list_foreach_scc@Base 0.12.1 + isl_id_list_free@Base 0.11 + isl_id_list_from_id@Base 0.11 + isl_id_list_get_ctx@Base 0.11 + isl_id_list_get_id@Base 0.11 + isl_id_list_insert@Base 0.11 + isl_id_list_n_id@Base 0.11 + isl_id_list_set_id@Base 0.11 + isl_id_list_sort@Base 0.12.1 + isl_id_none@Base 0.10 + isl_id_set_free_user@Base 0.11 + isl_id_to_ast_expr_alloc@Base 0.13 + isl_id_to_ast_expr_copy@Base 0.13 + isl_id_to_ast_expr_cow@Base 0.13 + isl_id_to_ast_expr_drop@Base 0.13 + isl_id_to_ast_expr_dump@Base 0.13 + isl_id_to_ast_expr_dup@Base 0.13 + isl_id_to_ast_expr_foreach@Base 0.13 + isl_id_to_ast_expr_free@Base 0.13 + isl_id_to_ast_expr_get@Base 0.13 + isl_id_to_ast_expr_get_ctx@Base 0.13 + isl_id_to_ast_expr_has@Base 0.13 + isl_id_to_ast_expr_set@Base 0.13 + isl_id_to_pw_aff_alloc@Base 0.13 + isl_id_to_pw_aff_copy@Base 0.13 + isl_id_to_pw_aff_cow@Base 0.13 + isl_id_to_pw_aff_drop@Base 0.13 + isl_id_to_pw_aff_dump@Base 0.13 + isl_id_to_pw_aff_dup@Base 0.13 + isl_id_to_pw_aff_foreach@Base 0.13 + isl_id_to_pw_aff_free@Base 0.13 + isl_id_to_pw_aff_get@Base 0.13 + isl_id_to_pw_aff_get_ctx@Base 0.13 + isl_id_to_pw_aff_has@Base 0.13 + isl_id_to_pw_aff_set@Base 0.13 + isl_id_to_str@Base 0.10 + isl_inequality_alloc@Base 0.10 + isl_inequality_from_aff@Base 0.10 + isl_inequality_negate@Base 0.10 + isl_local_space_add_dims@Base 0.10 + isl_local_space_add_div@Base 0.10 + isl_local_space_alloc@Base 0.10 + isl_local_space_alloc_div@Base 0.10 + isl_local_space_cmp@Base 0.13 + isl_local_space_copy@Base 0.10 + isl_local_space_cow@Base 0.10 + isl_local_space_dim@Base 0.10 + isl_local_space_div_is_known@Base 0.13 + isl_local_space_divs_known@Base 0.10 + isl_local_space_domain@Base 0.10 + isl_local_space_drop_dims@Base 0.10 + isl_local_space_dump@Base 0.10 + isl_local_space_dup@Base 0.10 + isl_local_space_find_dim_by_name@Base 0.15 + isl_local_space_flatten_domain@Base 0.13 + isl_local_space_flatten_range@Base 0.13 + isl_local_space_free@Base 0.10 + isl_local_space_from_domain@Base 0.10 + isl_local_space_from_space@Base 0.10 + isl_local_space_get_active@Base 0.10 + isl_local_space_get_ctx@Base 0.10 + isl_local_space_get_dim_id@Base 0.11 + isl_local_space_get_dim_name@Base 0.10 + isl_local_space_get_div@Base 0.10 + isl_local_space_get_space@Base 0.10 + isl_local_space_has_dim_id@Base 0.11 + isl_local_space_has_dim_name@Base 0.10 + isl_local_space_insert_dims@Base 0.10 + isl_local_space_intersect@Base 0.10 + isl_local_space_is_div_constraint@Base 0.10 + isl_local_space_is_equal@Base 0.10 + isl_local_space_is_named_or_nested@Base 0.10 + isl_local_space_is_params@Base 0.15 + isl_local_space_is_set@Base 0.10 + isl_local_space_lift@Base 0.10 + isl_local_space_lifting@Base 0.10 + isl_local_space_move_dims@Base 0.13 + isl_local_space_offset@Base 0.10 + isl_local_space_preimage_multi_aff@Base 0.11 + isl_local_space_range@Base 0.10 + isl_local_space_realign@Base 0.10 + isl_local_space_replace_divs@Base 0.10 + isl_local_space_reset_space@Base 0.10 + isl_local_space_set_dim_id@Base 0.10 + isl_local_space_set_dim_name@Base 0.10 + isl_local_space_set_tuple_id@Base 0.13 + isl_local_space_substitute@Base 0.10 + isl_local_space_substitute_equalities@Base 0.10 + isl_local_space_substitute_seq@Base 0.11 + isl_local_space_swap_div@Base 0.11 + isl_local_space_to_str@Base 0.10 + isl_local_space_wrap@Base 0.15 + isl_malloc_or_die@Base 0.13 + isl_map_add_basic_map@Base 0.10 + isl_map_add_constraint@Base 0.10 + isl_map_add_dims@Base 0.10 + isl_map_affine_hull@Base 0.10 + isl_map_align_divs@Base 0.10 + isl_map_align_divs_to_basic_map_list@Base 0.15 + isl_map_align_params@Base 0.10 + isl_map_align_params_map_map_and@Base 0.10 + isl_map_align_params_map_map_and_test@Base 0.10 + isl_map_alloc@Base 0.10 + isl_map_alloc_space@Base 0.10 + isl_map_apply_domain@Base 0.10 + isl_map_apply_pw_qpolynomial_fold@Base 0.10 + isl_map_apply_range@Base 0.10 + isl_map_can_curry@Base 0.10 + isl_map_can_uncurry@Base 0.11 + isl_map_can_zip@Base 0.10 + isl_map_coalesce@Base 0.10 + isl_map_compatible_domain@Base 0.10 + isl_map_compatible_range@Base 0.10 + isl_map_complement@Base 0.10 + isl_map_compute_divs@Base 0.10 + isl_map_contains_point@Base 0.10 + isl_map_convex_hull@Base 0.10 + isl_map_copy@Base 0.10 + isl_map_copy_basic_map@Base 0.10 + isl_map_cow@Base 0.10 + isl_map_curry@Base 0.10 + isl_map_deltas@Base 0.10 + isl_map_deltas_map@Base 0.10 + isl_map_detect_equalities@Base 0.10 + isl_map_dim@Base 0.10 + isl_map_dim_is_bounded@Base 0.10 + isl_map_dim_max@Base 0.10 + isl_map_domain@Base 0.10 + isl_map_domain_factor_domain@Base 0.15 + isl_map_domain_factor_range@Base 0.15 + isl_map_domain_is_wrapping@Base 0.13 + isl_map_domain_map@Base 0.10 + isl_map_domain_product@Base 0.10 + isl_map_drop@Base 0.10 + isl_map_drop_basic_map@Base 0.10 + isl_map_drop_constraints_involving_dims@Base 0.11 + isl_map_drop_inputs@Base 0.10 + isl_map_drop_redundant_divs@Base 0.10 + isl_map_dump@Base 0.10 + isl_map_dup@Base 0.10 + isl_map_eliminate@Base 0.10 + isl_map_empty@Base 0.10 + isl_map_equate@Base 0.10 + isl_map_factor_domain@Base 0.15 + isl_map_factor_range@Base 0.15 + isl_map_finalize@Base 0.10 + isl_map_find_dim_by_id@Base 0.10 + isl_map_find_dim_by_name@Base 0.10 + isl_map_fix@Base 0.10 + isl_map_fix_input_si@Base 0.10 + isl_map_fix_si@Base 0.10 + isl_map_fix_val@Base 0.12.1 + isl_map_fixed_power@Base 0.10 + isl_map_fixed_power_val@Base 0.12.1 + isl_map_flat_domain_product@Base 0.10 + isl_map_flat_product@Base 0.10 + isl_map_flat_range_product@Base 0.10 + isl_map_flatten@Base 0.10 + isl_map_flatten_domain@Base 0.10 + isl_map_flatten_range@Base 0.10 + isl_map_floordiv@Base 0.10 + isl_map_floordiv_val@Base 0.12.1 + isl_map_foreach_basic_map@Base 0.10 + isl_map_free@Base 0.10 + isl_map_from_aff@Base 0.10 + isl_map_from_basic_map@Base 0.10 + isl_map_from_domain@Base 0.10 + isl_map_from_domain_and_range@Base 0.10 + isl_map_from_multi_aff@Base 0.10 + isl_map_from_multi_pw_aff@Base 0.13 + isl_map_from_pw_aff@Base 0.10 + isl_map_from_pw_multi_aff@Base 0.10 + isl_map_from_range@Base 0.10 + isl_map_from_set@Base 0.10 + isl_map_from_union_map@Base 0.10 + isl_map_get_basic_map_list@Base 0.15 + isl_map_get_ctx@Base 0.10 + isl_map_get_dim_id@Base 0.10 + isl_map_get_dim_name@Base 0.10 + isl_map_get_hash@Base 0.10 + isl_map_get_space@Base 0.10 + isl_map_get_tuple_id@Base 0.10 + isl_map_get_tuple_name@Base 0.10 + isl_map_gist@Base 0.10 + isl_map_gist_basic_map@Base 0.10 + isl_map_gist_domain@Base 0.10 + isl_map_gist_params@Base 0.10 + isl_map_gist_range@Base 0.10 + isl_map_grow@Base 0.10 + isl_map_has_dim_id@Base 0.10 + isl_map_has_dim_name@Base 0.11 + isl_map_has_equal_space@Base 0.10 + isl_map_has_rational@Base 0.11 + isl_map_has_tuple_id@Base 0.10 + isl_map_has_tuple_name@Base 0.11 + isl_map_identity@Base 0.10 + isl_map_implicit_equalities@Base 0.10 + isl_map_inline_foreach_basic_map@Base 0.10 + isl_map_insert_dims@Base 0.10 + isl_map_intersect@Base 0.10 + isl_map_intersect_domain@Base 0.10 + isl_map_intersect_params@Base 0.10 + isl_map_intersect_range@Base 0.10 + isl_map_involves_dims@Base 0.10 + isl_map_is_bijective@Base 0.10 + isl_map_is_disjoint@Base 0.11 + isl_map_is_empty@Base 0.10 + isl_map_is_equal@Base 0.10 + isl_map_is_injective@Base 0.10 + isl_map_is_params@Base 0.10 + isl_map_is_set@Base 0.10 + isl_map_is_single_valued@Base 0.10 + isl_map_is_strict_subset@Base 0.10 + isl_map_is_subset@Base 0.10 + isl_map_is_transitively_closed@Base 0.10 + isl_map_is_translation@Base 0.10 + isl_map_lex_ge@Base 0.10 + isl_map_lex_ge_first@Base 0.10 + isl_map_lex_ge_map@Base 0.10 + isl_map_lex_gt@Base 0.10 + isl_map_lex_gt_first@Base 0.10 + isl_map_lex_gt_map@Base 0.10 + isl_map_lex_le@Base 0.10 + isl_map_lex_le_first@Base 0.10 + isl_map_lex_le_map@Base 0.10 + isl_map_lex_lt@Base 0.10 + isl_map_lex_lt_first@Base 0.10 + isl_map_lex_lt_map@Base 0.10 + isl_map_lexmax@Base 0.10 + isl_map_lexmax_pw_multi_aff@Base 0.11 + isl_map_lexmin@Base 0.10 + isl_map_lexmin_pw_multi_aff@Base 0.11 + isl_map_lexopt@Base 0.10 + isl_map_lexopt_pw_multi_aff@Base 0.11 + isl_map_list_add@Base 0.15 + isl_map_list_alloc@Base 0.15 + isl_map_list_concat@Base 0.15 + isl_map_list_copy@Base 0.15 + isl_map_list_cow@Base 0.15 + isl_map_list_drop@Base 0.15 + isl_map_list_dump@Base 0.15 + isl_map_list_dup@Base 0.15 + isl_map_list_foreach@Base 0.15 + isl_map_list_foreach_scc@Base 0.15 + isl_map_list_free@Base 0.15 + isl_map_list_from_map@Base 0.15 + isl_map_list_get_ctx@Base 0.15 + isl_map_list_get_map@Base 0.15 + isl_map_list_insert@Base 0.15 + isl_map_list_n_map@Base 0.15 + isl_map_list_set_map@Base 0.15 + isl_map_list_sort@Base 0.15 + isl_map_lower_bound@Base 0.10 + isl_map_lower_bound_si@Base 0.10 + isl_map_make_disjoint@Base 0.10 + isl_map_may_be_set@Base 0.10 + isl_map_move_dims@Base 0.10 + isl_map_n_basic_map@Base 0.14 + isl_map_n_in@Base 0.10 + isl_map_n_out@Base 0.10 + isl_map_n_param@Base 0.10 + isl_map_nat_universe@Base 0.10 + isl_map_neg@Base 0.10 + isl_map_normalize@Base 0.10 + isl_map_oppose@Base 0.10 + isl_map_order_divs@Base 0.10 + isl_map_order_ge@Base 0.13 + isl_map_order_gt@Base 0.10 + isl_map_order_le@Base 0.13 + isl_map_order_lt@Base 0.10 + isl_map_params@Base 0.10 + isl_map_partial_lexmax@Base 0.10 + isl_map_partial_lexmin@Base 0.10 + isl_map_plain_get_val_if_fixed@Base 0.12.1 + isl_map_plain_input_is_fixed@Base 0.10 + isl_map_plain_is_disjoint@Base 0.10 + isl_map_plain_is_empty@Base 0.10 + isl_map_plain_is_equal@Base 0.10 + isl_map_plain_is_fixed@Base 0.10 + isl_map_plain_is_injective@Base 0.10 + isl_map_plain_is_single_valued@Base 0.10 + isl_map_plain_is_singleton@Base 0.10 + isl_map_plain_is_universe@Base 0.10 + isl_map_polyhedral_hull@Base 0.10 + isl_map_power@Base 0.10 + isl_map_preimage_domain_multi_aff@Base 0.12.1 + isl_map_preimage_domain_multi_pw_aff@Base 0.13 + isl_map_preimage_domain_pw_multi_aff@Base 0.13 + isl_map_preimage_multi_aff@Base 0.12.1 + isl_map_preimage_multi_pw_aff@Base 0.13 + isl_map_preimage_pw_multi_aff@Base 0.13 + isl_map_preimage_range_multi_aff@Base 0.13 + isl_map_preimage_range_pw_multi_aff@Base 0.13 + isl_map_print_internal@Base 0.10 + isl_map_product@Base 0.10 + isl_map_project_out@Base 0.10 + isl_map_range@Base 0.10 + isl_map_range_factor_domain@Base 0.13 + isl_map_range_factor_range@Base 0.13 + isl_map_range_is_wrapping@Base 0.13 + isl_map_range_map@Base 0.10 + isl_map_range_product@Base 0.10 + isl_map_reaching_path_lengths@Base 0.10 + isl_map_read_from_file@Base 0.10 + isl_map_read_from_str@Base 0.10 + isl_map_realign@Base 0.10 + isl_map_remove_dims@Base 0.10 + isl_map_remove_divs@Base 0.10 + isl_map_remove_divs_involving_dims@Base 0.10 + isl_map_remove_empty_parts@Base 0.10 + isl_map_remove_inputs@Base 0.10 + isl_map_remove_obvious_duplicates@Base 0.14 + isl_map_remove_redundancies@Base 0.10 + isl_map_remove_unknown_divs@Base 0.10 + isl_map_reset@Base 0.10 + isl_map_reset_space@Base 0.10 + isl_map_reset_tuple_id@Base 0.10 + isl_map_reset_user@Base 0.13 + isl_map_reverse@Base 0.10 + isl_map_sample@Base 0.10 + isl_map_set_dim_id@Base 0.10 + isl_map_set_dim_name@Base 0.10 + isl_map_set_rational@Base 0.10 + isl_map_set_tuple_id@Base 0.10 + isl_map_set_tuple_name@Base 0.10 + isl_map_simple_hull@Base 0.10 + isl_map_solve_lp@Base 0.10 + isl_map_sort_divs@Base 0.10 + isl_map_subtract@Base 0.10 + isl_map_subtract_domain@Base 0.10 + isl_map_subtract_range@Base 0.10 + isl_map_sum@Base 0.10 + isl_map_to_basic_set_alloc@Base 0.13 + isl_map_to_basic_set_copy@Base 0.13 + isl_map_to_basic_set_cow@Base 0.13 + isl_map_to_basic_set_drop@Base 0.13 + isl_map_to_basic_set_dump@Base 0.13 + isl_map_to_basic_set_dup@Base 0.13 + isl_map_to_basic_set_foreach@Base 0.13 + isl_map_to_basic_set_free@Base 0.13 + isl_map_to_basic_set_get@Base 0.13 + isl_map_to_basic_set_get_ctx@Base 0.13 + isl_map_to_basic_set_has@Base 0.13 + isl_map_to_basic_set_set@Base 0.13 + isl_map_to_str@Base 0.10 + isl_map_transitive_closure@Base 0.10 + isl_map_uncurry@Base 0.11 + isl_map_underlying_set@Base 0.10 + isl_map_union@Base 0.10 + isl_map_union_disjoint@Base 0.10 + isl_map_universe@Base 0.10 + isl_map_unshifted_simple_hull@Base 0.11 + isl_map_unshifted_simple_hull_from_map_list@Base 0.15 + isl_map_upper_bound@Base 0.10 + isl_map_upper_bound_si@Base 0.10 + isl_map_wrap@Base 0.10 + isl_map_zip@Base 0.10 + isl_mat_add_rows@Base 0.10 + isl_mat_add_zero_cols@Base 0.10 + isl_mat_add_zero_rows@Base 0.10 + isl_mat_aff_direct_sum@Base 0.10 + isl_mat_alloc@Base 0.10 + isl_mat_cmp_div@Base 0.11 + isl_mat_col_add@Base 0.10 + isl_mat_col_combine@Base 0.10 + isl_mat_col_mul@Base 0.10 + isl_mat_col_scale@Base 0.10 + isl_mat_col_submul@Base 0.10 + isl_mat_cols@Base 0.10 + isl_mat_concat@Base 0.10 + isl_mat_copy@Base 0.10 + isl_mat_cow@Base 0.10 + isl_mat_diag@Base 0.10 + isl_mat_diagonal@Base 0.10 + isl_mat_drop_cols@Base 0.10 + isl_mat_drop_rows@Base 0.10 + isl_mat_dump@Base 0.10 + isl_mat_dup@Base 0.10 + isl_mat_extend@Base 0.10 + isl_mat_free@Base 0.10 + isl_mat_from_row_vec@Base 0.10 + isl_mat_gcd@Base 0.10 + isl_mat_get_ctx@Base 0.10 + isl_mat_get_element@Base 0.10 + isl_mat_get_element_val@Base 0.12.1 + isl_mat_get_row@Base 0.14 + isl_mat_identity@Base 0.10 + isl_mat_initial_non_zero_cols@Base 0.10 + isl_mat_insert_cols@Base 0.10 + isl_mat_insert_rows@Base 0.10 + isl_mat_insert_zero_cols@Base 0.10 + isl_mat_insert_zero_rows@Base 0.10 + isl_mat_inverse_product@Base 0.10 + isl_mat_is_equal@Base 0.10 + isl_mat_is_scaled_identity@Base 0.14 + isl_mat_left_hermite@Base 0.10 + isl_mat_lin_to_aff@Base 0.10 + isl_mat_move_cols@Base 0.10 + isl_mat_normalize@Base 0.10 + isl_mat_normalize_row@Base 0.10 + isl_mat_parameter_compression@Base 0.10 + isl_mat_parameter_compression_ext@Base 0.12.1 + isl_mat_print_internal@Base 0.10 + isl_mat_product@Base 0.10 + isl_mat_right_inverse@Base 0.10 + isl_mat_right_kernel@Base 0.10 + isl_mat_rows@Base 0.10 + isl_mat_scale_down@Base 0.10 + isl_mat_scale_down_row@Base 0.10 + isl_mat_set_element@Base 0.10 + isl_mat_set_element_si@Base 0.10 + isl_mat_set_element_val@Base 0.12.1 + isl_mat_sub_alloc6@Base 0.10 + isl_mat_sub_alloc@Base 0.10 + isl_mat_sub_copy@Base 0.10 + isl_mat_sub_neg@Base 0.10 + isl_mat_swap_cols@Base 0.10 + isl_mat_swap_rows@Base 0.10 + isl_mat_transpose@Base 0.10 + isl_mat_unimodular_complete@Base 0.10 + isl_mat_variable_compression@Base 0.10 + isl_mat_vec_concat@Base 0.10 + isl_mat_vec_inverse_product@Base 0.10 + isl_mat_vec_product@Base 0.10 + isl_memrchr@Base 0.10 + isl_merge_divs@Base 0.10 + isl_morph_alloc@Base 0.10 + isl_morph_basic_set@Base 0.10 + isl_morph_compose@Base 0.10 + isl_morph_copy@Base 0.10 + isl_morph_cow@Base 0.10 + isl_morph_dom_dim@Base 0.10 + isl_morph_dom_params@Base 0.10 + isl_morph_dump@Base 0.10 + isl_morph_dup@Base 0.10 + isl_morph_empty@Base 0.10 + isl_morph_free@Base 0.10 + isl_morph_get_ctx@Base 0.14 + isl_morph_get_dom_space@Base 0.14 + isl_morph_get_ran_space@Base 0.10 + isl_morph_get_var_multi_aff@Base 0.14 + isl_morph_identity@Base 0.10 + isl_morph_inverse@Base 0.10 + isl_morph_print_internal@Base 0.10 + isl_morph_ran_dim@Base 0.10 + isl_morph_ran_params@Base 0.10 + isl_morph_remove_dom_dims@Base 0.10 + isl_morph_remove_ran_dims@Base 0.10 + isl_morph_set@Base 0.10 + isl_morph_vec@Base 0.10 + isl_morph_vertices@Base 0.10 + isl_multi_aff_add@Base 0.10 + isl_multi_aff_add_dims@Base 0.11 + isl_multi_aff_add_on_domain@Base 0.10 + isl_multi_aff_align_divs@Base 0.10 + isl_multi_aff_align_params@Base 0.10 + isl_multi_aff_alloc@Base 0.10 + isl_multi_aff_apply_aligned_set@Base 0.15 + isl_multi_aff_copy@Base 0.10 + isl_multi_aff_cow@Base 0.10 + isl_multi_aff_dim@Base 0.10 + isl_multi_aff_domain_map@Base 0.13 + isl_multi_aff_drop_dims@Base 0.10 + isl_multi_aff_dump@Base 0.10 + isl_multi_aff_dup@Base 0.10 + isl_multi_aff_find_dim_by_id@Base 0.13 + isl_multi_aff_find_dim_by_name@Base 0.15 + isl_multi_aff_flat_range_product@Base 0.10 + isl_multi_aff_flatten_domain@Base 0.13 + isl_multi_aff_flatten_range@Base 0.11 + isl_multi_aff_floor@Base 0.13 + isl_multi_aff_free@Base 0.10 + isl_multi_aff_from_aff@Base 0.11 + isl_multi_aff_from_aff_list@Base 0.10 + isl_multi_aff_from_basic_set_equalities@Base 0.13 + isl_multi_aff_from_range@Base 0.13 + isl_multi_aff_get_aff@Base 0.10 + isl_multi_aff_get_ctx@Base 0.10 + isl_multi_aff_get_dim_id@Base 0.13 + isl_multi_aff_get_domain_space@Base 0.10 + isl_multi_aff_get_space@Base 0.10 + isl_multi_aff_get_tuple_id@Base 0.13 + isl_multi_aff_get_tuple_name@Base 0.10 + isl_multi_aff_gist@Base 0.10 + isl_multi_aff_gist_params@Base 0.10 + isl_multi_aff_has_tuple_id@Base 0.13 + isl_multi_aff_identity@Base 0.11 + isl_multi_aff_insert_dims@Base 0.11 + isl_multi_aff_involves_dims@Base 0.13 + isl_multi_aff_is_empty@Base 0.10 + isl_multi_aff_lex_ge_set@Base 0.11 + isl_multi_aff_lex_le_set@Base 0.11 + isl_multi_aff_lift@Base 0.10 + isl_multi_aff_mod_multi_val@Base 0.15 + isl_multi_aff_move_dims@Base 0.13 + isl_multi_aff_multi_val_on_space@Base 0.15 + isl_multi_aff_neg@Base 0.15 + isl_multi_aff_plain_is_equal@Base 0.10 + isl_multi_aff_product@Base 0.11 + isl_multi_aff_product_aligned@Base 0.13 + isl_multi_aff_project_out_map@Base 0.13 + isl_multi_aff_pullback_multi_aff@Base 0.11 + isl_multi_aff_range_factor_domain@Base 0.13 + isl_multi_aff_range_factor_range@Base 0.13 + isl_multi_aff_range_is_wrapping@Base 0.13 + isl_multi_aff_range_map@Base 0.13 + isl_multi_aff_range_product@Base 0.11 + isl_multi_aff_range_splice@Base 0.11 + isl_multi_aff_read_from_str@Base 0.10 + isl_multi_aff_realign_domain@Base 0.10 + isl_multi_aff_reset_domain_space@Base 0.10 + isl_multi_aff_reset_space@Base 0.10 + isl_multi_aff_reset_space_and_domain@Base 0.10 + isl_multi_aff_reset_tuple_id@Base 0.13 + isl_multi_aff_reset_user@Base 0.13 + isl_multi_aff_scale@Base 0.10 + isl_multi_aff_scale_down_multi_val@Base 0.13 + isl_multi_aff_scale_down_val@Base 0.15 + isl_multi_aff_scale_multi_val@Base 0.12.1 + isl_multi_aff_scale_val@Base 0.12.1 + isl_multi_aff_set_aff@Base 0.10 + isl_multi_aff_set_dim_id@Base 0.13 + isl_multi_aff_set_dim_name@Base 0.10 + isl_multi_aff_set_tuple_id@Base 0.10 + isl_multi_aff_set_tuple_name@Base 0.11 + isl_multi_aff_splice@Base 0.11 + isl_multi_aff_sub@Base 0.12.1 + isl_multi_aff_substitute@Base 0.10 + isl_multi_aff_to_str@Base 0.10 + isl_multi_aff_zero@Base 0.10 + isl_multi_pw_aff_add_dims@Base 0.11 + isl_multi_pw_aff_align_params@Base 0.11 + isl_multi_pw_aff_alloc@Base 0.11 + isl_multi_pw_aff_apply_aff@Base 0.13 + isl_multi_pw_aff_apply_aligned_set@Base 0.15 + isl_multi_pw_aff_apply_pw_aff@Base 0.13 + isl_multi_pw_aff_coalesce@Base 0.13 + isl_multi_pw_aff_copy@Base 0.11 + isl_multi_pw_aff_cow@Base 0.11 + isl_multi_pw_aff_dim@Base 0.11 + isl_multi_pw_aff_domain@Base 0.13 + isl_multi_pw_aff_drop_dims@Base 0.11 + isl_multi_pw_aff_dump@Base 0.11 + isl_multi_pw_aff_dup@Base 0.11 + isl_multi_pw_aff_eq_map@Base 0.15 + isl_multi_pw_aff_find_dim_by_id@Base 0.13 + isl_multi_pw_aff_find_dim_by_name@Base 0.15 + isl_multi_pw_aff_flat_range_product@Base 0.11 + isl_multi_pw_aff_flatten_range@Base 0.11 + isl_multi_pw_aff_free@Base 0.11 + isl_multi_pw_aff_from_multi_aff@Base 0.13 + isl_multi_pw_aff_from_pw_aff@Base 0.11 + isl_multi_pw_aff_from_pw_aff_list@Base 0.11 + isl_multi_pw_aff_from_pw_multi_aff@Base 0.13 + isl_multi_pw_aff_from_range@Base 0.13 + isl_multi_pw_aff_get_ctx@Base 0.11 + isl_multi_pw_aff_get_dim_id@Base 0.13 + isl_multi_pw_aff_get_domain_space@Base 0.11 + isl_multi_pw_aff_get_pw_aff@Base 0.11 + isl_multi_pw_aff_get_space@Base 0.11 + isl_multi_pw_aff_get_tuple_id@Base 0.13 + isl_multi_pw_aff_get_tuple_name@Base 0.11 + isl_multi_pw_aff_gist@Base 0.11 + isl_multi_pw_aff_gist_params@Base 0.11 + isl_multi_pw_aff_has_tuple_id@Base 0.13 + isl_multi_pw_aff_identity@Base 0.11 + isl_multi_pw_aff_insert_dims@Base 0.11 + isl_multi_pw_aff_intersect_domain@Base 0.13 + isl_multi_pw_aff_intersect_params@Base 0.13 + isl_multi_pw_aff_involves_dims@Base 0.13 + isl_multi_pw_aff_is_equal@Base 0.13 + isl_multi_pw_aff_lex_gt_map@Base 0.15 + isl_multi_pw_aff_lex_gt_map_on_space@Base 0.15 + isl_multi_pw_aff_lex_lt_map@Base 0.15 + isl_multi_pw_aff_lex_lt_map_on_space@Base 0.15 + isl_multi_pw_aff_mod_multi_val@Base 0.15 + isl_multi_pw_aff_move_dims@Base 0.13 + isl_multi_pw_aff_neg@Base 0.15 + isl_multi_pw_aff_plain_is_equal@Base 0.13 + isl_multi_pw_aff_product@Base 0.13 + isl_multi_pw_aff_product_aligned@Base 0.13 + isl_multi_pw_aff_pullback_multi_aff@Base 0.13 + isl_multi_pw_aff_pullback_multi_pw_aff@Base 0.13 + isl_multi_pw_aff_pullback_pw_multi_aff@Base 0.13 + isl_multi_pw_aff_range_factor_domain@Base 0.13 + isl_multi_pw_aff_range_factor_range@Base 0.13 + isl_multi_pw_aff_range_is_wrapping@Base 0.13 + isl_multi_pw_aff_range_product@Base 0.11 + isl_multi_pw_aff_range_splice@Base 0.11 + isl_multi_pw_aff_read_from_str@Base 0.13 + isl_multi_pw_aff_realign_domain@Base 0.11 + isl_multi_pw_aff_reset_domain_space@Base 0.11 + isl_multi_pw_aff_reset_space@Base 0.11 + isl_multi_pw_aff_reset_space_and_domain@Base 0.11 + isl_multi_pw_aff_reset_tuple_id@Base 0.13 + isl_multi_pw_aff_reset_user@Base 0.13 + isl_multi_pw_aff_scale_down_multi_val@Base 0.13 + isl_multi_pw_aff_scale_down_val@Base 0.15 + isl_multi_pw_aff_scale_multi_val@Base 0.12.1 + isl_multi_pw_aff_scale_val@Base 0.12.1 + isl_multi_pw_aff_set_dim_id@Base 0.13 + isl_multi_pw_aff_set_dim_name@Base 0.11 + isl_multi_pw_aff_set_pw_aff@Base 0.11 + isl_multi_pw_aff_set_tuple_id@Base 0.11 + isl_multi_pw_aff_set_tuple_name@Base 0.11 + isl_multi_pw_aff_splice@Base 0.11 + isl_multi_pw_aff_sub@Base 0.15 + isl_multi_pw_aff_to_str@Base 0.11 + isl_multi_pw_aff_zero@Base 0.11 + isl_multi_union_pw_aff_align_params@Base 0.15 + isl_multi_union_pw_aff_alloc@Base 0.15 + isl_multi_union_pw_aff_apply_aff@Base 0.15 + isl_multi_union_pw_aff_apply_aligned_set@Base 0.15 + isl_multi_union_pw_aff_apply_aligned_union_set@Base 0.15 + isl_multi_union_pw_aff_apply_multi_aff@Base 0.15 + isl_multi_union_pw_aff_apply_pw_aff@Base 0.15 + isl_multi_union_pw_aff_apply_pw_multi_aff@Base 0.15 + isl_multi_union_pw_aff_copy@Base 0.15 + isl_multi_union_pw_aff_cow@Base 0.15 + isl_multi_union_pw_aff_dim@Base 0.15 + isl_multi_union_pw_aff_domain@Base 0.15 + isl_multi_union_pw_aff_drop_dims@Base 0.15 + isl_multi_union_pw_aff_dump@Base 0.15 + isl_multi_union_pw_aff_dup@Base 0.15 + isl_multi_union_pw_aff_extract_multi_pw_aff@Base 0.15 + isl_multi_union_pw_aff_find_dim_by_id@Base 0.15 + isl_multi_union_pw_aff_find_dim_by_name@Base 0.15 + isl_multi_union_pw_aff_flat_range_product@Base 0.15 + isl_multi_union_pw_aff_flatten_range@Base 0.15 + isl_multi_union_pw_aff_floor@Base 0.15 + isl_multi_union_pw_aff_free@Base 0.15 + isl_multi_union_pw_aff_from_multi_aff@Base 0.15 + isl_multi_union_pw_aff_from_multi_pw_aff@Base 0.15 + isl_multi_union_pw_aff_from_range@Base 0.15 + isl_multi_union_pw_aff_from_union_map@Base 0.15 + isl_multi_union_pw_aff_from_union_pw_aff@Base 0.15 + isl_multi_union_pw_aff_from_union_pw_aff_list@Base 0.15 + isl_multi_union_pw_aff_from_union_pw_multi_aff@Base 0.15 + isl_multi_union_pw_aff_get_ctx@Base 0.15 + isl_multi_union_pw_aff_get_dim_id@Base 0.15 + isl_multi_union_pw_aff_get_domain_space@Base 0.15 + isl_multi_union_pw_aff_get_space@Base 0.15 + isl_multi_union_pw_aff_get_tuple_id@Base 0.15 + isl_multi_union_pw_aff_get_tuple_name@Base 0.15 + isl_multi_union_pw_aff_get_union_pw_aff@Base 0.15 + isl_multi_union_pw_aff_gist@Base 0.15 + isl_multi_union_pw_aff_gist_params@Base 0.15 + isl_multi_union_pw_aff_has_tuple_id@Base 0.15 + isl_multi_union_pw_aff_intersect_domain@Base 0.15 + isl_multi_union_pw_aff_intersect_params@Base 0.15 + isl_multi_union_pw_aff_intersect_range@Base 0.15 + isl_multi_union_pw_aff_mod_multi_val@Base 0.15 + isl_multi_union_pw_aff_multi_aff_on_domain@Base 0.15 + isl_multi_union_pw_aff_multi_val_on_domain@Base 0.15 + isl_multi_union_pw_aff_neg@Base 0.15 + isl_multi_union_pw_aff_plain_is_equal@Base 0.15 + isl_multi_union_pw_aff_pullback_union_pw_multi_aff@Base 0.15 + isl_multi_union_pw_aff_range_factor_domain@Base 0.15 + isl_multi_union_pw_aff_range_factor_range@Base 0.15 + isl_multi_union_pw_aff_range_is_wrapping@Base 0.15 + isl_multi_union_pw_aff_range_product@Base 0.15 + isl_multi_union_pw_aff_range_splice@Base 0.15 + isl_multi_union_pw_aff_read_from_str@Base 0.15 + isl_multi_union_pw_aff_realign_domain@Base 0.15 + isl_multi_union_pw_aff_reset_domain_space@Base 0.15 + isl_multi_union_pw_aff_reset_space@Base 0.15 + isl_multi_union_pw_aff_reset_space_and_domain@Base 0.15 + isl_multi_union_pw_aff_reset_tuple_id@Base 0.15 + isl_multi_union_pw_aff_reset_user@Base 0.15 + isl_multi_union_pw_aff_scale_down_multi_val@Base 0.15 + isl_multi_union_pw_aff_scale_down_val@Base 0.15 + isl_multi_union_pw_aff_scale_multi_val@Base 0.15 + isl_multi_union_pw_aff_scale_val@Base 0.15 + isl_multi_union_pw_aff_set_dim_id@Base 0.15 + isl_multi_union_pw_aff_set_dim_name@Base 0.15 + isl_multi_union_pw_aff_set_tuple_id@Base 0.15 + isl_multi_union_pw_aff_set_tuple_name@Base 0.15 + isl_multi_union_pw_aff_set_union_pw_aff@Base 0.15 + isl_multi_union_pw_aff_sub@Base 0.15 + isl_multi_union_pw_aff_to_str@Base 0.15 + isl_multi_union_pw_aff_union_add@Base 0.15 + isl_multi_union_pw_aff_zero@Base 0.15 + isl_multi_union_pw_aff_zero_union_set@Base 0.15 + isl_multi_val_add_dims@Base 0.12.1 + isl_multi_val_add_val@Base 0.12.1 + isl_multi_val_align_params@Base 0.12.1 + isl_multi_val_alloc@Base 0.12.1 + isl_multi_val_copy@Base 0.12.1 + isl_multi_val_cow@Base 0.12.1 + isl_multi_val_dim@Base 0.12.1 + isl_multi_val_drop_dims@Base 0.12.1 + isl_multi_val_dump@Base 0.13 + isl_multi_val_dup@Base 0.12.1 + isl_multi_val_find_dim_by_id@Base 0.13 + isl_multi_val_find_dim_by_name@Base 0.15 + isl_multi_val_flat_range_product@Base 0.12.1 + isl_multi_val_flatten_range@Base 0.12.1 + isl_multi_val_free@Base 0.12.1 + isl_multi_val_from_range@Base 0.13 + isl_multi_val_from_val_list@Base 0.12.1 + isl_multi_val_get_ctx@Base 0.12.1 + isl_multi_val_get_dim_id@Base 0.13 + isl_multi_val_get_domain_space@Base 0.12.1 + isl_multi_val_get_space@Base 0.12.1 + isl_multi_val_get_tuple_id@Base 0.13 + isl_multi_val_get_tuple_name@Base 0.12.1 + isl_multi_val_get_val@Base 0.12.1 + isl_multi_val_has_tuple_id@Base 0.13 + isl_multi_val_insert_dims@Base 0.12.1 + isl_multi_val_involves_dims@Base 0.13 + isl_multi_val_mod_multi_val@Base 0.15 + isl_multi_val_mod_val@Base 0.12.1 + isl_multi_val_neg@Base 0.15 + isl_multi_val_plain_is_equal@Base 0.13 + isl_multi_val_product@Base 0.13 + isl_multi_val_product_aligned@Base 0.13 + isl_multi_val_range_factor_domain@Base 0.13 + isl_multi_val_range_factor_range@Base 0.13 + isl_multi_val_range_is_wrapping@Base 0.13 + isl_multi_val_range_product@Base 0.12.1 + isl_multi_val_range_splice@Base 0.12.1 + isl_multi_val_read_from_str@Base 0.15 + isl_multi_val_realign_domain@Base 0.12.1 + isl_multi_val_reset_domain_space@Base 0.12.1 + isl_multi_val_reset_space@Base 0.12.1 + isl_multi_val_reset_space_and_domain@Base 0.12.1 + isl_multi_val_reset_tuple_id@Base 0.13 + isl_multi_val_reset_user@Base 0.13 + isl_multi_val_scale_down_multi_val@Base 0.13 + isl_multi_val_scale_down_val@Base 0.15 + isl_multi_val_scale_multi_val@Base 0.12.1 + isl_multi_val_scale_val@Base 0.12.1 + isl_multi_val_set_dim_id@Base 0.13 + isl_multi_val_set_dim_name@Base 0.12.1 + isl_multi_val_set_tuple_id@Base 0.12.1 + isl_multi_val_set_tuple_name@Base 0.12.1 + isl_multi_val_set_val@Base 0.12.1 + isl_multi_val_splice@Base 0.12.1 + isl_multi_val_sub@Base 0.15 + isl_multi_val_to_str@Base 0.13 + isl_multi_val_zero@Base 0.12.1 + isl_obj_map_vtable@Base 0.10 + isl_obj_none_vtable@Base 0.10 + isl_obj_pw_multi_aff_vtable@Base 0.13 + isl_obj_pw_qpolynomial_fold_vtable@Base 0.10 + isl_obj_pw_qpolynomial_vtable@Base 0.10 + isl_obj_schedule_vtable@Base 0.15 + isl_obj_set_vtable@Base 0.10 + isl_obj_union_map_vtable@Base 0.10 + isl_obj_union_pw_qpolynomial_fold_vtable@Base 0.10 + isl_obj_union_pw_qpolynomial_vtable@Base 0.10 + isl_obj_union_set_vtable@Base 0.10 + isl_obj_val_vtable@Base 0.12.1 + isl_options_args@Base 0.10 + isl_options_argsLIST@Base 0.10 + isl_options_free@Base 0.10 + isl_options_get_ast_always_print_block@Base 0.14 + isl_options_get_ast_build_allow_else@Base 0.11 + isl_options_get_ast_build_allow_or@Base 0.12.1 + isl_options_get_ast_build_atomic_upper_bound@Base 0.11 + isl_options_get_ast_build_exploit_nested_bounds@Base 0.11 + isl_options_get_ast_build_group_coscheduled@Base 0.11 + isl_options_get_ast_build_prefer_pdiv@Base 0.11 + isl_options_get_ast_build_scale_strides@Base 0.11 + isl_options_get_ast_build_separation_bounds@Base 0.11 + isl_options_get_ast_iterator_type@Base 0.11 + isl_options_get_bound@Base 0.10 + isl_options_get_coalesce_bounded_wrapping@Base 0.10 + isl_options_get_gbr_only_first@Base 0.10 + isl_options_get_on_error@Base 0.10 + isl_options_get_schedule_algorithm@Base 0.10 + isl_options_get_schedule_max_coefficient@Base 0.10 + isl_options_get_schedule_max_constant_term@Base 0.10 + isl_options_get_schedule_maximize_band_depth@Base 0.10 + isl_options_get_schedule_outer_coincidence@Base 0.13 + isl_options_get_schedule_separate_components@Base 0.10 + isl_options_get_schedule_serialize_sccs@Base 0.15 + isl_options_get_schedule_split_scaled@Base 0.10 + isl_options_get_tile_scale_tile_loops@Base 0.10 + isl_options_get_tile_shift_point_loops@Base 0.12.1 + isl_options_new_with_defaults@Base 0.10 + isl_options_parse@Base 0.10 + isl_options_set_ast_always_print_block@Base 0.14 + isl_options_set_ast_build_allow_else@Base 0.11 + isl_options_set_ast_build_allow_or@Base 0.12.1 + isl_options_set_ast_build_atomic_upper_bound@Base 0.11 + isl_options_set_ast_build_exploit_nested_bounds@Base 0.11 + isl_options_set_ast_build_group_coscheduled@Base 0.11 + isl_options_set_ast_build_prefer_pdiv@Base 0.11 + isl_options_set_ast_build_scale_strides@Base 0.11 + isl_options_set_ast_build_separation_bounds@Base 0.11 + isl_options_set_ast_iterator_type@Base 0.11 + isl_options_set_bound@Base 0.10 + isl_options_set_coalesce_bounded_wrapping@Base 0.10 + isl_options_set_gbr_only_first@Base 0.10 + isl_options_set_on_error@Base 0.10 + isl_options_set_schedule_algorithm@Base 0.10 + isl_options_set_schedule_max_coefficient@Base 0.10 + isl_options_set_schedule_max_constant_term@Base 0.10 + isl_options_set_schedule_maximize_band_depth@Base 0.10 + isl_options_set_schedule_outer_coincidence@Base 0.13 + isl_options_set_schedule_separate_components@Base 0.10 + isl_options_set_schedule_serialize_sccs@Base 0.15 + isl_options_set_schedule_split_scaled@Base 0.10 + isl_options_set_tile_scale_tile_loops@Base 0.10 + isl_options_set_tile_shift_point_loops@Base 0.12.1 + isl_parameter_alignment_reordering@Base 0.10 + isl_pip_context_choice@Base 0.10 + isl_point_add_ui@Base 0.10 + isl_point_alloc@Base 0.10 + isl_point_copy@Base 0.10 + isl_point_cow@Base 0.10 + isl_point_dump@Base 0.11 + isl_point_dup@Base 0.10 + isl_point_free@Base 0.10 + isl_point_get_coordinate@Base 0.10 + isl_point_get_coordinate_val@Base 0.12.1 + isl_point_get_ctx@Base 0.10 + isl_point_get_space@Base 0.10 + isl_point_is_void@Base 0.10 + isl_point_set_coordinate@Base 0.10 + isl_point_set_coordinate_val@Base 0.12.1 + isl_point_sub_ui@Base 0.10 + isl_point_to_str@Base 0.11 + isl_point_void@Base 0.10 + isl_point_zero@Base 0.10 + isl_printer_end_line@Base 0.10 + isl_printer_flush@Base 0.10 + isl_printer_free@Base 0.10 + isl_printer_get_ctx@Base 0.10 + isl_printer_get_file@Base 0.10 + isl_printer_get_output_format@Base 0.10 + isl_printer_get_str@Base 0.10 + isl_printer_get_yaml_style@Base 0.15 + isl_printer_indent@Base 0.10 + isl_printer_print_aff@Base 0.10 + isl_printer_print_aff_list@Base 0.10 + isl_printer_print_ast_expr@Base 0.11 + isl_printer_print_ast_expr_list@Base 0.11 + isl_printer_print_ast_graft@Base 0.11 + isl_printer_print_ast_graft_list@Base 0.11 + isl_printer_print_ast_node@Base 0.11 + isl_printer_print_ast_node_list@Base 0.11 + isl_printer_print_band@Base 0.10 + isl_printer_print_band_list@Base 0.10 + isl_printer_print_basic_map@Base 0.10 + isl_printer_print_basic_map_list@Base 0.15 + isl_printer_print_basic_set@Base 0.10 + isl_printer_print_basic_set_list@Base 0.10 + isl_printer_print_constraint@Base 0.10 + isl_printer_print_constraint_list@Base 0.11 + isl_printer_print_double@Base 0.11 + isl_printer_print_id@Base 0.10 + isl_printer_print_id_list@Base 0.11 + isl_printer_print_id_to_ast_expr@Base 0.13 + isl_printer_print_id_to_pw_aff@Base 0.13 + isl_printer_print_int@Base 0.10 + isl_printer_print_isl_int@Base 0.10 + isl_printer_print_local_space@Base 0.10 + isl_printer_print_map@Base 0.10 + isl_printer_print_map_list@Base 0.15 + isl_printer_print_map_to_basic_set@Base 0.13 + isl_printer_print_multi_aff@Base 0.10 + isl_printer_print_multi_pw_aff@Base 0.11 + isl_printer_print_multi_union_pw_aff@Base 0.15 + isl_printer_print_multi_val@Base 0.13 + isl_printer_print_point@Base 0.10 + isl_printer_print_pw_aff@Base 0.10 + isl_printer_print_pw_aff_list@Base 0.10 + isl_printer_print_pw_multi_aff@Base 0.10 + isl_printer_print_pw_qpolynomial@Base 0.10 + isl_printer_print_pw_qpolynomial_fold@Base 0.10 + isl_printer_print_qpolynomial@Base 0.10 + isl_printer_print_qpolynomial_fold@Base 0.10 + isl_printer_print_schedule@Base 0.10 + isl_printer_print_schedule_node@Base 0.15 + isl_printer_print_schedule_tree@Base 0.15 + isl_printer_print_schedule_tree_list@Base 0.15 + isl_printer_print_schedule_tree_mark@Base 0.15 + isl_printer_print_set@Base 0.10 + isl_printer_print_set_list@Base 0.10 + isl_printer_print_space@Base 0.10 + isl_printer_print_str@Base 0.10 + isl_printer_print_union_map@Base 0.10 + isl_printer_print_union_map_list@Base 0.15 + isl_printer_print_union_pw_aff@Base 0.15 + isl_printer_print_union_pw_aff_list@Base 0.15 + isl_printer_print_union_pw_multi_aff@Base 0.10 + isl_printer_print_union_pw_multi_aff_list@Base 0.15 + isl_printer_print_union_pw_qpolynomial@Base 0.10 + isl_printer_print_union_pw_qpolynomial_fold@Base 0.10 + isl_printer_print_union_set@Base 0.10 + isl_printer_print_union_set_list@Base 0.15 + isl_printer_print_val@Base 0.12.1 + isl_printer_print_val_list@Base 0.12.1 + isl_printer_print_vec@Base 0.10 + isl_printer_set_indent@Base 0.10 + isl_printer_set_indent_prefix@Base 0.13 + isl_printer_set_isl_int_width@Base 0.10 + isl_printer_set_output_format@Base 0.10 + isl_printer_set_prefix@Base 0.10 + isl_printer_set_suffix@Base 0.10 + isl_printer_set_yaml_style@Base 0.15 + isl_printer_start_line@Base 0.10 + isl_printer_to_file@Base 0.10 + isl_printer_to_str@Base 0.10 + isl_printer_yaml_end_mapping@Base 0.15 + isl_printer_yaml_end_sequence@Base 0.15 + isl_printer_yaml_next@Base 0.15 + isl_printer_yaml_start_mapping@Base 0.15 + isl_printer_yaml_start_sequence@Base 0.15 + isl_pw_aff_add@Base 0.10 + isl_pw_aff_add_dims@Base 0.10 + isl_pw_aff_add_disjoint@Base 0.10 + isl_pw_aff_add_piece@Base 0.10 + isl_pw_aff_align_params@Base 0.10 + isl_pw_aff_alloc@Base 0.10 + isl_pw_aff_alloc_size@Base 0.10 + isl_pw_aff_ceil@Base 0.10 + isl_pw_aff_check_match_domain_space@Base 0.12.1 + isl_pw_aff_coalesce@Base 0.10 + isl_pw_aff_cond@Base 0.10 + isl_pw_aff_copy@Base 0.10 + isl_pw_aff_cow@Base 0.10 + isl_pw_aff_dim@Base 0.10 + isl_pw_aff_div@Base 0.11 + isl_pw_aff_domain@Base 0.10 + isl_pw_aff_drop_dims@Base 0.10 + isl_pw_aff_dump@Base 0.10 + isl_pw_aff_dup@Base 0.10 + isl_pw_aff_empty@Base 0.10 + isl_pw_aff_eq_map@Base 0.15 + isl_pw_aff_eq_set@Base 0.10 + isl_pw_aff_find_dim_by_name@Base 0.15 + isl_pw_aff_fix_dim@Base 0.10 + isl_pw_aff_fix_si@Base 0.13 + isl_pw_aff_fix_val@Base 0.12.1 + isl_pw_aff_floor@Base 0.10 + isl_pw_aff_foreach_piece@Base 0.10 + isl_pw_aff_free@Base 0.10 + isl_pw_aff_from_aff@Base 0.10 + isl_pw_aff_from_range@Base 0.13 + isl_pw_aff_ge_set@Base 0.10 + isl_pw_aff_get_ctx@Base 0.10 + isl_pw_aff_get_dim_id@Base 0.10 + isl_pw_aff_get_dim_name@Base 0.10 + isl_pw_aff_get_domain_space@Base 0.10 + isl_pw_aff_get_space@Base 0.10 + isl_pw_aff_get_tuple_id@Base 0.10 + isl_pw_aff_get_tuple_name@Base 0.10 + isl_pw_aff_gist@Base 0.10 + isl_pw_aff_gist_params@Base 0.10 + isl_pw_aff_gt_map@Base 0.15 + isl_pw_aff_gt_set@Base 0.10 + isl_pw_aff_has_dim_id@Base 0.10 + isl_pw_aff_has_equal_space@Base 0.10 + isl_pw_aff_has_tuple_id@Base 0.10 + isl_pw_aff_has_tuple_name@Base 0.11 + isl_pw_aff_insert_dims@Base 0.10 + isl_pw_aff_intersect_domain@Base 0.10 + isl_pw_aff_intersect_params@Base 0.10 + isl_pw_aff_involves_dims@Base 0.10 + isl_pw_aff_involves_nan@Base 0.13 + isl_pw_aff_is_cst@Base 0.10 + isl_pw_aff_is_empty@Base 0.10 + isl_pw_aff_is_equal@Base 0.13 + isl_pw_aff_le_set@Base 0.10 + isl_pw_aff_list_add@Base 0.10 + isl_pw_aff_list_alloc@Base 0.10 + isl_pw_aff_list_concat@Base 0.10 + isl_pw_aff_list_copy@Base 0.10 + isl_pw_aff_list_cow@Base 0.11 + isl_pw_aff_list_drop@Base 0.11 + isl_pw_aff_list_dump@Base 0.10 + isl_pw_aff_list_dup@Base 0.10 + isl_pw_aff_list_eq_set@Base 0.10 + isl_pw_aff_list_foreach@Base 0.10 + isl_pw_aff_list_foreach_scc@Base 0.12.1 + isl_pw_aff_list_free@Base 0.10 + isl_pw_aff_list_from_pw_aff@Base 0.10 + isl_pw_aff_list_ge_set@Base 0.10 + isl_pw_aff_list_get_ctx@Base 0.10 + isl_pw_aff_list_get_pw_aff@Base 0.10 + isl_pw_aff_list_gt_set@Base 0.10 + isl_pw_aff_list_insert@Base 0.11 + isl_pw_aff_list_le_set@Base 0.10 + isl_pw_aff_list_lt_set@Base 0.10 + isl_pw_aff_list_max@Base 0.10 + isl_pw_aff_list_min@Base 0.10 + isl_pw_aff_list_n_pw_aff@Base 0.10 + isl_pw_aff_list_ne_set@Base 0.10 + isl_pw_aff_list_set_pw_aff@Base 0.11 + isl_pw_aff_list_set_rational@Base 0.11 + isl_pw_aff_list_sort@Base 0.12.1 + isl_pw_aff_lt_map@Base 0.15 + isl_pw_aff_lt_set@Base 0.10 + isl_pw_aff_matching_params@Base 0.13 + isl_pw_aff_max@Base 0.10 + isl_pw_aff_min@Base 0.10 + isl_pw_aff_mod@Base 0.10 + isl_pw_aff_mod_val@Base 0.12.1 + isl_pw_aff_move_dims@Base 0.13 + isl_pw_aff_mul@Base 0.10 + isl_pw_aff_mul_isl_int@Base 0.10 + isl_pw_aff_n_piece@Base 0.10 + isl_pw_aff_nan_on_domain@Base 0.13 + isl_pw_aff_ne_set@Base 0.10 + isl_pw_aff_neg@Base 0.10 + isl_pw_aff_non_zero_set@Base 0.10 + isl_pw_aff_nonneg_set@Base 0.10 + isl_pw_aff_normalize@Base 0.10 + isl_pw_aff_params@Base 0.13 + isl_pw_aff_plain_cmp@Base 0.13 + isl_pw_aff_plain_is_equal@Base 0.10 + isl_pw_aff_pos_set@Base 0.15 + isl_pw_aff_project_domain_on_params@Base 0.10 + isl_pw_aff_project_out@Base 0.10 + isl_pw_aff_pullback_multi_aff@Base 0.11 + isl_pw_aff_pullback_multi_pw_aff@Base 0.13 + isl_pw_aff_pullback_pw_multi_aff@Base 0.11 + isl_pw_aff_read_from_str@Base 0.10 + isl_pw_aff_realign_domain@Base 0.10 + isl_pw_aff_reset_domain_space@Base 0.10 + isl_pw_aff_reset_space@Base 0.10 + isl_pw_aff_reset_tuple_id@Base 0.13 + isl_pw_aff_reset_user@Base 0.15 + isl_pw_aff_scale@Base 0.10 + isl_pw_aff_scale_down@Base 0.10 + isl_pw_aff_scale_down_val@Base 0.12.1 + isl_pw_aff_scale_val@Base 0.12.1 + isl_pw_aff_set_dim_id@Base 0.10 + isl_pw_aff_set_dim_name@Base 0.10 + isl_pw_aff_set_rational@Base 0.11 + isl_pw_aff_set_tuple_id@Base 0.10 + isl_pw_aff_split_dims@Base 0.10 + isl_pw_aff_sub@Base 0.10 + isl_pw_aff_subtract_domain@Base 0.15 + isl_pw_aff_tdiv_q@Base 0.11 + isl_pw_aff_tdiv_r@Base 0.11 + isl_pw_aff_to_str@Base 0.10 + isl_pw_aff_union_add@Base 0.10 + isl_pw_aff_union_max@Base 0.10 + isl_pw_aff_union_min@Base 0.10 + isl_pw_aff_union_opt@Base 0.10 + isl_pw_aff_val_on_domain@Base 0.15 + isl_pw_aff_var_on_domain@Base 0.11 + isl_pw_aff_zero_on_domain@Base 0.11 + isl_pw_aff_zero_set@Base 0.10 + isl_pw_multi_aff_add@Base 0.10 + isl_pw_multi_aff_add_disjoint@Base 0.10 + isl_pw_multi_aff_add_piece@Base 0.10 + isl_pw_multi_aff_align_params@Base 0.10 + isl_pw_multi_aff_alloc@Base 0.10 + isl_pw_multi_aff_alloc_size@Base 0.10 + isl_pw_multi_aff_coalesce@Base 0.10 + isl_pw_multi_aff_copy@Base 0.10 + isl_pw_multi_aff_cow@Base 0.10 + isl_pw_multi_aff_dim@Base 0.10 + isl_pw_multi_aff_domain@Base 0.10 + isl_pw_multi_aff_drop_dims@Base 0.10 + isl_pw_multi_aff_dump@Base 0.10 + isl_pw_multi_aff_dup@Base 0.10 + isl_pw_multi_aff_empty@Base 0.10 + isl_pw_multi_aff_find_dim_by_name@Base 0.15 + isl_pw_multi_aff_fix_dim@Base 0.10 + isl_pw_multi_aff_fix_si@Base 0.13 + isl_pw_multi_aff_fix_val@Base 0.12.1 + isl_pw_multi_aff_flat_range_product@Base 0.10 + isl_pw_multi_aff_foreach_piece@Base 0.10 + isl_pw_multi_aff_free@Base 0.10 + isl_pw_multi_aff_from_domain@Base 0.10 + isl_pw_multi_aff_from_map@Base 0.10 + isl_pw_multi_aff_from_multi_aff@Base 0.10 + isl_pw_multi_aff_from_multi_pw_aff@Base 0.13 + isl_pw_multi_aff_from_pw_aff@Base 0.13 + isl_pw_multi_aff_from_range@Base 0.13 + isl_pw_multi_aff_from_set@Base 0.10 + isl_pw_multi_aff_get_ctx@Base 0.10 + isl_pw_multi_aff_get_dim_id@Base 0.10 + isl_pw_multi_aff_get_dim_name@Base 0.10 + isl_pw_multi_aff_get_domain_space@Base 0.10 + isl_pw_multi_aff_get_pw_aff@Base 0.10 + isl_pw_multi_aff_get_space@Base 0.10 + isl_pw_multi_aff_get_tuple_id@Base 0.10 + isl_pw_multi_aff_get_tuple_name@Base 0.10 + isl_pw_multi_aff_gist@Base 0.10 + isl_pw_multi_aff_gist_params@Base 0.10 + isl_pw_multi_aff_has_dim_id@Base 0.10 + isl_pw_multi_aff_has_equal_space@Base 0.10 + isl_pw_multi_aff_has_tuple_id@Base 0.10 + isl_pw_multi_aff_has_tuple_name@Base 0.11 + isl_pw_multi_aff_identity@Base 0.11 + isl_pw_multi_aff_intersect_domain@Base 0.10 + isl_pw_multi_aff_intersect_params@Base 0.10 + isl_pw_multi_aff_is_empty@Base 0.10 + isl_pw_multi_aff_move_dims@Base 0.13 + isl_pw_multi_aff_mul_isl_int@Base 0.10 + isl_pw_multi_aff_multi_val_on_domain@Base 0.15 + isl_pw_multi_aff_n_piece@Base 0.10 + isl_pw_multi_aff_neg@Base 0.15 + isl_pw_multi_aff_normalize@Base 0.10 + isl_pw_multi_aff_params@Base 0.13 + isl_pw_multi_aff_plain_is_equal@Base 0.10 + isl_pw_multi_aff_product@Base 0.11 + isl_pw_multi_aff_project_domain_on_params@Base 0.10 + isl_pw_multi_aff_project_out@Base 0.10 + isl_pw_multi_aff_project_out_map@Base 0.13 + isl_pw_multi_aff_pullback_multi_aff@Base 0.11 + isl_pw_multi_aff_pullback_pw_multi_aff@Base 0.11 + isl_pw_multi_aff_range_map@Base 0.15 + isl_pw_multi_aff_range_product@Base 0.11 + isl_pw_multi_aff_read_from_str@Base 0.10 + isl_pw_multi_aff_realign_domain@Base 0.10 + isl_pw_multi_aff_reset_domain_space@Base 0.10 + isl_pw_multi_aff_reset_space@Base 0.10 + isl_pw_multi_aff_reset_tuple_id@Base 0.13 + isl_pw_multi_aff_reset_user@Base 0.15 + isl_pw_multi_aff_scale@Base 0.10 + isl_pw_multi_aff_scale_down_val@Base 0.15 + isl_pw_multi_aff_scale_multi_val@Base 0.12.1 + isl_pw_multi_aff_scale_val@Base 0.12.1 + isl_pw_multi_aff_set_dim_id@Base 0.10 + isl_pw_multi_aff_set_dim_name@Base 0.10 + isl_pw_multi_aff_set_pw_aff@Base 0.11 + isl_pw_multi_aff_set_tuple_id@Base 0.10 + isl_pw_multi_aff_split_dims@Base 0.10 + isl_pw_multi_aff_sub@Base 0.12.1 + isl_pw_multi_aff_substitute@Base 0.10 + isl_pw_multi_aff_subtract_domain@Base 0.15 + isl_pw_multi_aff_to_str@Base 0.10 + isl_pw_multi_aff_union_add@Base 0.10 + isl_pw_multi_aff_union_lexmax@Base 0.11 + isl_pw_multi_aff_union_lexmin@Base 0.11 + isl_pw_multi_aff_zero@Base 0.13 + isl_pw_qpolynomial_add@Base 0.10 + isl_pw_qpolynomial_add_dims@Base 0.10 + isl_pw_qpolynomial_add_disjoint@Base 0.10 + isl_pw_qpolynomial_add_piece@Base 0.10 + isl_pw_qpolynomial_align_params@Base 0.10 + isl_pw_qpolynomial_alloc@Base 0.10 + isl_pw_qpolynomial_alloc_size@Base 0.10 + isl_pw_qpolynomial_bound@Base 0.10 + isl_pw_qpolynomial_coalesce@Base 0.10 + isl_pw_qpolynomial_copy@Base 0.10 + isl_pw_qpolynomial_cow@Base 0.10 + isl_pw_qpolynomial_dim@Base 0.10 + isl_pw_qpolynomial_domain@Base 0.10 + isl_pw_qpolynomial_drop_dims@Base 0.10 + isl_pw_qpolynomial_dump@Base 0.10 + isl_pw_qpolynomial_dup@Base 0.10 + isl_pw_qpolynomial_eval@Base 0.10 + isl_pw_qpolynomial_find_dim_by_name@Base 0.15 + isl_pw_qpolynomial_fix_dim@Base 0.10 + isl_pw_qpolynomial_fix_si@Base 0.13 + isl_pw_qpolynomial_fix_val@Base 0.12.1 + isl_pw_qpolynomial_fold_add@Base 0.10 + isl_pw_qpolynomial_fold_add_disjoint@Base 0.10 + isl_pw_qpolynomial_fold_add_piece@Base 0.10 + isl_pw_qpolynomial_fold_align_params@Base 0.10 + isl_pw_qpolynomial_fold_alloc@Base 0.10 + isl_pw_qpolynomial_fold_alloc_size@Base 0.10 + isl_pw_qpolynomial_fold_bound@Base 0.10 + isl_pw_qpolynomial_fold_coalesce@Base 0.10 + isl_pw_qpolynomial_fold_copy@Base 0.10 + isl_pw_qpolynomial_fold_covers@Base 0.10 + isl_pw_qpolynomial_fold_cow@Base 0.10 + isl_pw_qpolynomial_fold_dim@Base 0.10 + isl_pw_qpolynomial_fold_domain@Base 0.10 + isl_pw_qpolynomial_fold_drop_dims@Base 0.10 + isl_pw_qpolynomial_fold_dump@Base 0.10 + isl_pw_qpolynomial_fold_dup@Base 0.10 + isl_pw_qpolynomial_fold_eval@Base 0.10 + isl_pw_qpolynomial_fold_find_dim_by_name@Base 0.15 + isl_pw_qpolynomial_fold_fix_dim@Base 0.10 + isl_pw_qpolynomial_fold_fix_si@Base 0.13 + isl_pw_qpolynomial_fold_fix_val@Base 0.12.1 + isl_pw_qpolynomial_fold_fold@Base 0.10 + isl_pw_qpolynomial_fold_foreach_lifted_piece@Base 0.10 + isl_pw_qpolynomial_fold_foreach_piece@Base 0.10 + isl_pw_qpolynomial_fold_free@Base 0.10 + isl_pw_qpolynomial_fold_from_pw_qpolynomial@Base 0.10 + isl_pw_qpolynomial_fold_from_range@Base 0.13 + isl_pw_qpolynomial_fold_get_ctx@Base 0.10 + isl_pw_qpolynomial_fold_get_dim_id@Base 0.10 + isl_pw_qpolynomial_fold_get_dim_name@Base 0.10 + isl_pw_qpolynomial_fold_get_domain_space@Base 0.10 + isl_pw_qpolynomial_fold_get_space@Base 0.10 + isl_pw_qpolynomial_fold_get_tuple_id@Base 0.10 + isl_pw_qpolynomial_fold_get_tuple_name@Base 0.10 + isl_pw_qpolynomial_fold_gist@Base 0.10 + isl_pw_qpolynomial_fold_gist_params@Base 0.10 + isl_pw_qpolynomial_fold_has_dim_id@Base 0.10 + isl_pw_qpolynomial_fold_has_equal_space@Base 0.10 + isl_pw_qpolynomial_fold_has_tuple_id@Base 0.10 + isl_pw_qpolynomial_fold_has_tuple_name@Base 0.11 + isl_pw_qpolynomial_fold_insert_dims@Base 0.10 + isl_pw_qpolynomial_fold_intersect_domain@Base 0.10 + isl_pw_qpolynomial_fold_intersect_params@Base 0.10 + isl_pw_qpolynomial_fold_involves_dims@Base 0.10 + isl_pw_qpolynomial_fold_is_zero@Base 0.10 + isl_pw_qpolynomial_fold_max@Base 0.10 + isl_pw_qpolynomial_fold_min@Base 0.10 + isl_pw_qpolynomial_fold_morph_domain@Base 0.10 + isl_pw_qpolynomial_fold_move_dims@Base 0.10 + isl_pw_qpolynomial_fold_mul_isl_int@Base 0.10 + isl_pw_qpolynomial_fold_n_piece@Base 0.10 + isl_pw_qpolynomial_fold_normalize@Base 0.10 + isl_pw_qpolynomial_fold_opt@Base 0.10 + isl_pw_qpolynomial_fold_params@Base 0.13 + isl_pw_qpolynomial_fold_plain_is_equal@Base 0.10 + isl_pw_qpolynomial_fold_print@Base 0.10 + isl_pw_qpolynomial_fold_project_domain_on_params@Base 0.10 + isl_pw_qpolynomial_fold_project_out@Base 0.10 + isl_pw_qpolynomial_fold_realign_domain@Base 0.10 + isl_pw_qpolynomial_fold_reset_domain_space@Base 0.10 + isl_pw_qpolynomial_fold_reset_space@Base 0.10 + isl_pw_qpolynomial_fold_reset_tuple_id@Base 0.13 + isl_pw_qpolynomial_fold_reset_user@Base 0.15 + isl_pw_qpolynomial_fold_scale@Base 0.10 + isl_pw_qpolynomial_fold_scale_down_val@Base 0.15 + isl_pw_qpolynomial_fold_scale_val@Base 0.12.1 + isl_pw_qpolynomial_fold_set_dim_id@Base 0.10 + isl_pw_qpolynomial_fold_set_dim_name@Base 0.10 + isl_pw_qpolynomial_fold_set_tuple_id@Base 0.10 + isl_pw_qpolynomial_fold_size@Base 0.10 + isl_pw_qpolynomial_fold_split_dims@Base 0.10 + isl_pw_qpolynomial_fold_subtract_domain@Base 0.15 + isl_pw_qpolynomial_fold_to_str@Base 0.10 + isl_pw_qpolynomial_fold_zero@Base 0.10 + isl_pw_qpolynomial_foreach_lifted_piece@Base 0.10 + isl_pw_qpolynomial_foreach_piece@Base 0.10 + isl_pw_qpolynomial_free@Base 0.10 + isl_pw_qpolynomial_from_pw_aff@Base 0.10 + isl_pw_qpolynomial_from_qpolynomial@Base 0.10 + isl_pw_qpolynomial_from_range@Base 0.13 + isl_pw_qpolynomial_get_ctx@Base 0.10 + isl_pw_qpolynomial_get_dim_id@Base 0.10 + isl_pw_qpolynomial_get_dim_name@Base 0.10 + isl_pw_qpolynomial_get_domain_space@Base 0.10 + isl_pw_qpolynomial_get_space@Base 0.10 + isl_pw_qpolynomial_get_tuple_id@Base 0.10 + isl_pw_qpolynomial_get_tuple_name@Base 0.10 + isl_pw_qpolynomial_gist@Base 0.10 + isl_pw_qpolynomial_gist_params@Base 0.10 + isl_pw_qpolynomial_has_dim_id@Base 0.10 + isl_pw_qpolynomial_has_equal_space@Base 0.10 + isl_pw_qpolynomial_has_tuple_id@Base 0.10 + isl_pw_qpolynomial_has_tuple_name@Base 0.11 + isl_pw_qpolynomial_insert_dims@Base 0.10 + isl_pw_qpolynomial_intersect_domain@Base 0.10 + isl_pw_qpolynomial_intersect_params@Base 0.10 + isl_pw_qpolynomial_involves_dims@Base 0.10 + isl_pw_qpolynomial_is_one@Base 0.10 + isl_pw_qpolynomial_is_zero@Base 0.10 + isl_pw_qpolynomial_max@Base 0.10 + isl_pw_qpolynomial_min@Base 0.10 + isl_pw_qpolynomial_morph_domain@Base 0.10 + isl_pw_qpolynomial_move_dims@Base 0.10 + isl_pw_qpolynomial_mul@Base 0.10 + isl_pw_qpolynomial_mul_isl_int@Base 0.10 + isl_pw_qpolynomial_n_piece@Base 0.10 + isl_pw_qpolynomial_neg@Base 0.10 + isl_pw_qpolynomial_normalize@Base 0.10 + isl_pw_qpolynomial_opt@Base 0.10 + isl_pw_qpolynomial_params@Base 0.13 + isl_pw_qpolynomial_plain_is_equal@Base 0.10 + isl_pw_qpolynomial_pow@Base 0.10 + isl_pw_qpolynomial_print@Base 0.10 + isl_pw_qpolynomial_project_domain_on_params@Base 0.10 + isl_pw_qpolynomial_project_out@Base 0.10 + isl_pw_qpolynomial_read_from_file@Base 0.10 + isl_pw_qpolynomial_read_from_str@Base 0.10 + isl_pw_qpolynomial_realign_domain@Base 0.10 + isl_pw_qpolynomial_reset_domain_space@Base 0.10 + isl_pw_qpolynomial_reset_space@Base 0.10 + isl_pw_qpolynomial_reset_tuple_id@Base 0.13 + isl_pw_qpolynomial_reset_user@Base 0.15 + isl_pw_qpolynomial_scale@Base 0.10 + isl_pw_qpolynomial_scale_down_val@Base 0.15 + isl_pw_qpolynomial_scale_val@Base 0.12.1 + isl_pw_qpolynomial_set_dim_id@Base 0.10 + isl_pw_qpolynomial_set_dim_name@Base 0.10 + isl_pw_qpolynomial_set_tuple_id@Base 0.10 + isl_pw_qpolynomial_split_dims@Base 0.10 + isl_pw_qpolynomial_split_periods@Base 0.10 + isl_pw_qpolynomial_sub@Base 0.10 + isl_pw_qpolynomial_subtract_domain@Base 0.15 + isl_pw_qpolynomial_to_polynomial@Base 0.10 + isl_pw_qpolynomial_to_str@Base 0.10 + isl_pw_qpolynomial_zero@Base 0.10 + isl_qpolynomial_add@Base 0.10 + isl_qpolynomial_add_dims@Base 0.10 + isl_qpolynomial_add_isl_int@Base 0.10 + isl_qpolynomial_add_on_domain@Base 0.10 + isl_qpolynomial_align_params@Base 0.10 + isl_qpolynomial_alloc@Base 0.10 + isl_qpolynomial_as_polynomial_on_domain@Base 0.10 + isl_qpolynomial_bound_on_domain_bernstein@Base 0.10 + isl_qpolynomial_bound_on_domain_range@Base 0.10 + isl_qpolynomial_coeff@Base 0.10 + isl_qpolynomial_copy@Base 0.10 + isl_qpolynomial_cow@Base 0.10 + isl_qpolynomial_cst_on_domain@Base 0.10 + isl_qpolynomial_degree@Base 0.10 + isl_qpolynomial_dim@Base 0.10 + isl_qpolynomial_drop_dims@Base 0.10 + isl_qpolynomial_dump@Base 0.10 + isl_qpolynomial_dup@Base 0.10 + isl_qpolynomial_eval@Base 0.10 + isl_qpolynomial_extract_affine@Base 0.10 + isl_qpolynomial_fold_add_on_domain@Base 0.10 + isl_qpolynomial_fold_add_qpolynomial@Base 0.10 + isl_qpolynomial_fold_alloc@Base 0.10 + isl_qpolynomial_fold_copy@Base 0.10 + isl_qpolynomial_fold_cow@Base 0.10 + isl_qpolynomial_fold_drop_dims@Base 0.10 + isl_qpolynomial_fold_dump@Base 0.10 + isl_qpolynomial_fold_dup@Base 0.10 + isl_qpolynomial_fold_empty@Base 0.10 + isl_qpolynomial_fold_eval@Base 0.10 + isl_qpolynomial_fold_fold@Base 0.10 + isl_qpolynomial_fold_fold_on_domain@Base 0.10 + isl_qpolynomial_fold_foreach_qpolynomial@Base 0.10 + isl_qpolynomial_fold_free@Base 0.10 + isl_qpolynomial_fold_get_ctx@Base 0.10 + isl_qpolynomial_fold_get_domain_space@Base 0.10 + isl_qpolynomial_fold_get_space@Base 0.10 + isl_qpolynomial_fold_get_type@Base 0.10 + isl_qpolynomial_fold_gist@Base 0.10 + isl_qpolynomial_fold_gist_params@Base 0.10 + isl_qpolynomial_fold_insert_dims@Base 0.10 + isl_qpolynomial_fold_involves_dims@Base 0.10 + isl_qpolynomial_fold_is_empty@Base 0.10 + isl_qpolynomial_fold_is_nan@Base 0.15 + isl_qpolynomial_fold_lift@Base 0.10 + isl_qpolynomial_fold_morph_domain@Base 0.10 + isl_qpolynomial_fold_move_dims@Base 0.10 + isl_qpolynomial_fold_mul_isl_int@Base 0.10 + isl_qpolynomial_fold_opt_on_domain@Base 0.10 + isl_qpolynomial_fold_plain_is_equal@Base 0.10 + isl_qpolynomial_fold_print@Base 0.10 + isl_qpolynomial_fold_realign_domain@Base 0.10 + isl_qpolynomial_fold_reset_domain_space@Base 0.10 + isl_qpolynomial_fold_reset_space_and_domain@Base 0.10 + isl_qpolynomial_fold_scale@Base 0.10 + isl_qpolynomial_fold_scale_down_val@Base 0.15 + isl_qpolynomial_fold_scale_val@Base 0.12.1 + isl_qpolynomial_fold_set_dim_name@Base 0.10 + isl_qpolynomial_fold_substitute@Base 0.10 + isl_qpolynomial_fold_substitute_equalities@Base 0.10 + isl_qpolynomial_fold_to_str@Base 0.10 + isl_qpolynomial_foreach_term@Base 0.10 + isl_qpolynomial_free@Base 0.10 + isl_qpolynomial_from_aff@Base 0.10 + isl_qpolynomial_from_affine@Base 0.10 + isl_qpolynomial_from_constraint@Base 0.10 + isl_qpolynomial_from_term@Base 0.10 + isl_qpolynomial_get_constant_val@Base 0.12.1 + isl_qpolynomial_get_ctx@Base 0.10 + isl_qpolynomial_get_den@Base 0.10 + isl_qpolynomial_get_domain_space@Base 0.10 + isl_qpolynomial_get_space@Base 0.10 + isl_qpolynomial_gist@Base 0.10 + isl_qpolynomial_gist_params@Base 0.10 + isl_qpolynomial_homogenize@Base 0.10 + isl_qpolynomial_infty_on_domain@Base 0.10 + isl_qpolynomial_insert_dims@Base 0.10 + isl_qpolynomial_involves_dims@Base 0.10 + isl_qpolynomial_is_affine@Base 0.10 + isl_qpolynomial_is_cst@Base 0.10 + isl_qpolynomial_is_infty@Base 0.10 + isl_qpolynomial_is_nan@Base 0.10 + isl_qpolynomial_is_neginfty@Base 0.10 + isl_qpolynomial_is_one@Base 0.10 + isl_qpolynomial_is_zero@Base 0.10 + isl_qpolynomial_lift@Base 0.10 + isl_qpolynomial_morph_domain@Base 0.10 + isl_qpolynomial_move_dims@Base 0.10 + isl_qpolynomial_mul@Base 0.10 + isl_qpolynomial_mul_isl_int@Base 0.10 + isl_qpolynomial_nan_on_domain@Base 0.10 + isl_qpolynomial_neg@Base 0.10 + isl_qpolynomial_neginfty_on_domain@Base 0.10 + isl_qpolynomial_one_on_domain@Base 0.10 + isl_qpolynomial_opt_on_domain@Base 0.10 + isl_qpolynomial_plain_is_equal@Base 0.10 + isl_qpolynomial_pow@Base 0.10 + isl_qpolynomial_print@Base 0.10 + isl_qpolynomial_project_domain_on_params@Base 0.10 + isl_qpolynomial_rat_cst_on_domain@Base 0.10 + isl_qpolynomial_realign_domain@Base 0.10 + isl_qpolynomial_reset_domain_space@Base 0.10 + isl_qpolynomial_reset_space_and_domain@Base 0.10 + isl_qpolynomial_scale@Base 0.10 + isl_qpolynomial_scale_down_val@Base 0.15 + isl_qpolynomial_scale_val@Base 0.12.1 + isl_qpolynomial_set_dim_name@Base 0.10 + isl_qpolynomial_sgn@Base 0.10 + isl_qpolynomial_sub@Base 0.10 + isl_qpolynomial_substitute@Base 0.10 + isl_qpolynomial_substitute_equalities@Base 0.10 + isl_qpolynomial_terms_of_sign@Base 0.10 + isl_qpolynomial_to_str@Base 0.10 + isl_qpolynomial_val_on_domain@Base 0.12.1 + isl_qpolynomial_var_on_domain@Base 0.10 + isl_qpolynomial_var_pow_on_domain@Base 0.10 + isl_qpolynomial_zero_on_domain@Base 0.10 + isl_realloc_or_die@Base 0.13 + isl_reordering_alloc@Base 0.10 + isl_reordering_copy@Base 0.10 + isl_reordering_cow@Base 0.10 + isl_reordering_dump@Base 0.10 + isl_reordering_dup@Base 0.10 + isl_reordering_extend@Base 0.10 + isl_reordering_extend_space@Base 0.10 + isl_reordering_free@Base 0.10 + isl_restriction_empty@Base 0.10 + isl_restriction_free@Base 0.10 + isl_restriction_get_ctx@Base 0.10 + isl_restriction_input@Base 0.10 + isl_restriction_none@Base 0.10 + isl_restriction_output@Base 0.10 + isl_schedule_align_params@Base 0.15 + isl_schedule_band_align_params@Base 0.15 + isl_schedule_band_copy@Base 0.15 + isl_schedule_band_cow@Base 0.15 + isl_schedule_band_drop@Base 0.15 + isl_schedule_band_dup@Base 0.15 + isl_schedule_band_free@Base 0.15 + isl_schedule_band_from_multi_union_pw_aff@Base 0.15 + isl_schedule_band_get_ast_build_options@Base 0.15 + isl_schedule_band_get_ctx@Base 0.15 + isl_schedule_band_get_partial_schedule@Base 0.15 + isl_schedule_band_get_permutable@Base 0.15 + isl_schedule_band_get_space@Base 0.15 + isl_schedule_band_gist@Base 0.15 + isl_schedule_band_intersect_domain@Base 0.15 + isl_schedule_band_is_anchored@Base 0.15 + isl_schedule_band_member_get_ast_loop_type@Base 0.15 + isl_schedule_band_member_get_coincident@Base 0.15 + isl_schedule_band_member_get_isolate_ast_loop_type@Base 0.15 + isl_schedule_band_member_set_ast_loop_type@Base 0.15 + isl_schedule_band_member_set_coincident@Base 0.15 + isl_schedule_band_member_set_isolate_ast_loop_type@Base 0.15 + isl_schedule_band_n_member@Base 0.15 + isl_schedule_band_plain_is_equal@Base 0.15 + isl_schedule_band_point@Base 0.15 + isl_schedule_band_pullback_union_pw_multi_aff@Base 0.15 + isl_schedule_band_reset_user@Base 0.15 + isl_schedule_band_scale@Base 0.15 + isl_schedule_band_scale_down@Base 0.15 + isl_schedule_band_set_ast_build_options@Base 0.15 + isl_schedule_band_set_partial_schedule@Base 0.15 + isl_schedule_band_set_permutable@Base 0.15 + isl_schedule_band_tile@Base 0.15 + isl_schedule_constraints_compute_schedule@Base 0.13 + isl_schedule_constraints_copy@Base 0.13 + isl_schedule_constraints_dump@Base 0.13 + isl_schedule_constraints_free@Base 0.13 + isl_schedule_constraints_get_coincidence@Base 0.15 + isl_schedule_constraints_get_conditional_validity@Base 0.15 + isl_schedule_constraints_get_conditional_validity_condition@Base 0.15 + isl_schedule_constraints_get_ctx@Base 0.13 + isl_schedule_constraints_get_validity@Base 0.15 + isl_schedule_constraints_on_domain@Base 0.13 + isl_schedule_constraints_set_coincidence@Base 0.13 + isl_schedule_constraints_set_conditional_validity@Base 0.13 + isl_schedule_constraints_set_context@Base 0.15 + isl_schedule_constraints_set_proximity@Base 0.13 + isl_schedule_constraints_set_validity@Base 0.13 + isl_schedule_copy@Base 0.15 + isl_schedule_cow@Base 0.15 + isl_schedule_dump@Base 0.10 + isl_schedule_empty@Base 0.15 + isl_schedule_foreach_band@Base 0.10 + isl_schedule_foreach_schedule_node_top_down@Base 0.15 + isl_schedule_free@Base 0.10 + isl_schedule_from_domain@Base 0.15 + isl_schedule_from_schedule_tree@Base 0.15 + isl_schedule_get_band_forest@Base 0.10 + isl_schedule_get_ctx@Base 0.10 + isl_schedule_get_domain@Base 0.15 + isl_schedule_get_map@Base 0.10 + isl_schedule_get_root@Base 0.15 + isl_schedule_get_space@Base 0.15 + isl_schedule_insert_context@Base 0.15 + isl_schedule_insert_guard@Base 0.15 + isl_schedule_insert_partial_schedule@Base 0.15 + isl_schedule_intersect_domain@Base 0.15 + isl_schedule_map_schedule_node_bottom_up@Base 0.15 + isl_schedule_node_align_params@Base 0.15 + isl_schedule_node_alloc@Base 0.15 + isl_schedule_node_ancestor@Base 0.15 + isl_schedule_node_band_get_ast_build_options@Base 0.15 + isl_schedule_node_band_get_partial_schedule@Base 0.15 + isl_schedule_node_band_get_partial_schedule_union_map@Base 0.15 + isl_schedule_node_band_get_permutable@Base 0.15 + isl_schedule_node_band_get_space@Base 0.15 + isl_schedule_node_band_gist@Base 0.15 + isl_schedule_node_band_member_get_ast_loop_type@Base 0.15 + isl_schedule_node_band_member_get_coincident@Base 0.15 + isl_schedule_node_band_member_get_isolate_ast_loop_type@Base 0.15 + isl_schedule_node_band_member_set_ast_loop_type@Base 0.15 + isl_schedule_node_band_member_set_coincident@Base 0.15 + isl_schedule_node_band_member_set_isolate_ast_loop_type@Base 0.15 + isl_schedule_node_band_n_member@Base 0.15 + isl_schedule_node_band_scale@Base 0.15 + isl_schedule_node_band_scale_down@Base 0.15 + isl_schedule_node_band_set_ast_build_options@Base 0.15 + isl_schedule_node_band_set_permutable@Base 0.15 + isl_schedule_node_band_sink@Base 0.15 + isl_schedule_node_band_split@Base 0.15 + isl_schedule_node_band_tile@Base 0.15 + isl_schedule_node_child@Base 0.15 + isl_schedule_node_context_get_context@Base 0.15 + isl_schedule_node_copy@Base 0.15 + isl_schedule_node_cow@Base 0.15 + isl_schedule_node_cut@Base 0.15 + isl_schedule_node_delete@Base 0.15 + isl_schedule_node_domain_get_domain@Base 0.15 + isl_schedule_node_domain_intersect_domain@Base 0.15 + isl_schedule_node_dump@Base 0.15 + isl_schedule_node_dup@Base 0.15 + isl_schedule_node_expansion_get_contraction@Base 0.15 + isl_schedule_node_expansion_get_expansion@Base 0.15 + isl_schedule_node_expansion_set_contraction_and_expansion@Base 0.15 + isl_schedule_node_extension_get_extension@Base 0.15 + isl_schedule_node_extension_set_extension@Base 0.15 + isl_schedule_node_filter_get_filter@Base 0.15 + isl_schedule_node_filter_set_filter@Base 0.15 + isl_schedule_node_first_child@Base 0.15 + isl_schedule_node_foreach_ancestor_top_down@Base 0.15 + isl_schedule_node_foreach_descendant_top_down@Base 0.15 + isl_schedule_node_free@Base 0.15 + isl_schedule_node_from_domain@Base 0.15 + isl_schedule_node_from_extension@Base 0.15 + isl_schedule_node_get_ancestor_child_position@Base 0.15 + isl_schedule_node_get_child@Base 0.15 + isl_schedule_node_get_child_position@Base 0.15 + isl_schedule_node_get_ctx@Base 0.15 + isl_schedule_node_get_domain@Base 0.15 + isl_schedule_node_get_leaf@Base 0.15 + isl_schedule_node_get_parent_type@Base 0.15 + isl_schedule_node_get_prefix_schedule_multi_union_pw_aff@Base 0.15 + isl_schedule_node_get_prefix_schedule_relation@Base 0.15 + isl_schedule_node_get_prefix_schedule_union_map@Base 0.15 + isl_schedule_node_get_prefix_schedule_union_pw_multi_aff@Base 0.15 + isl_schedule_node_get_schedule@Base 0.15 + isl_schedule_node_get_schedule_depth@Base 0.15 + isl_schedule_node_get_shared_ancestor@Base 0.15 + isl_schedule_node_get_subtree_contraction@Base 0.15 + isl_schedule_node_get_subtree_expansion@Base 0.15 + isl_schedule_node_get_subtree_schedule_union_map@Base 0.15 + isl_schedule_node_get_tree@Base 0.15 + isl_schedule_node_get_tree_depth@Base 0.15 + isl_schedule_node_get_type@Base 0.15 + isl_schedule_node_get_universe_domain@Base 0.15 + isl_schedule_node_gist@Base 0.15 + isl_schedule_node_graft_after@Base 0.15 + isl_schedule_node_graft_before@Base 0.15 + isl_schedule_node_graft_tree@Base 0.15 + isl_schedule_node_group@Base 0.15 + isl_schedule_node_guard_get_guard@Base 0.15 + isl_schedule_node_has_children@Base 0.15 + isl_schedule_node_has_next_sibling@Base 0.15 + isl_schedule_node_has_parent@Base 0.15 + isl_schedule_node_has_previous_sibling@Base 0.15 + isl_schedule_node_insert_context@Base 0.15 + isl_schedule_node_insert_expansion@Base 0.15 + isl_schedule_node_insert_extension@Base 0.15 + isl_schedule_node_insert_filter@Base 0.15 + isl_schedule_node_insert_guard@Base 0.15 + isl_schedule_node_insert_mark@Base 0.15 + isl_schedule_node_insert_partial_schedule@Base 0.15 + isl_schedule_node_insert_sequence@Base 0.15 + isl_schedule_node_insert_set@Base 0.15 + isl_schedule_node_is_equal@Base 0.15 + isl_schedule_node_is_subtree_anchored@Base 0.15 + isl_schedule_node_map_descendant_bottom_up@Base 0.15 + isl_schedule_node_mark_get_id@Base 0.15 + isl_schedule_node_n_children@Base 0.15 + isl_schedule_node_next_sibling@Base 0.15 + isl_schedule_node_order_after@Base 0.15 + isl_schedule_node_parent@Base 0.15 + isl_schedule_node_peek_leaf@Base 0.15 + isl_schedule_node_previous_sibling@Base 0.15 + isl_schedule_node_pullback_union_pw_multi_aff@Base 0.15 + isl_schedule_node_reset_user@Base 0.15 + isl_schedule_node_root@Base 0.15 + isl_schedule_node_sequence_splice@Base 0.15 + isl_schedule_pair@Base 0.15 + isl_schedule_peek_leaf@Base 0.15 + isl_schedule_plain_is_equal@Base 0.15 + isl_schedule_pullback_union_pw_multi_aff@Base 0.15 + isl_schedule_read_from_file@Base 0.15 + isl_schedule_read_from_str@Base 0.15 + isl_schedule_reset_user@Base 0.15 + isl_schedule_sequence@Base 0.15 + isl_schedule_set@Base 0.15 + isl_schedule_set_root@Base 0.15 + isl_schedule_tree_align_params@Base 0.15 + isl_schedule_tree_append_to_leaves@Base 0.15 + isl_schedule_tree_band_get_ast_build_options@Base 0.15 + isl_schedule_tree_band_get_partial_schedule@Base 0.15 + isl_schedule_tree_band_get_permutable@Base 0.15 + isl_schedule_tree_band_get_space@Base 0.15 + isl_schedule_tree_band_gist@Base 0.15 + isl_schedule_tree_band_intersect_domain@Base 0.15 + isl_schedule_tree_band_member_get_ast_loop_type@Base 0.15 + isl_schedule_tree_band_member_get_coincident@Base 0.15 + isl_schedule_tree_band_member_get_isolate_ast_loop_type@Base 0.15 + isl_schedule_tree_band_member_set_ast_loop_type@Base 0.15 + isl_schedule_tree_band_member_set_coincident@Base 0.15 + isl_schedule_tree_band_member_set_isolate_ast_loop_type@Base 0.15 + isl_schedule_tree_band_n_member@Base 0.15 + isl_schedule_tree_band_scale@Base 0.15 + isl_schedule_tree_band_scale_down@Base 0.15 + isl_schedule_tree_band_set_ast_build_options@Base 0.15 + isl_schedule_tree_band_set_partial_schedule@Base 0.15 + isl_schedule_tree_band_set_permutable@Base 0.15 + isl_schedule_tree_band_split@Base 0.15 + isl_schedule_tree_band_tile@Base 0.15 + isl_schedule_tree_child@Base 0.15 + isl_schedule_tree_children_insert_filter@Base 0.15 + isl_schedule_tree_context_get_context@Base 0.15 + isl_schedule_tree_copy@Base 0.15 + isl_schedule_tree_cow@Base 0.15 + isl_schedule_tree_domain_get_domain@Base 0.15 + isl_schedule_tree_domain_set_domain@Base 0.15 + isl_schedule_tree_drop_child@Base 0.15 + isl_schedule_tree_dump@Base 0.15 + isl_schedule_tree_dup@Base 0.15 + isl_schedule_tree_expansion_get_contraction@Base 0.15 + isl_schedule_tree_expansion_get_expansion@Base 0.15 + isl_schedule_tree_expansion_set_contraction_and_expansion@Base 0.15 + isl_schedule_tree_extension_get_extension@Base 0.15 + isl_schedule_tree_extension_set_extension@Base 0.15 + isl_schedule_tree_filter_get_filter@Base 0.15 + isl_schedule_tree_filter_set_filter@Base 0.15 + isl_schedule_tree_first_schedule_descendant@Base 0.15 + isl_schedule_tree_free@Base 0.15 + isl_schedule_tree_from_band@Base 0.15 + isl_schedule_tree_from_children@Base 0.15 + isl_schedule_tree_from_context@Base 0.15 + isl_schedule_tree_from_domain@Base 0.15 + isl_schedule_tree_from_expansion@Base 0.15 + isl_schedule_tree_from_extension@Base 0.15 + isl_schedule_tree_from_filter@Base 0.15 + isl_schedule_tree_from_guard@Base 0.15 + isl_schedule_tree_from_mark@Base 0.15 + isl_schedule_tree_from_pair@Base 0.15 + isl_schedule_tree_get_child@Base 0.15 + isl_schedule_tree_get_ctx@Base 0.15 + isl_schedule_tree_get_subtree_schedule_union_map@Base 0.15 + isl_schedule_tree_get_type@Base 0.15 + isl_schedule_tree_guard_get_guard@Base 0.15 + isl_schedule_tree_has_children@Base 0.15 + isl_schedule_tree_insert_band@Base 0.15 + isl_schedule_tree_insert_context@Base 0.15 + isl_schedule_tree_insert_domain@Base 0.15 + isl_schedule_tree_insert_expansion@Base 0.15 + isl_schedule_tree_insert_extension@Base 0.15 + isl_schedule_tree_insert_filter@Base 0.15 + isl_schedule_tree_insert_guard@Base 0.15 + isl_schedule_tree_insert_mark@Base 0.15 + isl_schedule_tree_is_anchored@Base 0.15 + isl_schedule_tree_is_leaf@Base 0.15 + isl_schedule_tree_is_subtree_anchored@Base 0.15 + isl_schedule_tree_leaf@Base 0.15 + isl_schedule_tree_list_add@Base 0.15 + isl_schedule_tree_list_alloc@Base 0.15 + isl_schedule_tree_list_concat@Base 0.15 + isl_schedule_tree_list_copy@Base 0.15 + isl_schedule_tree_list_cow@Base 0.15 + isl_schedule_tree_list_drop@Base 0.15 + isl_schedule_tree_list_dump@Base 0.15 + isl_schedule_tree_list_dup@Base 0.15 + isl_schedule_tree_list_foreach@Base 0.15 + isl_schedule_tree_list_foreach_scc@Base 0.15 + isl_schedule_tree_list_free@Base 0.15 + isl_schedule_tree_list_from_schedule_tree@Base 0.15 + isl_schedule_tree_list_get_ctx@Base 0.15 + isl_schedule_tree_list_get_schedule_tree@Base 0.15 + isl_schedule_tree_list_insert@Base 0.15 + isl_schedule_tree_list_n_schedule_tree@Base 0.15 + isl_schedule_tree_list_set_schedule_tree@Base 0.15 + isl_schedule_tree_list_sort@Base 0.15 + isl_schedule_tree_mark_get_id@Base 0.15 + isl_schedule_tree_n_children@Base 0.15 + isl_schedule_tree_plain_is_equal@Base 0.15 + isl_schedule_tree_pullback_union_pw_multi_aff@Base 0.15 + isl_schedule_tree_replace_child@Base 0.15 + isl_schedule_tree_reset_children@Base 0.15 + isl_schedule_tree_reset_user@Base 0.15 + isl_schedule_tree_sequence_pair@Base 0.15 + isl_schedule_tree_sequence_splice@Base 0.15 + isl_schedule_tree_set_children@Base 0.15 + isl_schedule_tree_update_anchored@Base 0.15 + isl_seq_abs_max@Base 0.10 + isl_seq_abs_min_non_zero@Base 0.10 + isl_seq_addmul@Base 0.10 + isl_seq_cdiv_q@Base 0.10 + isl_seq_clr@Base 0.10 + isl_seq_cmp@Base 0.10 + isl_seq_combine@Base 0.10 + isl_seq_cpy@Base 0.10 + isl_seq_dump@Base 0.10 + isl_seq_elim@Base 0.10 + isl_seq_eq@Base 0.10 + isl_seq_fdiv_q@Base 0.10 + isl_seq_fdiv_r@Base 0.10 + isl_seq_first_non_zero@Base 0.10 + isl_seq_gcd@Base 0.10 + isl_seq_get_hash@Base 0.10 + isl_seq_get_hash_bits@Base 0.10 + isl_seq_hash@Base 0.10 + isl_seq_inner_product@Base 0.10 + isl_seq_is_neg@Base 0.10 + isl_seq_last_non_zero@Base 0.10 + isl_seq_lcm@Base 0.10 + isl_seq_neg@Base 0.10 + isl_seq_normalize@Base 0.10 + isl_seq_preimage@Base 0.11 + isl_seq_scale@Base 0.10 + isl_seq_scale_down@Base 0.10 + isl_seq_set@Base 0.10 + isl_seq_set_si@Base 0.10 + isl_seq_submul@Base 0.10 + isl_seq_substitute@Base 0.11 + isl_seq_swp_or_cpy@Base 0.10 + isl_set_add_basic_set@Base 0.10 + isl_set_add_constraint@Base 0.10 + isl_set_add_dims@Base 0.10 + isl_set_affine_hull@Base 0.10 + isl_set_align_divs@Base 0.10 + isl_set_align_params@Base 0.10 + isl_set_alloc@Base 0.10 + isl_set_alloc_space@Base 0.10 + isl_set_apply@Base 0.10 + isl_set_apply_pw_qpolynomial_fold@Base 0.10 + isl_set_bounded_simple_hull@Base 0.10 + isl_set_box_from_points@Base 0.10 + isl_set_coalesce@Base 0.10 + isl_set_coefficients@Base 0.10 + isl_set_complement@Base 0.10 + isl_set_compute_divs@Base 0.10 + isl_set_contains_point@Base 0.10 + isl_set_convex_hull@Base 0.10 + isl_set_copy@Base 0.10 + isl_set_copy_basic_set@Base 0.10 + isl_set_count@Base 0.10 + isl_set_count_upto@Base 0.10 + isl_set_count_val@Base 0.12.1 + isl_set_cow@Base 0.10 + isl_set_detect_equalities@Base 0.10 + isl_set_dim@Base 0.10 + isl_set_dim_has_any_lower_bound@Base 0.11 + isl_set_dim_has_any_upper_bound@Base 0.11 + isl_set_dim_has_lower_bound@Base 0.10 + isl_set_dim_has_upper_bound@Base 0.10 + isl_set_dim_is_bounded@Base 0.10 + isl_set_dim_is_unique@Base 0.10 + isl_set_dim_max@Base 0.10 + isl_set_dim_min@Base 0.10 + isl_set_dim_residue_class@Base 0.10 + isl_set_dim_residue_class_val@Base 0.12.1 + isl_set_drop@Base 0.10 + isl_set_drop_basic_set@Base 0.10 + isl_set_drop_constraints_involving_dims@Base 0.11 + isl_set_drop_dims@Base 0.10 + isl_set_drop_redundant_divs@Base 0.10 + isl_set_dump@Base 0.10 + isl_set_dup@Base 0.10 + isl_set_eliminate@Base 0.10 + isl_set_eliminate_dims@Base 0.10 + isl_set_empty@Base 0.10 + isl_set_equate@Base 0.10 + isl_set_finalize@Base 0.10 + isl_set_find_dim_by_id@Base 0.10 + isl_set_find_dim_by_name@Base 0.10 + isl_set_fix@Base 0.10 + isl_set_fix_dim_si@Base 0.10 + isl_set_fix_si@Base 0.10 + isl_set_fix_val@Base 0.12.1 + isl_set_flat_product@Base 0.10 + isl_set_flatten@Base 0.10 + isl_set_flatten_map@Base 0.10 + isl_set_follows_at@Base 0.10 + isl_set_foreach_basic_set@Base 0.10 + isl_set_foreach_orthant@Base 0.10 + isl_set_foreach_point@Base 0.10 + isl_set_free@Base 0.10 + isl_set_from_basic_set@Base 0.10 + isl_set_from_multi_pw_aff@Base 0.13 + isl_set_from_params@Base 0.10 + isl_set_from_point@Base 0.10 + isl_set_from_pw_aff@Base 0.10 + isl_set_from_pw_multi_aff@Base 0.10 + isl_set_from_underlying_set@Base 0.10 + isl_set_from_union_set@Base 0.10 + isl_set_get_ctx@Base 0.10 + isl_set_get_dim_id@Base 0.10 + isl_set_get_dim_name@Base 0.10 + isl_set_get_hash@Base 0.10 + isl_set_get_space@Base 0.10 + isl_set_get_tuple_id@Base 0.10 + isl_set_get_tuple_name@Base 0.10 + isl_set_gist@Base 0.10 + isl_set_gist_basic_set@Base 0.10 + isl_set_gist_params@Base 0.10 + isl_set_gist_params_basic_set@Base 0.10 + isl_set_grow@Base 0.10 + isl_set_has_dim_id@Base 0.10 + isl_set_has_dim_name@Base 0.10 + isl_set_has_equal_space@Base 0.10 + isl_set_has_rational@Base 0.11 + isl_set_has_tuple_id@Base 0.10 + isl_set_has_tuple_name@Base 0.10 + isl_set_identity@Base 0.10 + isl_set_indicator_function@Base 0.10 + isl_set_insert_dims@Base 0.10 + isl_set_intersect@Base 0.10 + isl_set_intersect_params@Base 0.10 + isl_set_involves_dims@Base 0.10 + isl_set_is_bounded@Base 0.10 + isl_set_is_box@Base 0.10 + isl_set_is_disjoint@Base 0.11 + isl_set_is_empty@Base 0.10 + isl_set_is_equal@Base 0.10 + isl_set_is_params@Base 0.10 + isl_set_is_singleton@Base 0.10 + isl_set_is_strict_subset@Base 0.10 + isl_set_is_subset@Base 0.10 + isl_set_is_wrapping@Base 0.10 + isl_set_lex_ge_set@Base 0.10 + isl_set_lex_gt_set@Base 0.10 + isl_set_lex_le_set@Base 0.10 + isl_set_lex_lt_set@Base 0.10 + isl_set_lexmax@Base 0.10 + isl_set_lexmax_pw_multi_aff@Base 0.12.1 + isl_set_lexmin@Base 0.10 + isl_set_lexmin_pw_multi_aff@Base 0.12.1 + isl_set_lift@Base 0.10 + isl_set_lifting@Base 0.10 + isl_set_list_add@Base 0.10 + isl_set_list_alloc@Base 0.10 + isl_set_list_concat@Base 0.10 + isl_set_list_copy@Base 0.10 + isl_set_list_cow@Base 0.11 + isl_set_list_drop@Base 0.11 + isl_set_list_dump@Base 0.10 + isl_set_list_dup@Base 0.10 + isl_set_list_foreach@Base 0.10 + isl_set_list_foreach_scc@Base 0.12.1 + isl_set_list_free@Base 0.10 + isl_set_list_from_set@Base 0.10 + isl_set_list_get_ctx@Base 0.10 + isl_set_list_get_set@Base 0.10 + isl_set_list_insert@Base 0.11 + isl_set_list_n_set@Base 0.10 + isl_set_list_set_set@Base 0.11 + isl_set_list_sort@Base 0.12.1 + isl_set_lower_bound@Base 0.10 + isl_set_lower_bound_dim@Base 0.10 + isl_set_lower_bound_si@Base 0.10 + isl_set_lower_bound_val@Base 0.12.1 + isl_set_make_disjoint@Base 0.10 + isl_set_max@Base 0.10 + isl_set_max_val@Base 0.12.1 + isl_set_min@Base 0.10 + isl_set_min_val@Base 0.12.1 + isl_set_move_dims@Base 0.10 + isl_set_n_basic_set@Base 0.10 + isl_set_n_dim@Base 0.10 + isl_set_n_param@Base 0.10 + isl_set_nat_universe@Base 0.10 + isl_set_neg@Base 0.10 + isl_set_normalize@Base 0.10 + isl_set_opt@Base 0.10 + isl_set_opt_val@Base 0.12.1 + isl_set_params@Base 0.10 + isl_set_partial_lexmax@Base 0.10 + isl_set_partial_lexmin@Base 0.10 + isl_set_plain_cmp@Base 0.10 + isl_set_plain_dim_has_fixed_lower_bound@Base 0.10 + isl_set_plain_dim_is_fixed@Base 0.10 + isl_set_plain_get_val_if_fixed@Base 0.12.1 + isl_set_plain_is_disjoint@Base 0.10 + isl_set_plain_is_empty@Base 0.10 + isl_set_plain_is_equal@Base 0.10 + isl_set_plain_is_fixed@Base 0.10 + isl_set_plain_is_universe@Base 0.10 + isl_set_polyhedral_hull@Base 0.10 + isl_set_preimage@Base 0.10 + isl_set_preimage_multi_aff@Base 0.11 + isl_set_preimage_multi_pw_aff@Base 0.13 + isl_set_preimage_pw_multi_aff@Base 0.11 + isl_set_print_internal@Base 0.10 + isl_set_product@Base 0.10 + isl_set_project_out@Base 0.10 + isl_set_read_from_file@Base 0.10 + isl_set_read_from_str@Base 0.10 + isl_set_realign@Base 0.10 + isl_set_recession_cone@Base 0.10 + isl_set_remove_dims@Base 0.10 + isl_set_remove_divs@Base 0.10 + isl_set_remove_divs_involving_dims@Base 0.10 + isl_set_remove_empty_parts@Base 0.10 + isl_set_remove_redundancies@Base 0.10 + isl_set_remove_unknown_divs@Base 0.10 + isl_set_reset_space@Base 0.10 + isl_set_reset_tuple_id@Base 0.10 + isl_set_reset_user@Base 0.13 + isl_set_sample@Base 0.10 + isl_set_sample_point@Base 0.10 + isl_set_scan@Base 0.10 + isl_set_set_dim_id@Base 0.10 + isl_set_set_dim_name@Base 0.10 + isl_set_set_rational@Base 0.10 + isl_set_set_tuple_id@Base 0.10 + isl_set_set_tuple_name@Base 0.10 + isl_set_simple_hull@Base 0.10 + isl_set_size@Base 0.10 + isl_set_solutions@Base 0.10 + isl_set_solve_lp@Base 0.10 + isl_set_split_dims@Base 0.10 + isl_set_substitute@Base 0.10 + isl_set_subtract@Base 0.10 + isl_set_sum@Base 0.10 + isl_set_to_str@Base 0.10 + isl_set_to_underlying_set@Base 0.10 + isl_set_union@Base 0.10 + isl_set_union_disjoint@Base 0.10 + isl_set_universe@Base 0.10 + isl_set_unshifted_simple_hull@Base 0.11 + isl_set_unshifted_simple_hull_from_set_list@Base 0.14 + isl_set_unwrap@Base 0.10 + isl_set_upper_bound@Base 0.10 + isl_set_upper_bound_si@Base 0.10 + isl_set_upper_bound_val@Base 0.12.1 + isl_set_wrap_facet@Base 0.10 + isl_set_wrapped_domain_map@Base 0.15 + isl_sort@Base 0.11 + isl_space_add_dims@Base 0.10 + isl_space_align_params@Base 0.10 + isl_space_alloc@Base 0.10 + isl_space_as_set_space@Base 0.10 + isl_space_can_curry@Base 0.10 + isl_space_can_uncurry@Base 0.11 + isl_space_can_zip@Base 0.10 + isl_space_cmp@Base 0.13 + isl_space_compatible@Base 0.10 + isl_space_copy@Base 0.10 + isl_space_cow@Base 0.10 + isl_space_curry@Base 0.10 + isl_space_dim@Base 0.10 + isl_space_domain@Base 0.10 + isl_space_domain_factor_domain@Base 0.13 + isl_space_domain_factor_range@Base 0.15 + isl_space_domain_is_wrapping@Base 0.13 + isl_space_domain_map@Base 0.13 + isl_space_domain_product@Base 0.10 + isl_space_drop_dims@Base 0.10 + isl_space_drop_inputs@Base 0.10 + isl_space_drop_outputs@Base 0.10 + isl_space_dump@Base 0.10 + isl_space_dup@Base 0.10 + isl_space_extend@Base 0.10 + isl_space_extend_domain_with_range@Base 0.10 + isl_space_factor_domain@Base 0.15 + isl_space_factor_range@Base 0.15 + isl_space_find_dim_by_id@Base 0.10 + isl_space_find_dim_by_name@Base 0.10 + isl_space_flatten@Base 0.10 + isl_space_flatten_domain@Base 0.10 + isl_space_flatten_range@Base 0.10 + isl_space_free@Base 0.10 + isl_space_from_domain@Base 0.10 + isl_space_from_range@Base 0.10 + isl_space_get_ctx@Base 0.10 + isl_space_get_dim_id@Base 0.10 + isl_space_get_dim_name@Base 0.10 + isl_space_get_hash@Base 0.10 + isl_space_get_tuple_id@Base 0.10 + isl_space_get_tuple_name@Base 0.10 + isl_space_has_dim_id@Base 0.10 + isl_space_has_dim_name@Base 0.10 + isl_space_has_named_params@Base 0.10 + isl_space_has_tuple_id@Base 0.10 + isl_space_has_tuple_name@Base 0.10 + isl_space_insert_dims@Base 0.10 + isl_space_is_domain@Base 0.10 + isl_space_is_domain_internal@Base 0.11 + isl_space_is_equal@Base 0.10 + isl_space_is_map@Base 0.11 + isl_space_is_named_or_nested@Base 0.10 + isl_space_is_params@Base 0.10 + isl_space_is_range@Base 0.11 + isl_space_is_range_internal@Base 0.11 + isl_space_is_set@Base 0.10 + isl_space_is_wrapping@Base 0.10 + isl_space_join@Base 0.10 + isl_space_lift@Base 0.10 + isl_space_map_from_domain_and_range@Base 0.10 + isl_space_map_from_set@Base 0.10 + isl_space_match@Base 0.10 + isl_space_may_be_set@Base 0.10 + isl_space_move_dims@Base 0.10 + isl_space_offset@Base 0.10 + isl_space_params@Base 0.10 + isl_space_params_alloc@Base 0.10 + isl_space_product@Base 0.10 + isl_space_range@Base 0.10 + isl_space_range_factor_domain@Base 0.13 + isl_space_range_factor_range@Base 0.13 + isl_space_range_is_wrapping@Base 0.13 + isl_space_range_map@Base 0.13 + isl_space_range_product@Base 0.10 + isl_space_replace@Base 0.10 + isl_space_reset@Base 0.10 + isl_space_reset_dim_id@Base 0.10 + isl_space_reset_tuple_id@Base 0.10 + isl_space_reset_user@Base 0.13 + isl_space_reverse@Base 0.10 + isl_space_set_alloc@Base 0.10 + isl_space_set_dim_id@Base 0.10 + isl_space_set_dim_name@Base 0.10 + isl_space_set_from_params@Base 0.10 + isl_space_set_tuple_id@Base 0.10 + isl_space_set_tuple_name@Base 0.10 + isl_space_to_str@Base 0.10 + isl_space_tuple_is_equal@Base 0.14 + isl_space_tuple_match@Base 0.10 + isl_space_uncurry@Base 0.11 + isl_space_underlying@Base 0.10 + isl_space_unwrap@Base 0.10 + isl_space_wrap@Base 0.10 + isl_space_zip@Base 0.10 + isl_stream_eat@Base 0.10 + isl_stream_eat_if_available@Base 0.10 + isl_stream_error@Base 0.10 + isl_stream_flush_tokens@Base 0.10 + isl_stream_free@Base 0.10 + isl_stream_get_ctx@Base 0.15 + isl_stream_is_empty@Base 0.10 + isl_stream_new_file@Base 0.10 + isl_stream_new_str@Base 0.10 + isl_stream_next_token@Base 0.10 + isl_stream_next_token_is@Base 0.10 + isl_stream_next_token_on_same_line@Base 0.10 + isl_stream_push_token@Base 0.10 + isl_stream_read_aff@Base 0.10 + isl_stream_read_ident_if_available@Base 0.10 + isl_stream_read_map@Base 0.10 + isl_stream_read_multi_aff@Base 0.10 + isl_stream_read_multi_pw_aff@Base 0.13 + isl_stream_read_multi_union_pw_aff@Base 0.15 + isl_stream_read_multi_val@Base 0.15 + isl_stream_read_obj@Base 0.10 + isl_stream_read_pw_aff@Base 0.10 + isl_stream_read_pw_multi_aff@Base 0.10 + isl_stream_read_pw_qpolynomial@Base 0.10 + isl_stream_read_schedule@Base 0.15 + isl_stream_read_set@Base 0.10 + isl_stream_read_union_map@Base 0.10 + isl_stream_read_union_pw_multi_aff@Base 0.12.1 + isl_stream_read_union_pw_qpolynomial@Base 0.10 + isl_stream_read_union_set@Base 0.10 + isl_stream_read_val@Base 0.12.1 + isl_stream_register_keyword@Base 0.10 + isl_stream_skip_line@Base 0.10 + isl_stream_yaml_next@Base 0.15 + isl_stream_yaml_read_end_mapping@Base 0.15 + isl_stream_yaml_read_end_sequence@Base 0.15 + isl_stream_yaml_read_start_mapping@Base 0.15 + isl_stream_yaml_read_start_sequence@Base 0.15 + isl_tab_add_div@Base 0.10 + isl_tab_add_eq@Base 0.10 + isl_tab_add_ineq@Base 0.10 + isl_tab_add_row@Base 0.10 + isl_tab_add_sample@Base 0.10 + isl_tab_add_valid_eq@Base 0.10 + isl_tab_alloc@Base 0.10 + isl_tab_allocate_con@Base 0.10 + isl_tab_allocate_var@Base 0.10 + isl_tab_basic_map_partial_lexopt@Base 0.10 + isl_tab_basic_set_non_neg_lexmin@Base 0.10 + isl_tab_basic_set_non_trivial_lexmin@Base 0.10 + isl_tab_compute_reduced_basis@Base 0.10 + isl_tab_cone_is_bounded@Base 0.10 + isl_tab_detect_equalities@Base 0.10 + isl_tab_detect_implicit_equalities@Base 0.10 + isl_tab_detect_redundant@Base 0.10 + isl_tab_drop_sample@Base 0.10 + isl_tab_dump@Base 0.10 + isl_tab_dup@Base 0.10 + isl_tab_extend_cons@Base 0.10 + isl_tab_extend_vars@Base 0.10 + isl_tab_free@Base 0.10 + isl_tab_freeze_constraint@Base 0.10 + isl_tab_from_basic_map@Base 0.10 + isl_tab_from_basic_set@Base 0.10 + isl_tab_from_recession_cone@Base 0.10 + isl_tab_get_ctx@Base 0.12.1 + isl_tab_get_sample_value@Base 0.10 + isl_tab_ineq_type@Base 0.10 + isl_tab_init_samples@Base 0.10 + isl_tab_insert_var@Base 0.15 + isl_tab_is_equality@Base 0.10 + isl_tab_is_redundant@Base 0.10 + isl_tab_kill_col@Base 0.10 + isl_tab_make_equalities_explicit@Base 0.11.2 + isl_tab_mark_empty@Base 0.10 + isl_tab_mark_rational@Base 0.15 + isl_tab_mark_redundant@Base 0.10 + isl_tab_min@Base 0.10 + isl_tab_min_at_most_neg_one@Base 0.10 + isl_tab_peek_bset@Base 0.10 + isl_tab_pivot@Base 0.10 + isl_tab_product@Base 0.10 + isl_tab_push@Base 0.10 + isl_tab_push_basis@Base 0.10 + isl_tab_push_callback@Base 0.10 + isl_tab_push_var@Base 0.10 + isl_tab_relax@Base 0.10 + isl_tab_rollback@Base 0.10 + isl_tab_row_is_redundant@Base 0.10 + isl_tab_sample@Base 0.10 + isl_tab_sample_is_integer@Base 0.10 + isl_tab_save_samples@Base 0.10 + isl_tab_select_facet@Base 0.10 + isl_tab_set_initial_basis_with_cone@Base 0.10 + isl_tab_shift_var@Base 0.15 + isl_tab_sign_of_max@Base 0.10 + isl_tab_snap@Base 0.10 + isl_tab_solve_lp@Base 0.10 + isl_tab_track_bmap@Base 0.10 + isl_tab_track_bset@Base 0.10 + isl_tab_unrestrict@Base 0.12.1 + isl_tab_var_from_row@Base 0.10 + isl_tarjan_graph_free@Base 0.11 + isl_tarjan_graph_init@Base 0.11 + isl_term_alloc@Base 0.10 + isl_term_copy@Base 0.10 + isl_term_cow@Base 0.10 + isl_term_dim@Base 0.10 + isl_term_dup@Base 0.10 + isl_term_free@Base 0.10 + isl_term_get_coefficient_val@Base 0.12.1 + isl_term_get_ctx@Base 0.10 + isl_term_get_den@Base 0.10 + isl_term_get_div@Base 0.10 + isl_term_get_exp@Base 0.10 + isl_term_get_num@Base 0.10 + isl_token_free@Base 0.10 + isl_token_get_str@Base 0.12.1 + isl_token_get_type@Base 0.12.1 + isl_token_get_val@Base 0.12.1 + isl_token_new@Base 0.10 + isl_union_access_info_compute_flow@Base 0.15 + isl_union_access_info_copy@Base 0.15 + isl_union_access_info_free@Base 0.15 + isl_union_access_info_from_sink@Base 0.15 + isl_union_access_info_get_ctx@Base 0.15 + isl_union_access_info_set_may_source@Base 0.15 + isl_union_access_info_set_must_source@Base 0.15 + isl_union_access_info_set_schedule@Base 0.15 + isl_union_access_info_set_schedule_map@Base 0.15 + isl_union_flow_dump@Base 0.15 + isl_union_flow_free@Base 0.15 + isl_union_flow_get_ctx@Base 0.15 + isl_union_flow_get_may_dependence@Base 0.15 + isl_union_flow_get_may_no_source@Base 0.15 + isl_union_flow_get_must_dependence@Base 0.15 + isl_union_flow_get_must_no_source@Base 0.15 + isl_union_map_add_map@Base 0.10 + isl_union_map_affine_hull@Base 0.10 + isl_union_map_align_params@Base 0.10 + isl_union_map_apply_domain@Base 0.10 + isl_union_map_apply_range@Base 0.10 + isl_union_map_apply_union_pw_qpolynomial_fold@Base 0.10 + isl_union_map_coalesce@Base 0.10 + isl_union_map_compute_divs@Base 0.10 + isl_union_map_compute_flow@Base 0.10 + isl_union_map_contains@Base 0.10 + isl_union_map_copy@Base 0.10 + isl_union_map_cow@Base 0.10 + isl_union_map_curry@Base 0.10 + isl_union_map_deltas@Base 0.10 + isl_union_map_deltas_map@Base 0.10 + isl_union_map_detect_equalities@Base 0.10 + isl_union_map_dim@Base 0.13 + isl_union_map_domain@Base 0.10 + isl_union_map_domain_factor_domain@Base 0.15 + isl_union_map_domain_factor_range@Base 0.15 + isl_union_map_domain_map@Base 0.10 + isl_union_map_domain_map_union_pw_multi_aff@Base 0.15 + isl_union_map_domain_product@Base 0.11 + isl_union_map_dump@Base 0.10 + isl_union_map_dup@Base 0.10 + isl_union_map_empty@Base 0.10 + isl_union_map_eq_at_multi_union_pw_aff@Base 0.15 + isl_union_map_extract_map@Base 0.10 + isl_union_map_factor_domain@Base 0.15 + isl_union_map_factor_range@Base 0.15 + isl_union_map_find_dim_by_name@Base 0.15 + isl_union_map_fixed_power@Base 0.10 + isl_union_map_fixed_power_val@Base 0.12.1 + isl_union_map_flat_domain_product@Base 0.15 + isl_union_map_flat_range_product@Base 0.10 + isl_union_map_foreach_map@Base 0.10 + isl_union_map_free@Base 0.10 + isl_union_map_from_basic_map@Base 0.11 + isl_union_map_from_domain@Base 0.10 + isl_union_map_from_domain_and_range@Base 0.10 + isl_union_map_from_map@Base 0.10 + isl_union_map_from_multi_union_pw_aff@Base 0.15 + isl_union_map_from_range@Base 0.10 + isl_union_map_from_union_pw_aff@Base 0.15 + isl_union_map_from_union_pw_multi_aff@Base 0.10 + isl_union_map_get_ctx@Base 0.10 + isl_union_map_get_dim_id@Base 0.13 + isl_union_map_get_space@Base 0.10 + isl_union_map_gist@Base 0.10 + isl_union_map_gist_domain@Base 0.10 + isl_union_map_gist_params@Base 0.10 + isl_union_map_gist_range@Base 0.10 + isl_union_map_intersect@Base 0.10 + isl_union_map_intersect_domain@Base 0.10 + isl_union_map_intersect_params@Base 0.10 + isl_union_map_intersect_range@Base 0.10 + isl_union_map_involves_dims@Base 0.15 + isl_union_map_is_bijective@Base 0.10 + isl_union_map_is_disjoint@Base 0.15 + isl_union_map_is_empty@Base 0.10 + isl_union_map_is_equal@Base 0.10 + isl_union_map_is_injective@Base 0.10 + isl_union_map_is_single_valued@Base 0.10 + isl_union_map_is_strict_subset@Base 0.10 + isl_union_map_is_subset@Base 0.10 + isl_union_map_is_transitively_closed@Base 0.10 + isl_union_map_lex_ge_union_map@Base 0.10 + isl_union_map_lex_gt_at_multi_union_pw_aff@Base 0.15 + isl_union_map_lex_gt_union_map@Base 0.10 + isl_union_map_lex_le_union_map@Base 0.10 + isl_union_map_lex_lt_at_multi_union_pw_aff@Base 0.15 + isl_union_map_lex_lt_union_map@Base 0.10 + isl_union_map_lexmax@Base 0.10 + isl_union_map_lexmin@Base 0.10 + isl_union_map_list_add@Base 0.15 + isl_union_map_list_alloc@Base 0.15 + isl_union_map_list_concat@Base 0.15 + isl_union_map_list_copy@Base 0.15 + isl_union_map_list_cow@Base 0.15 + isl_union_map_list_drop@Base 0.15 + isl_union_map_list_dump@Base 0.15 + isl_union_map_list_dup@Base 0.15 + isl_union_map_list_foreach@Base 0.15 + isl_union_map_list_foreach_scc@Base 0.15 + isl_union_map_list_free@Base 0.15 + isl_union_map_list_from_union_map@Base 0.15 + isl_union_map_list_get_ctx@Base 0.15 + isl_union_map_list_get_union_map@Base 0.15 + isl_union_map_list_insert@Base 0.15 + isl_union_map_list_n_union_map@Base 0.15 + isl_union_map_list_set_union_map@Base 0.15 + isl_union_map_list_sort@Base 0.15 + isl_union_map_n_map@Base 0.10 + isl_union_map_params@Base 0.10 + isl_union_map_plain_is_injective@Base 0.10 + isl_union_map_polyhedral_hull@Base 0.10 + isl_union_map_power@Base 0.10 + isl_union_map_preimage_domain_multi_aff@Base 0.12.1 + isl_union_map_preimage_domain_multi_pw_aff@Base 0.13 + isl_union_map_preimage_domain_pw_multi_aff@Base 0.13 + isl_union_map_preimage_domain_union_pw_multi_aff@Base 0.13 + isl_union_map_preimage_range_multi_aff@Base 0.13 + isl_union_map_preimage_range_pw_multi_aff@Base 0.13 + isl_union_map_preimage_range_union_pw_multi_aff@Base 0.13 + isl_union_map_product@Base 0.10 + isl_union_map_project_out@Base 0.13 + isl_union_map_range@Base 0.10 + isl_union_map_range_factor_range@Base 0.15 + isl_union_map_range_map@Base 0.10 + isl_union_map_range_product@Base 0.10 + isl_union_map_read_from_file@Base 0.10 + isl_union_map_read_from_str@Base 0.10 + isl_union_map_remove_redundancies@Base 0.15 + isl_union_map_reset_range_space@Base 0.15 + isl_union_map_reset_user@Base 0.13 + isl_union_map_reverse@Base 0.10 + isl_union_map_sample@Base 0.10 + isl_union_map_simple_hull@Base 0.10 + isl_union_map_subtract@Base 0.10 + isl_union_map_subtract_domain@Base 0.11 + isl_union_map_subtract_range@Base 0.11 + isl_union_map_to_str@Base 0.10 + isl_union_map_transitive_closure@Base 0.10 + isl_union_map_uncurry@Base 0.11 + isl_union_map_union@Base 0.10 + isl_union_map_universe@Base 0.10 + isl_union_map_wrap@Base 0.10 + isl_union_map_zip@Base 0.10 + isl_union_pw_aff_add@Base 0.15 + isl_union_pw_aff_add_pw_aff@Base 0.15 + isl_union_pw_aff_aff_on_domain@Base 0.15 + isl_union_pw_aff_align_params@Base 0.15 + isl_union_pw_aff_coalesce@Base 0.15 + isl_union_pw_aff_copy@Base 0.15 + isl_union_pw_aff_cow@Base 0.15 + isl_union_pw_aff_dim@Base 0.15 + isl_union_pw_aff_domain@Base 0.15 + isl_union_pw_aff_drop_dims@Base 0.15 + isl_union_pw_aff_dump@Base 0.15 + isl_union_pw_aff_dup@Base 0.15 + isl_union_pw_aff_empty@Base 0.15 + isl_union_pw_aff_extract_pw_aff@Base 0.15 + isl_union_pw_aff_find_dim_by_name@Base 0.15 + isl_union_pw_aff_floor@Base 0.15 + isl_union_pw_aff_foreach_pw_aff@Base 0.15 + isl_union_pw_aff_free@Base 0.15 + isl_union_pw_aff_from_pw_aff@Base 0.15 + isl_union_pw_aff_get_ctx@Base 0.15 + isl_union_pw_aff_get_space@Base 0.15 + isl_union_pw_aff_gist@Base 0.15 + isl_union_pw_aff_gist_params@Base 0.15 + isl_union_pw_aff_intersect_domain@Base 0.15 + isl_union_pw_aff_intersect_params@Base 0.15 + isl_union_pw_aff_list_add@Base 0.15 + isl_union_pw_aff_list_alloc@Base 0.15 + isl_union_pw_aff_list_concat@Base 0.15 + isl_union_pw_aff_list_copy@Base 0.15 + isl_union_pw_aff_list_cow@Base 0.15 + isl_union_pw_aff_list_drop@Base 0.15 + isl_union_pw_aff_list_dump@Base 0.15 + isl_union_pw_aff_list_dup@Base 0.15 + isl_union_pw_aff_list_foreach@Base 0.15 + isl_union_pw_aff_list_foreach_scc@Base 0.15 + isl_union_pw_aff_list_free@Base 0.15 + isl_union_pw_aff_list_from_union_pw_aff@Base 0.15 + isl_union_pw_aff_list_get_ctx@Base 0.15 + isl_union_pw_aff_list_get_union_pw_aff@Base 0.15 + isl_union_pw_aff_list_insert@Base 0.15 + isl_union_pw_aff_list_n_union_pw_aff@Base 0.15 + isl_union_pw_aff_list_set_union_pw_aff@Base 0.15 + isl_union_pw_aff_list_sort@Base 0.15 + isl_union_pw_aff_mod_val@Base 0.15 + isl_union_pw_aff_mul_isl_int@Base 0.15 + isl_union_pw_aff_n_pw_aff@Base 0.15 + isl_union_pw_aff_neg@Base 0.15 + isl_union_pw_aff_plain_is_equal@Base 0.15 + isl_union_pw_aff_pullback_union_pw_multi_aff@Base 0.15 + isl_union_pw_aff_reset_user@Base 0.15 + isl_union_pw_aff_scale_down_val@Base 0.15 + isl_union_pw_aff_scale_val@Base 0.15 + isl_union_pw_aff_set_dim_name@Base 0.15 + isl_union_pw_aff_sub@Base 0.15 + isl_union_pw_aff_subtract_domain@Base 0.15 + isl_union_pw_aff_to_str@Base 0.15 + isl_union_pw_aff_union_add@Base 0.15 + isl_union_pw_aff_val_on_domain@Base 0.15 + isl_union_pw_aff_zero_union_set@Base 0.15 + isl_union_pw_multi_aff_add@Base 0.10 + isl_union_pw_multi_aff_add_pw_multi_aff@Base 0.10 + isl_union_pw_multi_aff_align_params@Base 0.10 + isl_union_pw_multi_aff_coalesce@Base 0.10 + isl_union_pw_multi_aff_copy@Base 0.10 + isl_union_pw_multi_aff_cow@Base 0.10 + isl_union_pw_multi_aff_dim@Base 0.15 + isl_union_pw_multi_aff_domain@Base 0.10 + isl_union_pw_multi_aff_drop_dims@Base 0.15 + isl_union_pw_multi_aff_dump@Base 0.10 + isl_union_pw_multi_aff_dup@Base 0.10 + isl_union_pw_multi_aff_empty@Base 0.10 + isl_union_pw_multi_aff_extract_pw_multi_aff@Base 0.10 + isl_union_pw_multi_aff_find_dim_by_name@Base 0.15 + isl_union_pw_multi_aff_flat_range_product@Base 0.10 + isl_union_pw_multi_aff_foreach_pw_multi_aff@Base 0.10 + isl_union_pw_multi_aff_free@Base 0.10 + isl_union_pw_multi_aff_from_aff@Base 0.15 + isl_union_pw_multi_aff_from_domain@Base 0.10 + isl_union_pw_multi_aff_from_multi_union_pw_aff@Base 0.15 + isl_union_pw_multi_aff_from_pw_multi_aff@Base 0.10 + isl_union_pw_multi_aff_from_union_map@Base 0.12.1 + isl_union_pw_multi_aff_from_union_pw_aff@Base 0.15 + isl_union_pw_multi_aff_from_union_set@Base 0.12.1 + isl_union_pw_multi_aff_get_ctx@Base 0.10 + isl_union_pw_multi_aff_get_space@Base 0.10 + isl_union_pw_multi_aff_get_union_pw_aff@Base 0.15 + isl_union_pw_multi_aff_gist@Base 0.10 + isl_union_pw_multi_aff_gist_params@Base 0.10 + isl_union_pw_multi_aff_intersect_domain@Base 0.10 + isl_union_pw_multi_aff_intersect_params@Base 0.10 + isl_union_pw_multi_aff_list_add@Base 0.15 + isl_union_pw_multi_aff_list_alloc@Base 0.15 + isl_union_pw_multi_aff_list_concat@Base 0.15 + isl_union_pw_multi_aff_list_copy@Base 0.15 + isl_union_pw_multi_aff_list_cow@Base 0.15 + isl_union_pw_multi_aff_list_drop@Base 0.15 + isl_union_pw_multi_aff_list_dump@Base 0.15 + isl_union_pw_multi_aff_list_dup@Base 0.15 + isl_union_pw_multi_aff_list_foreach@Base 0.15 + isl_union_pw_multi_aff_list_foreach_scc@Base 0.15 + isl_union_pw_multi_aff_list_free@Base 0.15 + isl_union_pw_multi_aff_list_from_union_pw_multi_aff@Base 0.15 + isl_union_pw_multi_aff_list_get_ctx@Base 0.15 + isl_union_pw_multi_aff_list_get_union_pw_multi_aff@Base 0.15 + isl_union_pw_multi_aff_list_insert@Base 0.15 + isl_union_pw_multi_aff_list_n_union_pw_multi_aff@Base 0.15 + isl_union_pw_multi_aff_list_set_union_pw_multi_aff@Base 0.15 + isl_union_pw_multi_aff_list_sort@Base 0.15 + isl_union_pw_multi_aff_mul_isl_int@Base 0.10 + isl_union_pw_multi_aff_multi_val_on_domain@Base 0.15 + isl_union_pw_multi_aff_n_pw_multi_aff@Base 0.15 + isl_union_pw_multi_aff_neg@Base 0.15 + isl_union_pw_multi_aff_plain_is_equal@Base 0.10 + isl_union_pw_multi_aff_pullback_union_pw_multi_aff@Base 0.15 + isl_union_pw_multi_aff_read_from_str@Base 0.12.1 + isl_union_pw_multi_aff_reset_user@Base 0.15 + isl_union_pw_multi_aff_scale_down_val@Base 0.15 + isl_union_pw_multi_aff_scale_multi_val@Base 0.12.1 + isl_union_pw_multi_aff_scale_val@Base 0.12.1 + isl_union_pw_multi_aff_set_dim_name@Base 0.15 + isl_union_pw_multi_aff_sub@Base 0.12.1 + isl_union_pw_multi_aff_subtract_domain@Base 0.15 + isl_union_pw_multi_aff_to_str@Base 0.10 + isl_union_pw_multi_aff_union_add@Base 0.15 + isl_union_pw_qpolynomial_add@Base 0.10 + isl_union_pw_qpolynomial_add_pw_qpolynomial@Base 0.10 + isl_union_pw_qpolynomial_align_params@Base 0.10 + isl_union_pw_qpolynomial_bound@Base 0.10 + isl_union_pw_qpolynomial_coalesce@Base 0.10 + isl_union_pw_qpolynomial_copy@Base 0.10 + isl_union_pw_qpolynomial_cow@Base 0.10 + isl_union_pw_qpolynomial_dim@Base 0.15 + isl_union_pw_qpolynomial_domain@Base 0.10 + isl_union_pw_qpolynomial_drop_dims@Base 0.15 + isl_union_pw_qpolynomial_dump@Base 0.10 + isl_union_pw_qpolynomial_dup@Base 0.10 + isl_union_pw_qpolynomial_eval@Base 0.10 + isl_union_pw_qpolynomial_extract_pw_qpolynomial@Base 0.10 + isl_union_pw_qpolynomial_find_dim_by_name@Base 0.15 + isl_union_pw_qpolynomial_fold_add@Base 0.10 + isl_union_pw_qpolynomial_fold_add_pw_qpolynomial_fold@Base 0.10 + isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial@Base 0.10 + isl_union_pw_qpolynomial_fold_align_params@Base 0.10 + isl_union_pw_qpolynomial_fold_coalesce@Base 0.10 + isl_union_pw_qpolynomial_fold_copy@Base 0.10 + isl_union_pw_qpolynomial_fold_cow@Base 0.10 + isl_union_pw_qpolynomial_fold_dim@Base 0.15 + isl_union_pw_qpolynomial_fold_domain@Base 0.10 + isl_union_pw_qpolynomial_fold_drop_dims@Base 0.15 + isl_union_pw_qpolynomial_fold_dump@Base 0.10 + isl_union_pw_qpolynomial_fold_dup@Base 0.10 + isl_union_pw_qpolynomial_fold_eval@Base 0.10 + isl_union_pw_qpolynomial_fold_extract_pw_qpolynomial_fold@Base 0.10 + isl_union_pw_qpolynomial_fold_find_dim_by_name@Base 0.15 + isl_union_pw_qpolynomial_fold_fold@Base 0.10 + isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold@Base 0.10 + isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold@Base 0.10 + isl_union_pw_qpolynomial_fold_free@Base 0.10 + isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold@Base 0.10 + isl_union_pw_qpolynomial_fold_get_ctx@Base 0.10 + isl_union_pw_qpolynomial_fold_get_space@Base 0.10 + isl_union_pw_qpolynomial_fold_get_type@Base 0.10 + isl_union_pw_qpolynomial_fold_gist@Base 0.10 + isl_union_pw_qpolynomial_fold_gist_params@Base 0.10 + isl_union_pw_qpolynomial_fold_intersect_domain@Base 0.10 + isl_union_pw_qpolynomial_fold_intersect_params@Base 0.10 + isl_union_pw_qpolynomial_fold_mul_isl_int@Base 0.10 + isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold@Base 0.15 + isl_union_pw_qpolynomial_fold_plain_is_equal@Base 0.10 + isl_union_pw_qpolynomial_fold_reset_user@Base 0.15 + isl_union_pw_qpolynomial_fold_scale_down_val@Base 0.15 + isl_union_pw_qpolynomial_fold_scale_val@Base 0.12.1 + isl_union_pw_qpolynomial_fold_set_dim_name@Base 0.15 + isl_union_pw_qpolynomial_fold_subtract_domain@Base 0.15 + isl_union_pw_qpolynomial_fold_to_str@Base 0.10 + isl_union_pw_qpolynomial_fold_zero@Base 0.10 + isl_union_pw_qpolynomial_foreach_pw_qpolynomial@Base 0.10 + isl_union_pw_qpolynomial_free@Base 0.10 + isl_union_pw_qpolynomial_from_pw_qpolynomial@Base 0.10 + isl_union_pw_qpolynomial_get_ctx@Base 0.10 + isl_union_pw_qpolynomial_get_space@Base 0.10 + isl_union_pw_qpolynomial_gist@Base 0.10 + isl_union_pw_qpolynomial_gist_params@Base 0.10 + isl_union_pw_qpolynomial_intersect_domain@Base 0.10 + isl_union_pw_qpolynomial_intersect_params@Base 0.10 + isl_union_pw_qpolynomial_mul@Base 0.10 + isl_union_pw_qpolynomial_mul_isl_int@Base 0.10 + isl_union_pw_qpolynomial_n_pw_qpolynomial@Base 0.15 + isl_union_pw_qpolynomial_neg@Base 0.10 + isl_union_pw_qpolynomial_plain_is_equal@Base 0.10 + isl_union_pw_qpolynomial_read_from_str@Base 0.10 + isl_union_pw_qpolynomial_reset_user@Base 0.15 + isl_union_pw_qpolynomial_scale_down_val@Base 0.15 + isl_union_pw_qpolynomial_scale_val@Base 0.12.1 + isl_union_pw_qpolynomial_set_dim_name@Base 0.15 + isl_union_pw_qpolynomial_sub@Base 0.10 + isl_union_pw_qpolynomial_subtract_domain@Base 0.15 + isl_union_pw_qpolynomial_to_polynomial@Base 0.10 + isl_union_pw_qpolynomial_to_str@Base 0.10 + isl_union_pw_qpolynomial_zero@Base 0.10 + isl_union_set_add_set@Base 0.10 + isl_union_set_affine_hull@Base 0.10 + isl_union_set_align_params@Base 0.10 + isl_union_set_apply@Base 0.10 + isl_union_set_apply_union_pw_qpolynomial_fold@Base 0.10 + isl_union_set_coalesce@Base 0.10 + isl_union_set_coefficients@Base 0.10 + isl_union_set_compute_divs@Base 0.10 + isl_union_set_compute_schedule@Base 0.10 + isl_union_set_contains@Base 0.10 + isl_union_set_copy@Base 0.10 + isl_union_set_detect_equalities@Base 0.10 + isl_union_set_dim@Base 0.15 + isl_union_set_dump@Base 0.10 + isl_union_set_empty@Base 0.10 + isl_union_set_extract_set@Base 0.10 + isl_union_set_foreach_point@Base 0.10 + isl_union_set_foreach_set@Base 0.10 + isl_union_set_free@Base 0.10 + isl_union_set_from_basic_set@Base 0.11 + isl_union_set_from_set@Base 0.10 + isl_union_set_get_ctx@Base 0.10 + isl_union_set_get_space@Base 0.10 + isl_union_set_gist@Base 0.10 + isl_union_set_gist_params@Base 0.10 + isl_union_set_identity@Base 0.10 + isl_union_set_identity_union_pw_multi_aff@Base 0.15 + isl_union_set_intersect@Base 0.10 + isl_union_set_intersect_params@Base 0.10 + isl_union_set_is_disjoint@Base 0.15 + isl_union_set_is_empty@Base 0.10 + isl_union_set_is_equal@Base 0.10 + isl_union_set_is_params@Base 0.10 + isl_union_set_is_strict_subset@Base 0.10 + isl_union_set_is_subset@Base 0.10 + isl_union_set_lex_ge_union_set@Base 0.10 + isl_union_set_lex_gt_union_set@Base 0.10 + isl_union_set_lex_le_union_set@Base 0.10 + isl_union_set_lex_lt_union_set@Base 0.10 + isl_union_set_lexmax@Base 0.10 + isl_union_set_lexmin@Base 0.10 + isl_union_set_lift@Base 0.10 + isl_union_set_list_add@Base 0.15 + isl_union_set_list_alloc@Base 0.15 + isl_union_set_list_concat@Base 0.15 + isl_union_set_list_copy@Base 0.15 + isl_union_set_list_cow@Base 0.15 + isl_union_set_list_drop@Base 0.15 + isl_union_set_list_dump@Base 0.15 + isl_union_set_list_dup@Base 0.15 + isl_union_set_list_foreach@Base 0.15 + isl_union_set_list_foreach_scc@Base 0.15 + isl_union_set_list_free@Base 0.15 + isl_union_set_list_from_union_set@Base 0.15 + isl_union_set_list_get_ctx@Base 0.15 + isl_union_set_list_get_union_set@Base 0.15 + isl_union_set_list_insert@Base 0.15 + isl_union_set_list_n_union_set@Base 0.15 + isl_union_set_list_set_union_set@Base 0.15 + isl_union_set_list_sort@Base 0.15 + isl_union_set_list_union@Base 0.15 + isl_union_set_n_set@Base 0.10 + isl_union_set_params@Base 0.10 + isl_union_set_polyhedral_hull@Base 0.10 + isl_union_set_preimage_multi_aff@Base 0.13 + isl_union_set_preimage_pw_multi_aff@Base 0.13 + isl_union_set_preimage_union_pw_multi_aff@Base 0.13 + isl_union_set_product@Base 0.10 + isl_union_set_project_out@Base 0.15 + isl_union_set_read_from_file@Base 0.10 + isl_union_set_read_from_str@Base 0.10 + isl_union_set_remove_redundancies@Base 0.15 + isl_union_set_reset_user@Base 0.13 + isl_union_set_sample@Base 0.10 + isl_union_set_simple_hull@Base 0.10 + isl_union_set_solutions@Base 0.10 + isl_union_set_subtract@Base 0.10 + isl_union_set_to_str@Base 0.10 + isl_union_set_union@Base 0.10 + isl_union_set_universe@Base 0.10 + isl_union_set_unwrap@Base 0.10 + isl_union_set_wrapped_domain_map@Base 0.15 + isl_upoly_add_isl_int@Base 0.10 + isl_upoly_alloc_rec@Base 0.10 + isl_upoly_as_cst@Base 0.10 + isl_upoly_as_rec@Base 0.10 + isl_upoly_cmp@Base 0.10 + isl_upoly_coeff@Base 0.10 + isl_upoly_copy@Base 0.10 + isl_upoly_cow@Base 0.10 + isl_upoly_cst_add_isl_int@Base 0.10 + isl_upoly_cst_alloc@Base 0.10 + isl_upoly_cst_mul_isl_int@Base 0.10 + isl_upoly_degree@Base 0.10 + isl_upoly_drop@Base 0.10 + isl_upoly_dup@Base 0.10 + isl_upoly_dup_cst@Base 0.10 + isl_upoly_dup_rec@Base 0.10 + isl_upoly_eval@Base 0.10 + isl_upoly_foreach_term@Base 0.10 + isl_upoly_free@Base 0.10 + isl_upoly_from_affine@Base 0.10 + isl_upoly_homogenize@Base 0.10 + isl_upoly_infty@Base 0.10 + isl_upoly_is_affine@Base 0.10 + isl_upoly_is_cst@Base 0.10 + isl_upoly_is_equal@Base 0.10 + isl_upoly_is_infty@Base 0.10 + isl_upoly_is_nan@Base 0.10 + isl_upoly_is_neginfty@Base 0.10 + isl_upoly_is_negone@Base 0.10 + isl_upoly_is_one@Base 0.10 + isl_upoly_is_zero@Base 0.10 + isl_upoly_mul@Base 0.10 + isl_upoly_mul_cst@Base 0.10 + isl_upoly_mul_isl_int@Base 0.10 + isl_upoly_mul_rec@Base 0.10 + isl_upoly_nan@Base 0.10 + isl_upoly_neginfty@Base 0.10 + isl_upoly_one@Base 0.10 + isl_upoly_pow@Base 0.10 + isl_upoly_rat_cst@Base 0.10 + isl_upoly_sgn@Base 0.10 + isl_upoly_subs@Base 0.10 + isl_upoly_sum@Base 0.10 + isl_upoly_sum_cst@Base 0.10 + isl_upoly_update_affine@Base 0.10 + isl_upoly_var_pow@Base 0.10 + isl_upoly_zero@Base 0.10 + isl_val_2exp@Base 0.12.1 + isl_val_abs@Base 0.12.1 + isl_val_abs_eq@Base 0.15 + isl_val_add@Base 0.12.1 + isl_val_add_ui@Base 0.12.1 + isl_val_align_params@Base 0.13 + isl_val_alloc@Base 0.12.1 + isl_val_ceil@Base 0.12.1 + isl_val_check_match_domain_space@Base 0.12.1 + isl_val_cmp_si@Base 0.12.1 + isl_val_copy@Base 0.12.1 + isl_val_cow@Base 0.12.1 + isl_val_div@Base 0.12.1 + isl_val_drop_dims@Base 0.12.1 + isl_val_dump@Base 0.12.1 + isl_val_dup@Base 0.12.1 + isl_val_eq@Base 0.12.1 + isl_val_floor@Base 0.12.1 + isl_val_free@Base 0.12.1 + isl_val_from_gmp@Base 0.12.1 + isl_val_gcd@Base 0.12.1 + isl_val_gcdext@Base 0.12.1 + isl_val_ge@Base 0.12.1 + isl_val_get_abs_num_chunks@Base 0.12.1 + isl_val_get_ctx@Base 0.12.1 + isl_val_get_d@Base 0.12.1 + isl_val_get_den_gmp@Base 0.12.1 + isl_val_get_den_si@Base 0.12.1 + isl_val_get_num_gmp@Base 0.12.1 + isl_val_get_num_isl_int@Base 0.12.1 + isl_val_get_num_si@Base 0.12.1 + isl_val_get_space@Base 0.13 + isl_val_gt@Base 0.12.1 + isl_val_infty@Base 0.12.1 + isl_val_insert_dims@Base 0.12.1 + isl_val_int_from_chunks@Base 0.12.1 + isl_val_int_from_gmp@Base 0.12.1 + isl_val_int_from_isl_int@Base 0.12.1 + isl_val_int_from_si@Base 0.12.1 + isl_val_int_from_ui@Base 0.12.1 + isl_val_inv@Base 0.15 + isl_val_involves_dims@Base 0.13 + isl_val_is_divisible_by@Base 0.12.1 + isl_val_is_infty@Base 0.12.1 + isl_val_is_int@Base 0.12.1 + isl_val_is_nan@Base 0.12.1 + isl_val_is_neg@Base 0.12.1 + isl_val_is_neginfty@Base 0.12.1 + isl_val_is_negone@Base 0.12.1 + isl_val_is_nonneg@Base 0.12.1 + isl_val_is_nonpos@Base 0.12.1 + isl_val_is_one@Base 0.12.1 + isl_val_is_pos@Base 0.12.1 + isl_val_is_rat@Base 0.12.1 + isl_val_is_zero@Base 0.12.1 + isl_val_le@Base 0.12.1 + isl_val_list_add@Base 0.12.1 + isl_val_list_alloc@Base 0.12.1 + isl_val_list_concat@Base 0.12.1 + isl_val_list_copy@Base 0.12.1 + isl_val_list_cow@Base 0.12.1 + isl_val_list_drop@Base 0.12.1 + isl_val_list_dump@Base 0.12.1 + isl_val_list_dup@Base 0.12.1 + isl_val_list_foreach@Base 0.12.1 + isl_val_list_foreach_scc@Base 0.12.1 + isl_val_list_free@Base 0.12.1 + isl_val_list_from_val@Base 0.12.1 + isl_val_list_get_ctx@Base 0.12.1 + isl_val_list_get_val@Base 0.12.1 + isl_val_list_insert@Base 0.12.1 + isl_val_list_n_val@Base 0.12.1 + isl_val_list_set_val@Base 0.12.1 + isl_val_list_sort@Base 0.12.1 + isl_val_lt@Base 0.12.1 + isl_val_matching_params@Base 0.13 + isl_val_max@Base 0.12.1 + isl_val_min@Base 0.12.1 + isl_val_mod@Base 0.12.1 + isl_val_mod_val@Base 0.15 + isl_val_mul@Base 0.12.1 + isl_val_mul_ui@Base 0.12.1 + isl_val_n_abs_num_chunks@Base 0.12.1 + isl_val_nan@Base 0.12.1 + isl_val_ne@Base 0.12.1 + isl_val_neg@Base 0.12.1 + isl_val_neginfty@Base 0.12.1 + isl_val_negone@Base 0.13 + isl_val_normalize@Base 0.12.1 + isl_val_one@Base 0.12.1 + isl_val_plain_is_equal@Base 0.13 + isl_val_rat_from_isl_int@Base 0.12.1 + isl_val_read_from_str@Base 0.12.1 + isl_val_realign_domain@Base 0.12.1 + isl_val_reset_domain_space@Base 0.12.1 + isl_val_scale_down_val@Base 0.13 + isl_val_scale_val@Base 0.12.1 + isl_val_set_dim_name@Base 0.12.1 + isl_val_set_nan@Base 0.12.1 + isl_val_set_si@Base 0.12.1 + isl_val_set_zero@Base 0.12.1 + isl_val_sgn@Base 0.12.1 + isl_val_sub@Base 0.12.1 + isl_val_sub_ui@Base 0.12.1 + isl_val_to_str@Base 0.12.1 + isl_val_trunc@Base 0.12.1 + isl_val_zero@Base 0.12.1 + isl_val_zero_on_domain@Base 0.12.1 + isl_vec_add@Base 0.10 + isl_vec_alloc@Base 0.10 + isl_vec_ceil@Base 0.10 + isl_vec_clr@Base 0.10 + isl_vec_cmp_element@Base 0.12.1 + isl_vec_concat@Base 0.11 + isl_vec_copy@Base 0.10 + isl_vec_cow@Base 0.10 + isl_vec_drop_els@Base 0.10 + isl_vec_dump@Base 0.10 + isl_vec_dup@Base 0.10 + isl_vec_extend@Base 0.10 + isl_vec_fdiv_r@Base 0.11 + isl_vec_free@Base 0.10 + isl_vec_get_ctx@Base 0.10 + isl_vec_get_element@Base 0.10 + isl_vec_get_element_val@Base 0.12.1 + isl_vec_insert_els@Base 0.10 + isl_vec_insert_zero_els@Base 0.10 + isl_vec_is_equal@Base 0.10 + isl_vec_lcm@Base 0.10 + isl_vec_mat_product@Base 0.10 + isl_vec_move_els@Base 0.13 + isl_vec_neg@Base 0.10 + isl_vec_normalize@Base 0.10 + isl_vec_read_from_file@Base 0.10 + isl_vec_scale@Base 0.10 + isl_vec_set@Base 0.10 + isl_vec_set_element@Base 0.10 + isl_vec_set_element_si@Base 0.10 + isl_vec_set_element_val@Base 0.12.1 + isl_vec_set_si@Base 0.10 + isl_vec_set_val@Base 0.12.1 + isl_vec_size@Base 0.10 + isl_vec_sort@Base 0.10 + isl_vec_zero_extend@Base 0.10 + isl_version@Base 0.10 + isl_vertex_free@Base 0.10 + isl_vertex_get_ctx@Base 0.10 + isl_vertex_get_domain@Base 0.10 + isl_vertex_get_expr@Base 0.10 + isl_vertex_get_id@Base 0.10 + isl_vertices_copy@Base 0.10 + isl_vertices_foreach_cell@Base 0.10 + isl_vertices_foreach_disjoint_cell@Base 0.10 + isl_vertices_foreach_vertex@Base 0.10 + isl_vertices_free@Base 0.10 + isl_vertices_get_ctx@Base 0.10 + isl_vertices_get_n_vertices@Base 0.10 diff -Nru isl-0.12.2/debian/patches/open-runtime-lib.diff isl-0.15/debian/patches/open-runtime-lib.diff --- isl-0.12.2/debian/patches/open-runtime-lib.diff 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/debian/patches/open-runtime-lib.diff 2014-06-25 12:46:40.000000000 +0000 @@ -0,0 +1,24 @@ +Index: b/interface/isl.py +=================================================================== +--- a/interface/isl.py ++++ b/interface/isl.py +@@ -1,6 +1,6 @@ + from ctypes import * + +-isl = cdll.LoadLibrary("libisl.so") ++isl = cdll.LoadLibrary("libisl.so.13") + libc = cdll.LoadLibrary("libc.so.6") + + class Error(Exception): +Index: b/interface/isl.py.top +=================================================================== +--- a/interface/isl.py.top ++++ b/interface/isl.py.top +@@ -1,6 +1,6 @@ + from ctypes import * + +-isl = cdll.LoadLibrary("libisl.so") ++isl = cdll.LoadLibrary("libisl.so.13") + libc = cdll.LoadLibrary("libc.so.6") + + class Error(Exception): diff -Nru isl-0.12.2/debian/patches/python3-compat.diff isl-0.15/debian/patches/python3-compat.diff --- isl-0.12.2/debian/patches/python3-compat.diff 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/debian/patches/python3-compat.diff 2014-06-25 12:43:42.000000000 +0000 @@ -0,0 +1,494 @@ +Index: b/interface/isl.py +=================================================================== +--- a/interface/isl.py ++++ b/interface/isl.py +@@ -383,7 +383,7 @@ class union_map: + exc_info = [None] + fn = CFUNCTYPE(c_int, c_void_p, c_void_p) + def cb_func(cb_arg0, cb_arg1): +- cb_arg0 = map(ctx=arg0.ctx, ptr=cb_arg0) ++ cb_arg0 = list(map(ctx=arg0.ctx, ptr=cb_arg0)) + try: + arg1(cb_arg0) + except: +@@ -394,7 +394,7 @@ class union_map: + cb = fn(cb_func) + res = isl.isl_union_map_foreach_map(arg0.ptr, cb, None) + if exc_info[0] != None: +- raise exc_info[0][0], exc_info[0][1], exc_info[0][2] ++ raise exc_info[0][0](exc_info[0][1]).with_traceback(exc_info[0][2]) + return res + + isl.isl_union_map_from_basic_map.restype = c_void_p +@@ -457,7 +457,7 @@ class map(union_map): + def intersect_params(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: +@@ -466,32 +466,32 @@ class map(union_map): + except: + return union_map(arg0).intersect_params(arg1) + res = isl.isl_map_intersect_params(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def subtract(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).subtract(arg1) + res = isl.isl_map_subtract(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def complement(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_complement(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def deltas(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_deltas(isl.isl_map_copy(arg0.ptr)) +@@ -499,15 +499,15 @@ class map(union_map): + def detect_equalities(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_detect_equalities(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def affine_hull(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_affine_hull(isl.isl_map_copy(arg0.ptr)) +@@ -515,7 +515,7 @@ class map(union_map): + def polyhedral_hull(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_polyhedral_hull(isl.isl_map_copy(arg0.ptr)) +@@ -523,31 +523,31 @@ class map(union_map): + def flatten(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_flatten(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def flatten_domain(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_flatten_domain(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def flatten_range(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_flatten_range(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def sample(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_sample(isl.isl_map_copy(arg0.ptr)) +@@ -555,7 +555,7 @@ class map(union_map): + def is_empty(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_is_empty(arg0.ptr) +@@ -563,12 +563,12 @@ class map(union_map): + def is_subset(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).is_subset(arg1) + res = isl.isl_map_is_subset(arg0.ptr, arg1.ptr) +@@ -576,12 +576,12 @@ class map(union_map): + def is_strict_subset(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).is_strict_subset(arg1) + res = isl.isl_map_is_strict_subset(arg0.ptr, arg1.ptr) +@@ -589,12 +589,12 @@ class map(union_map): + def is_equal(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).is_equal(arg1) + res = isl.isl_map_is_equal(arg0.ptr, arg1.ptr) +@@ -602,12 +602,12 @@ class map(union_map): + def is_disjoint(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).is_disjoint(arg1) + res = isl.isl_map_is_disjoint(arg0.ptr, arg1.ptr) +@@ -615,7 +615,7 @@ class map(union_map): + def is_single_valued(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_is_single_valued(arg0.ptr) +@@ -623,7 +623,7 @@ class map(union_map): + def is_injective(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_is_injective(arg0.ptr) +@@ -631,7 +631,7 @@ class map(union_map): + def is_bijective(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_is_bijective(arg0.ptr) +@@ -639,44 +639,44 @@ class map(union_map): + def lexmin(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_lexmin(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def lexmax(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_lexmax(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def reverse(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_reverse(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def union(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).union(arg1) + res = isl.isl_map_union(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def intersect_domain(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: +@@ -685,11 +685,11 @@ class map(union_map): + except: + return union_map(arg0).intersect_domain(arg1) + res = isl.isl_map_intersect_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def intersect_range(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: +@@ -698,63 +698,63 @@ class map(union_map): + except: + return union_map(arg0).intersect_range(arg1) + res = isl.isl_map_intersect_range(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def apply_domain(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).apply_domain(arg1) + res = isl.isl_map_apply_domain(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def apply_range(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).apply_range(arg1) + res = isl.isl_map_apply_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def intersect(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).intersect(arg1) + res = isl.isl_map_intersect(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def gist(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_map(arg0).gist(arg1) + res = isl.isl_map_gist(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def gist_domain(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + try: +@@ -763,19 +763,19 @@ class map(union_map): + except: + return union_map(arg0).gist_domain(arg1) + res = isl.isl_map_gist_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def coalesce(arg0): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + res = isl.isl_map_coalesce(isl.isl_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def foreach_basic_map(arg0, arg1): + try: + if not arg0.__class__ is map: +- arg0 = map(arg0) ++ arg0 = list(map(arg0)) + except: + raise + exc_info = [None] +@@ -792,7 +792,7 @@ class map(union_map): + cb = fn(cb_func) + res = isl.isl_map_foreach_basic_map(arg0.ptr, cb, None) + if exc_info[0] != None: +- raise exc_info[0][0], exc_info[0][1], exc_info[0][2] ++ raise exc_info[0][0](exc_info[0][1]).with_traceback(exc_info[0][2]) + return res + + isl.isl_map_read_from_str.restype = c_void_p +@@ -946,7 +946,7 @@ class basic_map(map): + except: + return map(arg0).union(arg1) + res = isl.isl_basic_map_union(isl.isl_basic_map_copy(arg0.ptr), isl.isl_basic_map_copy(arg1.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def apply_domain(arg0, arg1): + try: + if not arg0.__class__ is basic_map: +@@ -1009,7 +1009,7 @@ class basic_map(map): + except: + raise + res = isl.isl_basic_map_lexmin(isl.isl_basic_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def lexmax(arg0): + try: + if not arg0.__class__ is basic_map: +@@ -1017,7 +1017,7 @@ class basic_map(map): + except: + raise + res = isl.isl_basic_map_lexmax(isl.isl_basic_map_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def is_empty(arg0): + try: + if not arg0.__class__ is basic_map: +@@ -1306,7 +1306,7 @@ class union_set: + cb = fn(cb_func) + res = isl.isl_union_set_foreach_set(arg0.ptr, cb, None) + if exc_info[0] != None: +- raise exc_info[0][0], exc_info[0][1], exc_info[0][2] ++ raise exc_info[0][0](exc_info[0][1]).with_traceback(exc_info[0][2]) + return res + + isl.isl_union_set_from_basic_set.restype = c_void_p +@@ -1364,7 +1364,7 @@ class set(union_set): + except: + raise + res = isl.isl_set_identity(isl.isl_set_copy(arg0.ptr)) +- return map(ctx=arg0.ctx, ptr=res) ++ return list(map(ctx=arg0.ctx, ptr=res)) + def is_wrapping(arg0): + try: + if not arg0.__class__ is set: +@@ -1497,7 +1497,7 @@ class set(union_set): + raise + try: + if not arg1.__class__ is map: +- arg1 = map(arg1) ++ arg1 = list(map(arg1)) + except: + return union_set(arg0).apply(arg1) + res = isl.isl_set_apply(isl.isl_set_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr)) +@@ -1603,7 +1603,7 @@ class set(union_set): + cb = fn(cb_func) + res = isl.isl_set_foreach_basic_set(arg0.ptr, cb, None) + if exc_info[0] != None: +- raise exc_info[0][0], exc_info[0][1], exc_info[0][2] ++ raise exc_info[0][0](exc_info[0][1]).with_traceback(exc_info[0][2]) + return res + + isl.isl_set_read_from_str.restype = c_void_p +Index: b/isl.py +=================================================================== +--- a/isl.py ++++ b/isl.py +@@ -64,10 +64,10 @@ class IslPrintCommand (gdb.Command): + printer = str_lookup_function(arg) + + if printer == None: +- print "No isl printer for this type" ++ print("No isl printer for this type") + return + +- print printer.to_string() ++ print(printer.to_string()) + + IslPrintCommand() + diff -Nru isl-0.12.2/debian/patches/series isl-0.15/debian/patches/series --- isl-0.12.2/debian/patches/series 2014-02-13 14:01:13.000000000 +0000 +++ isl-0.15/debian/patches/series 2014-11-11 11:28:15.000000000 +0000 @@ -1 +1,3 @@ fix-header.diff +#python3-compat.diff +open-runtime-lib.diff diff -Nru isl-0.12.2/debian/rules isl-0.15/debian/rules --- isl-0.12.2/debian/rules 2014-02-13 14:04:06.000000000 +0000 +++ isl-0.15/debian/rules 2015-07-25 16:33:30.000000000 +0000 @@ -1,11 +1,8 @@ #!/usr/bin/make -f -p = libisl10 +p = libisl15 DEB_HOST_MULTIARCH := $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) -export AUTOMAKE = automake-1.11 -export ACLOCAL = aclocal-1.11 - %: dh $@ --with autoreconf diff -Nru isl-0.12.2/depcomp isl-0.15/depcomp --- isl-0.12.2/depcomp 2014-01-12 11:45:02.000000000 +0000 +++ isl-0.15/depcomp 2014-10-26 07:36:33.000000000 +0000 @@ -251,6 +251,41 @@ exit 1 ;; +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, diff -Nru isl-0.12.2/doc/CodingStyle isl-0.15/doc/CodingStyle --- isl-0.12.2/doc/CodingStyle 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/doc/CodingStyle 2015-06-10 18:25:32.000000000 +0000 @@ -0,0 +1,42 @@ +This document describes some aspects of the coding style of isl, +which is similar to that of the linux kernel and git. + +The general rule is to use the same style as that of the surrounding code. + +More specific rules: + - every line should have at most 80 columns + - use tabs for indentation, where a tab counts for 8 characters + - use single spaces around binary operators such as '+', '-', '=', '!=' + - no space after unary operators such as '!' + - use a single space after a comma and a semicolon + (except at the end of a line) + - no space between function name and arguments + - use a single space after control keywords such as if, for and while + - use a single space between the type of a cast and the value + that is being cast + - no whitespace at the end of a line + - opening brace of a function is placed on a new line + - opening brace of other blocks stays on the same line + - the body of a control statement is placed on the next line(s) + - an else appears on the same line as the closing brace of + the then branch, if there is such a closing brace + - if either the then or the else branch of an if has braces, + then they both have braces + - no parentheses around argument of return keyword + - use only C style comments (/* ... */) + - no comments inside function bodies; + if some part of a function deserves additional comments, then + extract it out into a separate function first + - no #ifs inside function bodies + - variables are declared at the start of a block, before any + other statements + +There are some exceptions to the general rule of using +the same style as the surrounding code, most notably +when the surrounding code is very old. +In particular, an "isl_space" used to be called "isl_dim" and +some variables of this type are still called "dim" or some variant thereof. +New variables of this type should be called "space" or a more specific name. +Some old functions do not have memory management annotations yet. +All new functions should have memory management annotations, +whenever appropriate diff -Nru isl-0.12.2/doc/Makefile.in isl-0.15/doc/Makefile.in --- isl-0.12.2/doc/Makefile.in 2014-01-12 11:45:17.000000000 +0000 +++ isl-0.15/doc/Makefile.in 2015-06-11 10:47:03.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ esac; \ - test $$am__dry = yes; \ - } + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,7 +78,7 @@ build_triplet = @build@ host_triplet = @host@ subdir = doc -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \ $(top_srcdir)/m4/ax_cc_maxopt.m4 \ @@ -60,6 +87,8 @@ $(top_srcdir)/m4/ax_create_pkgconfig_info.m4 \ $(top_srcdir)/m4/ax_create_stdint_h.m4 \ $(top_srcdir)/m4/ax_detect_git_head.m4 \ + $(top_srcdir)/m4/ax_detect_gmp.m4 \ + $(top_srcdir)/m4/ax_detect_imath.m4 \ $(top_srcdir)/m4/ax_gcc_archflag.m4 \ $(top_srcdir)/m4/ax_gcc_warn_unused_result.m4 \ $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ @@ -71,16 +100,21 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/isl_config.h \ - $(top_builddir)/include/isl/config.h +CONFIG_HEADER = $(top_builddir)/isl_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -88,6 +122,7 @@ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -124,9 +159,6 @@ GIT_HEAD = @GIT_HEAD@ GIT_HEAD_ID = @GIT_HEAD_ID@ GIT_HEAD_VERSION = @GIT_HEAD_VERSION@ -GMP_CPPFLAGS = @GMP_CPPFLAGS@ -GMP_LDFLAGS = @GMP_LDFLAGS@ -GMP_LIBS = @GMP_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -145,6 +177,9 @@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MP_CPPFLAGS = @MP_CPPFLAGS@ +MP_LDFLAGS = @MP_LDFLAGS@ +MP_LIBS = @MP_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ @@ -161,9 +196,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ -PIPLIB_CPPFLAGS = @PIPLIB_CPPFLAGS@ -PIPLIB_LDFLAGS = @PIPLIB_LDFLAGS@ -PIPLIB_LIBS = @PIPLIB_LIBS@ POD2HTML = @POD2HTML@ PRTDIAG = @PRTDIAG@ RANLIB = @RANLIB@ @@ -269,11 +301,11 @@ clean-libtool: -rm -rf .libs _libs -tags: TAGS -TAGS: +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -409,15 +441,16 @@ .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am @GENERATE_DOC_TRUE@export TEXINPUTS := $(srcdir):$(TEXINPUTS) @GENERATE_DOC_TRUE@export BIBINPUTS := $(srcdir):$(BIBINPUTS) Binary files /tmp/q7LMisII0r/isl-0.12.2/doc/manual.pdf and /tmp/49YnvfWFR0/isl-0.15/doc/manual.pdf differ diff -Nru isl-0.12.2/doc/SubmittingPatches isl-0.15/doc/SubmittingPatches --- isl-0.12.2/doc/SubmittingPatches 2013-01-08 11:20:43.000000000 +0000 +++ isl-0.15/doc/SubmittingPatches 2015-04-19 12:02:52.000000000 +0000 @@ -23,6 +23,7 @@ - use "git format-patch -M" to create the patch - do not PGP sign your patch + - send a single patch per mail, e.g., using git-send-email(1) - do not attach your patch, but read in the mail body, unless you cannot teach your mailer to leave the formatting of the patch alone. @@ -39,3 +40,13 @@ (isl-development@googlegroups.com). If you use git-send-email(1), please test it first by sending email to yourself. + + Revisions: + + - add the revision number inside square brackets to + the subject line (e.g., use --subject-prefix='PATCH v2' + when creating the patch) + - recall the major issues discovered during the previous + review and explain how you addressed them or why you + disagree. Do so either in a cover letter, between the + "---" and the diffstat or in a separate message. diff -Nru isl-0.12.2/doc/user.pod isl-0.15/doc/user.pod --- isl-0.12.2/doc/user.pod 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/doc/user.pod 2015-06-11 10:46:17.000000000 +0000 @@ -5,7 +5,7 @@ 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. +using C or C. The C library offers functionality that is similar to that offered by the C and C libraries, but the underlying algorithms are in most cases completely different. @@ -17,7 +17,7 @@ scanner C and as part of an equivalence checker of static affine programs. For bug reports, feature requests and questions, -visit the the discussion group at +visit the discussion group at L. =head2 Backward Incompatible Changes @@ -181,6 +181,81 @@ =back +=head3 Changes since isl-0.12 + +=over + +=item * C has been replaced by C. +Some of the old functions are still available in C +but they will be removed in the future. + +=item * The functions C, +C, C +and C have been changed to return +an C instead of an C. + +=item * The function C +has been removed. Essentially the same functionality is available +through C, except that is requires +setting up coincidence constraints. +The option C has accordingly been +replaced by the option C. + +=item * The function C has been changed +to return an C instead of a rational C. +The function C has been changed to return +a regular basic set, rather than a rational basic set. + +=back + +=head3 Changes since isl-0.14 + +=over + +=item * Objects of type C can no longer contain +two or more C objects with the same domain space. + +=item * The function C now consistently +computes the sum on the shared definition domain. +The function C has been added +to compute the sum on the union of definition domains. +The original behavior of C was +confused and is no longer available. + +=item * Band forests have been replaced by schedule trees. + +=item * The function C has been +replaced by the function C. +Note that the may dependence relation returned by +C is the union of +the two dependence relations returned by +C. Similarly for the no source relations. +The function C is still available +for backward compatibility, but it will be removed in the future. + +=item * The function C has been +deprecated. + +=item * The function C has been +renamed to C. +The original name is still available +for backward compatibility, but it will be removed in the future. + +=item * The C AST generation option has been +deprecated. + +=item * The functions C and C +have been renamed to C and +C. The original names have been +kept for backward compatibility, but they will be removed in the future. + +=item * The C option has been replaced +by the C option. The effect +of setting the C option to C +is now obtained by turning on the C option. + +=back + =head1 License C is released under the MIT license. @@ -207,10 +282,13 @@ =back -Note that C currently requires C, which is released +Note that by default C requires C, which is released under the GNU Lesser General Public License (LGPL). This means that code linked against C is also linked against LGPL code. +When configuring with C<--with-int=imath>, C will link against C, a +library for exact integer arithmetic released under the MIT license. + =head1 Installation The source of C can be obtained either as a tarball @@ -234,6 +312,16 @@ git pull +=item 2 Optionally get C submodule + +To build C with C, you need to obtain the C +submodule by running in the git source tree of C + + git submodule init + git submodule update + +This will fetch the required version of C in a subdirectory of C. + =item 2 Generate C ./autogen.sh @@ -249,11 +337,12 @@ =item 1 Obtain C -Building C requires C, including its headers files. +By default, building C requires C, including its headers files. Your distribution may not provide these header files by default and you may need to install a package called C or something similar. Alternatively, C can be built from source, available from L. +C is not needed if you build C with C. =item 2 Configure @@ -269,22 +358,17 @@ Below we discuss some of the more common options. -C can optionally use C, but no -C functionality is currently used by default. -The C<--with-piplib> option can -be used to specify which C -library to use, either an installed version (C), -an externally built version (C) -or no version (C). The option C is mostly useful -in C scripts of larger projects that bundle both C -and C. - =over =item C<--prefix> Installation prefix for C +=item C<--with-int=[gmp|imath]> + +Select the integer library to be used by C, the default is C. +Note that C may run significantly slower if you use C. + =item C<--with-gmp-prefix> Installation prefix for C (architecture-independent files). @@ -293,35 +377,82 @@ Installation prefix for C (architecture-dependent files). -=item C<--with-piplib> +=back + +=item 3 Compile -Which copy of C to use, either C (default), C or C. + make -=item C<--with-piplib-prefix> +=item 4 Install (optional) -Installation prefix for C C (architecture-independent files). + make install -=item C<--with-piplib-exec-prefix> +=back -Installation prefix for C C (architecture-dependent files). +=head1 Integer Set Library -=item C<--with-piplib-builddir> +=head2 Memory Management -Location where C C was built. +Since a high-level operation on isl objects usually involves +several substeps and since the user is usually not interested in +the intermediate results, most functions that return a new object +will also release all the objects passed as arguments. +If the user still wants to use one or more of these arguments +after the function call, she should pass along a copy of the +object rather than the object itself. +The user is then responsible for making sure that the original +object gets used somewhere else or is explicitly freed. -=back +The arguments and return values of all documented functions are +annotated to make clear which arguments are released and which +arguments are preserved. In particular, the following annotations +are used -=item 3 Compile +=over - make +=item C<__isl_give> -=item 4 Install (optional) +C<__isl_give> means that a new object is returned. +The user should make sure that the returned pointer is +used exactly once as a value for an C<__isl_take> argument. +In between, it can be used as a value for as many +C<__isl_keep> arguments as the user likes. +There is one exception, and that is the case where the +pointer returned is C. Is this case, the user +is free to use it as an C<__isl_take> argument or not. +When applied to a C, the returned pointer needs to be +freed using C. - make install +=item C<__isl_null> -=back +C<__isl_null> means that a C value is returned. -=head1 Integer Set Library +=item C<__isl_take> + +C<__isl_take> means that the object the argument points to +is taken over by the function and may no longer be used +by the user as an argument to any other function. +The pointer value must be one returned by a function +returning an C<__isl_give> pointer. +If the user passes in a C value, then this will +be treated as an error in the sense that the function will +not perform its usual operation. However, it will still +make sure that all the other C<__isl_take> arguments +are released. + +=item C<__isl_keep> + +C<__isl_keep> means that the function will only use the object +temporarily. After the function has finished, the user +can still use it as an argument to other functions. +A C value will be treated in the same way as +a C value for an C<__isl_take> argument. +This annotation may also be used on return values of +type C, in which case the returned pointer should +not be freed by the user and is only valid until the object +from which it was derived is updated or freed. + +=back =head2 Initialization @@ -343,6 +474,130 @@ isl_ctx *isl_ctx_alloc(); void isl_ctx_free(isl_ctx *ctx); +The user can impose a bound on the number of low-level I +that can be performed by an C. This bound can be set and +retrieved using the following functions. A bound of zero means that +no bound is imposed. The number of operations performed can be +reset using C. Note that the number +of low-level operations needed to perform a high-level computation +may differ significantly across different versions +of C, but it should be the same across different platforms +for the same version of C. + +Warning: This feature is experimental. C has good support to abort and +bail out during the computation, but this feature may exercise error code paths +that are normally not used that much. Consequently, it is not unlikely that +hidden bugs will be exposed. + + void isl_ctx_set_max_operations(isl_ctx *ctx, + unsigned long max_operations); + unsigned long isl_ctx_get_max_operations(isl_ctx *ctx); + void isl_ctx_reset_operations(isl_ctx *ctx); + +In order to be able to create an object in the same context +as another object, most object types (described later in +this document) provide a function to obtain the context +in which the object was created. + + #include + isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val); + isl_ctx *isl_multi_val_get_ctx( + __isl_keep isl_multi_val *mv); + + #include + isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); + + #include + isl_ctx *isl_local_space_get_ctx( + __isl_keep isl_local_space *ls); + + #include + isl_ctx *isl_set_list_get_ctx( + __isl_keep isl_set_list *list); + + #include + isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff); + isl_ctx *isl_multi_aff_get_ctx( + __isl_keep isl_multi_aff *maff); + isl_ctx *isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pa); + isl_ctx *isl_pw_multi_aff_get_ctx( + __isl_keep isl_pw_multi_aff *pma); + isl_ctx *isl_multi_pw_aff_get_ctx( + __isl_keep isl_multi_pw_aff *mpa); + isl_ctx *isl_union_pw_aff_get_ctx( + __isl_keep isl_union_pw_aff *upa); + isl_ctx *isl_union_pw_multi_aff_get_ctx( + __isl_keep isl_union_pw_multi_aff *upma); + isl_ctx *isl_multi_union_pw_aff_get_ctx( + __isl_keep isl_multi_union_pw_aff *mupa); + + #include + isl_ctx *isl_id_to_ast_expr_get_ctx( + __isl_keep isl_id_to_ast_expr *id2expr); + + #include + isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt); + + #include + isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec); + + #include + isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat); + + #include + isl_ctx *isl_vertices_get_ctx( + __isl_keep isl_vertices *vertices); + isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex); + isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell); + + #include + isl_ctx *isl_restriction_get_ctx( + __isl_keep isl_restriction *restr); + isl_ctx *isl_union_access_info_get_ctx( + __isl_keep isl_union_access_info *access); + isl_ctx *isl_union_flow_get_ctx( + __isl_keep isl_union_flow *flow); + + #include + isl_ctx *isl_schedule_get_ctx( + __isl_keep isl_schedule *sched); + isl_ctx *isl_schedule_constraints_get_ctx( + __isl_keep isl_schedule_constraints *sc); + + #include + isl_ctx *isl_schedule_node_get_ctx( + __isl_keep isl_schedule_node *node); + + #include + isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band); + + #include + isl_ctx *isl_ast_build_get_ctx( + __isl_keep isl_ast_build *build); + + #include + isl_ctx *isl_ast_expr_get_ctx( + __isl_keep isl_ast_expr *expr); + isl_ctx *isl_ast_node_get_ctx( + __isl_keep isl_ast_node *node); + +=head2 Return Types + +C uses two special return types for functions that either return +a boolean or that in principle do not return anything. +In particular, the C type has three possible values: +C (a positive integer value), indicating I or I; +C (the integer value zero), indicating I or I; and +C (a negative integer value), indicating that something +went wrong. +The C type has two possible values: +C (the integer value zero), indicating a successful +operation; and +C (a negative integer value), indicating that something +went wrong. +See L for more information on +C and C. + =head2 Values An C represents an integer value, a rational value @@ -352,6 +607,7 @@ #include __isl_give isl_val *isl_val_zero(isl_ctx *ctx); __isl_give isl_val *isl_val_one(isl_ctx *ctx); + __isl_give isl_val *isl_val_negone(isl_ctx *ctx); __isl_give isl_val *isl_val_nan(isl_ctx *ctx); __isl_give isl_val *isl_val_infty(isl_ctx *ctx); __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx); @@ -374,12 +630,11 @@ #include __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v); - void *isl_val_free(__isl_take isl_val *v); + __isl_null isl_val *isl_val_free(__isl_take isl_val *v); They can be inspected using the following functions. #include - isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val); long isl_val_get_num_si(__isl_keep isl_val *v); long isl_val_get_den_si(__isl_keep isl_val *v); double isl_val_get_d(__isl_keep isl_val *v); @@ -408,41 +663,46 @@ #include int isl_val_sgn(__isl_keep isl_val *v); - int isl_val_is_zero(__isl_keep isl_val *v); - int isl_val_is_one(__isl_keep isl_val *v); - int isl_val_is_negone(__isl_keep isl_val *v); - int isl_val_is_nonneg(__isl_keep isl_val *v); - int isl_val_is_nonpos(__isl_keep isl_val *v); - int isl_val_is_pos(__isl_keep isl_val *v); - int isl_val_is_neg(__isl_keep isl_val *v); - int isl_val_is_int(__isl_keep isl_val *v); - int isl_val_is_rat(__isl_keep isl_val *v); - int isl_val_is_nan(__isl_keep isl_val *v); - int isl_val_is_infty(__isl_keep isl_val *v); - int isl_val_is_neginfty(__isl_keep isl_val *v); + isl_bool isl_val_is_zero(__isl_keep isl_val *v); + isl_bool isl_val_is_one(__isl_keep isl_val *v); + isl_bool isl_val_is_negone(__isl_keep isl_val *v); + isl_bool isl_val_is_nonneg(__isl_keep isl_val *v); + isl_bool isl_val_is_nonpos(__isl_keep isl_val *v); + isl_bool isl_val_is_pos(__isl_keep isl_val *v); + isl_bool isl_val_is_neg(__isl_keep isl_val *v); + isl_bool isl_val_is_int(__isl_keep isl_val *v); + isl_bool isl_val_is_rat(__isl_keep isl_val *v); + isl_bool isl_val_is_nan(__isl_keep isl_val *v); + isl_bool isl_val_is_infty(__isl_keep isl_val *v); + isl_bool isl_val_is_neginfty(__isl_keep isl_val *v); Note that the sign of NaN is undefined. The following binary properties are defined on pairs of Cs. #include - int isl_val_lt(__isl_keep isl_val *v1, + isl_bool isl_val_lt(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); + isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2); - int isl_val_le(__isl_keep isl_val *v1, + isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); - int isl_val_gt(__isl_keep isl_val *v1, + isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2); - int isl_val_ge(__isl_keep isl_val *v1, + isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); - int isl_val_eq(__isl_keep isl_val *v1, + isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2); - int isl_val_ne(__isl_keep isl_val *v1, + isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +The function C checks whether its two arguments +are equal in absolute value. + For integer Cs we additionally have the following binary property. #include - int isl_val_is_divisible_by(__isl_keep isl_val *v1, + isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2); An C can also be compared to an integer using the following @@ -459,16 +719,12 @@ __isl_give isl_val *isl_val_floor(__isl_take isl_val *v); __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v); __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v); + __isl_give isl_val *isl_val_inv(__isl_take isl_val *v); + __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v); The following binary operations are available on Cs. #include - __isl_give isl_val *isl_val_abs(__isl_take isl_val *v); - __isl_give isl_val *isl_val_neg(__isl_take isl_val *v); - __isl_give isl_val *isl_val_floor(__isl_take isl_val *v); - __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v); - __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v); - __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v); __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2); __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, @@ -504,18 +760,6 @@ of C and C as well as two integers C<*x> and C<*y> such that C<*x> * C + C<*y> * C = g. -A value can be read from input using - - #include - __isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx, - const char *str); - -A value can be printed using - - #include - __isl_give isl_printer *isl_printer_print_val( - __isl_take isl_printer *p, __isl_keep isl_val *v); - =head3 GMP specific functions These functions are only available if C has been compiled with C @@ -537,140 +781,6 @@ int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z); int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z); -=head3 Conversion from C - -The following functions are only temporarily available to ease -the transition from C to C. They will be removed -in the next release. - - #include - __isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, - isl_int n); - int isl_val_get_num_isl_int(__isl_keep isl_val *v, - isl_int *n); - -=head2 Integers (obsolescent) - -In previous versions of C, integers were represented -in the external interface using the C type. -This type has now been superseded by C. -The C type will be removed from the external interface -in future releases. New code should not use C. - -The operations below are currently available on Cs. -The meanings of these operations are essentially the same -as their C C counterparts. -As always with C types, Cs need to be -initialized with C before they can be used -and they need to be released with C -after the last use. -The user should not assume that an C is represented -as a C, but should instead explicitly convert between -Cs and Cs using C and -C whenever a C is required. - -=over - -=item isl_int_init(i) - -=item isl_int_clear(i) - -=item isl_int_set(r,i) - -=item isl_int_set_si(r,i) - -=item isl_int_set_gmp(r,g) - -=item isl_int_get_gmp(i,g) - -=item isl_int_abs(r,i) - -=item isl_int_neg(r,i) - -=item isl_int_swap(i,j) - -=item isl_int_swap_or_set(i,j) - -=item isl_int_add_ui(r,i,j) - -=item isl_int_sub_ui(r,i,j) - -=item isl_int_add(r,i,j) - -=item isl_int_sub(r,i,j) - -=item isl_int_mul(r,i,j) - -=item isl_int_mul_ui(r,i,j) - -=item isl_int_addmul(r,i,j) - -=item isl_int_submul(r,i,j) - -=item isl_int_gcd(r,i,j) - -=item isl_int_lcm(r,i,j) - -=item isl_int_divexact(r,i,j) - -=item isl_int_cdiv_q(r,i,j) - -=item isl_int_fdiv_q(r,i,j) - -=item isl_int_fdiv_r(r,i,j) - -=item isl_int_fdiv_q_ui(r,i,j) - -=item isl_int_read(r,s) - -=item isl_int_print(out,i,width) - -=item isl_int_sgn(i) - -=item isl_int_cmp(i,j) - -=item isl_int_cmp_si(i,si) - -=item isl_int_eq(i,j) - -=item isl_int_ne(i,j) - -=item isl_int_lt(i,j) - -=item isl_int_le(i,j) - -=item isl_int_gt(i,j) - -=item isl_int_ge(i,j) - -=item isl_int_abs_eq(i,j) - -=item isl_int_abs_ne(i,j) - -=item isl_int_abs_lt(i,j) - -=item isl_int_abs_gt(i,j) - -=item isl_int_abs_ge(i,j) - -=item isl_int_is_zero(i) - -=item isl_int_is_one(i) - -=item isl_int_is_negone(i) - -=item isl_int_is_pos(i) - -=item isl_int_is_neg(i) - -=item isl_int_is_nonpos(i) - -=item isl_int_is_nonneg(i) - -=item isl_int_is_divisible_by(i,j) - -=back - =head2 Sets and Relations C uses six types of objects for representing sets and relations, @@ -689,78 +799,29 @@ one set of variables, while relations have two sets of variables, input variables and output variables. -=head2 Memory Management +=head2 Error Handling -Since a high-level operation on sets and/or relations usually involves -several substeps and since the user is usually not interested in -the intermediate results, most functions that return a new object -will also release all the objects passed as arguments. -If the user still wants to use one or more of these arguments -after the function call, she should pass along a copy of the -object rather than the object itself. -The user is then responsible for making sure that the original -object gets used somewhere else or is explicitly freed. +C supports different ways to react in case a runtime error is triggered. +Runtime errors arise, e.g., if a function such as C is called +with two maps that have incompatible spaces. There are three possible ways +to react on error: to warn, to continue or to abort. -The arguments and return values of all documented functions are -annotated to make clear which arguments are released and which -arguments are preserved. In particular, the following annotations -are used +The default behavior is to warn. In this mode, C prints a warning, stores +the last error in the corresponding C and the function in which the +error was triggered returns a value indicating that some error has +occurred. In case of functions returning a pointer, this value is +C. In case of functions returning an C or an +C, this valus is C or C. +An error does not corrupt internal state, +such that isl can continue to be used. C also provides functions to +read the last error and to reset the memory that stores the last error. The +last error is only stored for information purposes. Its presence does not +change the behavior of C. Hence, resetting an error is not required to +continue to use isl, but only to observe new errors. -=over - -=item C<__isl_give> - -C<__isl_give> means that a new object is returned. -The user should make sure that the returned pointer is -used exactly once as a value for an C<__isl_take> argument. -In between, it can be used as a value for as many -C<__isl_keep> arguments as the user likes. -There is one exception, and that is the case where the -pointer returned is C. Is this case, the user -is free to use it as an C<__isl_take> argument or not. - -=item C<__isl_take> - -C<__isl_take> means that the object the argument points to -is taken over by the function and may no longer be used -by the user as an argument to any other function. -The pointer value must be one returned by a function -returning an C<__isl_give> pointer. -If the user passes in a C value, then this will -be treated as an error in the sense that the function will -not perform its usual operation. However, it will still -make sure that all the other C<__isl_take> arguments -are released. - -=item C<__isl_keep> - -C<__isl_keep> means that the function will only use the object -temporarily. After the function has finished, the user -can still use it as an argument to other functions. -A C value will be treated in the same way as -a C value for an C<__isl_take> argument. - -=back - -=head2 Error Handling - -C supports different ways to react in case a runtime error is triggered. -Runtime errors arise, e.g., if a function such as C is called -with two maps that have incompatible spaces. There are three possible ways -to react on error: to warn, to continue or to abort. - -The default behavior is to warn. In this mode, C prints a warning, stores -the last error in the corresponding C and the function in which the -error was triggered returns C. An error does not corrupt internal state, -such that isl can continue to be used. C also provides functions to -read the last error and to reset the memory that stores the last error. The -last error is only stored for information purposes. Its presence does not -change the behavior of C. Hence, resetting an error is not required to -continue to use isl, but only to observe new errors. - - #include - enum isl_error isl_ctx_last_error(isl_ctx *ctx); - void isl_ctx_reset_error(isl_ctx *ctx); + #include + enum isl_error isl_ctx_last_error(isl_ctx *ctx); + void isl_ctx_reset_error(isl_ctx *ctx); Another option is to continue on error. This is similar to warn on error mode, except that C does not print any warning. This allows a program to @@ -782,7 +843,7 @@ It is also possible to query the current error mode. #include - int isl_options_set_on_error(isl_ctx *ctx, int val); + isl_stat isl_options_set_on_error(isl_ctx *ctx, int val); int isl_options_get_on_error(isl_ctx *ctx); =head2 Identifiers @@ -807,9 +868,8 @@ __isl_take isl_id *id, __isl_give void (*free_user)(void *user)); __isl_give isl_id *isl_id_copy(isl_id *id); - void *isl_id_free(__isl_take isl_id *id); + __isl_null isl_id *isl_id_free(__isl_take isl_id *id); - isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); void *isl_id_get_user(__isl_keep isl_id *id); __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); @@ -824,7 +884,7 @@ =head2 Spaces -Whenever a new set, relation or similiar object is created from scratch, +Whenever a new set, relation or similar object is created from scratch, the space in which it lives needs to be specified using an C. Each space involves zero or more parameters and zero, one or two tuples of set or input/output dimensions. The parameters and dimensions @@ -850,9 +910,7 @@ __isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx, unsigned nparam, unsigned dim); __isl_give isl_space *isl_space_copy(__isl_keep isl_space *space); - void *isl_space_free(__isl_take isl_space *space); - unsigned isl_space_dim(__isl_keep isl_space *space, - enum isl_dim_type type); + __isl_null isl_space *isl_space_free(__isl_take isl_space *space); The space used for creating a parameter domain needs to be created using C. @@ -860,41 +918,44 @@ needs to be created using C, while for a relation, the space needs to be created using C. -C can be used -to find out the number of dimensions of each type in -a space, where type may be -C, C (only for relations), -C (only for relations), C -(only for sets) or C. To check whether a given space is that of a set or a map or whether it is a parameter space, use these functions: #include - int isl_space_is_params(__isl_keep isl_space *space); - int isl_space_is_set(__isl_keep isl_space *space); - int isl_space_is_map(__isl_keep isl_space *space); + isl_bool isl_space_is_params(__isl_keep isl_space *space); + isl_bool isl_space_is_set(__isl_keep isl_space *space); + isl_bool isl_space_is_map(__isl_keep isl_space *space); Spaces can be compared using the following functions: #include - int isl_space_is_equal(__isl_keep isl_space *space1, + isl_bool isl_space_is_equal(__isl_keep isl_space *space1, __isl_keep isl_space *space2); - int isl_space_is_domain(__isl_keep isl_space *space1, + isl_bool isl_space_is_domain(__isl_keep isl_space *space1, __isl_keep isl_space *space2); - int isl_space_is_range(__isl_keep isl_space *space1, + isl_bool isl_space_is_range(__isl_keep isl_space *space1, __isl_keep isl_space *space2); + isl_bool isl_space_tuple_is_equal( + __isl_keep isl_space *space1, + enum isl_dim_type type1, + __isl_keep isl_space *space2, + enum isl_dim_type type2); C checks whether the first argument is equal to the domain of the second argument. This requires in particular that the first argument is a set space and that the second argument -is a map space. +is a map space. C checks whether the given +tuples (C, C or C) of the given +spaces are the same. That is, it checks if they have the same +identifier (if any), the same dimension and the same internal structure +(if any). It is often useful to create objects that live in the same space as some other object. This can be accomplished by creating the new objects -(see L or -L) based on the space +(see L or +L) based on the space of the original object. #include @@ -960,26 +1021,116 @@ __isl_keep isl_pw_multi_aff *pma); __isl_give isl_space *isl_pw_multi_aff_get_space( __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_space *isl_union_pw_aff_get_space( + __isl_keep isl_union_pw_aff *upa); __isl_give isl_space *isl_union_pw_multi_aff_get_space( __isl_keep isl_union_pw_multi_aff *upma); __isl_give isl_space *isl_multi_pw_aff_get_domain_space( __isl_keep isl_multi_pw_aff *mpa); __isl_give isl_space *isl_multi_pw_aff_get_space( __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_space * + isl_multi_union_pw_aff_get_domain_space( + __isl_keep isl_multi_union_pw_aff *mupa); + __isl_give isl_space * + isl_multi_union_pw_aff_get_space( + __isl_keep isl_multi_union_pw_aff *mupa); #include __isl_give isl_space *isl_point_get_space( __isl_keep isl_point *pnt); -The identifiers or names of the individual dimensions may be set or read off -using the following functions. +The number of dimensions of a given type of space +may be read off from a space or an object that lives +in a space using the following functions. +In case of C, type may be +C, C (only for relations), +C (only for relations), C +(only for sets) or C. + + #include + unsigned isl_space_dim(__isl_keep isl_space *space, + enum isl_dim_type type); + + #include + int isl_local_space_dim(__isl_keep isl_local_space *ls, + enum isl_dim_type type); + + #include + unsigned isl_basic_set_dim(__isl_keep isl_basic_set *bset, + enum isl_dim_type type); + unsigned isl_set_dim(__isl_keep isl_set *set, + enum isl_dim_type type); + + #include + unsigned isl_union_set_dim(__isl_keep isl_union_set *uset, + enum isl_dim_type type); + + #include + unsigned isl_basic_map_dim(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type); + unsigned isl_map_dim(__isl_keep isl_map *map, + enum isl_dim_type type); + + #include + unsigned isl_union_map_dim(__isl_keep isl_union_map *umap, + enum isl_dim_type type); + + #include + unsigned isl_multi_val_dim(__isl_keep isl_multi_val *mv, + enum isl_dim_type type); + + #include + int isl_aff_dim(__isl_keep isl_aff *aff, + enum isl_dim_type type); + unsigned isl_multi_aff_dim(__isl_keep isl_multi_aff *maff, + enum isl_dim_type type); + unsigned isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff, + enum isl_dim_type type); + unsigned isl_pw_multi_aff_dim( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + unsigned isl_multi_pw_aff_dim( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type); + unsigned isl_union_pw_aff_dim( + __isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type); + unsigned isl_union_pw_multi_aff_dim( + __isl_keep isl_union_pw_multi_aff *upma, + enum isl_dim_type type); + unsigned isl_multi_union_pw_aff_dim( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + + #include + unsigned isl_union_pw_qpolynomial_dim( + __isl_keep isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type); + unsigned isl_union_pw_qpolynomial_fold_dim( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type); + +Note that an C, an C, +an C, +an C and +an C +only have parameters. + +The identifiers or names of the individual dimensions of spaces +may be set or read off using the following functions on spaces +or objects that live in spaces. +These functions are mostly useful to obtain the identifiers, positions +or names of the parameters. Identifiers of individual dimensions are +essentially only useful for printing. They are ignored by all other +operations and may not be preserved across those operations. #include __isl_give isl_space *isl_space_set_dim_id( __isl_take isl_space *space, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); - int isl_space_has_dim_id(__isl_keep isl_space *space, + isl_bool isl_space_has_dim_id(__isl_keep isl_space *space, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_space_get_dim_id( __isl_keep isl_space *space, @@ -988,384 +1139,615 @@ __isl_take isl_space *space, enum isl_dim_type type, unsigned pos, __isl_keep const char *name); - int isl_space_has_dim_name(__isl_keep isl_space *space, + isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, enum isl_dim_type type, unsigned pos); __isl_keep const char *isl_space_get_dim_name( __isl_keep isl_space *space, enum isl_dim_type type, unsigned pos); -Note that C returns a pointer to some internal -data structure, so the result can only be used while the -corresponding C is alive. -Also note that every function that operates on two sets or relations -requires that both arguments have the same parameters. This also -means that if one of the arguments has named parameters, then the -other needs to have named parameters too and the names need to match. -Pairs of C, C, C and/or C -arguments may have different parameters (as long as they are named), -in which case the result will have as parameters the union of the parameters of -the arguments. - -Given the identifier or name of a dimension (typically a parameter), -its position can be obtained from the following function. - - #include - int isl_space_find_dim_by_id(__isl_keep isl_space *space, - enum isl_dim_type type, __isl_keep isl_id *id); - int isl_space_find_dim_by_name(__isl_keep isl_space *space, - enum isl_dim_type type, const char *name); - -The identifiers or names of entire spaces may be set or read off -using the following functions. - - #include - __isl_give isl_space *isl_space_set_tuple_id( - __isl_take isl_space *space, - enum isl_dim_type type, __isl_take isl_id *id); - __isl_give isl_space *isl_space_reset_tuple_id( - __isl_take isl_space *space, enum isl_dim_type type); - int isl_space_has_tuple_id(__isl_keep isl_space *space, - enum isl_dim_type type); - __isl_give isl_id *isl_space_get_tuple_id( - __isl_keep isl_space *space, enum isl_dim_type type); - __isl_give isl_space *isl_space_set_tuple_name( - __isl_take isl_space *space, - enum isl_dim_type type, const char *s); - int isl_space_has_tuple_name(__isl_keep isl_space *space, - enum isl_dim_type type); - const char *isl_space_get_tuple_name(__isl_keep isl_space *space, - enum isl_dim_type type); - -The C argument needs to be one of C, C -or C. As with C, -the C function returns a pointer to some internal -data structure. -Binary operations require the corresponding spaces of their arguments -to have the same name. - -Spaces can be nested. In particular, the domain of a set or -the domain or range of a relation can be a nested relation. -The following functions can be used to construct and deconstruct -such nested spaces. - - #include - int isl_space_is_wrapping(__isl_keep isl_space *space); - __isl_give isl_space *isl_space_wrap(__isl_take isl_space *space); - __isl_give isl_space *isl_space_unwrap(__isl_take isl_space *space); - -The input to C and C should -be the space of a set, while that of -C should be the space of a relation. -Conversely, the output of C is the space -of a relation, while that of C is the space of a set. - -Spaces can be created from other spaces -using the following functions. - - __isl_give isl_space *isl_space_domain(__isl_take isl_space *space); - __isl_give isl_space *isl_space_from_domain(__isl_take isl_space *space); - __isl_give isl_space *isl_space_range(__isl_take isl_space *space); - __isl_give isl_space *isl_space_from_range(__isl_take isl_space *space); - __isl_give isl_space *isl_space_params( - __isl_take isl_space *space); - __isl_give isl_space *isl_space_set_from_params( - __isl_take isl_space *space); - __isl_give isl_space *isl_space_reverse(__isl_take isl_space *space); - __isl_give isl_space *isl_space_join(__isl_take isl_space *left, - __isl_take isl_space *right); - __isl_give isl_space *isl_space_align_params( - __isl_take isl_space *space1, __isl_take isl_space *space2) - __isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *space, - enum isl_dim_type type, unsigned pos, unsigned n); - __isl_give isl_space *isl_space_add_dims(__isl_take isl_space *space, - enum isl_dim_type type, unsigned n); - __isl_give isl_space *isl_space_drop_dims(__isl_take isl_space *space, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, - unsigned n); - __isl_give isl_space *isl_space_map_from_set( - __isl_take isl_space *space); - __isl_give isl_space *isl_space_map_from_domain_and_range( - __isl_take isl_space *domain, - __isl_take isl_space *range); - __isl_give isl_space *isl_space_zip(__isl_take isl_space *space); - __isl_give isl_space *isl_space_curry( - __isl_take isl_space *space); - __isl_give isl_space *isl_space_uncurry( - __isl_take isl_space *space); - -Note that if dimensions are added or removed from a space, then -the name and the internal structure are lost. - -=head2 Local Spaces - -A local space is essentially a space with -zero or more existentially quantified variables. -The local space of a (constraint of a) basic set or relation can be obtained -using the following functions. - - #include - __isl_give isl_local_space *isl_constraint_get_local_space( - __isl_keep isl_constraint *constraint); - - #include - __isl_give isl_local_space *isl_basic_set_get_local_space( - __isl_keep isl_basic_set *bset); - - #include - __isl_give isl_local_space *isl_basic_map_get_local_space( - __isl_keep isl_basic_map *bmap); - -A new local space can be created from a space using - #include - __isl_give isl_local_space *isl_local_space_from_space( - __isl_take isl_space *space); - -They can be inspected, modified, copied and freed using the following functions. - - #include - isl_ctx *isl_local_space_get_ctx( - __isl_keep isl_local_space *ls); - int isl_local_space_is_set(__isl_keep isl_local_space *ls); - int isl_local_space_dim(__isl_keep isl_local_space *ls, - enum isl_dim_type type); - int isl_local_space_has_dim_id( + __isl_give isl_local_space *isl_local_space_set_dim_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + isl_bool isl_local_space_has_dim_id( __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_local_space_get_dim_id( __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); - int isl_local_space_has_dim_name( + __isl_give isl_local_space *isl_local_space_set_dim_name( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, const char *s); + isl_bool isl_local_space_has_dim_name( __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos) const char *isl_local_space_get_dim_name( __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); - __isl_give isl_local_space *isl_local_space_set_dim_name( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned pos, const char *s); - __isl_give isl_local_space *isl_local_space_set_dim_id( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned pos, - __isl_take isl_id *id); - __isl_give isl_space *isl_local_space_get_space( - __isl_keep isl_local_space *ls); - __isl_give isl_aff *isl_local_space_get_div( - __isl_keep isl_local_space *ls, int pos); - __isl_give isl_local_space *isl_local_space_copy( - __isl_keep isl_local_space *ls); - void *isl_local_space_free(__isl_take isl_local_space *ls); -Note that C can only be used on local spaces -of sets. + #include + const char *isl_constraint_get_dim_name( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned pos); -Two local spaces can be compared using + #include + __isl_give isl_id *isl_basic_set_get_dim_id( + __isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos); + __isl_give isl_set *isl_set_set_dim_id( + __isl_take isl_set *set, enum isl_dim_type type, + unsigned pos, __isl_take isl_id *id); + isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_set_get_dim_id( + __isl_keep isl_set *set, enum isl_dim_type type, + unsigned pos); + const char *isl_basic_set_get_dim_name( + __isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned pos); + isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + const char *isl_set_get_dim_name( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); - int isl_local_space_is_equal(__isl_keep isl_local_space *ls1, - __isl_keep isl_local_space *ls2); + #include + __isl_give isl_map *isl_map_set_dim_id( + __isl_take isl_map *map, enum isl_dim_type type, + unsigned pos, __isl_take isl_id *id); + isl_bool isl_basic_map_has_dim_id( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_map_get_dim_id( + __isl_keep isl_map *map, enum isl_dim_type type, + unsigned pos); + __isl_give isl_id *isl_union_map_get_dim_id( + __isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned pos); + const char *isl_basic_map_get_dim_name( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + isl_bool isl_map_has_dim_name(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); + const char *isl_map_get_dim_name( + __isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); -Local spaces can be created from other local spaces -using the following functions. + #include + __isl_give isl_multi_val *isl_multi_val_set_dim_id( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_id *isl_multi_val_get_dim_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type, unsigned pos); + __isl_give isl_multi_val *isl_multi_val_set_dim_name( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned pos, const char *s); - __isl_give isl_local_space *isl_local_space_domain( - __isl_take isl_local_space *ls); - __isl_give isl_local_space *isl_local_space_range( - __isl_take isl_local_space *ls); - __isl_give isl_local_space *isl_local_space_from_domain( - __isl_take isl_local_space *ls); - __isl_give isl_local_space *isl_local_space_intersect( - __isl_take isl_local_space *ls1, - __isl_take isl_local_space *ls2); - __isl_give isl_local_space *isl_local_space_add_dims( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned n); - __isl_give isl_local_space *isl_local_space_insert_dims( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_local_space *isl_local_space_drop_dims( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned first, unsigned n); + #include + __isl_give isl_aff *isl_aff_set_dim_id( + __isl_take isl_aff *aff, enum isl_dim_type type, + unsigned pos, __isl_take isl_id *id); + __isl_give isl_multi_aff *isl_multi_aff_set_dim_id( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_pw_aff *isl_pw_aff_set_dim_id( + __isl_take isl_pw_aff *pma, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_dim_id( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_dim_id( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos, + __isl_take isl_id *id); + __isl_give isl_id *isl_multi_aff_get_dim_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, unsigned pos); + isl_bool isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_pw_aff_get_dim_id( + __isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_pw_multi_aff_get_dim_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_multi_pw_aff_get_dim_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_multi_union_pw_aff_get_dim_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos); + __isl_give isl_aff *isl_aff_set_dim_name( + __isl_take isl_aff *aff, enum isl_dim_type type, + unsigned pos, const char *s); + __isl_give isl_multi_aff *isl_multi_aff_set_dim_name( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, unsigned pos, const char *s); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_dim_name( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned pos, const char *s); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_set_dim_name( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_set_dim_name( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_dim_name( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned pos, + const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned pos); + const char *isl_pw_aff_get_dim_name( + __isl_keep isl_pw_aff *pa, + enum isl_dim_type type, unsigned pos); + const char *isl_pw_multi_aff_get_dim_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); -=head2 Input and Output + #include + __isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name( + __isl_take isl_qpolynomial *qp, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_set_dim_name( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_set_dim_name( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, unsigned pos, + const char *s); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, unsigned pos, + const char *s); -C supports its own input/output format, which is similar -to the C format, but also supports the C format -in some cases. +Note that C returns a pointer to some internal +data structure, so the result can only be used while the +corresponding C is alive. +Also note that every function that operates on two sets or relations +requires that both arguments have the same parameters. This also +means that if one of the arguments has named parameters, then the +other needs to have named parameters too and the names need to match. +Pairs of C, C, C and/or C +arguments may have different parameters (as long as they are named), +in which case the result will have as parameters the union of the parameters of +the arguments. -=head3 C format +Given the identifier or name of a dimension (typically a parameter), +its position can be obtained from the following functions. -The C format is similar to that of C, but has a different -syntax for describing the parameters and allows for the definition -of an existentially quantified variable as the integer division -of an affine expression. -For example, the set of integers C between C<0> and C -such that C can be described as + #include + int isl_space_find_dim_by_id(__isl_keep isl_space *space, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_space_find_dim_by_name(__isl_keep isl_space *space, + enum isl_dim_type type, const char *name); - [n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and - i - 10 a <= 6) } + #include + int isl_local_space_find_dim_by_name( + __isl_keep isl_local_space *ls, + enum isl_dim_type type, const char *name); -A set or relation can have several disjuncts, separated -by the keyword C. Each disjunct is either a conjunction -of constraints or a projection (C) of a conjunction -of constraints. The constraints are separated by the keyword -C. + #include + int isl_multi_val_find_dim_by_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_multi_val_find_dim_by_name( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type, const char *name); -=head3 C format + #include + int isl_set_find_dim_by_id(__isl_keep isl_set *set, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_set_find_dim_by_name(__isl_keep isl_set *set, + enum isl_dim_type type, const char *name); -If the represented set is a union, then the first line -contains a single number representing the number of disjuncts. -Otherwise, a line containing the number C<1> is optional. + #include + int isl_map_find_dim_by_id(__isl_keep isl_map *map, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_basic_map_find_dim_by_name( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, const char *name); + int isl_map_find_dim_by_name(__isl_keep isl_map *map, + enum isl_dim_type type, const char *name); + int isl_union_map_find_dim_by_name( + __isl_keep isl_union_map *umap, + enum isl_dim_type type, const char *name); -Each disjunct is represented by a matrix of constraints. -The first line contains two numbers representing -the number of rows and columns, -where the number of rows is equal to the number of constraints -and the number of columns is equal to two plus the number of variables. -The following lines contain the actual rows of the constraint matrix. -In each row, the first column indicates whether the constraint -is an equality (C<0>) or inequality (C<1>). The final column -corresponds to the constant term. + #include + int isl_multi_aff_find_dim_by_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_multi_pw_aff_find_dim_by_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_multi_union_pw_aff_find_dim_by_id( + __isl_keep isl_union_multi_pw_aff *mupa, + enum isl_dim_type type, __isl_keep isl_id *id); + int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, + enum isl_dim_type type, const char *name); + int isl_multi_aff_find_dim_by_name( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, const char *name); + int isl_pw_aff_find_dim_by_name(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, const char *name); + int isl_multi_pw_aff_find_dim_by_name( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, const char *name); + int isl_pw_multi_aff_find_dim_by_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, const char *name); + int isl_union_pw_aff_find_dim_by_name( + __isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type, const char *name); + int isl_union_pw_multi_aff_find_dim_by_name( + __isl_keep isl_union_pw_multi_aff *upma, + enum isl_dim_type type, const char *name); + int isl_multi_union_pw_aff_find_dim_by_name( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, const char *name); -If the set is parametric, then the coefficients of the parameters -appear in the last columns before the constant column. -The coefficients of any existentially quantified variables appear -between those of the set variables and those of the parameters. + #include + int isl_pw_qpolynomial_find_dim_by_name( + __isl_keep isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, const char *name); + int isl_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, const char *name); + int isl_union_pw_qpolynomial_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, const char *name); + int isl_union_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, const char *name); -=head3 Extended C format +The identifiers or names of entire spaces may be set or read off +using the following functions. -The extended C format is nearly identical to the -C format. The only difference is that the line -containing the number of rows and columns of a constraint matrix -also contains four additional numbers: -the number of output dimensions, the number of input dimensions, -the number of local dimensions (i.e., the number of existentially -quantified variables) and the number of parameters. -For sets, the number of ``output'' dimensions is equal -to the number of set dimensions, while the number of ``input'' -dimensions is zero. + #include + __isl_give isl_space *isl_space_set_tuple_id( + __isl_take isl_space *space, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_space *isl_space_reset_tuple_id( + __isl_take isl_space *space, enum isl_dim_type type); + isl_bool isl_space_has_tuple_id( + __isl_keep isl_space *space, + enum isl_dim_type type); + __isl_give isl_id *isl_space_get_tuple_id( + __isl_keep isl_space *space, enum isl_dim_type type); + __isl_give isl_space *isl_space_set_tuple_name( + __isl_take isl_space *space, + enum isl_dim_type type, const char *s); + isl_bool isl_space_has_tuple_name( + __isl_keep isl_space *space, + enum isl_dim_type type); + const char *isl_space_get_tuple_name(__isl_keep isl_space *space, + enum isl_dim_type type); -=head3 Input + #include + __isl_give isl_local_space *isl_local_space_set_tuple_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, __isl_take isl_id *id); #include - __isl_give isl_basic_set *isl_basic_set_read_from_file( - isl_ctx *ctx, FILE *input); - __isl_give isl_basic_set *isl_basic_set_read_from_str( - isl_ctx *ctx, const char *str); - __isl_give isl_set *isl_set_read_from_file(isl_ctx *ctx, - FILE *input); - __isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx, - const char *str); + __isl_give isl_basic_set *isl_basic_set_set_tuple_id( + __isl_take isl_basic_set *bset, + __isl_take isl_id *id); + __isl_give isl_set *isl_set_set_tuple_id( + __isl_take isl_set *set, __isl_take isl_id *id); + __isl_give isl_set *isl_set_reset_tuple_id( + __isl_take isl_set *set); + isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set); + __isl_give isl_id *isl_set_get_tuple_id( + __isl_keep isl_set *set); + __isl_give isl_basic_set *isl_basic_set_set_tuple_name( + __isl_take isl_basic_set *set, const char *s); + __isl_give isl_set *isl_set_set_tuple_name( + __isl_take isl_set *set, const char *s); + const char *isl_basic_set_get_tuple_name( + __isl_keep isl_basic_set *bset); + isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set); + const char *isl_set_get_tuple_name( + __isl_keep isl_set *set); #include - __isl_give isl_basic_map *isl_basic_map_read_from_file( - isl_ctx *ctx, FILE *input); - __isl_give isl_basic_map *isl_basic_map_read_from_str( - isl_ctx *ctx, const char *str); - __isl_give isl_map *isl_map_read_from_file( - isl_ctx *ctx, FILE *input); - __isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, - const char *str); + __isl_give isl_basic_map *isl_basic_map_set_tuple_id( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_map *isl_map_set_tuple_id( + __isl_take isl_map *map, enum isl_dim_type type, + __isl_take isl_id *id); + __isl_give isl_map *isl_map_reset_tuple_id( + __isl_take isl_map *map, enum isl_dim_type type); + isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, + enum isl_dim_type type); + __isl_give isl_id *isl_map_get_tuple_id( + __isl_keep isl_map *map, enum isl_dim_type type); + __isl_give isl_map *isl_map_set_tuple_name( + __isl_take isl_map *map, + enum isl_dim_type type, const char *s); + const char *isl_basic_map_get_tuple_name( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type); + __isl_give isl_basic_map *isl_basic_map_set_tuple_name( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, const char *s); + isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, + enum isl_dim_type type); + const char *isl_map_get_tuple_name( + __isl_keep isl_map *map, + enum isl_dim_type type); - #include - __isl_give isl_union_set *isl_union_set_read_from_file( - isl_ctx *ctx, FILE *input); - __isl_give isl_union_set *isl_union_set_read_from_str( - isl_ctx *ctx, const char *str); + #include + __isl_give isl_multi_val *isl_multi_val_set_tuple_id( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_val *isl_multi_val_reset_tuple_id( + __isl_take isl_multi_val *mv, + enum isl_dim_type type); + isl_bool isl_multi_val_has_tuple_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_val_get_tuple_id( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type); + __isl_give isl_multi_val *isl_multi_val_set_tuple_name( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, const char *s); + const char *isl_multi_val_get_tuple_name( + __isl_keep isl_multi_val *mv, + enum isl_dim_type type); - #include - __isl_give isl_union_map *isl_union_map_read_from_file( - isl_ctx *ctx, FILE *input); - __isl_give isl_union_map *isl_union_map_read_from_str( - isl_ctx *ctx, const char *str); + #include + __isl_give isl_aff *isl_aff_set_tuple_id( + __isl_take isl_aff *aff, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_aff *isl_multi_aff_set_tuple_id( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_pw_aff *isl_pw_aff_set_tuple_id( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_tuple_id( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, __isl_take isl_id *id); + __isl_give isl_multi_aff *isl_multi_aff_reset_tuple_id( + __isl_take isl_multi_aff *ma, + enum isl_dim_type type); + __isl_give isl_pw_aff *isl_pw_aff_reset_tuple_id( + __isl_take isl_pw_aff *pa, + enum isl_dim_type type); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_reset_tuple_id( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_reset_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_reset_tuple_id( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + isl_bool isl_multi_aff_has_tuple_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_aff_get_tuple_id( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type); + isl_bool isl_pw_aff_has_tuple_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type); + __isl_give isl_id *isl_pw_aff_get_tuple_id( + __isl_keep isl_pw_aff *pa, + enum isl_dim_type type); + isl_bool isl_pw_multi_aff_has_tuple_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + isl_bool isl_multi_pw_aff_has_tuple_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_pw_aff_get_tuple_id( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type); + isl_bool isl_multi_union_pw_aff_has_tuple_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + __isl_give isl_id *isl_multi_union_pw_aff_get_tuple_id( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); + __isl_give isl_multi_aff *isl_multi_aff_set_tuple_name( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, const char *s); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_set_tuple_name( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, const char *s); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_tuple_name( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, const char *s); + const char *isl_multi_aff_get_tuple_name( + __isl_keep isl_multi_aff *multi, + enum isl_dim_type type); + isl_bool isl_pw_multi_aff_has_tuple_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + const char *isl_pw_multi_aff_get_tuple_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + const char *isl_multi_union_pw_aff_get_tuple_name( + __isl_keep isl_multi_union_pw_aff *mupa, + enum isl_dim_type type); -The input format is autodetected and may be either the C format -or the C format. +The C argument needs to be one of C, C +or C. As with C, +the C function returns a pointer to some internal +data structure. +Binary operations require the corresponding spaces of their arguments +to have the same name. -=head3 Output +To keep the names of all parameters and tuples, but reset the user pointers +of all the corresponding identifiers, use the following function. -Before anything can be printed, an C needs to -be created. + #include + __isl_give isl_space *isl_space_reset_user( + __isl_take isl_space *space); - __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, - FILE *file); - __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx); - void *isl_printer_free(__isl_take isl_printer *printer); - __isl_give char *isl_printer_get_str( - __isl_keep isl_printer *printer); + #include + __isl_give isl_set *isl_set_reset_user( + __isl_take isl_set *set); -The printer can be inspected using the following functions. + #include + __isl_give isl_map *isl_map_reset_user( + __isl_take isl_map *map); - FILE *isl_printer_get_file( - __isl_keep isl_printer *printer); - int isl_printer_get_output_format( - __isl_keep isl_printer *p); + #include + __isl_give isl_union_set *isl_union_set_reset_user( + __isl_take isl_union_set *uset); -The behavior of the printer can be modified in various ways + #include + __isl_give isl_union_map *isl_union_map_reset_user( + __isl_take isl_union_map *umap); - __isl_give isl_printer *isl_printer_set_output_format( - __isl_take isl_printer *p, int output_format); - __isl_give isl_printer *isl_printer_set_indent( - __isl_take isl_printer *p, int indent); - __isl_give isl_printer *isl_printer_indent( - __isl_take isl_printer *p, int indent); - __isl_give isl_printer *isl_printer_set_prefix( - __isl_take isl_printer *p, const char *prefix); - __isl_give isl_printer *isl_printer_set_suffix( - __isl_take isl_printer *p, const char *suffix); + #include + __isl_give isl_multi_val *isl_multi_val_reset_user( + __isl_take isl_multi_val *mv); -The C may be either C, C, -C, C or C -and defaults to C. -Each line in the output is indented by C (set by -C) spaces -(default: 0), prefixed by C and suffixed by C. -In the C format output, -the coefficients of the existentially quantified variables -appear between those of the set variables and those -of the parameters. -The function C increases the indentation -by the specified amount (which may be negative). + #include + __isl_give isl_multi_aff *isl_multi_aff_reset_user( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_reset_user( + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_reset_user( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_reset_user( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_reset_user( + __isl_take isl_union_pw_multi_aff *upma); -To actually print something, use + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_reset_user( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_reset_user( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_reset_user( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_reset_user( + __isl_take isl_union_pw_qpolynomial_fold *upwf); - #include - __isl_give isl_printer *isl_printer_print_double( - __isl_take isl_printer *p, double d); +Spaces can be nested. In particular, the domain of a set or +the domain or range of a relation can be a nested relation. +This process is also called I. +The functions for detecting, constructing and deconstructing +such nested spaces can be found in the wrapping properties +of L, the wrapping operations +of L and the Cartesian product operations +of L. + +Spaces can be created from other spaces +using the functions described in L +and L. + +=head2 Local Spaces + +A local space is essentially a space with +zero or more existentially quantified variables. +The local space of various objects can be obtained +using the following functions. + + #include + __isl_give isl_local_space *isl_constraint_get_local_space( + __isl_keep isl_constraint *constraint); #include - __isl_give isl_printer *isl_printer_print_basic_set( - __isl_take isl_printer *printer, + __isl_give isl_local_space *isl_basic_set_get_local_space( __isl_keep isl_basic_set *bset); - __isl_give isl_printer *isl_printer_print_set( - __isl_take isl_printer *printer, - __isl_keep isl_set *set); #include - __isl_give isl_printer *isl_printer_print_basic_map( - __isl_take isl_printer *printer, + __isl_give isl_local_space *isl_basic_map_get_local_space( __isl_keep isl_basic_map *bmap); - __isl_give isl_printer *isl_printer_print_map( - __isl_take isl_printer *printer, - __isl_keep isl_map *map); - #include - __isl_give isl_printer *isl_printer_print_union_set( - __isl_take isl_printer *p, - __isl_keep isl_union_set *uset); + #include + __isl_give isl_local_space *isl_aff_get_domain_local_space( + __isl_keep isl_aff *aff); + __isl_give isl_local_space *isl_aff_get_local_space( + __isl_keep isl_aff *aff); - #include - __isl_give isl_printer *isl_printer_print_union_map( - __isl_take isl_printer *p, - __isl_keep isl_union_map *umap); +A new local space can be created from a space using -When called on a file printer, the following function flushes -the file. When called on a string printer, the buffer is cleared. + #include + __isl_give isl_local_space *isl_local_space_from_space( + __isl_take isl_space *space); - __isl_give isl_printer *isl_printer_flush( - __isl_take isl_printer *p); +They can be inspected, modified, copied and freed using the following functions. + + #include + isl_bool isl_local_space_is_params( + __isl_keep isl_local_space *ls); + isl_bool isl_local_space_is_set( + __isl_keep isl_local_space *ls); + __isl_give isl_space *isl_local_space_get_space( + __isl_keep isl_local_space *ls); + __isl_give isl_aff *isl_local_space_get_div( + __isl_keep isl_local_space *ls, int pos); + __isl_give isl_local_space *isl_local_space_copy( + __isl_keep isl_local_space *ls); + __isl_null isl_local_space *isl_local_space_free( + __isl_take isl_local_space *ls); + +Note that C can only be used on local spaces +of sets. + +Two local spaces can be compared using + + isl_bool isl_local_space_is_equal( + __isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2); + +Local spaces can be created from other local spaces +using the functions described in L +and L. =head2 Creating New Sets and Relations @@ -1492,14 +1874,6 @@ __isl_give isl_map *isl_map_from_union_map( __isl_take isl_union_map *umap); -A zero-dimensional (basic) set can be constructed on a given parameter domain -using the following function. - - __isl_give isl_basic_set *isl_basic_set_from_params( - __isl_take isl_basic_set *bset); - __isl_give isl_set *isl_set_from_params( - __isl_take isl_set *set); - Sets and relations can be copied and freed again using the following functions. @@ -1513,12 +1887,16 @@ __isl_give isl_map *isl_map_copy(__isl_keep isl_map *map); __isl_give isl_union_map *isl_union_map_copy( __isl_keep isl_union_map *umap); - void *isl_basic_set_free(__isl_take isl_basic_set *bset); - void *isl_set_free(__isl_take isl_set *set); - void *isl_union_set_free(__isl_take isl_union_set *uset); - void *isl_basic_map_free(__isl_take isl_basic_map *bmap); - void *isl_map_free(__isl_take isl_map *map); - void *isl_union_map_free(__isl_take isl_union_map *umap); + __isl_null isl_basic_set *isl_basic_set_free( + __isl_take isl_basic_set *bset); + __isl_null isl_set *isl_set_free(__isl_take isl_set *set); + __isl_null isl_union_set *isl_union_set_free( + __isl_take isl_union_set *uset); + __isl_null isl_basic_map *isl_basic_map_free( + __isl_take isl_basic_map *bmap); + __isl_null isl_map *isl_map_free(__isl_take isl_map *map); + __isl_null isl_union_map *isl_union_map_free( + __isl_take isl_union_map *umap); Other sets and relations can be constructed by starting from a universe set or relation, adding equality and/or @@ -1529,27 +1907,23 @@ using the following functions. #include - __isl_give isl_constraint *isl_equality_alloc( + __isl_give isl_constraint *isl_constraint_alloc_equality( __isl_take isl_local_space *ls); - __isl_give isl_constraint *isl_inequality_alloc( + __isl_give isl_constraint *isl_constraint_alloc_inequality( __isl_take isl_local_space *ls); - __isl_give isl_constraint *isl_constraint_set_constant( - __isl_take isl_constraint *constraint, isl_int v); __isl_give isl_constraint *isl_constraint_set_constant_si( __isl_take isl_constraint *constraint, int v); __isl_give isl_constraint *isl_constraint_set_constant_val( __isl_take isl_constraint *constraint, __isl_take isl_val *v); - __isl_give isl_constraint *isl_constraint_set_coefficient( - __isl_take isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_int v); __isl_give isl_constraint *isl_constraint_set_coefficient_si( __isl_take isl_constraint *constraint, enum isl_dim_type type, int pos, int v); __isl_give isl_constraint * isl_constraint_set_coefficient_val( __isl_take isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_val *v); + enum isl_dim_type type, int pos, + __isl_take isl_val *v); __isl_give isl_basic_map *isl_basic_map_add_constraint( __isl_take isl_basic_map *bmap, __isl_take isl_constraint *constraint); @@ -1562,9 +1936,6 @@ __isl_give isl_set *isl_set_add_constraint( __isl_take isl_set *set, __isl_take isl_constraint *constraint); - __isl_give isl_basic_set *isl_basic_set_drop_constraint( - __isl_take isl_basic_set *bset, - __isl_take isl_constraint *constraint); For example, to create a set containing the even integers between 10 and 42, you would use the following code. @@ -1578,17 +1949,17 @@ bset = isl_basic_set_universe(isl_space_copy(space)); ls = isl_local_space_from_space(space); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 2); bset = isl_basic_set_add_constraint(bset, c); - c = isl_inequality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); c = isl_constraint_set_constant_si(c, -10); c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); bset = isl_basic_set_add_constraint(bset, c); - c = isl_inequality_alloc(ls); + c = isl_constraint_alloc_inequality(ls); c = isl_constraint_set_constant_si(c, 42); c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); bset = isl_basic_set_add_constraint(bset, c); @@ -1627,8 +1998,7 @@ A (basic or union) set or relation can also be constructed from a (union) (piecewise) (multiple) affine expression or a list of affine expressions -(See L<"Piecewise Quasi Affine Expressions"> and -L<"Piecewise Multiple Quasi Affine Expressions">). +(See L). __isl_give isl_basic_map *isl_basic_map_from_aff( __isl_take isl_aff *aff); @@ -1649,13 +2019,25 @@ __isl_take isl_pw_multi_aff *pma); __isl_give isl_map *isl_map_from_pw_multi_aff( __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_set_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_map *isl_union_map_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); __isl_give isl_union_map * isl_union_map_from_union_pw_multi_aff( __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_map * + isl_union_map_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); -The C argument describes the domain of the resulting +The C argument describes the domain of the resulting basic relation. It is required because the C may consist of zero affine expressions. +The C passed to C +is not allowed to be zero-dimensional. The domain of the result +is the shared domain of the union piecewise affine elements. =head2 Inspecting Sets and Relations @@ -1734,11 +2116,13 @@ To iterate over all the sets or maps in a union set or map, use - int isl_union_set_foreach_set(__isl_keep isl_union_set *uset, - int (*fn)(__isl_take isl_set *set, void *user), + isl_stat isl_union_set_foreach_set( + __isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_set *set, void *user), void *user); - int isl_union_map_foreach_map(__isl_keep isl_union_map *umap, - int (*fn)(__isl_take isl_map *map, void *user), + isl_stat isl_union_map_foreach_map( + __isl_keep isl_union_map *umap, + isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user); The number of sets or maps in a union set or map can be obtained @@ -1758,11 +2142,13 @@ To iterate over all the basic sets or maps in a set or map, use - int isl_set_foreach_basic_set(__isl_keep isl_set *set, - int (*fn)(__isl_take isl_basic_set *bset, void *user), + isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_basic_set *bset, + void *user), void *user); - int isl_map_foreach_basic_map(__isl_keep isl_map *map, - int (*fn)(__isl_take isl_basic_map *bmap, void *user), + isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, + isl_stat (*fn)(__isl_take isl_basic_map *bmap, + void *user), void *user); The callback function C should return 0 if successful and @@ -1780,25 +2166,35 @@ __isl_take isl_map *map); The number of basic sets in a set can be obtained +or the number of basic maps in a map can be obtained from + #include int isl_set_n_basic_set(__isl_keep isl_set *set); + #include + int isl_map_n_basic_map(__isl_keep isl_map *map); + To iterate over the constraints of a basic set or map, use #include int isl_basic_set_n_constraint( __isl_keep isl_basic_set *bset); - int isl_basic_set_foreach_constraint( + isl_stat isl_basic_set_foreach_constraint( __isl_keep isl_basic_set *bset, - int (*fn)(__isl_take isl_constraint *c, void *user), + isl_stat (*fn)(__isl_take isl_constraint *c, + void *user), void *user); - int isl_basic_map_foreach_constraint( + int isl_basic_map_n_constraint( + __isl_keep isl_basic_map *bmap); + isl_stat isl_basic_map_foreach_constraint( __isl_keep isl_basic_map *bmap, - int (*fn)(__isl_take isl_constraint *c, void *user), + isl_stat (*fn)(__isl_take isl_constraint *c, + void *user), void *user); - void *isl_constraint_free(__isl_take isl_constraint *c); + __isl_null isl_constraint *isl_constraint_free( + __isl_take isl_constraint *c); Again, the callback function C should return 0 if successful and -1 if an error occurs. In the latter case, or if any other error @@ -1807,31 +2203,38 @@ Use the following function to find out whether a constraint represents an equality. If not, it represents an inequality. - int isl_constraint_is_equality( + isl_bool isl_constraint_is_equality( __isl_keep isl_constraint *constraint); +It is also possible to obtain a list of constraints from a basic +map or set + + #include + __isl_give isl_constraint_list * + isl_basic_map_get_constraint_list( + __isl_keep isl_basic_map *bmap); + __isl_give isl_constraint_list * + isl_basic_set_get_constraint_list( + __isl_keep isl_basic_set *bset); + +These functions require that all existentially quantified variables +have an explicit representation. +The returned list can be manipulated using the functions in L<"Lists">. + The coefficients of the constraints can be inspected using the following functions. - int isl_constraint_is_lower_bound( + isl_bool isl_constraint_is_lower_bound( __isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos); - int isl_constraint_is_upper_bound( + isl_bool isl_constraint_is_upper_bound( __isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos); - void isl_constraint_get_constant( - __isl_keep isl_constraint *constraint, isl_int *v); __isl_give isl_val *isl_constraint_get_constant_val( __isl_keep isl_constraint *constraint); - void isl_constraint_get_coefficient( - __isl_keep isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_int *v); __isl_give isl_val *isl_constraint_get_coefficient_val( __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos); - int isl_constraint_involves_dims( - __isl_keep isl_constraint *constraint, - enum isl_dim_type type, unsigned first, unsigned n); The explicit representations of the existentially quantified variables can be inspected using the following function. @@ -1841,7 +2244,7 @@ The existentially quantified variable is equal to the floor of the returned affine expression. The affine expression itself can be inspected using the functions in -L<"Piecewise Quasi Affine Expressions">. +L. __isl_give isl_aff *isl_constraint_get_div( __isl_keep isl_constraint *constraint, int pos); @@ -1869,3387 +2272,4992 @@ enum isl_dim_type c4, enum isl_dim_type c5); The C arguments dictate the order in which -different kinds of variables appear in the resulting matrix -and should be a permutation of C, C, +different kinds of variables appear in the resulting matrix. +For set inputs, they should be a permutation of +C, C, C and C. +For map inputs, they should be a permutation of +C, C, C, C and C. -The number of parameters, input, output or set dimensions can -be obtained using the following functions. - - unsigned isl_basic_set_dim(__isl_keep isl_basic_set *bset, - enum isl_dim_type type); - unsigned isl_basic_map_dim(__isl_keep isl_basic_map *bmap, - enum isl_dim_type type); - unsigned isl_set_dim(__isl_keep isl_set *set, - enum isl_dim_type type); - unsigned isl_map_dim(__isl_keep isl_map *map, - enum isl_dim_type type); +=head2 Points -To check whether the description of a set or relation depends -on one or more given dimensions, it is not necessary to iterate over all -constraints. Instead the following functions can be used. +Points are elements of a set. They can be used to construct +simple sets (boxes) or they can be used to represent the +individual elements of a set. +The zero point (the origin) can be created using - int isl_basic_set_involves_dims( - __isl_keep isl_basic_set *bset, - enum isl_dim_type type, unsigned first, unsigned n); - int isl_set_involves_dims(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned first, unsigned n); - int isl_basic_map_involves_dims( - __isl_keep isl_basic_map *bmap, - enum isl_dim_type type, unsigned first, unsigned n); - int isl_map_involves_dims(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_point *isl_point_zero(__isl_take isl_space *space); -Similarly, the following functions can be used to check whether -a given dimension is involved in any lower or upper bound. +The coordinates of a point can be inspected, set and changed +using - int isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); - int isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); + __isl_give isl_val *isl_point_get_coordinate_val( + __isl_keep isl_point *pnt, + enum isl_dim_type type, int pos); + __isl_give isl_point *isl_point_set_coordinate_val( + __isl_take isl_point *pnt, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); -Note that these functions return true even if there is a bound on -the dimension on only some of the basic sets of C. -To check if they have a bound for all of the basic sets in C, -use the following functions instead. + __isl_give isl_point *isl_point_add_ui( + __isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val); + __isl_give isl_point *isl_point_sub_ui( + __isl_take isl_point *pnt, + enum isl_dim_type type, int pos, unsigned val); - int isl_set_dim_has_lower_bound(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); - int isl_set_dim_has_upper_bound(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); +Points can be copied or freed using -The identifiers or names of the domain and range spaces of a set -or relation can be read off or set using the following functions. + __isl_give isl_point *isl_point_copy( + __isl_keep isl_point *pnt); + void isl_point_free(__isl_take isl_point *pnt); - __isl_give isl_set *isl_set_set_tuple_id( - __isl_take isl_set *set, __isl_take isl_id *id); - __isl_give isl_set *isl_set_reset_tuple_id( - __isl_take isl_set *set); - int isl_set_has_tuple_id(__isl_keep isl_set *set); - __isl_give isl_id *isl_set_get_tuple_id( - __isl_keep isl_set *set); - __isl_give isl_map *isl_map_set_tuple_id( - __isl_take isl_map *map, enum isl_dim_type type, - __isl_take isl_id *id); - __isl_give isl_map *isl_map_reset_tuple_id( - __isl_take isl_map *map, enum isl_dim_type type); - int isl_map_has_tuple_id(__isl_keep isl_map *map, - enum isl_dim_type type); - __isl_give isl_id *isl_map_get_tuple_id( - __isl_keep isl_map *map, enum isl_dim_type type); +A singleton set can be created from a point using - const char *isl_basic_set_get_tuple_name( - __isl_keep isl_basic_set *bset); - __isl_give isl_basic_set *isl_basic_set_set_tuple_name( - __isl_take isl_basic_set *set, const char *s); - int isl_set_has_tuple_name(__isl_keep isl_set *set); - const char *isl_set_get_tuple_name( - __isl_keep isl_set *set); - const char *isl_basic_map_get_tuple_name( - __isl_keep isl_basic_map *bmap, - enum isl_dim_type type); - __isl_give isl_basic_map *isl_basic_map_set_tuple_name( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, const char *s); - int isl_map_has_tuple_name(__isl_keep isl_map *map, - enum isl_dim_type type); - const char *isl_map_get_tuple_name( - __isl_keep isl_map *map, - enum isl_dim_type type); + __isl_give isl_basic_set *isl_basic_set_from_point( + __isl_take isl_point *pnt); + __isl_give isl_set *isl_set_from_point( + __isl_take isl_point *pnt); -As with C, the value returned points to -an internal data structure. -The identifiers, positions or names of individual dimensions can be -read off using the following functions. +and a box can be created from two opposite extremal points using - __isl_give isl_id *isl_basic_set_get_dim_id( - __isl_keep isl_basic_set *bset, - enum isl_dim_type type, unsigned pos); - __isl_give isl_set *isl_set_set_dim_id( - __isl_take isl_set *set, enum isl_dim_type type, - unsigned pos, __isl_take isl_id *id); - int isl_set_has_dim_id(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); - __isl_give isl_id *isl_set_get_dim_id( - __isl_keep isl_set *set, enum isl_dim_type type, - unsigned pos); - int isl_basic_map_has_dim_id( - __isl_keep isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos); - __isl_give isl_map *isl_map_set_dim_id( - __isl_take isl_map *map, enum isl_dim_type type, - unsigned pos, __isl_take isl_id *id); - int isl_map_has_dim_id(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos); - __isl_give isl_id *isl_map_get_dim_id( - __isl_keep isl_map *map, enum isl_dim_type type, - unsigned pos); + __isl_give isl_basic_set *isl_basic_set_box_from_points( + __isl_take isl_point *pnt1, + __isl_take isl_point *pnt2); + __isl_give isl_set *isl_set_box_from_points( + __isl_take isl_point *pnt1, + __isl_take isl_point *pnt2); - int isl_set_find_dim_by_id(__isl_keep isl_set *set, - enum isl_dim_type type, __isl_keep isl_id *id); - int isl_map_find_dim_by_id(__isl_keep isl_map *map, - enum isl_dim_type type, __isl_keep isl_id *id); - int isl_set_find_dim_by_name(__isl_keep isl_set *set, - enum isl_dim_type type, const char *name); - int isl_map_find_dim_by_name(__isl_keep isl_map *map, - enum isl_dim_type type, const char *name); +All elements of a B (union) set can be enumerated using +the following functions. - const char *isl_constraint_get_dim_name( - __isl_keep isl_constraint *constraint, - enum isl_dim_type type, unsigned pos); - const char *isl_basic_set_get_dim_name( - __isl_keep isl_basic_set *bset, - enum isl_dim_type type, unsigned pos); - int isl_set_has_dim_name(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); - const char *isl_set_get_dim_name( - __isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); - const char *isl_basic_map_get_dim_name( - __isl_keep isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos); - int isl_map_has_dim_name(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos); - const char *isl_map_get_dim_name( - __isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos); + isl_stat isl_set_foreach_point(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_point *pnt, + void *user), + void *user); + isl_stat isl_union_set_foreach_point( + __isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_point *pnt, + void *user), + void *user); -These functions are mostly useful to obtain the identifiers, positions -or names of the parameters. Identifiers of individual dimensions are -essentially only useful for printing. They are ignored by all other -operations and may not be preserved across those operations. +The function C is called for each integer point in +C with as second argument the last argument of +the C call. The function C +should return C<0> on success and C<-1> on failure. +In the latter case, C will stop +enumerating and return C<-1> as well. +If the enumeration is performed successfully and to completion, +then C returns C<0>. -=head2 Properties +To obtain a single point of a (basic) set, use -=head3 Unary Properties + __isl_give isl_point *isl_basic_set_sample_point( + __isl_take isl_basic_set *bset); + __isl_give isl_point *isl_set_sample_point( + __isl_take isl_set *set); -=over +If C does not contain any (integer) points, then the +resulting point will be ``void'', a property that can be +tested using -=item * Emptiness + isl_bool isl_point_is_void(__isl_keep isl_point *pnt); -The following functions test whether the given set or relation -contains any integer points. The ``plain'' variants do not perform -any computations, but simply check if the given set or relation -is already known to be empty. +=head2 Functions - int isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset); - int isl_basic_set_is_empty(__isl_keep isl_basic_set *bset); - int isl_set_plain_is_empty(__isl_keep isl_set *set); - int isl_set_is_empty(__isl_keep isl_set *set); - int isl_union_set_is_empty(__isl_keep isl_union_set *uset); - int isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap); - int isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap); - int isl_map_plain_is_empty(__isl_keep isl_map *map); - int isl_map_is_empty(__isl_keep isl_map *map); - int isl_union_map_is_empty(__isl_keep isl_union_map *umap); +Besides sets and relation, C also supports various types of functions. +Each of these types is derived from the value type (see L) +or from one of two primitive function types +through the application of zero or more type constructors. +We first describe the primitive type and then we describe +the types derived from these primitive types. + +=head3 Primitive Functions + +C support two primitive function types, quasi-affine +expressions and quasipolynomials. +A quasi-affine expression is defined either over a parameter +space or over a set and is composed of integer constants, +parameters and set variables, addition, subtraction and +integer division by an integer constant. +For example, the quasi-affine expression + + [n] -> { [x] -> [2*floor((4 n + x)/9] } + +maps C to C<2*floor((4 n + x)/9>. +A quasipolynomial is a polynomial expression in quasi-affine +expression. That is, it additionally allows for multiplication. +Note, though, that it is not allowed to construct an integer +division of an expression involving multiplications. +Here is an example of a quasipolynomial that is not +quasi-affine expression + + [n] -> { [x] -> (n*floor((4 n + x)/9) } + +Note that the external representations of quasi-affine expressions +and quasipolynomials are different. Quasi-affine expressions +use a notation with square brackets just like binary relations, +while quasipolynomials do not. This might change at some point. + +If a primitive function is defined over a parameter space, +then the space of the function itself is that of a set. +If it is defined over a set, then the space of the function +is that of a relation. In both cases, the set space (or +the output space) is single-dimensional, anonymous and unstructured. +To create functions with multiple dimensions or with other kinds +of set or output spaces, use multiple expressions +(see L). -=item * Universality +=over - int isl_basic_set_is_universe(__isl_keep isl_basic_set *bset); - int isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap); - int isl_set_plain_is_universe(__isl_keep isl_set *set); +=item * Quasi-affine Expressions -=item * Single-valuedness +Besides the expressions described above, a quasi-affine +expression can also be set to NaN. Such expressions +typically represent a failure to represent a result +as a quasi-affine expression. - int isl_basic_map_is_single_valued( - __isl_keep isl_basic_map *bmap); - int isl_map_plain_is_single_valued( - __isl_keep isl_map *map); - int isl_map_is_single_valued(__isl_keep isl_map *map); - int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap); +The zero quasi affine expression or the quasi affine expression +that is equal to a given value or +a specified dimension on a given domain can be created using -=item * Injectivity - - int isl_map_plain_is_injective(__isl_keep isl_map *map); - int isl_map_is_injective(__isl_keep isl_map *map); - int isl_union_map_plain_is_injective( - __isl_keep isl_union_map *umap); - int isl_union_map_is_injective( - __isl_keep isl_union_map *umap); + #include + __isl_give isl_aff *isl_aff_zero_on_domain( + __isl_take isl_local_space *ls); + __isl_give isl_aff *isl_aff_val_on_domain( + __isl_take isl_local_space *ls, + __isl_take isl_val *val); + __isl_give isl_aff *isl_aff_var_on_domain( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos); + __isl_give isl_aff *isl_aff_nan_on_domain( + __isl_take isl_local_space *ls); -=item * Bijectivity +Quasi affine expressions can be copied and freed using - int isl_map_is_bijective(__isl_keep isl_map *map); - int isl_union_map_is_bijective(__isl_keep isl_union_map *umap); + #include + __isl_give isl_aff *isl_aff_copy( + __isl_keep isl_aff *aff); + __isl_null isl_aff *isl_aff_free( + __isl_take isl_aff *aff); -=item * Position +A (rational) bound on a dimension can be extracted from an C +using the following function. The constraint is required to have +a non-zero coefficient for the specified dimension. - int isl_basic_map_plain_is_fixed( - __isl_keep isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, - isl_int *val); - int isl_set_plain_is_fixed(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos, - isl_int *val); - int isl_map_plain_is_fixed(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos, - isl_int *val); + #include + __isl_give isl_aff *isl_constraint_get_bound( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, int pos); -Check if the relation obviously lies on a hyperplane where the given dimension -has a fixed value and if so, return that value in C<*val>. +The entire affine expression of the constraint can also be extracted +using the following function. - __isl_give isl_val * - isl_basic_map_plain_get_val_if_fixed( - __isl_keep isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos); - __isl_give isl_val *isl_set_plain_get_val_if_fixed( - __isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos); - __isl_give isl_val *isl_map_plain_get_val_if_fixed( - __isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos); + #include + __isl_give isl_aff *isl_constraint_get_aff( + __isl_keep isl_constraint *constraint); -If the set or relation obviously lies on a hyperplane where the given dimension -has a fixed value, then return that value. -Otherwise return NaN. +Conversely, an equality constraint equating +the affine expression to zero or an inequality constraint enforcing +the affine expression to be non-negative, can be constructed using -=item * Stride + __isl_give isl_constraint *isl_equality_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_constraint *isl_inequality_from_aff( + __isl_take isl_aff *aff); - int isl_set_dim_residue_class_val( - __isl_keep isl_set *set, - int pos, __isl_give isl_val **modulo, - __isl_give isl_val **residue); +The coefficients and the integer divisions of an affine expression +can be inspected using the following functions. -Check if the values of the given set dimension are equal to a fixed -value modulo some integer value. If so, assign the modulo to C<*modulo> -and the fixed value to C<*residue>. If the given dimension attains only -a single value, then assign C<0> to C<*modulo> and the fixed value to -C<*residue>. -If the dimension does not attain only a single value and if no modulo -can be found then assign C<1> to C<*modulo> and C<1> to C<*residue>. + #include + __isl_give isl_val *isl_aff_get_constant_val( + __isl_keep isl_aff *aff); + __isl_give isl_val *isl_aff_get_coefficient_val( + __isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); + int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); + __isl_give isl_val *isl_aff_get_denominator_val( + __isl_keep isl_aff *aff); + __isl_give isl_aff *isl_aff_get_div( + __isl_keep isl_aff *aff, int pos); -=item * Space +They can be modified using the following functions. -To check whether a set is a parameter domain, use this function: + #include + __isl_give isl_aff *isl_aff_set_constant_si( + __isl_take isl_aff *aff, int v); + __isl_give isl_aff *isl_aff_set_constant_val( + __isl_take isl_aff *aff, __isl_take isl_val *v); + __isl_give isl_aff *isl_aff_set_coefficient_si( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v); + __isl_give isl_aff *isl_aff_set_coefficient_val( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); - int isl_set_is_params(__isl_keep isl_set *set); - int isl_union_set_is_params( - __isl_keep isl_union_set *uset); + __isl_give isl_aff *isl_aff_add_constant_si( + __isl_take isl_aff *aff, int v); + __isl_give isl_aff *isl_aff_add_constant_val( + __isl_take isl_aff *aff, __isl_take isl_val *v); + __isl_give isl_aff *isl_aff_add_constant_num_si( + __isl_take isl_aff *aff, int v); + __isl_give isl_aff *isl_aff_add_coefficient_si( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, int v); + __isl_give isl_aff *isl_aff_add_coefficient_val( + __isl_take isl_aff *aff, + enum isl_dim_type type, int pos, + __isl_take isl_val *v); -=item * Wrapping +Note that C and C +set the I of the constant or coefficient, while +C and C set +the constant or coefficient as a whole. +The C and C functions add an integer +or rational value to +the possibly rational constant or coefficient. +The C functions add an integer value to +the numerator. -The following functions check whether the domain of the given -(basic) set is a wrapped relation. +=item * Quasipolynomials - int isl_basic_set_is_wrapping( - __isl_keep isl_basic_set *bset); - int isl_set_is_wrapping(__isl_keep isl_set *set); +Some simple quasipolynomials can be created using the following functions. -=item * Internal Product + #include + __isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain( + __isl_take isl_space *domain); + __isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( + __isl_take isl_space *domain, + __isl_take isl_val *val); + __isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain( + __isl_take isl_space *domain, + enum isl_dim_type type, unsigned pos); + __isl_give isl_qpolynomial *isl_qpolynomial_from_aff( + __isl_take isl_aff *aff); - int isl_basic_map_can_zip( - __isl_keep isl_basic_map *bmap); - int isl_map_can_zip(__isl_keep isl_map *map); +Recall that the space in which a quasipolynomial lives is a map space +with a one-dimensional range. The C argument in some of +the functions above corresponds to the domain of this map space. -Check whether the product of domain and range of the given relation -can be computed, -i.e., whether both domain and range are nested relations. +Quasipolynomials can be copied and freed again using the following +functions. -=item * Currying + #include + __isl_give isl_qpolynomial *isl_qpolynomial_copy( + __isl_keep isl_qpolynomial *qp); + __isl_null isl_qpolynomial *isl_qpolynomial_free( + __isl_take isl_qpolynomial *qp); - int isl_basic_map_can_curry( - __isl_keep isl_basic_map *bmap); - int isl_map_can_curry(__isl_keep isl_map *map); +The constant term of a quasipolynomial can be extracted using -Check whether the domain of the (basic) relation is a wrapped relation. + __isl_give isl_val *isl_qpolynomial_get_constant_val( + __isl_keep isl_qpolynomial *qp); - int isl_basic_map_can_uncurry( - __isl_keep isl_basic_map *bmap); - int isl_map_can_uncurry(__isl_keep isl_map *map); +To iterate over all terms in a quasipolynomial, +use -Check whether the range of the (basic) relation is a wrapped relation. + isl_stat isl_qpolynomial_foreach_term( + __isl_keep isl_qpolynomial *qp, + isl_stat (*fn)(__isl_take isl_term *term, + void *user), void *user); -=back +The terms themselves can be inspected and freed using +these functions -=head3 Binary Properties + unsigned isl_term_dim(__isl_keep isl_term *term, + enum isl_dim_type type); + __isl_give isl_val *isl_term_get_coefficient_val( + __isl_keep isl_term *term); + int isl_term_get_exp(__isl_keep isl_term *term, + enum isl_dim_type type, unsigned pos); + __isl_give isl_aff *isl_term_get_div( + __isl_keep isl_term *term, unsigned pos); + void isl_term_free(__isl_take isl_term *term); -=over +Each term is a product of parameters, set variables and +integer divisions. The function C +returns the exponent of a given dimensions in the given term. -=item * Equality +=back - int isl_set_plain_is_equal(__isl_keep isl_set *set1, - __isl_keep isl_set *set2); - int isl_set_is_equal(__isl_keep isl_set *set1, - __isl_keep isl_set *set2); - int isl_union_set_is_equal( - __isl_keep isl_union_set *uset1, - __isl_keep isl_union_set *uset2); - int isl_basic_map_is_equal( - __isl_keep isl_basic_map *bmap1, - __isl_keep isl_basic_map *bmap2); - int isl_map_is_equal(__isl_keep isl_map *map1, - __isl_keep isl_map *map2); - int isl_map_plain_is_equal(__isl_keep isl_map *map1, - __isl_keep isl_map *map2); - int isl_union_map_is_equal( - __isl_keep isl_union_map *umap1, - __isl_keep isl_union_map *umap2); +=head3 Reductions -=item * Disjointness +A reduction represents a maximum or a minimum of its +base expressions. +The only reduction type defined by C is +C. + +There are currently no functions to directly create such +objects, but they do appear in the piecewise quasipolynomial +reductions returned by the C function. +See +L. - int isl_set_plain_is_disjoint(__isl_keep isl_set *set1, - __isl_keep isl_set *set2); - int isl_set_is_disjoint(__isl_keep isl_set *set1, - __isl_keep isl_set *set2); - int isl_map_is_disjoint(__isl_keep isl_map *map1, - __isl_keep isl_map *map2); +Reductions can be copied and freed using +the following functions. -=item * Subset + #include + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_copy( + __isl_keep isl_qpolynomial_fold *fold); + void isl_qpolynomial_fold_free( + __isl_take isl_qpolynomial_fold *fold); - int isl_basic_set_is_subset( - __isl_keep isl_basic_set *bset1, - __isl_keep isl_basic_set *bset2); - int isl_set_is_subset(__isl_keep isl_set *set1, - __isl_keep isl_set *set2); - int isl_set_is_strict_subset( - __isl_keep isl_set *set1, - __isl_keep isl_set *set2); - int isl_union_set_is_subset( - __isl_keep isl_union_set *uset1, - __isl_keep isl_union_set *uset2); - int isl_union_set_is_strict_subset( - __isl_keep isl_union_set *uset1, - __isl_keep isl_union_set *uset2); - int isl_basic_map_is_subset( - __isl_keep isl_basic_map *bmap1, - __isl_keep isl_basic_map *bmap2); - int isl_basic_map_is_strict_subset( - __isl_keep isl_basic_map *bmap1, - __isl_keep isl_basic_map *bmap2); - int isl_map_is_subset( - __isl_keep isl_map *map1, - __isl_keep isl_map *map2); - int isl_map_is_strict_subset( - __isl_keep isl_map *map1, - __isl_keep isl_map *map2); - int isl_union_map_is_subset( - __isl_keep isl_union_map *umap1, - __isl_keep isl_union_map *umap2); - int isl_union_map_is_strict_subset( - __isl_keep isl_union_map *umap1, - __isl_keep isl_union_map *umap2); +To iterate over all quasipolynomials in a reduction, use -Check whether the first argument is a (strict) subset of the -second argument. + isl_stat isl_qpolynomial_fold_foreach_qpolynomial( + __isl_keep isl_qpolynomial_fold *fold, + isl_stat (*fn)(__isl_take isl_qpolynomial *qp, + void *user), void *user); -=item * Order +=head3 Multiple Expressions - int isl_set_plain_cmp(__isl_keep isl_set *set1, - __isl_keep isl_set *set2); +A multiple expression represents a sequence of zero or +more base expressions, all defined on the same domain space. +The domain space of the multiple expression is the same +as that of the base expressions, but the range space +can be any space. In case the base expressions have +a set space, the corresponding multiple expression +also has a set space. +Objects of the value type do not have an associated space. +The space of a multiple value is therefore always a set space. +Similarly, the space of a multiple union piecewise +affine expression is always a set space. + +The multiple expression types defined by C +are C, C, C, +C. -This function is useful for sorting Cs. -The order depends on the internal representation of the inputs. -The order is fixed over different calls to the function (assuming -the internal representation of the inputs has not changed), but may -change over different versions of C. +A multiple expression with the value zero for +each output (or set) dimension can be created +using the following functions. -=back + #include + __isl_give isl_multi_val *isl_multi_val_zero( + __isl_take isl_space *space); -=head2 Unary Operations + #include + __isl_give isl_multi_aff *isl_multi_aff_zero( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_zero( + __isl_take isl_space *space); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_zero( + __isl_take isl_space *space); -=over +Since there is no canonical way of representing a zero +value of type C, the space passed +to C needs to be zero-dimensional. + +An identity function can be created using the following +functions. The space needs to be that of a relation +with the same number of input and output dimensions. -=item * Complement + #include + __isl_give isl_multi_aff *isl_multi_aff_identity( + __isl_take isl_space *space); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity( + __isl_take isl_space *space); - __isl_give isl_set *isl_set_complement( - __isl_take isl_set *set); - __isl_give isl_map *isl_map_complement( - __isl_take isl_map *map); +A function that performs a projection on a universe +relation or set can be created using the following functions. +See also the corresponding +projection operations in L. -=item * Inverse map + #include + __isl_give isl_multi_aff *isl_multi_aff_domain_map( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_multi_aff_range_map( + __isl_take isl_space *space); + __isl_give isl_multi_aff *isl_multi_aff_project_out_map( + __isl_take isl_space *space, + enum isl_dim_type type, + unsigned first, unsigned n); - __isl_give isl_basic_map *isl_basic_map_reverse( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_reverse( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_reverse( - __isl_take isl_union_map *umap); +A multiple expression can be created from a single +base expression using the following functions. +The space of the created multiple expression is the same +as that of the base expression, except for +C where the input +lives in a parameter space and the output lives +in a single-dimensional set space. -=item * Projection + #include + __isl_give isl_multi_aff *isl_multi_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + +A multiple expression can be created from a list +of base expression in a specified space. +The domain of this space needs to be the same +as the domains of the base expressions in the list. +If the base expressions have a set space (or no associated space), +then this space also needs to be a set space. - __isl_give isl_basic_set *isl_basic_set_project_out( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_basic_map *isl_basic_map_project_out( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_basic_set *isl_basic_set_params( - __isl_take isl_basic_set *bset); - __isl_give isl_basic_set *isl_basic_map_domain( - __isl_take isl_basic_map *bmap); - __isl_give isl_basic_set *isl_basic_map_range( - __isl_take isl_basic_map *bmap); - __isl_give isl_set *isl_set_params(__isl_take isl_set *set); - __isl_give isl_set *isl_map_params(__isl_take isl_map *map); - __isl_give isl_set *isl_map_domain( - __isl_take isl_map *bmap); - __isl_give isl_set *isl_map_range( - __isl_take isl_map *map); - __isl_give isl_set *isl_union_set_params( - __isl_take isl_union_set *uset); - __isl_give isl_set *isl_union_map_params( - __isl_take isl_union_map *umap); - __isl_give isl_union_set *isl_union_map_domain( - __isl_take isl_union_map *umap); - __isl_give isl_union_set *isl_union_map_range( - __isl_take isl_union_map *umap); + #include + __isl_give isl_multi_val *isl_multi_val_from_val_list( + __isl_take isl_space *space, + __isl_take isl_val_list *list); - __isl_give isl_basic_map *isl_basic_map_domain_map( - __isl_take isl_basic_map *bmap); - __isl_give isl_basic_map *isl_basic_map_range_map( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map); - __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_domain_map( - __isl_take isl_union_map *umap); - __isl_give isl_union_map *isl_union_map_range_map( - __isl_take isl_union_map *umap); + #include + __isl_give isl_multi_aff *isl_multi_aff_from_aff_list( + __isl_take isl_space *space, + __isl_take isl_aff_list *list); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_pw_aff_list( + __isl_take isl_space *space, + __isl_take isl_union_pw_aff_list *list); -The functions above construct a (basic, regular or union) relation -that maps (a wrapped version of) the input relation to its domain or range. +As a convenience, a multiple piecewise expression can +also be created from a multiple expression. +Each piecewise expression in the result has a single +universe cell. -=item * Elimination + #include + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); - __isl_give isl_basic_set *isl_basic_set_eliminate( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_set *isl_set_eliminate( - __isl_take isl_set *set, enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_basic_map *isl_basic_map_eliminate( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_map *isl_map_eliminate( - __isl_take isl_map *map, enum isl_dim_type type, - unsigned first, unsigned n); +Similarly, a multiple union expression can be +created from a multiple expression. -Eliminate the coefficients for the given dimensions from the constraints, -without removing the dimensions. + #include + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); -=item * Slicing +A multiple quasi-affine expression can be created from +a multiple value with a given domain space using the following +function. - __isl_give isl_basic_set *isl_basic_set_fix( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned pos, - isl_int value); - __isl_give isl_basic_set *isl_basic_set_fix_si( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_basic_set *isl_basic_set_fix_val( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned pos, - __isl_take isl_val *v); - __isl_give isl_set *isl_set_fix(__isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, - isl_int value); - __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_set *isl_set_fix_val( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, - __isl_take isl_val *v); - __isl_give isl_basic_map *isl_basic_map_fix_si( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_basic_map *isl_basic_map_fix_val( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, - __isl_take isl_val *v); - __isl_give isl_map *isl_map_fix(__isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, - isl_int value); - __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_map *isl_map_fix_val( - __isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, - __isl_take isl_val *v); + #include + __isl_give isl_multi_aff * + isl_multi_aff_multi_val_on_space( + __isl_take isl_space *space, + __isl_take isl_multi_val *mv); -Intersect the set or relation with the hyperplane where the given -dimension has the fixed given value. +Similarly, +a multiple union piecewise affine expression can be created from +a multiple value with a given domain or +a multiple affine expression with a given domain +using the following functions. - __isl_give isl_basic_map *isl_basic_map_lower_bound_si( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_basic_map *isl_basic_map_upper_bound_si( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_set *isl_set_lower_bound( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, - isl_int value); - __isl_give isl_set *isl_set_lower_bound_si( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_set *isl_set_lower_bound_val( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, - __isl_take isl_val *value); - __isl_give isl_map *isl_map_lower_bound_si( - __isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_set *isl_set_upper_bound( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, - isl_int value); - __isl_give isl_set *isl_set_upper_bound_si( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, int value); - __isl_give isl_set *isl_set_upper_bound_val( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, - __isl_take isl_val *value); - __isl_give isl_map *isl_map_upper_bound_si( - __isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, int value); + #include + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_multi_val_on_domain( + __isl_take isl_union_set *domain, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_multi_aff_on_domain( + __isl_take isl_union_set *domain, + __isl_take isl_multi_aff *ma); -Intersect the set or relation with the half-space where the given -dimension has a value bounded by the fixed given integer value. +Multiple expressions can be copied and freed using +the following functions. - __isl_give isl_set *isl_set_equate(__isl_take isl_set *set, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); - __isl_give isl_basic_map *isl_basic_map_equate( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); - __isl_give isl_map *isl_map_equate(__isl_take isl_map *map, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); + #include + __isl_give isl_multi_val *isl_multi_val_copy( + __isl_keep isl_multi_val *mv); + __isl_null isl_multi_val *isl_multi_val_free( + __isl_take isl_multi_val *mv); -Intersect the set or relation with the hyperplane where the given -dimensions are equal to each other. + #include + __isl_give isl_multi_aff *isl_multi_aff_copy( + __isl_keep isl_multi_aff *maff); + __isl_null isl_multi_aff *isl_multi_aff_free( + __isl_take isl_multi_aff *maff); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_copy( + __isl_keep isl_multi_pw_aff *mpa); + __isl_null isl_multi_pw_aff *isl_multi_pw_aff_free( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_copy( + __isl_keep isl_multi_union_pw_aff *mupa); + __isl_null isl_multi_union_pw_aff * + isl_multi_union_pw_aff_free( + __isl_take isl_multi_union_pw_aff *mupa); - __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); +The base expression at a given position of a multiple +expression can be extracted using the following functions. -Intersect the relation with the hyperplane where the given -dimensions have opposite values. + #include + __isl_give isl_val *isl_multi_val_get_val( + __isl_keep isl_multi_val *mv, int pos); - __isl_give isl_basic_map *isl_basic_map_order_ge( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); - __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); - __isl_give isl_basic_map *isl_basic_map_order_gt( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); - __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map, - enum isl_dim_type type1, int pos1, - enum isl_dim_type type2, int pos2); + #include + __isl_give isl_aff *isl_multi_aff_get_aff( + __isl_keep isl_multi_aff *multi, int pos); + __isl_give isl_pw_aff *isl_multi_pw_aff_get_pw_aff( + __isl_keep isl_multi_pw_aff *mpa, int pos); + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_get_union_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, int pos); -Intersect the relation with the half-space where the given -dimensions satisfy the given ordering. +It can be replaced using the following functions. -=item * Identity + #include + __isl_give isl_multi_val *isl_multi_val_set_val( + __isl_take isl_multi_val *mv, int pos, + __isl_take isl_val *val); - __isl_give isl_map *isl_set_identity( - __isl_take isl_set *set); - __isl_give isl_union_map *isl_union_set_identity( - __isl_take isl_union_set *uset); + #include + __isl_give isl_multi_aff *isl_multi_aff_set_aff( + __isl_take isl_multi_aff *multi, int pos, + __isl_take isl_aff *aff); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_set_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, int pos, + __isl_take isl_union_pw_aff *upa); + +As a convenience, a sequence of base expressions that have +their domains in a given space can be extracted from a sequence +of union expressions using the following function. -Construct an identity relation on the given (union) set. + #include + __isl_give isl_multi_pw_aff * + isl_multi_union_pw_aff_extract_multi_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, + __isl_take isl_space *space); -=item * Deltas +Note that there is a difference between C +and C objects. The first is a sequence +of unions of piecewise expressions, while the second is a union +of piecewise sequences. In particular, multiple affine expressions +in an C may live in different spaces, +while there is only a single multiple expression in +an C, which can therefore only live +in a single space. This means that not every +C can be converted to +an C. Conversely, a zero-dimensional +C carries no information +about any possible domain and therefore cannot be converted +to an C. Moreover, the elements +of an C may be defined over different domains, +while each multiple expression inside an C +has a single domain. The conversion of an C +of dimension greater than one may therefore not be exact. +The following functions can +be used to perform these conversions when they are possible. - __isl_give isl_basic_set *isl_basic_map_deltas( - __isl_take isl_basic_map *bmap); - __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map); - __isl_give isl_union_set *isl_union_map_deltas( - __isl_take isl_union_map *umap); + #include + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); -These functions return a (basic) set containing the differences -between image elements and corresponding domain elements in the input. +=head3 Piecewise Expressions - __isl_give isl_basic_map *isl_basic_map_deltas_map( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_deltas_map( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_deltas_map( - __isl_take isl_union_map *umap); +A piecewise expression is an expression that is described +using zero or more base expression defined over the same +number of cells in the domain space of the base expressions. +All base expressions are defined over the same +domain space and the cells are disjoint. +The space of a piecewise expression is the same as +that of the base expressions. +If the union of the cells is a strict subset of the domain +space, then the value of the piecewise expression outside +this union is different for types derived from quasi-affine +expressions and those derived from quasipolynomials. +Piecewise expressions derived from quasi-affine expressions +are considered to be undefined outside the union of their cells. +Piecewise expressions derived from quasipolynomials +are considered to be zero outside the union of their cells. -The functions above construct a (basic, regular or union) relation -that maps (a wrapped version of) the input relation to its delta set. +Piecewise quasipolynomials are mainly used by the C +library for representing the number of elements in a parametric set or map. +For example, the piecewise quasipolynomial -=item * Coalescing + [n] -> { [x] -> ((1 + n) - x) : x <= n and x >= 0 } -Simplify the representation of a set or relation by trying -to combine pairs of basic sets or relations into a single -basic set or relation. +represents the number of points in the map - __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); - __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map); - __isl_give isl_union_set *isl_union_set_coalesce( - __isl_take isl_union_set *uset); - __isl_give isl_union_map *isl_union_map_coalesce( - __isl_take isl_union_map *umap); + [n] -> { [x] -> [y] : x,y >= 0 and 0 <= x + y <= n } -One of the methods for combining pairs of basic sets or relations -can result in coefficients that are much larger than those that appear -in the constraints of the input. By default, the coefficients are -not allowed to grow larger, but this can be changed by unsetting -the following option. +The piecewise expression types defined by C +are C, C, +C and C. - int isl_options_set_coalesce_bounded_wrapping( - isl_ctx *ctx, int val); - int isl_options_get_coalesce_bounded_wrapping( - isl_ctx *ctx); +A piecewise expression with no cells can be created using +the following functions. -=item * Detecting equalities + #include + __isl_give isl_pw_aff *isl_pw_aff_empty( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty( + __isl_take isl_space *space); - __isl_give isl_basic_set *isl_basic_set_detect_equalities( - __isl_take isl_basic_set *bset); - __isl_give isl_basic_map *isl_basic_map_detect_equalities( - __isl_take isl_basic_map *bmap); - __isl_give isl_set *isl_set_detect_equalities( - __isl_take isl_set *set); - __isl_give isl_map *isl_map_detect_equalities( - __isl_take isl_map *map); - __isl_give isl_union_set *isl_union_set_detect_equalities( - __isl_take isl_union_set *uset); - __isl_give isl_union_map *isl_union_map_detect_equalities( - __isl_take isl_union_map *umap); +A piecewise expression with a single universe cell can be +created using the following functions. -Simplify the representation of a set or relation by detecting implicit -equalities. + #include + __isl_give isl_pw_aff *isl_pw_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); -=item * Removing redundant constraints + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_from_qpolynomial( + __isl_take isl_qpolynomial *qp); - __isl_give isl_basic_set *isl_basic_set_remove_redundancies( - __isl_take isl_basic_set *bset); - __isl_give isl_set *isl_set_remove_redundancies( - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_basic_map_remove_redundancies( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_remove_redundancies( - __isl_take isl_map *map); +A piecewise expression with a single specified cell can be +created using the following functions. -=item * Convex hull + #include + __isl_give isl_pw_aff *isl_pw_aff_alloc( + __isl_take isl_set *set, __isl_take isl_aff *aff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc( + __isl_take isl_set *set, + __isl_take isl_multi_aff *maff); - __isl_give isl_basic_set *isl_set_convex_hull( - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_map_convex_hull( - __isl_take isl_map *map); + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_alloc( + __isl_take isl_set *set, + __isl_take isl_qpolynomial *qp); -If the input set or relation has any existentially quantified -variables, then the result of these operations is currently undefined. +The following convenience functions first create a base expression and +then create a piecewise expression over a universe domain. -=item * Simple hull + #include + __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain( + __isl_take isl_local_space *ls); + __isl_give isl_pw_aff *isl_pw_aff_var_on_domain( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos); + __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain( + __isl_take isl_local_space *ls); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_project_out_map( + __isl_take isl_space *space, + enum isl_dim_type type, + unsigned first, unsigned n); - __isl_give isl_basic_set * - isl_set_unshifted_simple_hull( - __isl_take isl_set *set); - __isl_give isl_basic_map * - isl_map_unshifted_simple_hull( - __isl_take isl_map *map); - __isl_give isl_basic_set *isl_set_simple_hull( - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_map_simple_hull( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_simple_hull( - __isl_take isl_union_map *umap); + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero( + __isl_take isl_space *space); -These functions compute a single basic set or relation -that contains the whole input set or relation. -In particular, the output is described by translates -of the constraints describing the basic sets or relations in the input. -In case of C, only the original -constraints are used, without any translation. +The following convenience functions first create a base expression and +then create a piecewise expression over a given domain. -=begin latex + #include + __isl_give isl_pw_aff *isl_pw_aff_val_on_domain( + __isl_take isl_set *domain, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_multi_val_on_domain( + __isl_take isl_set *domain, + __isl_take isl_multi_val *mv); -(See \autoref{s:simple hull}.) +As a convenience, a piecewise multiple expression can +also be created from a piecewise expression. +Each multiple expression in the result is derived +from the corresponding base expression. -=end latex + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); -=item * Affine hull +Similarly, a piecewise quasipolynomial can be +created from a piecewise quasi-affine expression using +the following function. - __isl_give isl_basic_set *isl_basic_set_affine_hull( - __isl_take isl_basic_set *bset); - __isl_give isl_basic_set *isl_set_affine_hull( - __isl_take isl_set *set); - __isl_give isl_union_set *isl_union_set_affine_hull( - __isl_take isl_union_set *uset); - __isl_give isl_basic_map *isl_basic_map_affine_hull( - __isl_take isl_basic_map *bmap); - __isl_give isl_basic_map *isl_map_affine_hull( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_affine_hull( - __isl_take isl_union_map *umap); + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_from_pw_aff( + __isl_take isl_pw_aff *pwaff); -In case of union sets and relations, the affine hull is computed -per space. +Piecewise expressions can be copied and freed using the following functions. -=item * Polyhedral hull + #include + __isl_give isl_pw_aff *isl_pw_aff_copy( + __isl_keep isl_pw_aff *pwaff); + __isl_null isl_pw_aff *isl_pw_aff_free( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( + __isl_keep isl_pw_multi_aff *pma); + __isl_null isl_pw_multi_aff *isl_pw_multi_aff_free( + __isl_take isl_pw_multi_aff *pma); - __isl_give isl_basic_set *isl_set_polyhedral_hull( - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_map_polyhedral_hull( - __isl_take isl_map *map); - __isl_give isl_union_set *isl_union_set_polyhedral_hull( - __isl_take isl_union_set *uset); - __isl_give isl_union_map *isl_union_map_polyhedral_hull( - __isl_take isl_union_map *umap); + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_copy( + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_null isl_pw_qpolynomial *isl_pw_qpolynomial_free( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_copy( + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_null isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_free( + __isl_take isl_pw_qpolynomial_fold *pwf); -These functions compute a single basic set or relation -not involving any existentially quantified variables -that contains the whole input set or relation. -In case of union sets and relations, the polyhedral hull is computed -per space. +To iterate over the different cells of a piecewise expression, +use the following functions. -=item * Other approximations + #include + isl_bool isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); + int isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); + isl_stat isl_pw_aff_foreach_piece( + __isl_keep isl_pw_aff *pwaff, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_aff *aff, + void *user), void *user); + isl_stat isl_pw_multi_aff_foreach_piece( + __isl_keep isl_pw_multi_aff *pma, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_multi_aff *maff, + void *user), void *user); - __isl_give isl_basic_set * - isl_basic_set_drop_constraints_involving_dims( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_basic_map * - isl_basic_map_drop_constraints_involving_dims( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_basic_set * - isl_basic_set_drop_constraints_not_involving_dims( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_set * - isl_set_drop_constraints_involving_dims( - __isl_take isl_set *set, - enum isl_dim_type type, - unsigned first, unsigned n); - __isl_give isl_map * - isl_map_drop_constraints_involving_dims( - __isl_take isl_map *map, - enum isl_dim_type type, - unsigned first, unsigned n); + #include + isl_stat isl_pw_qpolynomial_foreach_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, + void *user), void *user); + isl_stat isl_pw_qpolynomial_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial *qp, + void *user), void *user); + isl_stat isl_pw_qpolynomial_fold_foreach_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, + void *user), void *user); + isl_stat isl_pw_qpolynomial_fold_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, + void *user), void *user); -These functions drop any constraints (not) involving the specified dimensions. -Note that the result depends on the representation of the input. +As usual, the function C should return C<0> on success +and C<-1> on failure. The difference between +C and +C is that +C will first +compute unique representations for all existentially quantified +variables and then turn these existentially quantified variables +into extra set variables, adapting the associated quasipolynomial +accordingly. This means that the C passed to C +will not have any existentially quantified variables, but that +the dimensions of the sets may be different for different +invocations of C. +Similarly for C +and C. -=item * Feasibility +A piecewise expression consisting of the expressions at a given +position of a piecewise multiple expression can be extracted +using the following function. - __isl_give isl_basic_set *isl_basic_set_sample( - __isl_take isl_basic_set *bset); - __isl_give isl_basic_set *isl_set_sample( - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_basic_map_sample( - __isl_take isl_basic_map *bmap); - __isl_give isl_basic_map *isl_map_sample( - __isl_take isl_map *map); + #include + __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( + __isl_keep isl_pw_multi_aff *pma, int pos); -If the input (basic) set or relation is non-empty, then return -a singleton subset of the input. Otherwise, return an empty set. +These expressions can be replaced using the following function. -=item * Optimization + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( + __isl_take isl_pw_multi_aff *pma, unsigned pos, + __isl_take isl_pw_aff *pa); - #include - enum isl_lp_result isl_basic_set_max( - __isl_keep isl_basic_set *bset, - __isl_keep isl_aff *obj, isl_int *opt) - __isl_give isl_val *isl_basic_set_max_val( - __isl_keep isl_basic_set *bset, - __isl_keep isl_aff *obj); - enum isl_lp_result isl_set_min(__isl_keep isl_set *set, - __isl_keep isl_aff *obj, isl_int *opt); - __isl_give isl_val *isl_set_min_val( - __isl_keep isl_set *set, - __isl_keep isl_aff *obj); - enum isl_lp_result isl_set_max(__isl_keep isl_set *set, - __isl_keep isl_aff *obj, isl_int *opt); - __isl_give isl_val *isl_set_max_val( - __isl_keep isl_set *set, - __isl_keep isl_aff *obj); - -Compute the minimum or maximum of the integer affine expression C -over the points in C, returning the result in C. -The return value may be one of C, -C, C or C, in case of -an C. If the result is an C then -the result is C in case of an error, the optimal value in case -there is one, negative infinity or infinity if the problem is unbounded and -NaN if the problem is empty. +Note that there is a difference between C and +C objects. The first is a sequence of piecewise +affine expressions, while the second is a piecewise sequence +of affine expressions. In particular, each of the piecewise +affine expressions in an C may have a different +domain, while all multiple expressions associated to a cell +in an C have the same domain. +It is possible to convert between the two, but when converting +an C to an C, the domain +of the result is the intersection of the domains of the input. +The reverse conversion is exact. -=item * Parametric optimization + #include + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); - __isl_give isl_pw_aff *isl_set_dim_min( - __isl_take isl_set *set, int pos); - __isl_give isl_pw_aff *isl_set_dim_max( - __isl_take isl_set *set, int pos); - __isl_give isl_pw_aff *isl_map_dim_max( - __isl_take isl_map *map, int pos); +=head3 Union Expressions -Compute the minimum or maximum of the given set or output dimension -as a function of the parameters (and input dimensions), but independently -of the other set or output dimensions. -For lexicographic optimization, see L<"Lexicographic Optimization">. +A union expression collects base expressions defined +over different domains. The space of a union expression +is that of the shared parameter space. -=item * Dual +The union expression types defined by C +are C, C, +C and C. -The following functions compute either the set of (rational) coefficient -values of valid constraints for the given set or the set of (rational) -values satisfying the constraints with coefficients from the given set. -Internally, these two sets of functions perform essentially the -same operations, except that the set of coefficients is assumed to -be a cone, while the set of values may be any polyhedron. -The current implementation is based on the Farkas lemma and -Fourier-Motzkin elimination, but this may change or be made optional -in future. In particular, future implementations may use different -dualization algorithms or skip the elimination step. +An empty union expression can be created using the following functions. - __isl_give isl_basic_set *isl_basic_set_coefficients( - __isl_take isl_basic_set *bset); - __isl_give isl_basic_set *isl_set_coefficients( - __isl_take isl_set *set); - __isl_give isl_union_set *isl_union_set_coefficients( - __isl_take isl_union_set *bset); - __isl_give isl_basic_set *isl_basic_set_solutions( - __isl_take isl_basic_set *bset); - __isl_give isl_basic_set *isl_set_solutions( - __isl_take isl_set *set); - __isl_give isl_union_set *isl_union_set_solutions( - __isl_take isl_union_set *bset); + #include + __isl_give isl_union_pw_aff *isl_union_pw_aff_empty( + __isl_take isl_space *space); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_empty( + __isl_take isl_space *space); -=item * Power + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_zero( + __isl_take isl_space *space); - __isl_give isl_map *isl_map_fixed_power( - __isl_take isl_map *map, isl_int exp); - __isl_give isl_map *isl_map_fixed_power_val( - __isl_take isl_map *map, - __isl_take isl_val *exp); - __isl_give isl_union_map *isl_union_map_fixed_power( - __isl_take isl_union_map *umap, isl_int exp); - __isl_give isl_union_map * - isl_union_map_fixed_power_val( - __isl_take isl_union_map *umap, - __isl_take isl_val *exp); +A union expression containing a single base expression +can be created using the following functions. -Compute the given power of C, where C is assumed to be non-zero. -If the exponent C is negative, then the -C th power of the inverse -of C is computed. + #include + __isl_give isl_union_pw_aff * + isl_union_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_aff( + __isl_take isl_aff *aff); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); - __isl_give isl_map *isl_map_power(__isl_take isl_map *map, - int *exact); - __isl_give isl_union_map *isl_union_map_power( - __isl_take isl_union_map *umap, int *exact); + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_from_pw_qpolynomial( + __isl_take isl_pw_qpolynomial *pwqp); -Compute a parametric representation for all positive powers I of C. -The result maps I to a nested relation corresponding to the -Ith power of C. -The result may be an overapproximation. If the result is known to be exact, -then C<*exact> is set to C<1>. +The following functions create a base expression on each +of the sets in the union set and collect the results. -=item * Transitive closure + #include + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_aff * + isl_union_pw_multi_aff_get_union_pw_aff( + __isl_keep isl_union_pw_multi_aff *upma, int pos); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_val_on_domain( + __isl_take isl_union_set *domain, + __isl_take isl_val *v); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_multi_val_on_domain( + __isl_take isl_union_set *domain, + __isl_take isl_multi_val *mv); - __isl_give isl_map *isl_map_transitive_closure( - __isl_take isl_map *map, int *exact); - __isl_give isl_union_map *isl_union_map_transitive_closure( - __isl_take isl_union_map *umap, int *exact); +An C that is equal to a (parametric) affine +expression on a given domain can be created using the following +function. -Compute the transitive closure of C. -The result may be an overapproximation. If the result is known to be exact, -then C<*exact> is set to C<1>. + #include + __isl_give isl_union_pw_aff * + isl_union_pw_aff_aff_on_domain( + __isl_take isl_union_set *domain, + __isl_take isl_aff *aff); -=item * Reaching path lengths +A base expression can be added to a union expression using +the following functions. - __isl_give isl_map *isl_map_reaching_path_lengths( - __isl_take isl_map *map, int *exact); + #include + __isl_give isl_union_pw_aff * + isl_union_pw_aff_add_pw_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_pw_aff *pa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_add_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_pw_multi_aff *pma); -Compute a relation that maps each element in the range of C -to the lengths of all paths composed of edges in C that -end up in the given element. -The result may be an overapproximation. If the result is known to be exact, -then C<*exact> is set to C<1>. -To compute the I path length, the resulting relation -should be postprocessed by C. -In particular, if the input relation is a dependence relation -(mapping sources to sinks), then the maximal path length corresponds -to the free schedule. -Note, however, that C expects the maximum to be -finite, so if the path lengths are unbounded (possibly due to -the overapproximation), then you will get an error message. + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_add_pw_qpolynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_pw_qpolynomial *pwqp); -=item * Wrapping +Union expressions can be copied and freed using +the following functions. - __isl_give isl_basic_set *isl_basic_map_wrap( - __isl_take isl_basic_map *bmap); - __isl_give isl_set *isl_map_wrap( - __isl_take isl_map *map); - __isl_give isl_union_set *isl_union_map_wrap( - __isl_take isl_union_map *umap); - __isl_give isl_basic_map *isl_basic_set_unwrap( - __isl_take isl_basic_set *bset); - __isl_give isl_map *isl_set_unwrap( - __isl_take isl_set *set); - __isl_give isl_union_map *isl_union_set_unwrap( - __isl_take isl_union_set *uset); + #include + __isl_give isl_union_pw_aff *isl_union_pw_aff_copy( + __isl_keep isl_union_pw_aff *upa); + __isl_null isl_union_pw_aff *isl_union_pw_aff_free( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_copy( + __isl_keep isl_union_pw_multi_aff *upma); + __isl_null isl_union_pw_multi_aff * + isl_union_pw_multi_aff_free( + __isl_take isl_union_pw_multi_aff *upma); -=item * Flattening + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_copy( + __isl_keep isl_union_pw_qpolynomial *upwqp); + __isl_null isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_free( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_copy( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + __isl_null isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_free( + __isl_take isl_union_pw_qpolynomial_fold *upwf); -Remove any internal structure of domain (and range) of the given -set or relation. If there is any such internal structure in the input, -then the name of the space is also removed. +To iterate over the base expressions in a union expression, +use the following functions. - __isl_give isl_basic_set *isl_basic_set_flatten( - __isl_take isl_basic_set *bset); - __isl_give isl_set *isl_set_flatten( - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_basic_map_flatten_domain( - __isl_take isl_basic_map *bmap); - __isl_give isl_basic_map *isl_basic_map_flatten_range( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_flatten_range( - __isl_take isl_map *map); - __isl_give isl_map *isl_map_flatten_domain( - __isl_take isl_map *map); - __isl_give isl_basic_map *isl_basic_map_flatten( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_flatten( - __isl_take isl_map *map); + #include + int isl_union_pw_aff_n_pw_aff( + __isl_keep isl_union_pw_aff *upa); + isl_stat isl_union_pw_aff_foreach_pw_aff( + __isl_keep isl_union_pw_aff *upa, + isl_stat (*fn)(__isl_take isl_pw_aff *ma, + void *user), void *user); + int isl_union_pw_multi_aff_n_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma); + isl_stat isl_union_pw_multi_aff_foreach_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, + void *user), void *user); - __isl_give isl_map *isl_set_flatten_map( - __isl_take isl_set *set); + #include + int isl_union_pw_qpolynomial_n_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp); + isl_stat isl_union_pw_qpolynomial_foreach_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial *pwqp, + void *user), void *user); + int isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); + isl_stat isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, + void *user), void *user); -The function above constructs a relation -that maps the input set to a flattened version of the set. +To extract the base expression in a given space from a union, use +the following functions. -=item * Lifting + #include + __isl_give isl_pw_aff *isl_union_pw_aff_extract_pw_aff( + __isl_keep isl_union_pw_aff *upa, + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff * + isl_union_pw_multi_aff_extract_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, + __isl_take isl_space *space); -Lift the input set to a space with extra dimensions corresponding -to the existentially quantified variables in the input. -In particular, the result lives in a wrapped map where the domain -is the original space and the range corresponds to the original -existentially quantified variables. + #include + __isl_give isl_pw_qpolynomial * + isl_union_pw_qpolynomial_extract_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp, + __isl_take isl_space *space); - __isl_give isl_basic_set *isl_basic_set_lift( - __isl_take isl_basic_set *bset); - __isl_give isl_set *isl_set_lift( - __isl_take isl_set *set); - __isl_give isl_union_set *isl_union_set_lift( - __isl_take isl_union_set *uset); +=head2 Input and Output -Given a local space that contains the existentially quantified -variables of a set, a basic relation that, when applied to -a basic set, has essentially the same effect as C, -can be constructed using the following function. +For set and relation, +C supports its own input/output format, which is similar +to the C format, but also supports the C format +in some cases. +For other object types, typically only an C format is supported. - #include - __isl_give isl_basic_map *isl_local_space_lifting( - __isl_take isl_local_space *ls); +=head3 C format -=item * Internal Product +The C format is similar to that of C, but has a different +syntax for describing the parameters and allows for the definition +of an existentially quantified variable as the integer division +of an affine expression. +For example, the set of integers C between C<0> and C +such that C can be described as - __isl_give isl_basic_map *isl_basic_map_zip( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_zip( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_zip( - __isl_take isl_union_map *umap); + [n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and + i - 10 a <= 6) } -Given a relation with nested relations for domain and range, -interchange the range of the domain with the domain of the range. +A set or relation can have several disjuncts, separated +by the keyword C. Each disjunct is either a conjunction +of constraints or a projection (C) of a conjunction +of constraints. The constraints are separated by the keyword +C. -=item * Currying +=head3 C format - __isl_give isl_basic_map *isl_basic_map_curry( - __isl_take isl_basic_map *bmap); - __isl_give isl_basic_map *isl_basic_map_uncurry( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_curry( - __isl_take isl_map *map); - __isl_give isl_map *isl_map_uncurry( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_curry( - __isl_take isl_union_map *umap); - __isl_give isl_union_map *isl_union_map_uncurry( - __isl_take isl_union_map *umap); +If the represented set is a union, then the first line +contains a single number representing the number of disjuncts. +Otherwise, a line containing the number C<1> is optional. -Given a relation with a nested relation for domain, -the C functions -move the range of the nested relation out of the domain -and use it as the domain of a nested relation in the range, -with the original range as range of this nested relation. -The C functions perform the inverse operation. +Each disjunct is represented by a matrix of constraints. +The first line contains two numbers representing +the number of rows and columns, +where the number of rows is equal to the number of constraints +and the number of columns is equal to two plus the number of variables. +The following lines contain the actual rows of the constraint matrix. +In each row, the first column indicates whether the constraint +is an equality (C<0>) or inequality (C<1>). The final column +corresponds to the constant term. -=item * Aligning parameters +If the set is parametric, then the coefficients of the parameters +appear in the last columns before the constant column. +The coefficients of any existentially quantified variables appear +between those of the set variables and those of the parameters. - __isl_give isl_basic_set *isl_basic_set_align_params( - __isl_take isl_basic_set *bset, - __isl_take isl_space *model); - __isl_give isl_set *isl_set_align_params( - __isl_take isl_set *set, - __isl_take isl_space *model); - __isl_give isl_basic_map *isl_basic_map_align_params( - __isl_take isl_basic_map *bmap, - __isl_take isl_space *model); - __isl_give isl_map *isl_map_align_params( - __isl_take isl_map *map, - __isl_take isl_space *model); +=head3 Extended C format -Change the order of the parameters of the given set or relation -such that the first parameters match those of C. -This may involve the introduction of extra parameters. -All parameters need to be named. +The extended C format is nearly identical to the +C format. The only difference is that the line +containing the number of rows and columns of a constraint matrix +also contains four additional numbers: +the number of output dimensions, the number of input dimensions, +the number of local dimensions (i.e., the number of existentially +quantified variables) and the number of parameters. +For sets, the number of ``output'' dimensions is equal +to the number of set dimensions, while the number of ``input'' +dimensions is zero. -=item * Dimension manipulation +=head3 Input - __isl_give isl_basic_set *isl_basic_set_add_dims( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned n); - __isl_give isl_set *isl_set_add_dims( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned n); - __isl_give isl_map *isl_map_add_dims( - __isl_take isl_map *map, - enum isl_dim_type type, unsigned n); - __isl_give isl_basic_set *isl_basic_set_insert_dims( - __isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned pos, - unsigned n); - __isl_give isl_basic_map *isl_basic_map_insert_dims( - __isl_take isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, - unsigned n); - __isl_give isl_set *isl_set_insert_dims( - __isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, unsigned n); - __isl_give isl_map *isl_map_insert_dims( - __isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, unsigned n); - __isl_give isl_basic_set *isl_basic_set_move_dims( - __isl_take isl_basic_set *bset, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, - unsigned n); - __isl_give isl_basic_map *isl_basic_map_move_dims( - __isl_take isl_basic_map *bmap, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, - unsigned n); - __isl_give isl_set *isl_set_move_dims( - __isl_take isl_set *set, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, - unsigned n); - __isl_give isl_map *isl_map_move_dims( - __isl_take isl_map *map, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, - unsigned n); +Objects can be read from input using the following functions. -It is usually not advisable to directly change the (input or output) -space of a set or a relation as this removes the name and the internal -structure of the space. However, the above functions can be useful -to add new parameters, assuming -C and C -are not sufficient. + #include + __isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx, + const char *str); + __isl_give isl_multi_val *isl_multi_val_read_from_str( + isl_ctx *ctx, const char *str); -=back + #include + __isl_give isl_basic_set *isl_basic_set_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_basic_set *isl_basic_set_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_set *isl_set_read_from_file(isl_ctx *ctx, + FILE *input); + __isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx, + const char *str); -=head2 Binary Operations + #include + __isl_give isl_basic_map *isl_basic_map_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_basic_map *isl_basic_map_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_map *isl_map_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, + const char *str); -The two arguments of a binary operation not only need to live -in the same C, they currently also need to have -the same (number of) parameters. + #include + __isl_give isl_union_set *isl_union_set_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_union_set *isl_union_set_read_from_str( + isl_ctx *ctx, const char *str); -=head3 Basic Operations + #include + __isl_give isl_union_map *isl_union_map_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_union_map *isl_union_map_read_from_str( + isl_ctx *ctx, const char *str); -=over + #include + __isl_give isl_aff *isl_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_multi_aff *isl_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_pw_aff *isl_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_read_from_str( + isl_ctx *ctx, const char *str); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); -=item * Intersection + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_read_from_str( + isl_ctx *ctx, const char *str); - __isl_give isl_basic_set *isl_basic_set_intersect_params( - __isl_take isl_basic_set *bset1, - __isl_take isl_basic_set *bset2); - __isl_give isl_basic_set *isl_basic_set_intersect( - __isl_take isl_basic_set *bset1, - __isl_take isl_basic_set *bset2); - __isl_give isl_set *isl_set_intersect_params( - __isl_take isl_set *set, - __isl_take isl_set *params); - __isl_give isl_set *isl_set_intersect( - __isl_take isl_set *set1, - __isl_take isl_set *set2); - __isl_give isl_union_set *isl_union_set_intersect_params( - __isl_take isl_union_set *uset, - __isl_take isl_set *set); - __isl_give isl_union_map *isl_union_map_intersect_params( - __isl_take isl_union_map *umap, - __isl_take isl_set *set); - __isl_give isl_union_set *isl_union_set_intersect( - __isl_take isl_union_set *uset1, - __isl_take isl_union_set *uset2); - __isl_give isl_basic_map *isl_basic_map_intersect_domain( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_set *bset); - __isl_give isl_basic_map *isl_basic_map_intersect_range( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_set *bset); - __isl_give isl_basic_map *isl_basic_map_intersect( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_map *isl_map_intersect_params( - __isl_take isl_map *map, - __isl_take isl_set *params); - __isl_give isl_map *isl_map_intersect_domain( - __isl_take isl_map *map, - __isl_take isl_set *set); - __isl_give isl_map *isl_map_intersect_range( - __isl_take isl_map *map, - __isl_take isl_set *set); - __isl_give isl_map *isl_map_intersect( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_map *isl_union_map_intersect_domain( - __isl_take isl_union_map *umap, - __isl_take isl_union_set *uset); - __isl_give isl_union_map *isl_union_map_intersect_range( - __isl_take isl_union_map *umap, - __isl_take isl_union_set *uset); - __isl_give isl_union_map *isl_union_map_intersect( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); +For sets and relations, +the input format is autodetected and may be either the C format +or the C format. -The second argument to the C<_params> functions needs to be -a parametric (basic) set. For the other functions, a parametric set -for either argument is only allowed if the other argument is -a parametric set as well. +=head3 Output -=item * Union +Before anything can be printed, an C needs to +be created. - __isl_give isl_set *isl_basic_set_union( - __isl_take isl_basic_set *bset1, - __isl_take isl_basic_set *bset2); - __isl_give isl_map *isl_basic_map_union( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_set *isl_set_union( - __isl_take isl_set *set1, - __isl_take isl_set *set2); - __isl_give isl_map *isl_map_union( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_set *isl_union_set_union( - __isl_take isl_union_set *uset1, - __isl_take isl_union_set *uset2); - __isl_give isl_union_map *isl_union_map_union( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); + __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, + FILE *file); + __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx); + __isl_null isl_printer *isl_printer_free( + __isl_take isl_printer *printer); + __isl_give char *isl_printer_get_str( + __isl_keep isl_printer *printer); -=item * Set difference +The printer can be inspected using the following functions. - __isl_give isl_set *isl_set_subtract( - __isl_take isl_set *set1, - __isl_take isl_set *set2); - __isl_give isl_map *isl_map_subtract( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_map *isl_map_subtract_domain( - __isl_take isl_map *map, - __isl_take isl_set *dom); - __isl_give isl_map *isl_map_subtract_range( - __isl_take isl_map *map, - __isl_take isl_set *dom); - __isl_give isl_union_set *isl_union_set_subtract( - __isl_take isl_union_set *uset1, - __isl_take isl_union_set *uset2); - __isl_give isl_union_map *isl_union_map_subtract( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); - __isl_give isl_union_map *isl_union_map_subtract_domain( - __isl_take isl_union_map *umap, - __isl_take isl_union_set *dom); - __isl_give isl_union_map *isl_union_map_subtract_range( - __isl_take isl_union_map *umap, - __isl_take isl_union_set *dom); - -=item * Application + FILE *isl_printer_get_file( + __isl_keep isl_printer *printer); + int isl_printer_get_output_format( + __isl_keep isl_printer *p); + int isl_printer_get_yaml_style(__isl_keep isl_printer *p); - __isl_give isl_basic_set *isl_basic_set_apply( - __isl_take isl_basic_set *bset, - __isl_take isl_basic_map *bmap); - __isl_give isl_set *isl_set_apply( - __isl_take isl_set *set, - __isl_take isl_map *map); - __isl_give isl_union_set *isl_union_set_apply( - __isl_take isl_union_set *uset, - __isl_take isl_union_map *umap); - __isl_give isl_basic_map *isl_basic_map_apply_domain( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_basic_map *isl_basic_map_apply_range( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_map *isl_map_apply_domain( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_map *isl_union_map_apply_domain( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); - __isl_give isl_map *isl_map_apply_range( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_map *isl_union_map_apply_range( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); +The behavior of the printer can be modified in various ways -=item * Preimage + __isl_give isl_printer *isl_printer_set_output_format( + __isl_take isl_printer *p, int output_format); + __isl_give isl_printer *isl_printer_set_indent( + __isl_take isl_printer *p, int indent); + __isl_give isl_printer *isl_printer_set_indent_prefix( + __isl_take isl_printer *p, const char *prefix); + __isl_give isl_printer *isl_printer_indent( + __isl_take isl_printer *p, int indent); + __isl_give isl_printer *isl_printer_set_prefix( + __isl_take isl_printer *p, const char *prefix); + __isl_give isl_printer *isl_printer_set_suffix( + __isl_take isl_printer *p, const char *suffix); + __isl_give isl_printer *isl_printer_set_yaml_style( + __isl_take isl_printer *p, int yaml_style); - __isl_give isl_basic_set * - isl_basic_set_preimage_multi_aff( - __isl_take isl_basic_set *bset, - __isl_take isl_multi_aff *ma); - __isl_give isl_set *isl_set_preimage_multi_aff( - __isl_take isl_set *set, - __isl_take isl_multi_aff *ma); - __isl_give isl_set *isl_set_preimage_pw_multi_aff( - __isl_take isl_set *set, - __isl_take isl_pw_multi_aff *pma); - __isl_give isl_map *isl_map_preimage_domain_multi_aff( - __isl_take isl_map *map, - __isl_take isl_multi_aff *ma); - __isl_give isl_union_map * - isl_union_map_preimage_domain_multi_aff( - __isl_take isl_union_map *umap, - __isl_take isl_multi_aff *ma); +The C may be either C, C, +C, C or C +and defaults to C. +Each line in the output is prefixed by C, +indented by C (set by C) spaces +(default: 0), prefixed by C and suffixed by C. +In the C format output, +the coefficients of the existentially quantified variables +appear between those of the set variables and those +of the parameters. +The function C increases the indentation +by the specified amount (which may be negative). +The YAML style may be either C or +C and when we are printing something +in YAML format. -These functions compute the preimage of the given set or map domain under -the given function. In other words, the expression is plugged -into the set description or into the domain of the map. -Objects of types C and C are described in -L. +To actually print something, use -=item * Cartesian Product + #include + __isl_give isl_printer *isl_printer_print_double( + __isl_take isl_printer *p, double d); - __isl_give isl_set *isl_set_product( - __isl_take isl_set *set1, - __isl_take isl_set *set2); - __isl_give isl_union_set *isl_union_set_product( - __isl_take isl_union_set *uset1, - __isl_take isl_union_set *uset2); - __isl_give isl_basic_map *isl_basic_map_domain_product( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_basic_map *isl_basic_map_range_product( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_basic_map *isl_basic_map_product( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_map *isl_map_domain_product( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_map *isl_map_range_product( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_map *isl_union_map_domain_product( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); - __isl_give isl_union_map *isl_union_map_range_product( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); - __isl_give isl_map *isl_map_product( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_map *isl_union_map_product( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); + #include + __isl_give isl_printer *isl_printer_print_val( + __isl_take isl_printer *p, __isl_keep isl_val *v); -The above functions compute the cross product of the given -sets or relations. The domains and ranges of the results -are wrapped maps between domains and ranges of the inputs. -To obtain a ``flat'' product, use the following functions -instead. + #include + __isl_give isl_printer *isl_printer_print_basic_set( + __isl_take isl_printer *printer, + __isl_keep isl_basic_set *bset); + __isl_give isl_printer *isl_printer_print_set( + __isl_take isl_printer *printer, + __isl_keep isl_set *set); - __isl_give isl_basic_set *isl_basic_set_flat_product( - __isl_take isl_basic_set *bset1, - __isl_take isl_basic_set *bset2); - __isl_give isl_set *isl_set_flat_product( - __isl_take isl_set *set1, - __isl_take isl_set *set2); - __isl_give isl_basic_map *isl_basic_map_flat_range_product( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_map *isl_map_flat_domain_product( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_map *isl_map_flat_range_product( - __isl_take isl_map *map1, - __isl_take isl_map *map2); - __isl_give isl_union_map *isl_union_map_flat_range_product( - __isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2); - __isl_give isl_basic_map *isl_basic_map_flat_product( - __isl_take isl_basic_map *bmap1, - __isl_take isl_basic_map *bmap2); - __isl_give isl_map *isl_map_flat_product( - __isl_take isl_map *map1, - __isl_take isl_map *map2); + #include + __isl_give isl_printer *isl_printer_print_basic_map( + __isl_take isl_printer *printer, + __isl_keep isl_basic_map *bmap); + __isl_give isl_printer *isl_printer_print_map( + __isl_take isl_printer *printer, + __isl_keep isl_map *map); -=item * Simplification + #include + __isl_give isl_printer *isl_printer_print_union_set( + __isl_take isl_printer *p, + __isl_keep isl_union_set *uset); - __isl_give isl_basic_set *isl_basic_set_gist( - __isl_take isl_basic_set *bset, - __isl_take isl_basic_set *context); - __isl_give isl_set *isl_set_gist(__isl_take isl_set *set, - __isl_take isl_set *context); - __isl_give isl_set *isl_set_gist_params( - __isl_take isl_set *set, - __isl_take isl_set *context); - __isl_give isl_union_set *isl_union_set_gist( - __isl_take isl_union_set *uset, - __isl_take isl_union_set *context); - __isl_give isl_union_set *isl_union_set_gist_params( - __isl_take isl_union_set *uset, - __isl_take isl_set *set); - __isl_give isl_basic_map *isl_basic_map_gist( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_map *context); - __isl_give isl_map *isl_map_gist(__isl_take isl_map *map, - __isl_take isl_map *context); - __isl_give isl_map *isl_map_gist_params( - __isl_take isl_map *map, - __isl_take isl_set *context); - __isl_give isl_map *isl_map_gist_domain( - __isl_take isl_map *map, - __isl_take isl_set *context); - __isl_give isl_map *isl_map_gist_range( - __isl_take isl_map *map, - __isl_take isl_set *context); - __isl_give isl_union_map *isl_union_map_gist( - __isl_take isl_union_map *umap, - __isl_take isl_union_map *context); - __isl_give isl_union_map *isl_union_map_gist_params( - __isl_take isl_union_map *umap, - __isl_take isl_set *set); - __isl_give isl_union_map *isl_union_map_gist_domain( - __isl_take isl_union_map *umap, - __isl_take isl_union_set *uset); - __isl_give isl_union_map *isl_union_map_gist_range( - __isl_take isl_union_map *umap, - __isl_take isl_union_set *uset); + #include + __isl_give isl_printer *isl_printer_print_union_map( + __isl_take isl_printer *p, + __isl_keep isl_union_map *umap); -The gist operation returns a set or relation that has the -same intersection with the context as the input set or relation. -Any implicit equality in the intersection is made explicit in the result, -while all inequalities that are redundant with respect to the intersection -are removed. -In case of union sets and relations, the gist operation is performed -per space. + #include + __isl_give isl_printer *isl_printer_print_multi_val( + __isl_take isl_printer *p, + __isl_keep isl_multi_val *mv); -=back + #include + __isl_give isl_printer *isl_printer_print_aff( + __isl_take isl_printer *p, __isl_keep isl_aff *aff); + __isl_give isl_printer *isl_printer_print_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_multi_aff *maff); + __isl_give isl_printer *isl_printer_print_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_pw_aff *pwaff); + __isl_give isl_printer *isl_printer_print_pw_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_printer *isl_printer_print_multi_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_printer *isl_printer_print_union_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_aff *upa); + __isl_give isl_printer *isl_printer_print_union_pw_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_multi_aff *upma); + __isl_give isl_printer * + isl_printer_print_multi_union_pw_aff( + __isl_take isl_printer *p, + __isl_keep isl_multi_union_pw_aff *mupa); -=head3 Lexicographic Optimization - -Given a (basic) set C (or C) and a zero-dimensional domain C, -the following functions -compute a set that contains the lexicographic minimum or maximum -of the elements in C (or C) for those values of the parameters -that satisfy C. -If C is not C, then C<*empty> is assigned a set -that contains the parameter values in C for which C (or C) -has no elements. -In other words, the union of the parameter values -for which the result is non-empty and of C<*empty> -is equal to C. - - __isl_give isl_set *isl_basic_set_partial_lexmin( - __isl_take isl_basic_set *bset, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_set *isl_basic_set_partial_lexmax( - __isl_take isl_basic_set *bset, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_set *isl_set_partial_lexmin( - __isl_take isl_set *set, __isl_take isl_set *dom, - __isl_give isl_set **empty); - __isl_give isl_set *isl_set_partial_lexmax( - __isl_take isl_set *set, __isl_take isl_set *dom, - __isl_give isl_set **empty); + #include + __isl_give isl_printer *isl_printer_print_qpolynomial( + __isl_take isl_printer *p, + __isl_keep isl_qpolynomial *qp); + __isl_give isl_printer *isl_printer_print_pw_qpolynomial( + __isl_take isl_printer *p, + __isl_keep isl_pw_qpolynomial *pwqp); + __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_qpolynomial *upwqp); -Given a (basic) set C (or C), the following functions simply -return a set containing the lexicographic minimum or maximum -of the elements in C (or C). -In case of union sets, the optimum is computed per space. + __isl_give isl_printer * + isl_printer_print_pw_qpolynomial_fold( + __isl_take isl_printer *p, + __isl_keep isl_pw_qpolynomial_fold *pwf); + __isl_give isl_printer * + isl_printer_print_union_pw_qpolynomial_fold( + __isl_take isl_printer *p, + __isl_keep isl_union_pw_qpolynomial_fold *upwf); - __isl_give isl_set *isl_basic_set_lexmin( - __isl_take isl_basic_set *bset); - __isl_give isl_set *isl_basic_set_lexmax( - __isl_take isl_basic_set *bset); - __isl_give isl_set *isl_set_lexmin( - __isl_take isl_set *set); - __isl_give isl_set *isl_set_lexmax( - __isl_take isl_set *set); - __isl_give isl_union_set *isl_union_set_lexmin( - __isl_take isl_union_set *uset); - __isl_give isl_union_set *isl_union_set_lexmax( - __isl_take isl_union_set *uset); +For C, +C and +C, +the output format of the printer +needs to be set to either C or C. +For C and +C, only C +is supported. +In case of printing in C, the user may want +to set the names of all dimensions first. -Given a (basic) relation C (or C) and a domain C, -the following functions -compute a relation that maps each element of C -to the single lexicographic minimum or maximum -of the elements that are associated to that same -element in C (or C). -If C is not C, then C<*empty> is assigned a set -that contains the elements in C that do not map -to any elements in C (or C). -In other words, the union of the domain of the result and of C<*empty> -is equal to C. +C also provides limited support for printing YAML documents, +just enough for the internal use for printing such documents. - __isl_give isl_map *isl_basic_map_partial_lexmax( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_map *isl_basic_map_partial_lexmin( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_map *isl_map_partial_lexmax( - __isl_take isl_map *map, __isl_take isl_set *dom, - __isl_give isl_set **empty); - __isl_give isl_map *isl_map_partial_lexmin( - __isl_take isl_map *map, __isl_take isl_set *dom, - __isl_give isl_set **empty); + #include + __isl_give isl_printer *isl_printer_yaml_start_mapping( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_end_mapping( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_start_sequence( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_end_sequence( + __isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_yaml_next( + __isl_take isl_printer *p); -Given a (basic) map C (or C), the following functions simply -return a map mapping each element in the domain of -C (or C) to the lexicographic minimum or maximum -of all elements associated to that element. -In case of union relations, the optimum is computed per space. +A document is started by a call to either +C or C. +Anything printed to the printer after such a call belong to the +first key of the mapping or the first element in the sequence. +The function C moves to the value if +we are currently printing a mapping key, the next key if we +are printing a value or the next element if we are printing +an element in a sequence. +Nested mappings and sequences are initiated by the same +C or C. +Each call to these functions needs to have a corresponding call to +C or C. - __isl_give isl_map *isl_basic_map_lexmin( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_basic_map_lexmax( - __isl_take isl_basic_map *bmap); - __isl_give isl_map *isl_map_lexmin( - __isl_take isl_map *map); - __isl_give isl_map *isl_map_lexmax( - __isl_take isl_map *map); - __isl_give isl_union_map *isl_union_map_lexmin( - __isl_take isl_union_map *umap); - __isl_give isl_union_map *isl_union_map_lexmax( - __isl_take isl_union_map *umap); +When called on a file printer, the following function flushes +the file. When called on a string printer, the buffer is cleared. -The following functions return their result in the form of -a piecewise multi-affine expression -(See L<"Piecewise Multiple Quasi Affine Expressions">), -but are otherwise equivalent to the corresponding functions -returning a basic set or relation. + __isl_give isl_printer *isl_printer_flush( + __isl_take isl_printer *p); - __isl_give isl_pw_multi_aff * - isl_basic_map_lexmin_pw_multi_aff( - __isl_take isl_basic_map *bmap); - __isl_give isl_pw_multi_aff * - isl_basic_set_partial_lexmin_pw_multi_aff( - __isl_take isl_basic_set *bset, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_pw_multi_aff * - isl_basic_set_partial_lexmax_pw_multi_aff( - __isl_take isl_basic_set *bset, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_pw_multi_aff * - isl_basic_map_partial_lexmin_pw_multi_aff( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_pw_multi_aff * - isl_basic_map_partial_lexmax_pw_multi_aff( - __isl_take isl_basic_map *bmap, - __isl_take isl_basic_set *dom, - __isl_give isl_set **empty); - __isl_give isl_pw_multi_aff *isl_set_lexmin_pw_multi_aff( - __isl_take isl_set *set); - __isl_give isl_pw_multi_aff *isl_set_lexmax_pw_multi_aff( - __isl_take isl_set *set); - __isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff( - __isl_take isl_map *map); - __isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff( - __isl_take isl_map *map); +Alternatively, a string representation can be obtained +directly using the following functions, which always print +in isl format. -=head2 Lists + #include + __isl_give char *isl_space_to_str( + __isl_keep isl_space *space); -Lists are defined over several element types, including -C, C, C, C, C, -C, C, C and C. -Here we take lists of Cs as an example. -Lists can be created, copied, modified and freed using the following functions. + #include + __isl_give char *isl_val_to_str(__isl_keep isl_val *v); + __isl_give char *isl_multi_val_to_str( + __isl_keep isl_multi_val *mv); - #include - __isl_give isl_set_list *isl_set_list_from_set( - __isl_take isl_set *el); - __isl_give isl_set_list *isl_set_list_alloc( - isl_ctx *ctx, int n); - __isl_give isl_set_list *isl_set_list_copy( - __isl_keep isl_set_list *list); - __isl_give isl_set_list *isl_set_list_insert( - __isl_take isl_set_list *list, unsigned pos, - __isl_take isl_set *el); - __isl_give isl_set_list *isl_set_list_add( - __isl_take isl_set_list *list, - __isl_take isl_set *el); - __isl_give isl_set_list *isl_set_list_drop( - __isl_take isl_set_list *list, - unsigned first, unsigned n); - __isl_give isl_set_list *isl_set_list_set_set( - __isl_take isl_set_list *list, int index, - __isl_take isl_set *set); - __isl_give isl_set_list *isl_set_list_concat( - __isl_take isl_set_list *list1, - __isl_take isl_set_list *list2); - __isl_give isl_set_list *isl_set_list_sort( - __isl_take isl_set_list *list, - int (*cmp)(__isl_keep isl_set *a, - __isl_keep isl_set *b, void *user), - void *user); - void *isl_set_list_free(__isl_take isl_set_list *list); + #include + __isl_give char *isl_set_to_str( + __isl_keep isl_set *set); -C creates an empty list with a capacity for -C elements. C creates a list with a single -element. + #include + __isl_give char *isl_union_set_to_str( + __isl_keep isl_union_set *uset); -Lists can be inspected using the following functions. + #include + __isl_give char *isl_map_to_str( + __isl_keep isl_map *map); - #include - isl_ctx *isl_set_list_get_ctx(__isl_keep isl_set_list *list); - int isl_set_list_n_set(__isl_keep isl_set_list *list); - __isl_give isl_set *isl_set_list_get_set( - __isl_keep isl_set_list *list, int index); - int isl_set_list_foreach(__isl_keep isl_set_list *list, - int (*fn)(__isl_take isl_set *el, void *user), - void *user); - int isl_set_list_foreach_scc(__isl_keep isl_set_list *list, - int (*follows)(__isl_keep isl_set *a, - __isl_keep isl_set *b, void *user), - void *follows_user - int (*fn)(__isl_take isl_set *el, void *user), - void *fn_user); + #include + __isl_give char *isl_union_map_to_str( + __isl_keep isl_union_map *umap); -The function C calls C on each of the -strongly connected components of the graph with as vertices the elements -of C and a directed edge from vertex C to vertex C -iff C returns C<1>. The callbacks C and C -should return C<-1> on error. + #include + __isl_give char *isl_multi_aff_to_str( + __isl_keep isl_multi_aff *aff); + __isl_give char *isl_union_pw_aff_to_str( + __isl_keep isl_union_pw_aff *upa); + __isl_give char *isl_union_pw_multi_aff_to_str( + __isl_keep isl_union_pw_multi_aff *upma); + __isl_give char *isl_multi_union_pw_aff_to_str( + __isl_keep isl_multi_union_pw_aff *mupa); -Lists can be printed using +=head2 Properties - #include - __isl_give isl_printer *isl_printer_print_set_list( - __isl_take isl_printer *p, - __isl_keep isl_set_list *list); +=head3 Unary Properties -=head2 Multiple Values +=over -An C object represents a sequence of zero or more values, -living in a set space. +=item * Emptiness -An C can be constructed from an C -using the following function +The following functions test whether the given set or relation +contains any integer points. The ``plain'' variants do not perform +any computations, but simply check if the given set or relation +is already known to be empty. - #include - __isl_give isl_multi_val *isl_multi_val_from_val_list( - __isl_take isl_space *space, - __isl_take isl_val_list *list); + isl_bool isl_basic_set_plain_is_empty( + __isl_keep isl_basic_set *bset); + isl_bool isl_basic_set_is_empty( + __isl_keep isl_basic_set *bset); + isl_bool isl_set_plain_is_empty( + __isl_keep isl_set *set); + isl_bool isl_set_is_empty(__isl_keep isl_set *set); + isl_bool isl_union_set_is_empty( + __isl_keep isl_union_set *uset); + isl_bool isl_basic_map_plain_is_empty( + __isl_keep isl_basic_map *bmap); + isl_bool isl_basic_map_is_empty( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_plain_is_empty( + __isl_keep isl_map *map); + isl_bool isl_map_is_empty(__isl_keep isl_map *map); + isl_bool isl_union_map_is_empty( + __isl_keep isl_union_map *umap); -The zero multiple value (with value zero for each set dimension) -can be created using the following function. +=item * Universality - #include - __isl_give isl_multi_val *isl_multi_val_zero( - __isl_take isl_space *space); + isl_bool isl_basic_set_is_universe( + __isl_keep isl_basic_set *bset); + isl_bool isl_basic_map_is_universe( + __isl_keep isl_basic_map *bmap); + isl_bool isl_set_plain_is_universe( + __isl_keep isl_set *set); + isl_bool isl_map_plain_is_universe( + __isl_keep isl_map *map); -Multiple values can be copied and freed using +=item * Single-valuedness - #include - __isl_give isl_multi_val *isl_multi_val_copy( - __isl_keep isl_multi_val *mv); - void *isl_multi_val_free(__isl_take isl_multi_val *mv); + #include + isl_bool isl_set_is_singleton(__isl_keep isl_set *set); -They can be inspected using + #include + isl_bool isl_basic_map_is_single_valued( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_plain_is_single_valued( + __isl_keep isl_map *map); + isl_bool isl_map_is_single_valued(__isl_keep isl_map *map); - #include - isl_ctx *isl_multi_val_get_ctx( - __isl_keep isl_multi_val *mv); - unsigned isl_multi_val_dim(__isl_keep isl_multi_val *mv, - enum isl_dim_type type); - __isl_give isl_val *isl_multi_val_get_val( - __isl_keep isl_multi_val *mv, int pos); - const char *isl_multi_val_get_tuple_name( - __isl_keep isl_multi_val *mv, - enum isl_dim_type type); + #include + isl_bool isl_union_map_is_single_valued( + __isl_keep isl_union_map *umap); -They can be modified using +=item * Injectivity - #include - __isl_give isl_multi_val *isl_multi_val_set_val( - __isl_take isl_multi_val *mv, int pos, - __isl_take isl_val *val); - __isl_give isl_multi_val *isl_multi_val_set_dim_name( - __isl_take isl_multi_val *mv, - enum isl_dim_type type, unsigned pos, const char *s); - __isl_give isl_multi_val *isl_multi_val_set_tuple_name( - __isl_take isl_multi_val *mv, - enum isl_dim_type type, const char *s); - __isl_give isl_multi_val *isl_multi_val_set_tuple_id( - __isl_take isl_multi_val *mv, - enum isl_dim_type type, __isl_take isl_id *id); + isl_bool isl_map_plain_is_injective( + __isl_keep isl_map *map); + isl_bool isl_map_is_injective( + __isl_keep isl_map *map); + isl_bool isl_union_map_plain_is_injective( + __isl_keep isl_union_map *umap); + isl_bool isl_union_map_is_injective( + __isl_keep isl_union_map *umap); - __isl_give isl_multi_val *isl_multi_val_insert_dims( - __isl_take isl_multi_val *mv, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_multi_val *isl_multi_val_add_dims( - __isl_take isl_multi_val *mv, - enum isl_dim_type type, unsigned n); - __isl_give isl_multi_val *isl_multi_val_drop_dims( - __isl_take isl_multi_val *mv, - enum isl_dim_type type, unsigned first, unsigned n); +=item * Bijectivity -Operations include + isl_bool isl_map_is_bijective( + __isl_keep isl_map *map); + isl_bool isl_union_map_is_bijective( + __isl_keep isl_union_map *umap); - #include - __isl_give isl_multi_val *isl_multi_val_align_params( - __isl_take isl_multi_val *mv, - __isl_take isl_space *model); - __isl_give isl_multi_val *isl_multi_val_range_splice( - __isl_take isl_multi_val *mv1, unsigned pos, - __isl_take isl_multi_val *mv2); - __isl_give isl_multi_val *isl_multi_val_range_product( - __isl_take isl_multi_val *mv1, - __isl_take isl_multi_val *mv2); - __isl_give isl_multi_val *isl_multi_val_flat_range_product( - __isl_take isl_multi_val *mv1, - __isl_take isl_multi_aff *mv2); - __isl_give isl_multi_val *isl_multi_val_add_val( - __isl_take isl_multi_val *mv, - __isl_take isl_val *v); - __isl_give isl_multi_val *isl_multi_val_mod_val( - __isl_take isl_multi_val *mv, - __isl_take isl_val *v); - __isl_give isl_multi_val *isl_multi_val_scale_val( - __isl_take isl_multi_val *mv, - __isl_take isl_val *v); - __isl_give isl_multi_val *isl_multi_val_scale_multi_val( - __isl_take isl_multi_val *mv1, - __isl_take isl_multi_val *mv2); +=item * Position -=head2 Vectors + __isl_give isl_val * + isl_basic_map_plain_get_val_if_fixed( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos); + __isl_give isl_val *isl_set_plain_get_val_if_fixed( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + __isl_give isl_val *isl_map_plain_get_val_if_fixed( + __isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos); -Vectors can be created, copied and freed using the following functions. +If the set or relation obviously lies on a hyperplane where the given dimension +has a fixed value, then return that value. +Otherwise return NaN. - #include - __isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx, - unsigned size); - __isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec); - void *isl_vec_free(__isl_take isl_vec *vec); +=item * Stride -Note that the elements of a newly created vector may have arbitrary values. -The elements can be changed and inspected using the following functions. + isl_stat isl_set_dim_residue_class_val( + __isl_keep isl_set *set, + int pos, __isl_give isl_val **modulo, + __isl_give isl_val **residue); - isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec); - int isl_vec_size(__isl_keep isl_vec *vec); - int isl_vec_get_element(__isl_keep isl_vec *vec, - int pos, isl_int *v); - __isl_give isl_val *isl_vec_get_element_val( - __isl_keep isl_vec *vec, int pos); - __isl_give isl_vec *isl_vec_set_element( - __isl_take isl_vec *vec, int pos, isl_int v); - __isl_give isl_vec *isl_vec_set_element_si( - __isl_take isl_vec *vec, int pos, int v); - __isl_give isl_vec *isl_vec_set_element_val( - __isl_take isl_vec *vec, int pos, - __isl_take isl_val *v); - __isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, - isl_int v); - __isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, - int v); - __isl_give isl_vec *isl_vec_set_val( - __isl_take isl_vec *vec, __isl_take isl_val *v); - int isl_vec_cmp_element(__isl_keep isl_vec *vec1, - __isl_keep isl_vec *vec2, int pos); - __isl_give isl_vec *isl_vec_fdiv_r(__isl_take isl_vec *vec, - isl_int m); +Check if the values of the given set dimension are equal to a fixed +value modulo some integer value. If so, assign the modulo to C<*modulo> +and the fixed value to C<*residue>. If the given dimension attains only +a single value, then assign C<0> to C<*modulo> and the fixed value to +C<*residue>. +If the dimension does not attain only a single value and if no modulo +can be found then assign C<1> to C<*modulo> and C<1> to C<*residue>. -C will return a negative value if anything went wrong. -In that case, the value of C<*v> is undefined. +=item * Dependence -The following function can be used to concatenate two vectors. +To check whether the description of a set, relation or function depends +on one or more given dimensions, +the following functions can be used. - __isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, - __isl_take isl_vec *vec2); + #include + isl_bool isl_constraint_involves_dims( + __isl_keep isl_constraint *constraint, + enum isl_dim_type type, unsigned first, unsigned n); -=head2 Matrices + #include + isl_bool isl_basic_set_involves_dims( + __isl_keep isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_set_involves_dims(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); -Matrices can be created, copied and freed using the following functions. + #include + isl_bool isl_basic_map_involves_dims( + __isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_map_involves_dims(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); - #include - __isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx, - unsigned n_row, unsigned n_col); - __isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat); - void *isl_mat_free(__isl_take isl_mat *mat); + #include + isl_bool isl_union_map_involves_dims( + __isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n); -Note that the elements of a newly created matrix may have arbitrary values. -The elements can be changed and inspected using the following functions. + #include + isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_pw_aff_involves_dims( + __isl_keep isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_multi_aff_involves_dims( + __isl_keep isl_multi_aff *ma, + enum isl_dim_type type, unsigned first, unsigned n); + isl_bool isl_multi_pw_aff_involves_dims( + __isl_keep isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned first, unsigned n); - isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat); - int isl_mat_rows(__isl_keep isl_mat *mat); - int isl_mat_cols(__isl_keep isl_mat *mat); - int isl_mat_get_element(__isl_keep isl_mat *mat, - int row, int col, isl_int *v); - __isl_give isl_val *isl_mat_get_element_val( - __isl_keep isl_mat *mat, int row, int col); - __isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat, - int row, int col, isl_int v); - __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, - int row, int col, int v); - __isl_give isl_mat *isl_mat_set_element_val( - __isl_take isl_mat *mat, int row, int col, - __isl_take isl_val *v); + #include + isl_bool isl_qpolynomial_involves_dims( + __isl_keep isl_qpolynomial *qp, + enum isl_dim_type type, unsigned first, unsigned n); -C will return a negative value if anything went wrong. -In that case, the value of C<*v> is undefined. +Similarly, the following functions can be used to check whether +a given dimension is involved in any lower or upper bound. -The following function can be used to compute the (right) inverse -of a matrix, i.e., a matrix such that the product of the original -and the inverse (in that order) is a multiple of the identity matrix. -The input matrix is assumed to be of full row-rank. + #include + isl_bool isl_set_dim_has_any_lower_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + isl_bool isl_set_dim_has_any_upper_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); - __isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat); +Note that these functions return true even if there is a bound on +the dimension on only some of the basic sets of C. +To check if they have a bound for all of the basic sets in C, +use the following functions instead. -The following function can be used to compute the (right) kernel -(or null space) of a matrix, i.e., a matrix such that the product of -the original and the kernel (in that order) is the zero matrix. + #include + isl_bool isl_set_dim_has_lower_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); + isl_bool isl_set_dim_has_upper_bound( + __isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos); - __isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat); +=item * Space -=head2 Piecewise Quasi Affine Expressions +To check whether a set is a parameter domain, use this function: -The zero quasi affine expression or the quasi affine expression -that is equal to a specified dimension on a given domain can be created using + isl_bool isl_set_is_params(__isl_keep isl_set *set); + isl_bool isl_union_set_is_params( + __isl_keep isl_union_set *uset); - __isl_give isl_aff *isl_aff_zero_on_domain( - __isl_take isl_local_space *ls); - __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain( - __isl_take isl_local_space *ls); - __isl_give isl_aff *isl_aff_var_on_domain( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned pos); - __isl_give isl_pw_aff *isl_pw_aff_var_on_domain( - __isl_take isl_local_space *ls, - enum isl_dim_type type, unsigned pos); +=item * Wrapping -Note that the space in which the resulting objects live is a map space -with the given space as domain and a one-dimensional range. +The following functions check whether the space of the given +(basic) set or relation range is a wrapped relation. -An empty piecewise quasi affine expression (one with no cells) -or a piecewise quasi affine expression with a single cell can -be created using the following functions. + #include + isl_bool isl_space_is_wrapping( + __isl_keep isl_space *space); + isl_bool isl_space_domain_is_wrapping( + __isl_keep isl_space *space); + isl_bool isl_space_range_is_wrapping( + __isl_keep isl_space *space); - #include - __isl_give isl_pw_aff *isl_pw_aff_empty( - __isl_take isl_space *space); - __isl_give isl_pw_aff *isl_pw_aff_alloc( - __isl_take isl_set *set, __isl_take isl_aff *aff); - __isl_give isl_pw_aff *isl_pw_aff_from_aff( - __isl_take isl_aff *aff); + #include + isl_bool isl_basic_set_is_wrapping( + __isl_keep isl_basic_set *bset); + isl_bool isl_set_is_wrapping(__isl_keep isl_set *set); -A piecewise quasi affine expression that is equal to 1 on a set -and 0 outside the set can be created using the following function. + #include + isl_bool isl_map_domain_is_wrapping( + __isl_keep isl_map *map); + isl_bool isl_map_range_is_wrapping( + __isl_keep isl_map *map); + + #include + isl_bool isl_multi_val_range_is_wrapping( + __isl_keep isl_multi_val *mv); #include - __isl_give isl_pw_aff *isl_set_indicator_function( - __isl_take isl_set *set); + isl_bool isl_multi_aff_range_is_wrapping( + __isl_keep isl_multi_aff *ma); + isl_bool isl_multi_pw_aff_range_is_wrapping( + __isl_keep isl_multi_pw_aff *mpa); + isl_bool isl_multi_union_pw_aff_range_is_wrapping( + __isl_keep isl_multi_union_pw_aff *mupa); -Quasi affine expressions can be copied and freed using +The input to C should +be the space of a set, while that of +C and +C should be the space of a relation. - #include - __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff); - void *isl_aff_free(__isl_take isl_aff *aff); +=item * Internal Product - __isl_give isl_pw_aff *isl_pw_aff_copy( - __isl_keep isl_pw_aff *pwaff); - void *isl_pw_aff_free(__isl_take isl_pw_aff *pwaff); + isl_bool isl_basic_map_can_zip( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_can_zip(__isl_keep isl_map *map); -A (rational) bound on a dimension can be extracted from an C -using the following function. The constraint is required to have -a non-zero coefficient for the specified dimension. +Check whether the product of domain and range of the given relation +can be computed, +i.e., whether both domain and range are nested relations. - #include - __isl_give isl_aff *isl_constraint_get_bound( - __isl_keep isl_constraint *constraint, - enum isl_dim_type type, int pos); +=item * Currying -The entire affine expression of the constraint can also be extracted -using the following function. + isl_bool isl_basic_map_can_curry( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_can_curry(__isl_keep isl_map *map); - #include - __isl_give isl_aff *isl_constraint_get_aff( - __isl_keep isl_constraint *constraint); +Check whether the domain of the (basic) relation is a wrapped relation. -Conversely, an equality constraint equating -the affine expression to zero or an inequality constraint enforcing -the affine expression to be non-negative, can be constructed using + isl_bool isl_basic_map_can_uncurry( + __isl_keep isl_basic_map *bmap); + isl_bool isl_map_can_uncurry(__isl_keep isl_map *map); - __isl_give isl_constraint *isl_equality_from_aff( - __isl_take isl_aff *aff); - __isl_give isl_constraint *isl_inequality_from_aff( - __isl_take isl_aff *aff); +Check whether the range of the (basic) relation is a wrapped relation. -The expression can be inspected using +=item * Special Values #include - isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff); - int isl_aff_dim(__isl_keep isl_aff *aff, - enum isl_dim_type type); - __isl_give isl_local_space *isl_aff_get_domain_local_space( - __isl_keep isl_aff *aff); - __isl_give isl_local_space *isl_aff_get_local_space( - __isl_keep isl_aff *aff); - const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, - enum isl_dim_type type, unsigned pos); - const char *isl_pw_aff_get_dim_name( - __isl_keep isl_pw_aff *pa, - enum isl_dim_type type, unsigned pos); - int isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, - enum isl_dim_type type, unsigned pos); - __isl_give isl_id *isl_pw_aff_get_dim_id( - __isl_keep isl_pw_aff *pa, - enum isl_dim_type type, unsigned pos); - __isl_give isl_id *isl_pw_aff_get_tuple_id( - __isl_keep isl_pw_aff *pa, - enum isl_dim_type type); - int isl_aff_get_constant(__isl_keep isl_aff *aff, - isl_int *v); - __isl_give isl_val *isl_aff_get_constant_val( - __isl_keep isl_aff *aff); - int isl_aff_get_coefficient(__isl_keep isl_aff *aff, - enum isl_dim_type type, int pos, isl_int *v); - __isl_give isl_val *isl_aff_get_coefficient_val( - __isl_keep isl_aff *aff, - enum isl_dim_type type, int pos); - int isl_aff_get_denominator(__isl_keep isl_aff *aff, - isl_int *v); - __isl_give isl_val *isl_aff_get_denominator_val( + isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff); + isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); + +Check whether the given expression is a constant. + + #include + isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff); + isl_bool isl_pw_aff_involves_nan( + __isl_keep isl_pw_aff *pa); + + #include + isl_bool isl_qpolynomial_fold_is_nan( + __isl_keep isl_qpolynomial_fold *fold); + +Check whether the given expression is equal to or involves NaN. + + #include + isl_bool isl_aff_plain_is_zero( __isl_keep isl_aff *aff); - __isl_give isl_aff *isl_aff_get_div( - __isl_keep isl_aff *aff, int pos); - int isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); - int isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff, - int (*fn)(__isl_take isl_set *set, - __isl_take isl_aff *aff, - void *user), void *user); +Check whether the affine expression is obviously zero. - int isl_aff_is_cst(__isl_keep isl_aff *aff); - int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); +=back - int isl_aff_involves_dims(__isl_keep isl_aff *aff, - enum isl_dim_type type, unsigned first, unsigned n); - int isl_pw_aff_involves_dims(__isl_keep isl_pw_aff *pwaff, - enum isl_dim_type type, unsigned first, unsigned n); +=head3 Binary Properties - isl_ctx *isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pwaff); - unsigned isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff, - enum isl_dim_type type); - int isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); +=over -It can be modified using +=item * Equality - #include - __isl_give isl_pw_aff *isl_pw_aff_set_tuple_id( - __isl_take isl_pw_aff *pwaff, - enum isl_dim_type type, __isl_take isl_id *id); - __isl_give isl_aff *isl_aff_set_dim_name( - __isl_take isl_aff *aff, enum isl_dim_type type, - unsigned pos, const char *s); - __isl_give isl_aff *isl_aff_set_dim_id( - __isl_take isl_aff *aff, enum isl_dim_type type, - unsigned pos, __isl_take isl_id *id); - __isl_give isl_pw_aff *isl_pw_aff_set_dim_id( - __isl_take isl_pw_aff *pma, - enum isl_dim_type type, unsigned pos, - __isl_take isl_id *id); - __isl_give isl_aff *isl_aff_set_constant( - __isl_take isl_aff *aff, isl_int v); - __isl_give isl_aff *isl_aff_set_constant_si( - __isl_take isl_aff *aff, int v); - __isl_give isl_aff *isl_aff_set_constant_val( - __isl_take isl_aff *aff, __isl_take isl_val *v); - __isl_give isl_aff *isl_aff_set_coefficient( - __isl_take isl_aff *aff, - enum isl_dim_type type, int pos, isl_int v); - __isl_give isl_aff *isl_aff_set_coefficient_si( - __isl_take isl_aff *aff, - enum isl_dim_type type, int pos, int v); - __isl_give isl_aff *isl_aff_set_coefficient_val( - __isl_take isl_aff *aff, - enum isl_dim_type type, int pos, - __isl_take isl_val *v); - __isl_give isl_aff *isl_aff_set_denominator( - __isl_take isl_aff *aff, isl_int v); +The following functions check whether two objects +represent the same set, relation or function. +The C variants only return true if the objects +are obviously the same. That is, they may return false +even if the objects are the same, but they will never +return true if the objects are not the same. - __isl_give isl_aff *isl_aff_add_constant( - __isl_take isl_aff *aff, isl_int v); - __isl_give isl_aff *isl_aff_add_constant_si( - __isl_take isl_aff *aff, int v); - __isl_give isl_aff *isl_aff_add_constant_val( - __isl_take isl_aff *aff, __isl_take isl_val *v); - __isl_give isl_aff *isl_aff_add_constant_num( - __isl_take isl_aff *aff, isl_int v); - __isl_give isl_aff *isl_aff_add_constant_num_si( - __isl_take isl_aff *aff, int v); - __isl_give isl_aff *isl_aff_add_coefficient( - __isl_take isl_aff *aff, - enum isl_dim_type type, int pos, isl_int v); - __isl_give isl_aff *isl_aff_add_coefficient_si( - __isl_take isl_aff *aff, - enum isl_dim_type type, int pos, int v); - __isl_give isl_aff *isl_aff_add_coefficient_val( - __isl_take isl_aff *aff, - enum isl_dim_type type, int pos, - __isl_take isl_val *v); + #include + isl_bool isl_basic_set_plain_is_equal( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_basic_set_is_equal( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_set_plain_is_equal( + __isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_set_is_equal(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); - __isl_give isl_aff *isl_aff_insert_dims( - __isl_take isl_aff *aff, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_pw_aff *isl_pw_aff_insert_dims( - __isl_take isl_pw_aff *pwaff, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_aff *isl_aff_add_dims( - __isl_take isl_aff *aff, - enum isl_dim_type type, unsigned n); - __isl_give isl_pw_aff *isl_pw_aff_add_dims( - __isl_take isl_pw_aff *pwaff, - enum isl_dim_type type, unsigned n); - __isl_give isl_aff *isl_aff_drop_dims( - __isl_take isl_aff *aff, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_pw_aff *isl_pw_aff_drop_dims( - __isl_take isl_pw_aff *pwaff, - enum isl_dim_type type, unsigned first, unsigned n); + #include + isl_bool isl_basic_map_is_equal( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_map_is_equal(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); + isl_bool isl_map_plain_is_equal( + __isl_keep isl_map *map1, + __isl_keep isl_map *map2); -Note that C, C, -C and C -set the I of the constant or coefficient, while -C and C set -the constant or coefficient as a whole. -The C and C functions add an integer -or rational value to -the possibly rational constant or coefficient. -The C functions add an integer value to -the numerator. + #include + isl_bool isl_union_set_is_equal( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); -To check whether an affine expressions is obviously zero -or obviously equal to some other affine expression, use + #include + isl_bool isl_union_map_is_equal( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); #include - int isl_aff_plain_is_zero(__isl_keep isl_aff *aff); - int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, + isl_bool isl_aff_plain_is_equal( + __isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2); - int isl_pw_aff_plain_is_equal( + isl_bool isl_multi_aff_plain_is_equal( + __isl_keep isl_multi_aff *maff1, + __isl_keep isl_multi_aff *maff2); + isl_bool isl_pw_aff_plain_is_equal( __isl_keep isl_pw_aff *pwaff1, __isl_keep isl_pw_aff *pwaff2); + isl_bool isl_pw_multi_aff_plain_is_equal( + __isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); + isl_bool isl_multi_pw_aff_plain_is_equal( + __isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2); + isl_bool isl_multi_pw_aff_is_equal( + __isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2); + isl_bool isl_union_pw_aff_plain_is_equal( + __isl_keep isl_union_pw_aff *upa1, + __isl_keep isl_union_pw_aff *upa2); + isl_bool isl_union_pw_multi_aff_plain_is_equal( + __isl_keep isl_union_pw_multi_aff *upma1, + __isl_keep isl_union_pw_multi_aff *upma2); + isl_bool isl_multi_union_pw_aff_plain_is_equal( + __isl_keep isl_multi_union_pw_aff *mupa1, + __isl_keep isl_multi_union_pw_aff *mupa2); -Operations include + #include + isl_bool isl_union_pw_qpolynomial_plain_is_equal( + __isl_keep isl_union_pw_qpolynomial *upwqp1, + __isl_keep isl_union_pw_qpolynomial *upwqp2); + isl_bool isl_union_pw_qpolynomial_fold_plain_is_equal( + __isl_keep isl_union_pw_qpolynomial_fold *upwf1, + __isl_keep isl_union_pw_qpolynomial_fold *upwf2); - #include - __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, - __isl_take isl_aff *aff2); - __isl_give isl_pw_aff *isl_pw_aff_add( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_pw_aff *isl_pw_aff_min( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_pw_aff *isl_pw_aff_max( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, - __isl_take isl_aff *aff2); - __isl_give isl_pw_aff *isl_pw_aff_sub( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff); - __isl_give isl_pw_aff *isl_pw_aff_neg( - __isl_take isl_pw_aff *pwaff); - __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff); - __isl_give isl_pw_aff *isl_pw_aff_ceil( - __isl_take isl_pw_aff *pwaff); - __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff); - __isl_give isl_pw_aff *isl_pw_aff_floor( - __isl_take isl_pw_aff *pwaff); - __isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, - isl_int mod); - __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, - __isl_take isl_val *mod); - __isl_give isl_pw_aff *isl_pw_aff_mod( - __isl_take isl_pw_aff *pwaff, isl_int mod); - __isl_give isl_pw_aff *isl_pw_aff_mod_val( - __isl_take isl_pw_aff *pa, - __isl_take isl_val *mod); - __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, - isl_int f); - __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, - __isl_take isl_val *v); - __isl_give isl_pw_aff *isl_pw_aff_scale( - __isl_take isl_pw_aff *pwaff, isl_int f); - __isl_give isl_pw_aff *isl_pw_aff_scale_val( - __isl_take isl_pw_aff *pa, __isl_take isl_val *v); - __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, - isl_int f); - __isl_give isl_aff *isl_aff_scale_down_ui( - __isl_take isl_aff *aff, unsigned f); - __isl_give isl_aff *isl_aff_scale_down_val( - __isl_take isl_aff *aff, __isl_take isl_val *v); - __isl_give isl_pw_aff *isl_pw_aff_scale_down( - __isl_take isl_pw_aff *pwaff, isl_int f); - __isl_give isl_pw_aff *isl_pw_aff_scale_down_val( - __isl_take isl_pw_aff *pa, - __isl_take isl_val *f); +=item * Disjointness - __isl_give isl_pw_aff *isl_pw_aff_list_min( - __isl_take isl_pw_aff_list *list); - __isl_give isl_pw_aff *isl_pw_aff_list_max( - __isl_take isl_pw_aff_list *list); + #include + isl_bool isl_basic_set_is_disjoint( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_set_plain_is_disjoint( + __isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); - __isl_give isl_pw_aff *isl_pw_aff_coalesce( - __isl_take isl_pw_aff *pwqp); + #include + isl_bool isl_basic_map_is_disjoint( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); - __isl_give isl_aff *isl_aff_align_params( - __isl_take isl_aff *aff, - __isl_take isl_space *model); - __isl_give isl_pw_aff *isl_pw_aff_align_params( - __isl_take isl_pw_aff *pwaff, - __isl_take isl_space *model); + #include + isl_bool isl_union_set_is_disjoint( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); - __isl_give isl_aff *isl_aff_project_domain_on_params( - __isl_take isl_aff *aff); + #include + isl_bool isl_union_map_is_disjoint( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); - __isl_give isl_aff *isl_aff_gist_params( - __isl_take isl_aff *aff, - __isl_take isl_set *context); - __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, - __isl_take isl_set *context); - __isl_give isl_pw_aff *isl_pw_aff_gist_params( - __isl_take isl_pw_aff *pwaff, - __isl_take isl_set *context); - __isl_give isl_pw_aff *isl_pw_aff_gist( - __isl_take isl_pw_aff *pwaff, - __isl_take isl_set *context); +=item * Subset - __isl_give isl_set *isl_pw_aff_domain( - __isl_take isl_pw_aff *pwaff); - __isl_give isl_pw_aff *isl_pw_aff_intersect_domain( - __isl_take isl_pw_aff *pa, - __isl_take isl_set *set); - __isl_give isl_pw_aff *isl_pw_aff_intersect_params( - __isl_take isl_pw_aff *pa, - __isl_take isl_set *set); + isl_bool isl_basic_set_is_subset( + __isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); + isl_bool isl_set_is_subset(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_set_is_strict_subset( + __isl_keep isl_set *set1, + __isl_keep isl_set *set2); + isl_bool isl_union_set_is_subset( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + isl_bool isl_union_set_is_strict_subset( + __isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); + isl_bool isl_basic_map_is_subset( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_basic_map_is_strict_subset( + __isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); + isl_bool isl_map_is_subset( + __isl_keep isl_map *map1, + __isl_keep isl_map *map2); + isl_bool isl_map_is_strict_subset( + __isl_keep isl_map *map1, + __isl_keep isl_map *map2); + isl_bool isl_union_map_is_subset( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); + isl_bool isl_union_map_is_strict_subset( + __isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); - __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1, - __isl_take isl_aff *aff2); - __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1, - __isl_take isl_aff *aff2); - __isl_give isl_pw_aff *isl_pw_aff_mul( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_pw_aff *isl_pw_aff_div( - __isl_take isl_pw_aff *pa1, - __isl_take isl_pw_aff *pa2); - __isl_give isl_pw_aff *isl_pw_aff_tdiv_q( - __isl_take isl_pw_aff *pa1, - __isl_take isl_pw_aff *pa2); - __isl_give isl_pw_aff *isl_pw_aff_tdiv_r( - __isl_take isl_pw_aff *pa1, - __isl_take isl_pw_aff *pa2); +Check whether the first argument is a (strict) subset of the +second argument. -When multiplying two affine expressions, at least one of the two needs -to be a constant. Similarly, when dividing an affine expression by another, -the second expression needs to be a constant. -C computes the quotient of an integer division with -rounding towards zero. C computes the corresponding -remainder. - - #include - __isl_give isl_aff *isl_aff_pullback_multi_aff( - __isl_take isl_aff *aff, - __isl_take isl_multi_aff *ma); - __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_aff( - __isl_take isl_pw_aff *pa, - __isl_take isl_multi_aff *ma); - __isl_give isl_pw_aff *isl_pw_aff_pullback_pw_multi_aff( - __isl_take isl_pw_aff *pa, - __isl_take isl_pw_multi_aff *pma); +=item * Order -These functions precompose the input expression by the given -C or C. In other words, -the C or C is plugged -into the (piecewise) affine expression. -Objects of type C are described in -L. +Every comparison function returns a negative value if the first +argument is considered smaller than the second, a positive value +if the first argument is considered greater and zero if the two +constraints are considered the same by the comparison criterion. - #include - __isl_give isl_basic_set *isl_aff_zero_basic_set( - __isl_take isl_aff *aff); - __isl_give isl_basic_set *isl_aff_neg_basic_set( - __isl_take isl_aff *aff); - __isl_give isl_basic_set *isl_aff_le_basic_set( - __isl_take isl_aff *aff1, __isl_take isl_aff *aff2); - __isl_give isl_basic_set *isl_aff_ge_basic_set( - __isl_take isl_aff *aff1, __isl_take isl_aff *aff2); - __isl_give isl_set *isl_pw_aff_eq_set( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_set *isl_pw_aff_ne_set( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_set *isl_pw_aff_le_set( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_set *isl_pw_aff_lt_set( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_set *isl_pw_aff_ge_set( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_set *isl_pw_aff_gt_set( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); + #include + int isl_constraint_plain_cmp( + __isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); - __isl_give isl_set *isl_pw_aff_list_eq_set( - __isl_take isl_pw_aff_list *list1, - __isl_take isl_pw_aff_list *list2); - __isl_give isl_set *isl_pw_aff_list_ne_set( - __isl_take isl_pw_aff_list *list1, - __isl_take isl_pw_aff_list *list2); - __isl_give isl_set *isl_pw_aff_list_le_set( - __isl_take isl_pw_aff_list *list1, - __isl_take isl_pw_aff_list *list2); - __isl_give isl_set *isl_pw_aff_list_lt_set( - __isl_take isl_pw_aff_list *list1, - __isl_take isl_pw_aff_list *list2); - __isl_give isl_set *isl_pw_aff_list_ge_set( - __isl_take isl_pw_aff_list *list1, - __isl_take isl_pw_aff_list *list2); - __isl_give isl_set *isl_pw_aff_list_gt_set( - __isl_take isl_pw_aff_list *list1, - __isl_take isl_pw_aff_list *list2); +This function is useful for sorting Cs. +The order depends on the internal representation of the inputs. +The order is fixed over different calls to the function (assuming +the internal representation of the inputs has not changed), but may +change over different versions of C. -The function C returns a basic set -containing those elements in the domain space -of C where C is negative. -The function C returns a basic set -containing those elements in the shared space -of C and C where C is greater than or equal to C. -The function C returns a set -containing those elements in the shared domain -of C and C where C is greater than or equal to C. -The functions operating on C apply the corresponding -C function to each pair of elements in the two lists. + #include + int isl_constraint_cmp_last_non_zero( + __isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); + +This function can be used to sort constraints that live in the same +local space. Constraints that involve ``earlier'' dimensions or +that have a smaller coefficient for the shared latest dimension +are considered smaller than other constraints. +This function only defines a B order. - #include - __isl_give isl_set *isl_pw_aff_nonneg_set( - __isl_take isl_pw_aff *pwaff); - __isl_give isl_set *isl_pw_aff_zero_set( - __isl_take isl_pw_aff *pwaff); - __isl_give isl_set *isl_pw_aff_non_zero_set( - __isl_take isl_pw_aff *pwaff); + #include + int isl_set_plain_cmp(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); -The function C returns a set -containing those elements in the domain -of C where C is non-negative. +This function is useful for sorting Cs. +The order depends on the internal representation of the inputs. +The order is fixed over different calls to the function (assuming +the internal representation of the inputs has not changed), but may +change over different versions of C. #include - __isl_give isl_pw_aff *isl_pw_aff_cond( - __isl_take isl_pw_aff *cond, - __isl_take isl_pw_aff *pwaff_true, - __isl_take isl_pw_aff *pwaff_false); - -The function C performs a conditional operator -and returns an expression that is equal to C -for elements where C is non-zero and equal to C for elements -where C is zero. + int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2); - #include - __isl_give isl_pw_aff *isl_pw_aff_union_min( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_pw_aff *isl_pw_aff_union_max( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); - __isl_give isl_pw_aff *isl_pw_aff_union_add( - __isl_take isl_pw_aff *pwaff1, - __isl_take isl_pw_aff *pwaff2); +The function C can be used to sort +Cs. The order is not strictly defined. +The current order sorts expressions that only involve +earlier dimensions before those that involve later dimensions. -The function C computes a piecewise quasi-affine -expression with a domain that is the union of those of C and -C and such that on each cell, the quasi-affine expression is -the maximum of those of C and C. If only one of -C or C is defined on a given cell, then the -associated expression is the defined one. +=back -An expression can be read from input using +=head2 Unary Operations - #include - __isl_give isl_aff *isl_aff_read_from_str( - isl_ctx *ctx, const char *str); - __isl_give isl_pw_aff *isl_pw_aff_read_from_str( - isl_ctx *ctx, const char *str); +=over -An expression can be printed using +=item * Complement - #include - __isl_give isl_printer *isl_printer_print_aff( - __isl_take isl_printer *p, __isl_keep isl_aff *aff); + __isl_give isl_set *isl_set_complement( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_complement( + __isl_take isl_map *map); - __isl_give isl_printer *isl_printer_print_pw_aff( - __isl_take isl_printer *p, - __isl_keep isl_pw_aff *pwaff); +=item * Inverse map -=head2 Piecewise Multiple Quasi Affine Expressions + #include + __isl_give isl_space *isl_space_reverse( + __isl_take isl_space *space); -An C object represents a sequence of -zero or more affine expressions, all defined on the same domain space. -Similarly, an C object represents a sequence of -zero or more piecewise affine expressions. - -An C can be constructed from a single -C or an C using the -following functions. Similarly for C. + #include + __isl_give isl_basic_map *isl_basic_map_reverse( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_reverse( + __isl_take isl_map *map); - #include - __isl_give isl_multi_aff *isl_multi_aff_from_aff( - __isl_take isl_aff *aff); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff( - __isl_take isl_pw_aff *pa); - __isl_give isl_multi_aff *isl_multi_aff_from_aff_list( - __isl_take isl_space *space, - __isl_take isl_aff_list *list); + #include + __isl_give isl_union_map *isl_union_map_reverse( + __isl_take isl_union_map *umap); -An empty piecewise multiple quasi affine expression (one with no cells), -the zero piecewise multiple quasi affine expression (with value zero -for each output dimension), -a piecewise multiple quasi affine expression with a single cell (with -either a universe or a specified domain) or -a zero-dimensional piecewise multiple quasi affine expression -on a given domain -can be created using the following functions. +=item * Projection - #include - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty( - __isl_take isl_space *space); - __isl_give isl_multi_aff *isl_multi_aff_zero( - __isl_take isl_space *space); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_zero( - __isl_take isl_space *space); - __isl_give isl_multi_aff *isl_multi_aff_identity( + #include + __isl_give isl_space *isl_space_domain( __isl_take isl_space *space); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( + __isl_give isl_space *isl_space_range( __isl_take isl_space *space); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity( + __isl_give isl_space *isl_space_params( __isl_take isl_space *space); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_from_multi_aff( - __isl_take isl_multi_aff *ma); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc( - __isl_take isl_set *set, - __isl_take isl_multi_aff *maff); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( - __isl_take isl_set *set); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_empty( - __isl_take isl_space *space); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_add_pw_multi_aff( - __isl_take isl_union_pw_multi_aff *upma, - __isl_take isl_pw_multi_aff *pma); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_from_domain( - __isl_take isl_union_set *uset); + #include + __isl_give isl_local_space *isl_local_space_domain( + __isl_take isl_local_space *ls); + __isl_give isl_local_space *isl_local_space_range( + __isl_take isl_local_space *ls); -A piecewise multiple quasi affine expression can also be initialized -from an C or C, provided the C is a singleton -and the C is single-valued. -In case of a conversion from an C or an C -to an C, these properties need to hold in each space. + #include + __isl_give isl_basic_set *isl_basic_set_project_out( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_basic_set *isl_basic_set_params( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_params(__isl_take isl_set *set); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set( - __isl_take isl_set *set); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map( + #include + __isl_give isl_basic_map *isl_basic_map_project_out( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_basic_set *isl_basic_map_domain( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_set *isl_basic_map_range( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_map_params(__isl_take isl_map *map); + __isl_give isl_set *isl_map_domain( + __isl_take isl_map *bmap); + __isl_give isl_set *isl_map_range( __isl_take isl_map *map); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_from_union_set( + #include + __isl_give isl_union_set *isl_union_set_project_out( + __isl_take isl_union_set *uset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set *isl_union_set_params( __isl_take isl_union_set *uset); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_from_union_map( + +The function C can only project out +parameters. + + #include + __isl_give isl_union_map *isl_union_map_project_out( + __isl_take isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_set *isl_union_map_params( + __isl_take isl_union_map *umap); + __isl_give isl_union_set *isl_union_map_domain( + __isl_take isl_union_map *umap); + __isl_give isl_union_set *isl_union_map_range( __isl_take isl_union_map *umap); -Multiple quasi affine expressions can be copied and freed using +The function C can only project out +parameters. #include - __isl_give isl_multi_aff *isl_multi_aff_copy( - __isl_keep isl_multi_aff *maff); - void *isl_multi_aff_free(__isl_take isl_multi_aff *maff); - - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( - __isl_keep isl_pw_multi_aff *pma); - void *isl_pw_multi_aff_free( + __isl_give isl_aff *isl_aff_project_domain_on_params( + __isl_take isl_aff *aff); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_project_domain_on_params( __isl_take isl_pw_multi_aff *pma); - - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_copy( - __isl_keep isl_union_pw_multi_aff *upma); - void *isl_union_pw_multi_aff_free( - __isl_take isl_union_pw_multi_aff *upma); - - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_copy( - __isl_keep isl_multi_pw_aff *mpa); - void *isl_multi_pw_aff_free( + __isl_give isl_set *isl_pw_aff_domain( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_multi_aff_domain( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_multi_pw_aff_domain( __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_set *isl_union_pw_aff_domain( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_set *isl_union_pw_multi_aff_domain( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_set * + isl_multi_union_pw_aff_domain( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_set *isl_pw_aff_params( + __isl_take isl_pw_aff *pwa); -The expression can be inspected using +The function C requires its +input to have at least one set dimension. - #include - isl_ctx *isl_multi_aff_get_ctx( - __isl_keep isl_multi_aff *maff); - isl_ctx *isl_pw_multi_aff_get_ctx( - __isl_keep isl_pw_multi_aff *pma); - isl_ctx *isl_union_pw_multi_aff_get_ctx( - __isl_keep isl_union_pw_multi_aff *upma); - isl_ctx *isl_multi_pw_aff_get_ctx( - __isl_keep isl_multi_pw_aff *mpa); - unsigned isl_multi_aff_dim(__isl_keep isl_multi_aff *maff, - enum isl_dim_type type); - unsigned isl_pw_multi_aff_dim( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type); - unsigned isl_multi_pw_aff_dim( - __isl_keep isl_multi_pw_aff *mpa, - enum isl_dim_type type); - __isl_give isl_aff *isl_multi_aff_get_aff( - __isl_keep isl_multi_aff *multi, int pos); - __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( - __isl_keep isl_pw_multi_aff *pma, int pos); - __isl_give isl_pw_aff *isl_multi_pw_aff_get_pw_aff( - __isl_keep isl_multi_pw_aff *mpa, int pos); - const char *isl_pw_multi_aff_get_dim_name( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type, unsigned pos); - __isl_give isl_id *isl_pw_multi_aff_get_dim_id( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type, unsigned pos); - const char *isl_multi_aff_get_tuple_name( - __isl_keep isl_multi_aff *multi, - enum isl_dim_type type); - int isl_pw_multi_aff_has_tuple_name( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type); - const char *isl_pw_multi_aff_get_tuple_name( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type); - int isl_pw_multi_aff_has_tuple_id( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type); - __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( - __isl_keep isl_pw_multi_aff *pma, - enum isl_dim_type type); + #include + __isl_give isl_qpolynomial * + isl_qpolynomial_project_domain_on_params( + __isl_take isl_qpolynomial *qp); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_project_domain_on_params( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_project_domain_on_params( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_set *isl_pw_qpolynomial_domain( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_set *isl_union_pw_qpolynomial_fold_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + __isl_give isl_union_set *isl_union_pw_qpolynomial_domain( + __isl_take isl_union_pw_qpolynomial *upwqp); - int isl_pw_multi_aff_foreach_piece( - __isl_keep isl_pw_multi_aff *pma, - int (*fn)(__isl_take isl_set *set, - __isl_take isl_multi_aff *maff, - void *user), void *user); + #include + __isl_give isl_space *isl_space_domain_map( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_map( + __isl_take isl_space *space); - int isl_union_pw_multi_aff_foreach_pw_multi_aff( - __isl_keep isl_union_pw_multi_aff *upma, - int (*fn)(__isl_take isl_pw_multi_aff *pma, - void *user), void *user); + #include + __isl_give isl_map *isl_set_wrapped_domain_map( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_basic_map_domain_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_basic_map_range_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map); + __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map); -It can be modified using + #include + __isl_give isl_union_map *isl_union_map_domain_map( + __isl_take isl_union_map *umap); + __isl_give isl_union_pw_multi_aff * + isl_union_map_domain_map_union_pw_multi_aff( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_range_map( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_set_wrapped_domain_map( + __isl_take isl_union_set *uset); - #include - __isl_give isl_multi_aff *isl_multi_aff_set_aff( - __isl_take isl_multi_aff *multi, int pos, - __isl_take isl_aff *aff); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( - __isl_take isl_pw_multi_aff *pma, unsigned pos, - __isl_take isl_pw_aff *pa); - __isl_give isl_multi_aff *isl_multi_aff_set_dim_name( - __isl_take isl_multi_aff *maff, - enum isl_dim_type type, unsigned pos, const char *s); - __isl_give isl_multi_aff *isl_multi_aff_set_tuple_name( - __isl_take isl_multi_aff *maff, - enum isl_dim_type type, const char *s); - __isl_give isl_multi_aff *isl_multi_aff_set_tuple_id( - __isl_take isl_multi_aff *maff, - enum isl_dim_type type, __isl_take isl_id *id); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( - __isl_take isl_pw_multi_aff *pma, - enum isl_dim_type type, __isl_take isl_id *id); +The functions above construct a (basic, regular or union) relation +that maps (a wrapped version of) the input relation to its domain or range. +C maps the input set to the domain +of its wrapped relation. - __isl_give isl_multi_pw_aff * - isl_multi_pw_aff_set_dim_name( - __isl_take isl_multi_pw_aff *mpa, - enum isl_dim_type type, unsigned pos, const char *s); - __isl_give isl_multi_pw_aff * - isl_multi_pw_aff_set_tuple_name( - __isl_take isl_multi_pw_aff *mpa, - enum isl_dim_type type, const char *s); +=item * Elimination - __isl_give isl_multi_aff *isl_multi_aff_insert_dims( - __isl_take isl_multi_aff *ma, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_multi_aff *isl_multi_aff_add_dims( - __isl_take isl_multi_aff *ma, - enum isl_dim_type type, unsigned n); - __isl_give isl_multi_aff *isl_multi_aff_drop_dims( - __isl_take isl_multi_aff *maff, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_dims( - __isl_take isl_pw_multi_aff *pma, - enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_basic_set *isl_basic_set_eliminate( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set *isl_set_eliminate( + __isl_take isl_set *set, enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_basic_map *isl_basic_map_eliminate( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_map *isl_map_eliminate( + __isl_take isl_map *map, enum isl_dim_type type, + unsigned first, unsigned n); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_insert_dims( - __isl_take isl_multi_pw_aff *mpa, - enum isl_dim_type type, unsigned first, unsigned n); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_add_dims( - __isl_take isl_multi_pw_aff *mpa, - enum isl_dim_type type, unsigned n); +Eliminate the coefficients for the given dimensions from the constraints, +without removing the dimensions. -To check whether two multiple affine expressions are -obviously equal to each other, use +=item * Constructing a set from a parameter domain - int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1, - __isl_keep isl_multi_aff *maff2); - int isl_pw_multi_aff_plain_is_equal( - __isl_keep isl_pw_multi_aff *pma1, - __isl_keep isl_pw_multi_aff *pma2); +A zero-dimensional space or (basic) set can be constructed +on a given parameter domain using the following functions. -Operations include + #include + __isl_give isl_space *isl_space_set_from_params( + __isl_take isl_space *space); - #include - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_multi_aff *isl_multi_aff_add( - __isl_take isl_multi_aff *maff1, - __isl_take isl_multi_aff *maff2); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add( - __isl_take isl_union_pw_multi_aff *upma1, - __isl_take isl_union_pw_multi_aff *upma2); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_multi_aff *isl_multi_aff_sub( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_sub( - __isl_take isl_union_pw_multi_aff *upma1, - __isl_take isl_union_pw_multi_aff *upma2); + #include + __isl_give isl_basic_set *isl_basic_set_from_params( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_from_params( + __isl_take isl_set *set); -C subtracts the second argument from the first. +=item * Constructing a relation from a set - __isl_give isl_multi_aff *isl_multi_aff_scale( - __isl_take isl_multi_aff *maff, - isl_int f); - __isl_give isl_multi_aff *isl_multi_aff_scale_val( - __isl_take isl_multi_aff *ma, - __isl_take isl_val *v); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_val( - __isl_take isl_pw_multi_aff *pma, - __isl_take isl_val *v); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_val( - __isl_take isl_multi_pw_aff *mpa, - __isl_take isl_val *v); - __isl_give isl_multi_aff *isl_multi_aff_scale_multi_val( - __isl_take isl_multi_aff *ma, - __isl_take isl_multi_val *mv); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_scale_multi_val( - __isl_take isl_pw_multi_aff *pma, - __isl_take isl_multi_val *mv); - __isl_give isl_multi_pw_aff * - isl_multi_pw_aff_scale_multi_val( - __isl_take isl_multi_pw_aff *mpa, - __isl_take isl_multi_val *mv); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_scale_multi_val( - __isl_take isl_union_pw_multi_aff *upma, - __isl_take isl_multi_val *mv); +Create a relation with the given set as domain or range. +The range or domain of the created relation is a zero-dimensional +flat anonymous space. -C scales the elements of C -by the corresponding elements of C. + #include + __isl_give isl_space *isl_space_from_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_from_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_map_from_set( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_map_from_domain_and_range( + __isl_take isl_space *domain, + __isl_take isl_space *range); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_params( - __isl_take isl_pw_multi_aff *pma, + #include + __isl_give isl_local_space *isl_local_space_from_domain( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_map *isl_map_from_domain( __isl_take isl_set *set); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain( - __isl_take isl_pw_multi_aff *pma, + __isl_give isl_map *isl_map_from_range( + __isl_take isl_set *set); + + #include + __isl_give isl_multi_val *isl_multi_val_from_range( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff *isl_multi_aff_from_range( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_from_range( + __isl_take isl_pw_aff *pwa); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_range( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( __isl_take isl_set *set); __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_intersect_domain( - __isl_take isl_union_pw_multi_aff *upma, + isl_union_pw_multi_aff_from_domain( __isl_take isl_union_set *uset); - __isl_give isl_multi_aff *isl_multi_aff_lift( - __isl_take isl_multi_aff *maff, - __isl_give isl_local_space **ls); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_coalesce( - __isl_take isl_pw_multi_aff *pma); - __isl_give isl_multi_aff *isl_multi_aff_align_params( - __isl_take isl_multi_aff *multi, - __isl_take isl_space *model); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_align_params( - __isl_take isl_pw_multi_aff *pma, - __isl_take isl_space *model); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_project_domain_on_params( - __isl_take isl_pw_multi_aff *pma); - __isl_give isl_multi_aff *isl_multi_aff_gist_params( - __isl_take isl_multi_aff *maff, - __isl_take isl_set *context); - __isl_give isl_multi_aff *isl_multi_aff_gist( - __isl_take isl_multi_aff *maff, - __isl_take isl_set *context); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist_params( - __isl_take isl_pw_multi_aff *pma, - __isl_take isl_set *set); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist( - __isl_take isl_pw_multi_aff *pma, - __isl_take isl_set *set); - __isl_give isl_set *isl_pw_multi_aff_domain( - __isl_take isl_pw_multi_aff *pma); - __isl_give isl_union_set *isl_union_pw_multi_aff_domain( - __isl_take isl_union_pw_multi_aff *upma); - __isl_give isl_multi_aff *isl_multi_aff_range_splice( - __isl_take isl_multi_aff *ma1, unsigned pos, - __isl_take isl_multi_aff *ma2); - __isl_give isl_multi_aff *isl_multi_aff_splice( - __isl_take isl_multi_aff *ma1, - unsigned in_pos, unsigned out_pos, - __isl_take isl_multi_aff *ma2); - __isl_give isl_multi_aff *isl_multi_aff_range_product( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - __isl_give isl_multi_aff *isl_multi_aff_flat_range_product( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - __isl_give isl_multi_aff *isl_multi_aff_product( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_range_product( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_flat_range_product( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_flat_range_product( - __isl_take isl_union_pw_multi_aff *upma1, - __isl_take isl_union_pw_multi_aff *upma2); - __isl_give isl_multi_pw_aff * - isl_multi_pw_aff_range_splice( - __isl_take isl_multi_pw_aff *mpa1, unsigned pos, - __isl_take isl_multi_pw_aff *mpa2); - __isl_give isl_multi_pw_aff *isl_multi_pw_aff_splice( - __isl_take isl_multi_pw_aff *mpa1, - unsigned in_pos, unsigned out_pos, - __isl_take isl_multi_pw_aff *mpa2); - __isl_give isl_multi_pw_aff * - isl_multi_pw_aff_range_product( - __isl_take isl_multi_pw_aff *mpa1, - __isl_take isl_multi_pw_aff *mpa2); - __isl_give isl_multi_pw_aff * - isl_multi_pw_aff_flat_range_product( - __isl_take isl_multi_pw_aff *mpa1, - __isl_take isl_multi_pw_aff *mpa2); -If the C argument of C is not C, -then it is assigned the local space that lies at the basis of -the lifting applied. +=item * Slicing + + #include + __isl_give isl_basic_set *isl_basic_set_fix_si( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_basic_set *isl_basic_set_fix_val( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_fix_val( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + + #include + __isl_give isl_basic_map *isl_basic_map_fix_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_basic_map *isl_basic_map_fix_val( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); + __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_map *isl_map_fix_val( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *v); #include - __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_pullback_multi_aff( + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_fix_si( __isl_take isl_pw_multi_aff *pma, - __isl_take isl_multi_aff *ma); - __isl_give isl_pw_multi_aff * - isl_pw_multi_aff_pullback_pw_multi_aff( - __isl_take isl_pw_multi_aff *pma1, - __isl_take isl_pw_multi_aff *pma2); + enum isl_dim_type type, unsigned pos, int value); -The function C precomposes C by C. -In other words, C is plugged -into C. + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_val( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, unsigned n, + __isl_take isl_val *v); - __isl_give isl_set *isl_multi_aff_lex_le_set( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - __isl_give isl_set *isl_multi_aff_lex_ge_set( - __isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); +Intersect the set, relation or function domain +with the hyperplane where the given +dimension has the fixed given value. -The function C returns a set -containing those elements in the shared domain space -where C is lexicographically smaller than or -equal to C. + __isl_give isl_basic_map *isl_basic_map_lower_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_basic_map *isl_basic_map_upper_bound_si( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_lower_bound_si( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_lower_bound_val( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_map *isl_map_lower_bound_si( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_upper_bound_si( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, int value); + __isl_give isl_set *isl_set_upper_bound_val( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, + __isl_take isl_val *value); + __isl_give isl_map *isl_map_upper_bound_si( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, int value); -An expression can be read from input using +Intersect the set or relation with the half-space where the given +dimension has a value bounded by the fixed given integer value. - #include - __isl_give isl_multi_aff *isl_multi_aff_read_from_str( - isl_ctx *ctx, const char *str); - __isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str( - isl_ctx *ctx, const char *str); - __isl_give isl_union_pw_multi_aff * - isl_union_pw_multi_aff_read_from_str( - isl_ctx *ctx, const char *str); + __isl_give isl_set *isl_set_equate(__isl_take isl_set *set, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_basic_map *isl_basic_map_equate( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_equate(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); -An expression can be printed using +Intersect the set or relation with the hyperplane where the given +dimensions are equal to each other. - #include - __isl_give isl_printer *isl_printer_print_multi_aff( - __isl_take isl_printer *p, - __isl_keep isl_multi_aff *maff); - __isl_give isl_printer *isl_printer_print_pw_multi_aff( - __isl_take isl_printer *p, - __isl_keep isl_pw_multi_aff *pma); - __isl_give isl_printer *isl_printer_print_union_pw_multi_aff( - __isl_take isl_printer *p, - __isl_keep isl_union_pw_multi_aff *upma); - __isl_give isl_printer *isl_printer_print_multi_pw_aff( - __isl_take isl_printer *p, - __isl_keep isl_multi_pw_aff *mpa); + __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); -=head2 Points +Intersect the relation with the hyperplane where the given +dimensions have opposite values. -Points are elements of a set. They can be used to construct -simple sets (boxes) or they can be used to represent the -individual elements of a set. -The zero point (the origin) can be created using + __isl_give isl_map *isl_map_order_le( + __isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_basic_map *isl_basic_map_order_ge( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_order_ge( + __isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_basic_map *isl_basic_map_order_gt( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); + __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2); - __isl_give isl_point *isl_point_zero(__isl_take isl_space *space); +Intersect the relation with the half-space where the given +dimensions satisfy the given ordering. -The coordinates of a point can be inspected, set and changed -using +=item * Locus - int isl_point_get_coordinate(__isl_keep isl_point *pnt, - enum isl_dim_type type, int pos, isl_int *v); - __isl_give isl_val *isl_point_get_coordinate_val( - __isl_keep isl_point *pnt, - enum isl_dim_type type, int pos); - __isl_give isl_point *isl_point_set_coordinate( - __isl_take isl_point *pnt, - enum isl_dim_type type, int pos, isl_int v); - __isl_give isl_point *isl_point_set_coordinate_val( - __isl_take isl_point *pnt, - enum isl_dim_type type, int pos, - __isl_take isl_val *v); + #include + __isl_give isl_basic_set *isl_aff_zero_basic_set( + __isl_take isl_aff *aff); + __isl_give isl_basic_set *isl_aff_neg_basic_set( + __isl_take isl_aff *aff); + __isl_give isl_set *isl_pw_aff_pos_set( + __isl_take isl_pw_aff *pa); + __isl_give isl_set *isl_pw_aff_nonneg_set( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_aff_zero_set( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_set *isl_pw_aff_non_zero_set( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_union_set * + isl_union_pw_aff_zero_union_set( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_set * + isl_multi_union_pw_aff_zero_union_set( + __isl_take isl_multi_union_pw_aff *mupa); - __isl_give isl_point *isl_point_add_ui( - __isl_take isl_point *pnt, - enum isl_dim_type type, int pos, unsigned val); - __isl_give isl_point *isl_point_sub_ui( - __isl_take isl_point *pnt, - enum isl_dim_type type, int pos, unsigned val); +The function C returns a basic set +containing those elements in the domain space +of C where C is negative. +The function C returns a set +containing those elements in the domain +of C where C is non-negative. +The function C +returns a union set containing those elements +in the domains of its elements where they are all zero. -Other properties can be obtained using +=item * Identity - isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt); + __isl_give isl_map *isl_set_identity( + __isl_take isl_set *set); + __isl_give isl_union_map *isl_union_set_identity( + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_set_identity_union_pw_multi_aff( + __isl_take isl_union_set *uset); -Points can be copied or freed using +Construct an identity relation on the given (union) set. - __isl_give isl_point *isl_point_copy( - __isl_keep isl_point *pnt); - void isl_point_free(__isl_take isl_point *pnt); +=item * Function Extraction -A singleton set can be created from a point using +A piecewise quasi affine expression that is equal to 1 on a set +and 0 outside the set can be created using the following function. - __isl_give isl_basic_set *isl_basic_set_from_point( - __isl_take isl_point *pnt); - __isl_give isl_set *isl_set_from_point( - __isl_take isl_point *pnt); + #include + __isl_give isl_pw_aff *isl_set_indicator_function( + __isl_take isl_set *set); -and a box can be created from two opposite extremal points using +A piecewise multiple quasi affine expression can be extracted +from an C or C, provided the C is a singleton +and the C is single-valued. +In case of a conversion from an C +to an C, these properties need to hold +in each domain space. +A conversion to a C additionally +requires that the input is non-empty and involves only a single +range space. - __isl_give isl_basic_set *isl_basic_set_box_from_points( - __isl_take isl_point *pnt1, - __isl_take isl_point *pnt2); - __isl_give isl_set *isl_set_box_from_points( - __isl_take isl_point *pnt1, - __isl_take isl_point *pnt2); + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set( + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map( + __isl_take isl_map *map); -All elements of a B (union) set can be enumerated using -the following functions. + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_union_set( + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_from_union_map( + __isl_take isl_union_map *umap); - int isl_set_foreach_point(__isl_keep isl_set *set, - int (*fn)(__isl_take isl_point *pnt, void *user), - void *user); - int isl_union_set_foreach_point(__isl_keep isl_union_set *uset, - int (*fn)(__isl_take isl_point *pnt, void *user), - void *user); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_from_union_map( + __isl_take isl_union_map *umap); -The function C is called for each integer point in -C with as second argument the last argument of -the C call. The function C -should return C<0> on success and C<-1> on failure. -In the latter case, C will stop -enumerating and return C<-1> as well. -If the enumeration is performed successfully and to completion, -then C returns C<0>. +=item * Deltas -To obtain a single point of a (basic) set, use + __isl_give isl_basic_set *isl_basic_map_deltas( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map); + __isl_give isl_union_set *isl_union_map_deltas( + __isl_take isl_union_map *umap); - __isl_give isl_point *isl_basic_set_sample_point( - __isl_take isl_basic_set *bset); - __isl_give isl_point *isl_set_sample_point( - __isl_take isl_set *set); +These functions return a (basic) set containing the differences +between image elements and corresponding domain elements in the input. -If C does not contain any (integer) points, then the -resulting point will be ``void'', a property that can be -tested using + __isl_give isl_basic_map *isl_basic_map_deltas_map( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_deltas_map( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_deltas_map( + __isl_take isl_union_map *umap); - int isl_point_is_void(__isl_keep isl_point *pnt); +The functions above construct a (basic, regular or union) relation +that maps (a wrapped version of) the input relation to its delta set. -=head2 Piecewise Quasipolynomials +=item * Coalescing -A piecewise quasipolynomial is a particular kind of function that maps -a parametric point to a rational value. -More specifically, a quasipolynomial is a polynomial expression in greatest -integer parts of affine expressions of parameters and variables. -A piecewise quasipolynomial is a subdivision of a given parametric -domain into disjoint cells with a quasipolynomial associated to -each cell. The value of the piecewise quasipolynomial at a given -point is the value of the quasipolynomial associated to the cell -that contains the point. Outside of the union of cells, -the value is assumed to be zero. -For example, the piecewise quasipolynomial +Simplify the representation of a set, relation or functions by trying +to combine pairs of basic sets or relations into a single +basic set or relation. - [n] -> { [x] -> ((1 + n) - x) : x <= n and x >= 0 } + #include + __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); -maps C to C<1 + n - x> for values of C between C<0> and C. -A given piecewise quasipolynomial has a fixed domain dimension. -Union piecewise quasipolynomials are used to contain piecewise quasipolynomials -defined over different domains. -Piecewise quasipolynomials are mainly used by the C -library for representing the number of elements in a parametric set or map. -For example, the piecewise quasipolynomial above represents -the number of points in the map + #include + __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map); - [n] -> { [x] -> [y] : x,y >= 0 and 0 <= x + y <= n } + #include + __isl_give isl_union_set *isl_union_set_coalesce( + __isl_take isl_union_set *uset); -=head3 Input and Output + #include + __isl_give isl_union_map *isl_union_map_coalesce( + __isl_take isl_union_map *umap); -Piecewise quasipolynomials can be read from input using + #include + __isl_give isl_pw_aff *isl_pw_aff_coalesce( + __isl_take isl_pw_aff *pwqp); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_coalesce( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_pw_aff *isl_union_pw_aff_coalesce( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_coalesce( + __isl_take isl_union_pw_multi_aff *upma); + #include + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_coalesce( + __isl_take isl_pw_qpolynomial_fold *pwf); __isl_give isl_union_pw_qpolynomial * - isl_union_pw_qpolynomial_read_from_str( - isl_ctx *ctx, const char *str); + isl_union_pw_qpolynomial_coalesce( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_coalesce( + __isl_take isl_union_pw_qpolynomial_fold *upwf); -Quasipolynomials and piecewise quasipolynomials can be printed -using the following functions. +One of the methods for combining pairs of basic sets or relations +can result in coefficients that are much larger than those that appear +in the constraints of the input. By default, the coefficients are +not allowed to grow larger, but this can be changed by unsetting +the following option. - __isl_give isl_printer *isl_printer_print_qpolynomial( - __isl_take isl_printer *p, - __isl_keep isl_qpolynomial *qp); + isl_stat isl_options_set_coalesce_bounded_wrapping( + isl_ctx *ctx, int val); + int isl_options_get_coalesce_bounded_wrapping( + isl_ctx *ctx); - __isl_give isl_printer *isl_printer_print_pw_qpolynomial( - __isl_take isl_printer *p, - __isl_keep isl_pw_qpolynomial *pwqp); +=item * Detecting equalities - __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( - __isl_take isl_printer *p, - __isl_keep isl_union_pw_qpolynomial *upwqp); + __isl_give isl_basic_set *isl_basic_set_detect_equalities( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_map *isl_basic_map_detect_equalities( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_set_detect_equalities( + __isl_take isl_set *set); + __isl_give isl_map *isl_map_detect_equalities( + __isl_take isl_map *map); + __isl_give isl_union_set *isl_union_set_detect_equalities( + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_detect_equalities( + __isl_take isl_union_map *umap); -The output format of the printer -needs to be set to either C or C. -For C, only C -is supported. -In case of printing in C, the user may want -to set the names of all dimensions +Simplify the representation of a set or relation by detecting implicit +equalities. - __isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name( - __isl_take isl_qpolynomial *qp, - enum isl_dim_type type, unsigned pos, - const char *s); - __isl_give isl_pw_qpolynomial * - isl_pw_qpolynomial_set_dim_name( - __isl_take isl_pw_qpolynomial *pwqp, - enum isl_dim_type type, unsigned pos, - const char *s); +=item * Removing redundant constraints -=head3 Creating New (Piecewise) Quasipolynomials + #include + __isl_give isl_basic_set *isl_basic_set_remove_redundancies( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_remove_redundancies( + __isl_take isl_set *set); -Some simple quasipolynomials can be created using the following functions. -More complicated quasipolynomials can be created by applying -operations such as addition and multiplication -on the resulting quasipolynomials + #include + __isl_give isl_union_set * + isl_union_set_remove_redundancies( + __isl_take isl_union_set *uset); - __isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain( - __isl_take isl_space *domain); - __isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain( - __isl_take isl_space *domain); - __isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain( - __isl_take isl_space *domain); - __isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain( - __isl_take isl_space *domain); - __isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain( - __isl_take isl_space *domain); - __isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain( - __isl_take isl_space *domain, - const isl_int n, const isl_int d); - __isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( - __isl_take isl_space *domain, - __isl_take isl_val *val); - __isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain( - __isl_take isl_space *domain, - enum isl_dim_type type, unsigned pos); - __isl_give isl_qpolynomial *isl_qpolynomial_from_aff( - __isl_take isl_aff *aff); + #include + __isl_give isl_basic_map *isl_basic_map_remove_redundancies( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_remove_redundancies( + __isl_take isl_map *map); -Note that the space in which a quasipolynomial lives is a map space -with a one-dimensional range. The C argument in some of -the functions above corresponds to the domain of this map space. + #include + __isl_give isl_union_map * + isl_union_map_remove_redundancies( + __isl_take isl_union_map *umap); -The zero piecewise quasipolynomial or a piecewise quasipolynomial -with a single cell can be created using the following functions. -Multiple of these single cell piecewise quasipolynomials can -be combined to create more complicated piecewise quasipolynomials. +=item * Convex hull - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero( - __isl_take isl_space *space); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_alloc( - __isl_take isl_set *set, - __isl_take isl_qpolynomial *qp); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial( - __isl_take isl_qpolynomial *qp); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_pw_aff( - __isl_take isl_pw_aff *pwaff); + __isl_give isl_basic_set *isl_set_convex_hull( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_map_convex_hull( + __isl_take isl_map *map); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_zero( - __isl_take isl_space *space); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_from_pw_qpolynomial( - __isl_take isl_pw_qpolynomial *pwqp); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add_pw_qpolynomial( - __isl_take isl_union_pw_qpolynomial *upwqp, - __isl_take isl_pw_qpolynomial *pwqp); +If the input set or relation has any existentially quantified +variables, then the result of these operations is currently undefined. -Quasipolynomials can be copied and freed again using the following -functions. +=item * Simple hull - __isl_give isl_qpolynomial *isl_qpolynomial_copy( - __isl_keep isl_qpolynomial *qp); - void *isl_qpolynomial_free(__isl_take isl_qpolynomial *qp); + #include + __isl_give isl_basic_set * + isl_set_unshifted_simple_hull( + __isl_take isl_set *set); + __isl_give isl_basic_set *isl_set_simple_hull( + __isl_take isl_set *set); + __isl_give isl_basic_set * + isl_set_unshifted_simple_hull_from_set_list( + __isl_take isl_set *set, + __isl_take isl_set_list *list); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_copy( - __isl_keep isl_pw_qpolynomial *pwqp); - void *isl_pw_qpolynomial_free( - __isl_take isl_pw_qpolynomial *pwqp); + #include + __isl_give isl_basic_map * + isl_map_unshifted_simple_hull( + __isl_take isl_map *map); + __isl_give isl_basic_map *isl_map_simple_hull( + __isl_take isl_map *map); + __isl_give isl_basic_map * + isl_map_unshifted_simple_hull_from_map_list( + __isl_take isl_map *map, + __isl_take isl_map_list *list); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_copy( - __isl_keep isl_union_pw_qpolynomial *upwqp); - void *isl_union_pw_qpolynomial_free( - __isl_take isl_union_pw_qpolynomial *upwqp); + #include + __isl_give isl_union_map *isl_union_map_simple_hull( + __isl_take isl_union_map *umap); -=head3 Inspecting (Piecewise) Quasipolynomials +These functions compute a single basic set or relation +that contains the whole input set or relation. +In particular, the output is described by translates +of the constraints describing the basic sets or relations in the input. +In case of C, only the original +constraints are used, without any translation. +In case of C and +C, the +constraints are taken from the elements of the second argument. -To iterate over all piecewise quasipolynomials in a union -piecewise quasipolynomial, use the following function +=begin latex - int isl_union_pw_qpolynomial_foreach_pw_qpolynomial( - __isl_keep isl_union_pw_qpolynomial *upwqp, - int (*fn)(__isl_take isl_pw_qpolynomial *pwqp, void *user), - void *user); +(See \autoref{s:simple hull}.) -To extract the piecewise quasipolynomial in a given space from a union, use +=end latex - __isl_give isl_pw_qpolynomial * - isl_union_pw_qpolynomial_extract_pw_qpolynomial( - __isl_keep isl_union_pw_qpolynomial *upwqp, - __isl_take isl_space *space); +=item * Affine hull -To iterate over the cells in a piecewise quasipolynomial, -use either of the following two functions + __isl_give isl_basic_set *isl_basic_set_affine_hull( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_affine_hull( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_affine_hull( + __isl_take isl_union_set *uset); + __isl_give isl_basic_map *isl_basic_map_affine_hull( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_map_affine_hull( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_affine_hull( + __isl_take isl_union_map *umap); - int isl_pw_qpolynomial_foreach_piece( - __isl_keep isl_pw_qpolynomial *pwqp, - int (*fn)(__isl_take isl_set *set, - __isl_take isl_qpolynomial *qp, - void *user), void *user); - int isl_pw_qpolynomial_foreach_lifted_piece( - __isl_keep isl_pw_qpolynomial *pwqp, - int (*fn)(__isl_take isl_set *set, - __isl_take isl_qpolynomial *qp, - void *user), void *user); +In case of union sets and relations, the affine hull is computed +per space. -As usual, the function C should return C<0> on success -and C<-1> on failure. The difference between -C and -C is that -C will first -compute unique representations for all existentially quantified -variables and then turn these existentially quantified variables -into extra set variables, adapting the associated quasipolynomial -accordingly. This means that the C passed to C -will not have any existentially quantified variables, but that -the dimensions of the sets may be different for different -invocations of C. +=item * Polyhedral hull -The constant term of a quasipolynomial can be extracted using + __isl_give isl_basic_set *isl_set_polyhedral_hull( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_map_polyhedral_hull( + __isl_take isl_map *map); + __isl_give isl_union_set *isl_union_set_polyhedral_hull( + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_polyhedral_hull( + __isl_take isl_union_map *umap); - __isl_give isl_val *isl_qpolynomial_get_constant_val( - __isl_keep isl_qpolynomial *qp); +These functions compute a single basic set or relation +not involving any existentially quantified variables +that contains the whole input set or relation. +In case of union sets and relations, the polyhedral hull is computed +per space. -To iterate over all terms in a quasipolynomial, -use +=item * Other approximations - int isl_qpolynomial_foreach_term( - __isl_keep isl_qpolynomial *qp, - int (*fn)(__isl_take isl_term *term, - void *user), void *user); + #include + __isl_give isl_basic_set * + isl_basic_set_drop_constraints_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_basic_set * + isl_basic_set_drop_constraints_not_involving_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_set * + isl_set_drop_constraints_involving_dims( + __isl_take isl_set *set, + enum isl_dim_type type, + unsigned first, unsigned n); -The terms themselves can be inspected and freed using -these functions + #include + __isl_give isl_basic_map * + isl_basic_map_drop_constraints_involving_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_map * + isl_map_drop_constraints_involving_dims( + __isl_take isl_map *map, + enum isl_dim_type type, + unsigned first, unsigned n); - unsigned isl_term_dim(__isl_keep isl_term *term, - enum isl_dim_type type); - void isl_term_get_num(__isl_keep isl_term *term, - isl_int *n); - void isl_term_get_den(__isl_keep isl_term *term, - isl_int *d); - __isl_give isl_val *isl_term_get_coefficient_val( - __isl_keep isl_term *term); - int isl_term_get_exp(__isl_keep isl_term *term, - enum isl_dim_type type, unsigned pos); - __isl_give isl_aff *isl_term_get_div( - __isl_keep isl_term *term, unsigned pos); - void isl_term_free(__isl_take isl_term *term); +These functions drop any constraints (not) involving the specified dimensions. +Note that the result depends on the representation of the input. -Each term is a product of parameters, set variables and -integer divisions. The function C -returns the exponent of a given dimensions in the given term. -The Cs in the arguments of C -and C need to have been initialized -using C before calling these functions. + #include + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial( + __isl_take isl_pw_qpolynomial *pwqp, int sign); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_to_polynomial( + __isl_take isl_union_pw_qpolynomial *upwqp, int sign); -=head3 Properties of (Piecewise) Quasipolynomials +Approximate each quasipolynomial by a polynomial. If C is positive, +the polynomial will be an overapproximation. If C is negative, +it will be an underapproximation. If C is zero, the approximation +will lie somewhere in between. -To check whether a quasipolynomial is actually a constant, -use the following function. +=item * Feasibility - int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp, - isl_int *n, isl_int *d); + __isl_give isl_basic_set *isl_basic_set_sample( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_sample( + __isl_take isl_set *set); + __isl_give isl_basic_map *isl_basic_map_sample( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_map_sample( + __isl_take isl_map *map); -If C is a constant and if C and C are not C -then the numerator and denominator of the constant -are returned in C<*n> and C<*d>, respectively. +If the input (basic) set or relation is non-empty, then return +a singleton subset of the input. Otherwise, return an empty set. -To check whether two union piecewise quasipolynomials are -obviously equal, use +=item * Optimization - int isl_union_pw_qpolynomial_plain_is_equal( - __isl_keep isl_union_pw_qpolynomial *upwqp1, - __isl_keep isl_union_pw_qpolynomial *upwqp2); + #include + __isl_give isl_val *isl_basic_set_max_val( + __isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj); + __isl_give isl_val *isl_set_min_val( + __isl_keep isl_set *set, + __isl_keep isl_aff *obj); + __isl_give isl_val *isl_set_max_val( + __isl_keep isl_set *set, + __isl_keep isl_aff *obj); + +Compute the minimum or maximum of the integer affine expression C +over the points in C, returning the result in C. +The result is C in case of an error, the optimal value in case +there is one, negative infinity or infinity if the problem is unbounded and +NaN if the problem is empty. + +=item * Parametric optimization + + __isl_give isl_pw_aff *isl_set_dim_min( + __isl_take isl_set *set, int pos); + __isl_give isl_pw_aff *isl_set_dim_max( + __isl_take isl_set *set, int pos); + __isl_give isl_pw_aff *isl_map_dim_max( + __isl_take isl_map *map, int pos); + +Compute the minimum or maximum of the given set or output dimension +as a function of the parameters (and input dimensions), but independently +of the other set or output dimensions. +For lexicographic optimization, see L<"Lexicographic Optimization">. + +=item * Dual + +The following functions compute either the set of (rational) coefficient +values of valid constraints for the given set or the set of (rational) +values satisfying the constraints with coefficients from the given set. +Internally, these two sets of functions perform essentially the +same operations, except that the set of coefficients is assumed to +be a cone, while the set of values may be any polyhedron. +The current implementation is based on the Farkas lemma and +Fourier-Motzkin elimination, but this may change or be made optional +in future. In particular, future implementations may use different +dualization algorithms or skip the elimination step. + + __isl_give isl_basic_set *isl_basic_set_coefficients( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_coefficients( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_coefficients( + __isl_take isl_union_set *bset); + __isl_give isl_basic_set *isl_basic_set_solutions( + __isl_take isl_basic_set *bset); + __isl_give isl_basic_set *isl_set_solutions( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_solutions( + __isl_take isl_union_set *bset); + +=item * Power + + __isl_give isl_map *isl_map_fixed_power_val( + __isl_take isl_map *map, + __isl_take isl_val *exp); + __isl_give isl_union_map * + isl_union_map_fixed_power_val( + __isl_take isl_union_map *umap, + __isl_take isl_val *exp); + +Compute the given power of C, where C is assumed to be non-zero. +If the exponent C is negative, then the -C th power of the inverse +of C is computed. + + __isl_give isl_map *isl_map_power(__isl_take isl_map *map, + int *exact); + __isl_give isl_union_map *isl_union_map_power( + __isl_take isl_union_map *umap, int *exact); + +Compute a parametric representation for all positive powers I of C. +The result maps I to a nested relation corresponding to the +Ith power of C. +The result may be an overapproximation. If the result is known to be exact, +then C<*exact> is set to C<1>. + +=item * Transitive closure + + __isl_give isl_map *isl_map_transitive_closure( + __isl_take isl_map *map, int *exact); + __isl_give isl_union_map *isl_union_map_transitive_closure( + __isl_take isl_union_map *umap, int *exact); + +Compute the transitive closure of C. +The result may be an overapproximation. If the result is known to be exact, +then C<*exact> is set to C<1>. + +=item * Reaching path lengths + + __isl_give isl_map *isl_map_reaching_path_lengths( + __isl_take isl_map *map, int *exact); + +Compute a relation that maps each element in the range of C +to the lengths of all paths composed of edges in C that +end up in the given element. +The result may be an overapproximation. If the result is known to be exact, +then C<*exact> is set to C<1>. +To compute the I path length, the resulting relation +should be postprocessed by C. +In particular, if the input relation is a dependence relation +(mapping sources to sinks), then the maximal path length corresponds +to the free schedule. +Note, however, that C expects the maximum to be +finite, so if the path lengths are unbounded (possibly due to +the overapproximation), then you will get an error message. + +=item * Wrapping + + #include + __isl_give isl_space *isl_space_wrap( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_unwrap( + __isl_take isl_space *space); + + #include + __isl_give isl_local_space *isl_local_space_wrap( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_basic_map *isl_basic_set_unwrap( + __isl_take isl_basic_set *bset); + __isl_give isl_map *isl_set_unwrap( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_set *isl_basic_map_wrap( + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_map_wrap( + __isl_take isl_map *map); -=head3 Operations on (Piecewise) Quasipolynomials + #include + __isl_give isl_union_map *isl_union_set_unwrap( + __isl_take isl_union_set *uset); + + #include + __isl_give isl_union_set *isl_union_map_wrap( + __isl_take isl_union_map *umap); + +The input to C should +be the space of a set, while that of +C should be the space of a relation. +Conversely, the output of C is the space +of a relation, while that of C is the space of a set. + +=item * Flattening + +Remove any internal structure of domain (and range) of the given +set or relation. If there is any such internal structure in the input, +then the name of the space is also removed. + + #include + __isl_give isl_local_space * + isl_local_space_flatten_domain( + __isl_take isl_local_space *ls); + __isl_give isl_local_space * + isl_local_space_flatten_range( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_basic_set *isl_basic_set_flatten( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_flatten( + __isl_take isl_set *set); + + #include + __isl_give isl_basic_map *isl_basic_map_flatten_domain( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_basic_map_flatten_range( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_flatten_range( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_flatten_domain( + __isl_take isl_map *map); + __isl_give isl_basic_map *isl_basic_map_flatten( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_flatten( + __isl_take isl_map *map); + + #include + __isl_give isl_multi_val *isl_multi_val_flatten_range( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff *isl_multi_aff_flatten_domain( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_aff *isl_multi_aff_flatten_range( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_flatten_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_flatten_range( + __isl_take isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_map *isl_set_flatten_map( + __isl_take isl_set *set); + +The function above constructs a relation +that maps the input set to a flattened version of the set. + +=item * Lifting + +Lift the input set to a space with extra dimensions corresponding +to the existentially quantified variables in the input. +In particular, the result lives in a wrapped map where the domain +is the original space and the range corresponds to the original +existentially quantified variables. + + #include + __isl_give isl_basic_set *isl_basic_set_lift( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_lift( + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_lift( + __isl_take isl_union_set *uset); + +Given a local space that contains the existentially quantified +variables of a set, a basic relation that, when applied to +a basic set, has essentially the same effect as C, +can be constructed using the following function. + + #include + __isl_give isl_basic_map *isl_local_space_lifting( + __isl_take isl_local_space *ls); + + #include + __isl_give isl_multi_aff *isl_multi_aff_lift( + __isl_take isl_multi_aff *maff, + __isl_give isl_local_space **ls); + +If the C argument of C is not C, +then it is assigned the local space that lies at the basis of +the lifting applied. + +=item * Internal Product + + #include + __isl_give isl_space *isl_space_zip( + __isl_take isl_space *space); + + #include + __isl_give isl_basic_map *isl_basic_map_zip( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_zip( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_zip( + __isl_take isl_union_map *umap); + +Given a relation with nested relations for domain and range, +interchange the range of the domain with the domain of the range. + +=item * Currying + + #include + __isl_give isl_space *isl_space_curry( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_uncurry( + __isl_take isl_space *space); + + #include + __isl_give isl_basic_map *isl_basic_map_curry( + __isl_take isl_basic_map *bmap); + __isl_give isl_basic_map *isl_basic_map_uncurry( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_curry( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_uncurry( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_curry( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_uncurry( + __isl_take isl_union_map *umap); + +Given a relation with a nested relation for domain, +the C functions +move the range of the nested relation out of the domain +and use it as the domain of a nested relation in the range, +with the original range as range of this nested relation. +The C functions perform the inverse operation. + +=item * Aligning parameters + +Change the order of the parameters of the given set, relation +or function +such that the first parameters match those of C. +This may involve the introduction of extra parameters. +All parameters need to be named. + + #include + __isl_give isl_space *isl_space_align_params( + __isl_take isl_space *space1, + __isl_take isl_space *space2) + + #include + __isl_give isl_basic_set *isl_basic_set_align_params( + __isl_take isl_basic_set *bset, + __isl_take isl_space *model); + __isl_give isl_set *isl_set_align_params( + __isl_take isl_set *set, + __isl_take isl_space *model); + + #include + __isl_give isl_basic_map *isl_basic_map_align_params( + __isl_take isl_basic_map *bmap, + __isl_take isl_space *model); + __isl_give isl_map *isl_map_align_params( + __isl_take isl_map *map, + __isl_take isl_space *model); + + #include + __isl_give isl_multi_val *isl_multi_val_align_params( + __isl_take isl_multi_val *mv, + __isl_take isl_space *model); + + #include + __isl_give isl_aff *isl_aff_align_params( + __isl_take isl_aff *aff, + __isl_take isl_space *model); + __isl_give isl_multi_aff *isl_multi_aff_align_params( + __isl_take isl_multi_aff *multi, + __isl_take isl_space *model); + __isl_give isl_pw_aff *isl_pw_aff_align_params( + __isl_take isl_pw_aff *pwaff, + __isl_take isl_space *model); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_align_params( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_space *model); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_align_params( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_space *model); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_align_params( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_space *model); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_align_params( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_space *model); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_align_params( + __isl_take isl_qpolynomial *qp, + __isl_take isl_space *model); + +=item * Unary Arithmethic Operations + + #include + __isl_give isl_multi_val *isl_multi_val_neg( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_aff *isl_aff_neg( + __isl_take isl_aff *aff); + __isl_give isl_multi_aff *isl_multi_aff_neg( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_neg( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_neg( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_neg( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_union_pw_aff *isl_union_pw_aff_neg( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_neg( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_neg( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_aff *isl_aff_ceil( + __isl_take isl_aff *aff); + __isl_give isl_pw_aff *isl_pw_aff_ceil( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_aff *isl_aff_floor( + __isl_take isl_aff *aff); + __isl_give isl_multi_aff *isl_multi_aff_floor( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_floor( + __isl_take isl_pw_aff *pwaff); + __isl_give isl_union_pw_aff *isl_union_pw_aff_floor( + __isl_take isl_union_pw_aff *upa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_floor( + __isl_take isl_multi_union_pw_aff *mupa); + + #include + __isl_give isl_pw_aff *isl_pw_aff_list_min( + __isl_take isl_pw_aff_list *list); + __isl_give isl_pw_aff *isl_pw_aff_list_max( + __isl_take isl_pw_aff_list *list); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_neg( + __isl_take isl_qpolynomial *qp); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_neg( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_qpolynomial *isl_qpolynomial_pow( + __isl_take isl_qpolynomial *qp, + unsigned exponent); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( + __isl_take isl_pw_qpolynomial *pwqp, + unsigned exponent); + +=item * Evaluation + +The following functions evaluate a function in a point. + + #include + __isl_give isl_val *isl_pw_qpolynomial_eval( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_pw_qpolynomial_fold_eval( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_union_pw_qpolynomial_eval( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_point *pnt); + __isl_give isl_val *isl_union_pw_qpolynomial_fold_eval( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_point *pnt); + +=item * Dimension manipulation + +It is usually not advisable to directly change the (input or output) +space of a set or a relation as this removes the name and the internal +structure of the space. However, the functions below can be useful +to add new parameters, assuming +C and C +are not sufficient. + + #include + __isl_give isl_space *isl_space_add_dims( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned n); + __isl_give isl_space *isl_space_insert_dims( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned pos, unsigned n); + __isl_give isl_space *isl_space_drop_dims( + __isl_take isl_space *space, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_space *isl_space_move_dims( + __isl_take isl_space *space, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_local_space *isl_local_space_add_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned n); + __isl_give isl_local_space *isl_local_space_insert_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_local_space *isl_local_space_drop_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + __isl_give isl_basic_set *isl_basic_set_add_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned n); + __isl_give isl_set *isl_set_add_dims( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned n); + __isl_give isl_basic_set *isl_basic_set_insert_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, + unsigned n); + __isl_give isl_set *isl_set_insert_dims( + __isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, unsigned n); + __isl_give isl_basic_set *isl_basic_set_move_dims( + __isl_take isl_basic_set *bset, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_set *isl_set_move_dims( + __isl_take isl_set *set, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_basic_map *isl_basic_map_add_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned n); + __isl_give isl_map *isl_map_add_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned n); + __isl_give isl_basic_map *isl_basic_map_insert_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, + unsigned n); + __isl_give isl_map *isl_map_insert_dims( + __isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, unsigned n); + __isl_give isl_basic_map *isl_basic_map_move_dims( + __isl_take isl_basic_map *bmap, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_map *isl_map_move_dims( + __isl_take isl_map *map, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_multi_val *isl_multi_val_insert_dims( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_val *isl_multi_val_add_dims( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned n); + __isl_give isl_multi_val *isl_multi_val_drop_dims( + __isl_take isl_multi_val *mv, + enum isl_dim_type type, unsigned first, unsigned n); + + #include + __isl_give isl_aff *isl_aff_insert_dims( + __isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_insert_dims( + __isl_take isl_multi_aff *ma, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_insert_dims( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_insert_dims( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_aff *isl_aff_add_dims( + __isl_take isl_aff *aff, + enum isl_dim_type type, unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_add_dims( + __isl_take isl_multi_aff *ma, + enum isl_dim_type type, unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_add_dims( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned n); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_add_dims( + __isl_take isl_multi_pw_aff *mpa, + enum isl_dim_type type, unsigned n); + __isl_give isl_aff *isl_aff_drop_dims( + __isl_take isl_aff *aff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_drop_dims( + __isl_take isl_multi_aff *maff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_drop_dims( + __isl_take isl_pw_aff *pwaff, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_dims( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_union_pw_aff *isl_union_pw_aff_drop_dims( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_drop_dims( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_drop_dims( + __isl_take isl_multi_union_pw_aff *mupa, + enum isl_dim_type type, unsigned first, + unsigned n); + __isl_give isl_aff *isl_aff_move_dims( + __isl_take isl_aff *aff, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_multi_aff *isl_multi_aff_move_dims( + __isl_take isl_multi_aff *ma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_pw_aff *isl_pw_aff_move_dims( + __isl_take isl_pw_aff *pa, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_dims( + __isl_take isl_multi_pw_aff *pma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, + unsigned n); + + #include + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_drop_dims( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, + unsigned first, unsigned n); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_drop_dims( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, + unsigned first, unsigned n); + +The operations on union expressions can only manipulate parameters. + +=back + +=head2 Binary Operations + +The two arguments of a binary operation not only need to live +in the same C, they currently also need to have +the same (number of) parameters. + +=head3 Basic Operations + +=over + +=item * Intersection + + #include + __isl_give isl_local_space *isl_local_space_intersect( + __isl_take isl_local_space *ls1, + __isl_take isl_local_space *ls2); + + #include + __isl_give isl_basic_set *isl_basic_set_intersect_params( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_basic_set *isl_basic_set_intersect( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_basic_set *isl_basic_set_list_intersect( + __isl_take struct isl_basic_set_list *list); + __isl_give isl_set *isl_set_intersect_params( + __isl_take isl_set *set, + __isl_take isl_set *params); + __isl_give isl_set *isl_set_intersect( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_basic_map *isl_basic_map_intersect_domain( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset); + __isl_give isl_basic_map *isl_basic_map_intersect_range( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *bset); + __isl_give isl_basic_map *isl_basic_map_intersect( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_list_intersect( + __isl_take isl_basic_map_list *list); + __isl_give isl_map *isl_map_intersect_params( + __isl_take isl_map *map, + __isl_take isl_set *params); + __isl_give isl_map *isl_map_intersect_domain( + __isl_take isl_map *map, + __isl_take isl_set *set); + __isl_give isl_map *isl_map_intersect_range( + __isl_take isl_map *map, + __isl_take isl_set *set); + __isl_give isl_map *isl_map_intersect( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_set *isl_union_set_intersect_params( + __isl_take isl_union_set *uset, + __isl_take isl_set *set); + __isl_give isl_union_set *isl_union_set_intersect( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + + #include + __isl_give isl_union_map *isl_union_map_intersect_params( + __isl_take isl_union_map *umap, + __isl_take isl_set *set); + __isl_give isl_union_map *isl_union_map_intersect_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_intersect_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_intersect( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_pw_aff *isl_pw_aff_intersect_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_intersect_domain( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *domain); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_intersect_domain( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *uset); + __isl_give isl_pw_aff *isl_pw_aff_intersect_params( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_intersect_params( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_params( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_intersect_params( + __isl_take isl_union_pw_aff *upa, + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_intersect_params( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_set *set); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_intersect_params( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_set *params); + isl_multi_union_pw_aff_intersect_range( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_set *set); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_intersect_domain( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_intersect_params( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_intersect_params( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_intersect_params( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_intersect_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_set *set); + +The second argument to the C<_params> functions needs to be +a parametric (basic) set. For the other functions, a parametric set +for either argument is only allowed if the other argument is +a parametric set as well. +The list passed to C needs to have +at least one element and all elements need to live in the same space. +The function C +restricts the input function to those shared domain elements +that map to the specified range. + +=item * Union + + #include + __isl_give isl_set *isl_basic_set_union( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_set *isl_set_union( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_map *isl_basic_map_union( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_union( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_set *isl_union_set_union( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + __isl_give isl_union_set *isl_union_set_list_union( + __isl_take isl_union_set_list *list); + + #include + __isl_give isl_union_map *isl_union_map_union( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + +=item * Set difference + + #include + __isl_give isl_set *isl_set_subtract( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_map *isl_map_subtract( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_subtract_domain( + __isl_take isl_map *map, + __isl_take isl_set *dom); + __isl_give isl_map *isl_map_subtract_range( + __isl_take isl_map *map, + __isl_take isl_set *dom); + + #include + __isl_give isl_union_set *isl_union_set_subtract( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + + #include + __isl_give isl_union_map *isl_union_map_subtract( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_subtract_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *dom); + __isl_give isl_union_map *isl_union_map_subtract_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *dom); + + #include + __isl_give isl_pw_aff *isl_pw_aff_subtract_domain( + __isl_take isl_pw_aff *pa, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_subtract_domain( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_subtract_domain( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_subtract_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_set *set); + + #include + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_subtract_domain( + __isl_take isl_pw_qpolynomial *pwpq, + __isl_take isl_set *set); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *set); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_subtract_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); + +=item * Application + + #include + __isl_give isl_space *isl_space_join( + __isl_take isl_space *left, + __isl_take isl_space *right); + + #include + __isl_give isl_basic_set *isl_basic_set_apply( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_map *bmap); + __isl_give isl_set *isl_set_apply( + __isl_take isl_set *set, + __isl_take isl_map *map); + __isl_give isl_union_set *isl_union_set_apply( + __isl_take isl_union_set *uset, + __isl_take isl_union_map *umap); + __isl_give isl_basic_map *isl_basic_map_apply_domain( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_apply_range( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_apply_domain( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_apply_range( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_map *isl_union_map_apply_domain( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_apply_range( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_aff *aff); + __isl_give isl_union_pw_aff * + isl_multi_union_pw_aff_apply_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_aff *pa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_apply_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma); + +The result of C is defined +over the shared domain of the elements of the input. The dimension is +required to be greater than zero. +The C argument of +C is allowed to be zero-dimensional, +but only if the range of the C argument +is also zero-dimensional. +Similarly for C. + + #include + __isl_give isl_pw_qpolynomial_fold * + isl_set_apply_pw_qpolynomial_fold( + __isl_take isl_set *set, + __isl_take isl_pw_qpolynomial_fold *pwf, + int *tight); + __isl_give isl_pw_qpolynomial_fold * + isl_map_apply_pw_qpolynomial_fold( + __isl_take isl_map *map, + __isl_take isl_pw_qpolynomial_fold *pwf, + int *tight); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_set_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_qpolynomial_fold *upwf, + int *tight); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_map_apply_union_pw_qpolynomial_fold( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_qpolynomial_fold *upwf, + int *tight); + +The functions taking a map +compose the given map with the given piecewise quasipolynomial reduction. +That is, compute a bound (of the same type as C or C itself) +over all elements in the intersection of the range of the map +and the domain of the piecewise quasipolynomial reduction +as a function of an element in the domain of the map. +The functions taking a set compute a bound over all elements in the +intersection of the set and the domain of the +piecewise quasipolynomial reduction. + +=item * Preimage + + #include + __isl_give isl_basic_set * + isl_basic_set_preimage_multi_aff( + __isl_take isl_basic_set *bset, + __isl_take isl_multi_aff *ma); + __isl_give isl_set *isl_set_preimage_multi_aff( + __isl_take isl_set *set, + __isl_take isl_multi_aff *ma); + __isl_give isl_set *isl_set_preimage_pw_multi_aff( + __isl_take isl_set *set, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_set *isl_set_preimage_multi_pw_aff( + __isl_take isl_set *set, + __isl_take isl_multi_pw_aff *mpa); + + #include + __isl_give isl_union_set * + isl_union_set_preimage_multi_aff( + __isl_take isl_union_set *uset, + __isl_take isl_multi_aff *ma); + __isl_give isl_union_set * + isl_union_set_preimage_pw_multi_aff( + __isl_take isl_union_set *uset, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_set * + isl_union_set_preimage_union_pw_multi_aff( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_multi_aff *upma); + + #include + __isl_give isl_basic_map * + isl_basic_map_preimage_domain_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_multi_aff *ma); + __isl_give isl_map *isl_map_preimage_domain_multi_aff( + __isl_take isl_map *map, + __isl_take isl_multi_aff *ma); + __isl_give isl_map *isl_map_preimage_range_multi_aff( + __isl_take isl_map *map, + __isl_take isl_multi_aff *ma); + __isl_give isl_map * + isl_map_preimage_domain_pw_multi_aff( + __isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map * + isl_map_preimage_range_pw_multi_aff( + __isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map * + isl_map_preimage_domain_multi_pw_aff( + __isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_basic_map * + isl_basic_map_preimage_range_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_multi_aff *ma); + + #include + __isl_give isl_union_map * + isl_union_map_preimage_domain_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_aff *ma); + __isl_give isl_union_map * + isl_union_map_preimage_range_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_aff *ma); + __isl_give isl_union_map * + isl_union_map_preimage_domain_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_map * + isl_union_map_preimage_range_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_union_map * + isl_union_map_preimage_domain_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_map * + isl_union_map_preimage_range_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); + +These functions compute the preimage of the given set or map domain/range under +the given function. In other words, the expression is plugged +into the set description or into the domain/range of the map. + +=item * Pullback + + #include + __isl_give isl_aff *isl_aff_pullback_aff( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_aff *isl_aff_pullback_multi_aff( + __isl_take isl_aff *aff, + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_aff( + __isl_take isl_pw_aff *pa, + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_aff *isl_pw_aff_pullback_pw_multi_aff( + __isl_take isl_pw_aff *pa, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( + __isl_take isl_pw_aff *pa, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_pullback_multi_aff( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_pullback_multi_aff( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_pullback_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_pullback_pw_multi_aff( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_pullback_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_union_pw_aff * + isl_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma); + +These functions precompose the first expression by the second function. +In other words, the second function is plugged +into the first expression. + +=item * Locus + + #include + __isl_give isl_basic_set *isl_aff_le_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_basic_set *isl_aff_ge_basic_set( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_set *isl_pw_aff_eq_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_ne_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_le_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_lt_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_ge_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_set *isl_pw_aff_gt_set( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + + __isl_give isl_set *isl_multi_aff_lex_le_set( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_set *isl_multi_aff_lex_ge_set( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + + __isl_give isl_set *isl_pw_aff_list_eq_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_ne_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_le_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_lt_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_ge_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + __isl_give isl_set *isl_pw_aff_list_gt_set( + __isl_take isl_pw_aff_list *list1, + __isl_take isl_pw_aff_list *list2); + +The function C returns a basic set +containing those elements in the shared space +of C and C where C is greater than or equal to C. +The function C returns a set +containing those elements in the shared domain +of C and C where C is +greater than or equal to C. +The function C returns a set +containing those elements in the shared domain space +where C is lexicographically smaller than or +equal to C. +The functions operating on C apply the corresponding +C function to each pair of elements in the two lists. + + #include + __isl_give isl_map *isl_pw_aff_eq_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_map *isl_pw_aff_lt_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_map *isl_pw_aff_gt_map( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + + __isl_give isl_map *isl_multi_pw_aff_eq_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_map *isl_multi_pw_aff_lex_lt_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_map *isl_multi_pw_aff_lex_gt_map( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + +These functions return a map between domain elements of the arguments +where the function values satisfy the given relation. + + #include + __isl_give isl_union_map * + isl_union_map_eq_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map * + isl_union_map_lex_lt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map * + isl_union_map_lex_gt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + +These functions select the subset of elements in the union map +that have an equal or lexicographically smaller function value. + +=item * Cartesian Product + + #include + __isl_give isl_space *isl_space_product( + __isl_take isl_space *space1, + __isl_take isl_space *space2); + __isl_give isl_space *isl_space_domain_product( + __isl_take isl_space *space1, + __isl_take isl_space *space2); + __isl_give isl_space *isl_space_range_product( + __isl_take isl_space *space1, + __isl_take isl_space *space2); + +The functions +C, C +and C take pairs or relation spaces and +produce a single relations space, where either the domain, the range +or both domain and range are wrapped spaces of relations between +the domains and/or ranges of the input spaces. +If the product is only constructed over the domain or the range +then the ranges or the domains of the inputs should be the same. +The function C also accepts a pair of set spaces, +in which case it returns a wrapped space of a relation between the +two input spaces. + + #include + __isl_give isl_set *isl_set_product( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_basic_map *isl_basic_map_domain_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_basic_map *isl_basic_map_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_domain_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_range_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_set *isl_union_set_product( + __isl_take isl_union_set *uset1, + __isl_take isl_union_set *uset2); + + #include + __isl_give isl_union_map *isl_union_map_domain_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map *isl_union_map_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_multi_val *isl_multi_val_range_product( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_product( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_range_product( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_aff *isl_multi_aff_product( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_product( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_product( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_range_product( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_product( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + +The above functions compute the cross product of the given +sets, relations or functions. The domains and ranges of the results +are wrapped maps between domains and ranges of the inputs. +To obtain a ``flat'' product, use the following functions +instead. + + #include + __isl_give isl_basic_set *isl_basic_set_flat_product( + __isl_take isl_basic_set *bset1, + __isl_take isl_basic_set *bset2); + __isl_give isl_set *isl_set_flat_product( + __isl_take isl_set *set1, + __isl_take isl_set *set2); + + #include + __isl_give isl_basic_map *isl_basic_map_flat_range_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_flat_domain_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_map *isl_map_flat_range_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_basic_map *isl_basic_map_flat_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_flat_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + + #include + __isl_give isl_union_map * + isl_union_map_flat_domain_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + __isl_give isl_union_map * + isl_union_map_flat_range_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); + + #include + __isl_give isl_multi_val *isl_multi_val_flat_range_product( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_aff *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_flat_range_product( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_flat_range_product( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_flat_range_product( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_flat_range_product( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_flat_range_product( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + + #include + __isl_give isl_space *isl_space_factor_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_factor_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_domain_factor_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_domain_factor_range( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_factor_domain( + __isl_take isl_space *space); + __isl_give isl_space *isl_space_range_factor_range( + __isl_take isl_space *space); + +The functions C and +C extract the two arguments from +the result of a call to C. + +The arguments of a call to C can be extracted +from the result using the following functions. + + #include + __isl_give isl_map *isl_map_factor_domain( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_factor_range( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_domain_factor_domain( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_domain_factor_range( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_range_factor_domain( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_range_factor_range( + __isl_take isl_map *map); + + #include + __isl_give isl_union_map *isl_union_map_factor_domain( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_factor_range( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_domain_factor_domain( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_domain_factor_range( + __isl_take isl_union_map *umap); + __isl_give isl_union_map * + isl_union_map_range_factor_range( + __isl_take isl_union_map *umap); + + #include + __isl_give isl_multi_val * + isl_multi_val_range_factor_domain( + __isl_take isl_multi_val *mv); + __isl_give isl_multi_val * + isl_multi_val_range_factor_range( + __isl_take isl_multi_val *mv); + + #include + __isl_give isl_multi_aff * + isl_multi_aff_range_factor_domain( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_aff * + isl_multi_aff_range_factor_range( + __isl_take isl_multi_aff *ma); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_factor_domain( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_factor_range( + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_factor_domain( + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_factor_range( + __isl_take isl_multi_union_pw_aff *mupa); + +The splice functions are a generalization of the flat product functions, +where the second argument may be inserted at any position inside +the first argument rather than being placed at the end. + + #include + __isl_give isl_multi_val *isl_multi_val_range_splice( + __isl_take isl_multi_val *mv1, unsigned pos, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_range_splice( + __isl_take isl_multi_aff *ma1, unsigned pos, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_aff *isl_multi_aff_splice( + __isl_take isl_multi_aff *ma1, + unsigned in_pos, unsigned out_pos, + __isl_take isl_multi_aff *ma2); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_range_splice( + __isl_take isl_multi_pw_aff *mpa1, unsigned pos, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_splice( + __isl_take isl_multi_pw_aff *mpa1, + unsigned in_pos, unsigned out_pos, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_range_splice( + __isl_take isl_multi_union_pw_aff *mupa1, + unsigned pos, + __isl_take isl_multi_union_pw_aff *mupa2); + +=item * Simplification + +When applied to a set or relation, +the gist operation returns a set or relation that has the +same intersection with the context as the input set or relation. +Any implicit equality in the intersection is made explicit in the result, +while all inequalities that are redundant with respect to the intersection +are removed. +In case of union sets and relations, the gist operation is performed +per space. + +When applied to a function, +the gist operation applies the set gist operation to each of +the cells in the domain of the input piecewise expression. +The context is also exploited +to simplify the expression associated to each cell. + + #include + __isl_give isl_basic_set *isl_basic_set_gist( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *context); + __isl_give isl_set *isl_set_gist(__isl_take isl_set *set, + __isl_take isl_set *context); + __isl_give isl_set *isl_set_gist_params( + __isl_take isl_set *set, + __isl_take isl_set *context); + + #include + __isl_give isl_basic_map *isl_basic_map_gist( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_map *context); + __isl_give isl_basic_map *isl_basic_map_gist_domain( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *context); + __isl_give isl_map *isl_map_gist(__isl_take isl_map *map, + __isl_take isl_map *context); + __isl_give isl_map *isl_map_gist_params( + __isl_take isl_map *map, + __isl_take isl_set *context); + __isl_give isl_map *isl_map_gist_domain( + __isl_take isl_map *map, + __isl_take isl_set *context); + __isl_give isl_map *isl_map_gist_range( + __isl_take isl_map *map, + __isl_take isl_set *context); + + #include + __isl_give isl_union_set *isl_union_set_gist( + __isl_take isl_union_set *uset, + __isl_take isl_union_set *context); + __isl_give isl_union_set *isl_union_set_gist_params( + __isl_take isl_union_set *uset, + __isl_take isl_set *set); + + #include + __isl_give isl_union_map *isl_union_map_gist( + __isl_take isl_union_map *umap, + __isl_take isl_union_map *context); + __isl_give isl_union_map *isl_union_map_gist_params( + __isl_take isl_union_map *umap, + __isl_take isl_set *set); + __isl_give isl_union_map *isl_union_map_gist_domain( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + __isl_give isl_union_map *isl_union_map_gist_range( + __isl_take isl_union_map *umap, + __isl_take isl_union_set *uset); + + #include + __isl_give isl_aff *isl_aff_gist_params( + __isl_take isl_aff *aff, + __isl_take isl_set *context); + __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, + __isl_take isl_set *context); + __isl_give isl_multi_aff *isl_multi_aff_gist_params( + __isl_take isl_multi_aff *maff, + __isl_take isl_set *context); + __isl_give isl_multi_aff *isl_multi_aff_gist( + __isl_take isl_multi_aff *maff, + __isl_take isl_set *context); + __isl_give isl_pw_aff *isl_pw_aff_gist_params( + __isl_take isl_pw_aff *pwaff, + __isl_take isl_set *context); + __isl_give isl_pw_aff *isl_pw_aff_gist( + __isl_take isl_pw_aff *pwaff, + __isl_take isl_set *context); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist_params( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist_params( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *set); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_set *set); + __isl_give isl_union_pw_aff *isl_union_pw_aff_gist( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_set *context); + __isl_give isl_union_pw_aff *isl_union_pw_aff_gist_params( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_set *context); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_gist_params( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_set *context); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_gist( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *context); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_gist_params( + __isl_take isl_multi_union_pw_aff *aff, + __isl_take isl_set *context); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_gist( + __isl_take isl_multi_union_pw_aff *aff, + __isl_take isl_union_set *context); + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_gist_params( + __isl_take isl_qpolynomial *qp, + __isl_take isl_set *context); + __isl_give isl_qpolynomial *isl_qpolynomial_gist( + __isl_take isl_qpolynomial *qp, + __isl_take isl_set *context); + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_gist_params( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_set *context); + __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist_params( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_gist( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *context); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_gist_params( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_set *context); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_gist_params( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_set *context); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_union_set *context); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_gist( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *context); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_gist_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_set *context); + +=item * Binary Arithmethic Operations + + #include + __isl_give isl_multi_val *isl_multi_val_sub( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_aff *isl_aff_add( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_multi_aff *isl_multi_aff_add( + __isl_take isl_multi_aff *maff1, + __isl_take isl_multi_aff *maff2); + __isl_give isl_pw_aff *isl_pw_aff_add( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_aff *isl_union_pw_aff_add( + __isl_take isl_union_pw_aff *upa1, + __isl_take isl_union_pw_aff *upa2); + __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_pw_aff *isl_pw_aff_min( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_aff *isl_pw_aff_max( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_aff *isl_aff_sub( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_multi_aff *isl_multi_aff_sub( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + __isl_give isl_pw_aff *isl_pw_aff_sub( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_sub( + __isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_aff *isl_union_pw_aff_sub( + __isl_take isl_union_pw_aff *upa1, + __isl_take isl_union_pw_aff *upa2); + __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_sub( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_sub( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + +C subtracts the second argument from the first. + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_add( + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_disjoint( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); + __isl_give isl_qpolynomial *isl_qpolynomial_sub( + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub( + __isl_take isl_union_pw_qpolynomial *upwqp1, + __isl_take isl_union_pw_qpolynomial *upwqp2); + __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( + __isl_take isl_pw_qpolynomial_fold *pwf1, + __isl_take isl_pw_qpolynomial_fold *pwf2); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_fold( + __isl_take isl_union_pw_qpolynomial_fold *upwf1, + __isl_take isl_union_pw_qpolynomial_fold *upwf2); + + #include + __isl_give isl_pw_aff *isl_pw_aff_union_add( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( + __isl_take isl_union_pw_aff *upa1, + __isl_take isl_union_pw_aff *upa2); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_union_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_union_add( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + __isl_give isl_pw_aff *isl_pw_aff_union_min( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_aff *isl_pw_aff_union_max( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + +The function C computes a piecewise quasi-affine +expression with a domain that is the union of those of C and +C and such that on each cell, the quasi-affine expression is +the maximum of those of C and C. If only one of +C or C is defined on a given cell, then the +associated expression is the defined one. +This in contrast to the C function, which is +only defined on the shared definition domain of the arguments. + + #include + __isl_give isl_multi_val *isl_multi_val_add_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + __isl_give isl_multi_val *isl_multi_val_mod_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + __isl_give isl_multi_val *isl_multi_val_scale_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + __isl_give isl_multi_val *isl_multi_val_scale_down_val( + __isl_take isl_multi_val *mv, + __isl_take isl_val *v); + + #include + __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, + __isl_take isl_val *mod); + __isl_give isl_pw_aff *isl_pw_aff_mod_val( + __isl_take isl_pw_aff *pa, + __isl_take isl_val *mod); + __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_val *f); + __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, + __isl_take isl_val *v); + __isl_give isl_multi_aff *isl_multi_aff_scale_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_val *v); + __isl_give isl_pw_aff *isl_pw_aff_scale_val( + __isl_take isl_pw_aff *pa, __isl_take isl_val *v); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_val *v); + __isl_give isl_union_pw_multi_aff * + __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_val *f); + isl_union_pw_multi_aff_scale_val( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_val *val); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_val *v); + __isl_give isl_aff *isl_aff_scale_down_ui( + __isl_take isl_aff *aff, unsigned f); + __isl_give isl_aff *isl_aff_scale_down_val( + __isl_take isl_aff *aff, __isl_take isl_val *v); + __isl_give isl_multi_aff *isl_multi_aff_scale_down_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_val *v); + __isl_give isl_pw_aff *isl_pw_aff_scale_down_val( + __isl_take isl_pw_aff *pa, + __isl_take isl_val *f); + __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_down_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_val *v); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_val *v); + __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_val *v); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_scale_down_val( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_val *val); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_down_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_val *v); - __isl_give isl_qpolynomial *isl_qpolynomial_scale( - __isl_take isl_qpolynomial *qp, isl_int v); + #include __isl_give isl_qpolynomial *isl_qpolynomial_scale_val( __isl_take isl_qpolynomial *qp, __isl_take isl_val *v); - __isl_give isl_qpolynomial *isl_qpolynomial_neg( - __isl_take isl_qpolynomial *qp); - __isl_give isl_qpolynomial *isl_qpolynomial_add( - __isl_take isl_qpolynomial *qp1, - __isl_take isl_qpolynomial *qp2); - __isl_give isl_qpolynomial *isl_qpolynomial_sub( - __isl_take isl_qpolynomial *qp1, - __isl_take isl_qpolynomial *qp2); - __isl_give isl_qpolynomial *isl_qpolynomial_mul( - __isl_take isl_qpolynomial *qp1, - __isl_take isl_qpolynomial *qp2); - __isl_give isl_qpolynomial *isl_qpolynomial_pow( - __isl_take isl_qpolynomial *qp, unsigned exponent); - - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_val( - __isl_take isl_pw_qpolynomial *pwqp, - enum isl_dim_type type, unsigned n, + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_scale_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v); __isl_give isl_pw_qpolynomial * isl_pw_qpolynomial_scale_val( __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_val *v); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add( - __isl_take isl_pw_qpolynomial *pwqp1, - __isl_take isl_pw_qpolynomial *pwqp2); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub( - __isl_take isl_pw_qpolynomial *pwqp1, - __isl_take isl_pw_qpolynomial *pwqp2); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_disjoint( - __isl_take isl_pw_qpolynomial *pwqp1, - __isl_take isl_pw_qpolynomial *pwqp2); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg( - __isl_take isl_pw_qpolynomial *pwqp); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( - __isl_take isl_pw_qpolynomial *pwqp1, - __isl_take isl_pw_qpolynomial *pwqp2); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( - __isl_take isl_pw_qpolynomial *pwqp, unsigned exponent); - + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_scale_val( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_val *v); __isl_give isl_union_pw_qpolynomial * isl_union_pw_qpolynomial_scale_val( __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_val *v); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add( - __isl_take isl_union_pw_qpolynomial *upwqp1, - __isl_take isl_union_pw_qpolynomial *upwqp2); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub( - __isl_take isl_union_pw_qpolynomial *upwqp1, - __isl_take isl_union_pw_qpolynomial *upwqp2); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_scale_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_val *v); + __isl_give isl_qpolynomial * + isl_qpolynomial_scale_down_val( + __isl_take isl_qpolynomial *qp, + __isl_take isl_val *v); + __isl_give isl_qpolynomial_fold * + isl_qpolynomial_fold_scale_down_val( + __isl_take isl_qpolynomial_fold *fold, + __isl_take isl_val *v); + __isl_give isl_pw_qpolynomial * + isl_pw_qpolynomial_scale_down_val( + __isl_take isl_pw_qpolynomial *pwqp, + __isl_take isl_val *v); + __isl_give isl_pw_qpolynomial_fold * + isl_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_pw_qpolynomial_fold *pwf, + __isl_take isl_val *v); + __isl_give isl_union_pw_qpolynomial * + isl_union_pw_qpolynomial_scale_down_val( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_val *v); + __isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_val *v); + + #include + __isl_give isl_multi_val *isl_multi_val_mod_multi_val( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val *isl_multi_val_scale_multi_val( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + __isl_give isl_multi_val * + isl_multi_val_scale_down_multi_val( + __isl_take isl_multi_val *mv1, + __isl_take isl_multi_val *mv2); + + #include + __isl_give isl_multi_aff *isl_multi_aff_mod_multi_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_mod_multi_val( + __isl_take isl_multi_union_pw_aff *upma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_mod_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_aff *isl_multi_aff_scale_multi_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv); + __isl_give isl_pw_multi_aff * + isl_pw_multi_aff_scale_multi_val( + __isl_take isl_pw_multi_aff *pma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_scale_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_multi_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_val *mv); + __isl_give isl_union_pw_multi_aff * + isl_union_pw_multi_aff_scale_multi_val( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_aff * + isl_multi_aff_scale_down_multi_val( + __isl_take isl_multi_aff *ma, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_pw_aff * + isl_multi_pw_aff_scale_down_multi_val( + __isl_take isl_multi_pw_aff *mpa, + __isl_take isl_multi_val *mv); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_scale_down_multi_val( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_multi_val *mv); + +C scales the elements of C +by the corresponding elements of C. + + #include + __isl_give isl_aff *isl_aff_mul( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_aff *isl_aff_div( + __isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_pw_aff *isl_pw_aff_mul( + __isl_take isl_pw_aff *pwaff1, + __isl_take isl_pw_aff *pwaff2); + __isl_give isl_pw_aff *isl_pw_aff_div( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_pw_aff *isl_pw_aff_tdiv_q( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_pw_aff *isl_pw_aff_tdiv_r( + __isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + +When multiplying two affine expressions, at least one of the two needs +to be a constant. Similarly, when dividing an affine expression by another, +the second expression needs to be a constant. +C computes the quotient of an integer division with +rounding towards zero. C computes the corresponding +remainder. + + #include + __isl_give isl_qpolynomial *isl_qpolynomial_mul( + __isl_take isl_qpolynomial *qp1, + __isl_take isl_qpolynomial *qp2); + __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( + __isl_take isl_pw_qpolynomial *pwqp1, + __isl_take isl_pw_qpolynomial *pwqp2); __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( __isl_take isl_union_pw_qpolynomial *upwqp1, __isl_take isl_union_pw_qpolynomial *upwqp2); - __isl_give isl_qpolynomial *isl_pw_qpolynomial_eval( - __isl_take isl_pw_qpolynomial *pwqp, - __isl_take isl_point *pnt); +=back - __isl_give isl_qpolynomial *isl_union_pw_qpolynomial_eval( - __isl_take isl_union_pw_qpolynomial *upwqp, - __isl_take isl_point *pnt); +=head3 Lexicographic Optimization - __isl_give isl_set *isl_pw_qpolynomial_domain( - __isl_take isl_pw_qpolynomial *pwqp); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_domain( - __isl_take isl_pw_qpolynomial *pwpq, +Given a (basic) set C (or C) and a zero-dimensional domain C, +the following functions +compute a set that contains the lexicographic minimum or maximum +of the elements in C (or C) for those values of the parameters +that satisfy C. +If C is not C, then C<*empty> is assigned a set +that contains the parameter values in C for which C (or C) +has no elements. +In other words, the union of the parameter values +for which the result is non-empty and of C<*empty> +is equal to C. + + #include + __isl_give isl_set *isl_basic_set_partial_lexmin( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_set *isl_basic_set_partial_lexmax( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_set *isl_set_partial_lexmin( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty); + __isl_give isl_set *isl_set_partial_lexmax( + __isl_take isl_set *set, __isl_take isl_set *dom, + __isl_give isl_set **empty); + +Given a (basic) set C (or C), the following functions simply +return a set containing the lexicographic minimum or maximum +of the elements in C (or C). +In case of union sets, the optimum is computed per space. + + #include + __isl_give isl_set *isl_basic_set_lexmin( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_basic_set_lexmax( + __isl_take isl_basic_set *bset); + __isl_give isl_set *isl_set_lexmin( __isl_take isl_set *set); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_params( - __isl_take isl_pw_qpolynomial *pwpq, + __isl_give isl_set *isl_set_lexmax( __isl_take isl_set *set); - - __isl_give isl_union_set *isl_union_pw_qpolynomial_domain( - __isl_take isl_union_pw_qpolynomial *upwqp); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_intersect_domain( - __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_give isl_union_set *isl_union_set_lexmin( + __isl_take isl_union_set *uset); + __isl_give isl_union_set *isl_union_set_lexmax( __isl_take isl_union_set *uset); - __isl_give isl_union_pw_qpolynomial * - isl_union_pw_qpolynomial_intersect_params( - __isl_take isl_union_pw_qpolynomial *upwpq, - __isl_take isl_set *set); - __isl_give isl_qpolynomial *isl_qpolynomial_align_params( - __isl_take isl_qpolynomial *qp, - __isl_take isl_space *model); +Given a (basic) relation C (or C) and a domain C, +the following functions +compute a relation that maps each element of C +to the single lexicographic minimum or maximum +of the elements that are associated to that same +element in C (or C). +If C is not C, then C<*empty> is assigned a set +that contains the elements in C that do not map +to any elements in C (or C). +In other words, the union of the domain of the result and of C<*empty> +is equal to C. - __isl_give isl_qpolynomial *isl_qpolynomial_project_domain_on_params( - __isl_take isl_qpolynomial *qp); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_project_domain_on_params( - __isl_take isl_pw_qpolynomial *pwqp); + #include + __isl_give isl_map *isl_basic_map_partial_lexmax( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_map *isl_basic_map_partial_lexmin( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_map *isl_map_partial_lexmax( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty); + __isl_give isl_map *isl_map_partial_lexmin( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_coalesce( - __isl_take isl_union_pw_qpolynomial *upwqp); +Given a (basic) map C (or C), the following functions simply +return a map mapping each element in the domain of +C (or C) to the lexicographic minimum or maximum +of all elements associated to that element. +In case of union relations, the optimum is computed per space. - __isl_give isl_qpolynomial *isl_qpolynomial_gist_params( - __isl_take isl_qpolynomial *qp, - __isl_take isl_set *context); - __isl_give isl_qpolynomial *isl_qpolynomial_gist( - __isl_take isl_qpolynomial *qp, - __isl_take isl_set *context); + #include + __isl_give isl_map *isl_basic_map_lexmin( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_basic_map_lexmax( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_lexmin( + __isl_take isl_map *map); + __isl_give isl_map *isl_map_lexmax( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_lexmin( + __isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_lexmax( + __isl_take isl_union_map *umap); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist_params( - __isl_take isl_pw_qpolynomial *pwqp, - __isl_take isl_set *context); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist( - __isl_take isl_pw_qpolynomial *pwqp, - __isl_take isl_set *context); +The following functions return their result in the form of +a piecewise multi-affine expression, +but are otherwise equivalent to the corresponding functions +returning a basic set or relation. - __isl_give isl_union_pw_qpolynomial * - isl_union_pw_qpolynomial_gist_params( - __isl_take isl_union_pw_qpolynomial *upwqp, - __isl_take isl_set *context); - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist( - __isl_take isl_union_pw_qpolynomial *upwqp, - __isl_take isl_union_set *context); + #include + __isl_give isl_pw_multi_aff * + isl_basic_set_partial_lexmin_pw_multi_aff( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff * + isl_basic_set_partial_lexmax_pw_multi_aff( + __isl_take isl_basic_set *bset, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff *isl_set_lexmin_pw_multi_aff( + __isl_take isl_set *set); + __isl_give isl_pw_multi_aff *isl_set_lexmax_pw_multi_aff( + __isl_take isl_set *set); -The gist operation applies the gist operation to each of -the cells in the domain of the input piecewise quasipolynomial. -The context is also exploited -to simplify the quasipolynomials associated to each cell. + #include + __isl_give isl_pw_multi_aff * + isl_basic_map_lexmin_pw_multi_aff( + __isl_take isl_basic_map *bmap); + __isl_give isl_pw_multi_aff * + isl_basic_map_partial_lexmin_pw_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff * + isl_basic_map_partial_lexmax_pw_multi_aff( + __isl_take isl_basic_map *bmap, + __isl_take isl_basic_set *dom, + __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff( + __isl_take isl_map *map); + __isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff( + __isl_take isl_map *map); - __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial( - __isl_take isl_pw_qpolynomial *pwqp, int sign); - __isl_give isl_union_pw_qpolynomial * - isl_union_pw_qpolynomial_to_polynomial( - __isl_take isl_union_pw_qpolynomial *upwqp, int sign); +The following functions return the lexicographic minimum or maximum +on the shared domain of the inputs and the single defined function +on those parts of the domain where only a single function is defined. -Approximate each quasipolynomial by a polynomial. If C is positive, -the polynomial will be an overapproximation. If C is negative, -it will be an underapproximation. If C is zero, the approximation -will lie somewhere in between. + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax( + __isl_take isl_pw_multi_aff *pma1, + __isl_take isl_pw_multi_aff *pma2); -=head2 Bounds on Piecewise Quasipolynomials and Piecewise Quasipolynomial Reductions +=head2 Ternary Operations -A piecewise quasipolynomial reduction is a piecewise -reduction (or fold) of quasipolynomials. -In particular, the reduction can be maximum or a minimum. -The objects are mainly used to represent the result of -an upper or lower bound on a quasipolynomial over its domain, -i.e., as the result of the following function. + #include + __isl_give isl_pw_aff *isl_pw_aff_cond( + __isl_take isl_pw_aff *cond, + __isl_take isl_pw_aff *pwaff_true, + __isl_take isl_pw_aff *pwaff_false); - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_bound( - __isl_take isl_pw_qpolynomial *pwqp, - enum isl_fold type, int *tight); +The function C performs a conditional operator +and returns an expression that is equal to C +for elements where C is non-zero and equal to C for elements +where C is zero. - __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_bound( - __isl_take isl_union_pw_qpolynomial *upwqp, - enum isl_fold type, int *tight); +=head2 Lists -The C argument may be either C or C. -If C is not C, then C<*tight> is set to C<1> -is the returned bound is known be tight, i.e., for each value -of the parameters there is at least -one element in the domain that reaches the bound. -If the domain of C is not wrapping, then the bound is computed -over all elements in that domain and the result has a purely parametric -domain. If the domain of C is wrapping, then the bound is -computed over the range of the wrapped relation. The domain of the -wrapped relation becomes the domain of the result. +Lists are defined over several element types, including +C, C, C, C, C, +C, C, +C, C, C, C, C, +C, C and C. +Here we take lists of Cs as an example. +Lists can be created, copied, modified and freed using the following functions. -A (piecewise) quasipolynomial reduction can be copied or freed using the -following functions. + #include + __isl_give isl_set_list *isl_set_list_from_set( + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_alloc( + isl_ctx *ctx, int n); + __isl_give isl_set_list *isl_set_list_copy( + __isl_keep isl_set_list *list); + __isl_give isl_set_list *isl_set_list_insert( + __isl_take isl_set_list *list, unsigned pos, + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_add( + __isl_take isl_set_list *list, + __isl_take isl_set *el); + __isl_give isl_set_list *isl_set_list_drop( + __isl_take isl_set_list *list, + unsigned first, unsigned n); + __isl_give isl_set_list *isl_set_list_set_set( + __isl_take isl_set_list *list, int index, + __isl_take isl_set *set); + __isl_give isl_set_list *isl_set_list_concat( + __isl_take isl_set_list *list1, + __isl_take isl_set_list *list2); + __isl_give isl_set_list *isl_set_list_sort( + __isl_take isl_set_list *list, + int (*cmp)(__isl_keep isl_set *a, + __isl_keep isl_set *b, void *user), + void *user); + __isl_null isl_set_list *isl_set_list_free( + __isl_take isl_set_list *list); - __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy( - __isl_keep isl_qpolynomial_fold *fold); - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_copy( - __isl_keep isl_pw_qpolynomial_fold *pwf); - __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_copy( - __isl_keep isl_union_pw_qpolynomial_fold *upwf); - void isl_qpolynomial_fold_free( - __isl_take isl_qpolynomial_fold *fold); - void *isl_pw_qpolynomial_fold_free( - __isl_take isl_pw_qpolynomial_fold *pwf); - void *isl_union_pw_qpolynomial_fold_free( - __isl_take isl_union_pw_qpolynomial_fold *upwf); +C creates an empty list with an initial capacity +for C elements. C and C +add elements to a list, increasing its capacity as needed. +C creates a list with a single element. -=head3 Printing Piecewise Quasipolynomial Reductions +Lists can be inspected using the following functions. -Piecewise quasipolynomial reductions can be printed -using the following function. + #include + int isl_set_list_n_set(__isl_keep isl_set_list *list); + __isl_give isl_set *isl_set_list_get_set( + __isl_keep isl_set_list *list, int index); + isl_stat isl_set_list_foreach(__isl_keep isl_set_list *list, + isl_stat (*fn)(__isl_take isl_set *el, void *user), + void *user); + isl_stat isl_set_list_foreach_scc( + __isl_keep isl_set_list *list, + isl_bool (*follows)(__isl_keep isl_set *a, + __isl_keep isl_set *b, void *user), + void *follows_user + isl_stat (*fn)(__isl_take isl_set *el, void *user), + void *fn_user); - __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold( - __isl_take isl_printer *p, - __isl_keep isl_pw_qpolynomial_fold *pwf); - __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold( - __isl_take isl_printer *p, - __isl_keep isl_union_pw_qpolynomial_fold *upwf); +The function C calls C on each of the +strongly connected components of the graph with as vertices the elements +of C and a directed edge from vertex C to vertex C +iff C returns C<1>. The callbacks C and C +should return C<-1> on error. -For C, -output format of the printer -needs to be set to either C or C. -For C, -output format of the printer -needs to be set to C. -In case of printing in C, the user may want -to set the names of all dimensions +Lists can be printed using - __isl_give isl_pw_qpolynomial_fold * - isl_pw_qpolynomial_fold_set_dim_name( - __isl_take isl_pw_qpolynomial_fold *pwf, - enum isl_dim_type type, unsigned pos, - const char *s); + #include + __isl_give isl_printer *isl_printer_print_set_list( + __isl_take isl_printer *p, + __isl_keep isl_set_list *list); -=head3 Inspecting (Piecewise) Quasipolynomial Reductions +=head2 Associative arrays -To iterate over all piecewise quasipolynomial reductions in a union -piecewise quasipolynomial reduction, use the following function +Associative arrays map isl objects of a specific type to isl objects +of some (other) specific type. They are defined for several pairs +of types, including (C, C), +(C, C) and. +(C, C). +Here, we take associative arrays that map Cs to Cs +as an example. - int isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( - __isl_keep isl_union_pw_qpolynomial_fold *upwf, - int (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, - void *user), void *user); +Associative arrays can be created, copied and freed using +the following functions. -To iterate over the cells in a piecewise quasipolynomial reduction, -use either of the following two functions + #include + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_alloc( + isl_ctx *ctx, int min_size); + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_copy( + __isl_keep isl_id_to_ast_expr *id2expr); + __isl_null isl_id_to_ast_expr *isl_id_to_ast_expr_free( + __isl_take isl_id_to_ast_expr *id2expr); + +The C argument to C can be used +to specify the expected size of the associative array. +The associative array will be grown automatically as needed. + +Associative arrays can be inspected using the following functions. + + #include + isl_bool isl_id_to_ast_expr_has( + __isl_keep isl_id_to_ast_expr *id2expr, + __isl_keep isl_id *key); + __isl_give isl_ast_expr *isl_id_to_ast_expr_get( + __isl_keep isl_id_to_ast_expr *id2expr, + __isl_take isl_id *key); + isl_stat isl_id_to_ast_expr_foreach( + __isl_keep isl_id_to_ast_expr *id2expr, + isl_stat (*fn)(__isl_take isl_id *key, + __isl_take isl_ast_expr *val, void *user), + void *user); - int isl_pw_qpolynomial_fold_foreach_piece( - __isl_keep isl_pw_qpolynomial_fold *pwf, - int (*fn)(__isl_take isl_set *set, - __isl_take isl_qpolynomial_fold *fold, - void *user), void *user); - int isl_pw_qpolynomial_fold_foreach_lifted_piece( - __isl_keep isl_pw_qpolynomial_fold *pwf, - int (*fn)(__isl_take isl_set *set, - __isl_take isl_qpolynomial_fold *fold, - void *user), void *user); +They can be modified using the following function. -See L for an explanation -of the difference between these two functions. + #include + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_set( + __isl_take isl_id_to_ast_expr *id2expr, + __isl_take isl_id *key, + __isl_take isl_ast_expr *val); + __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_drop( + __isl_take isl_id_to_ast_expr *id2expr, + __isl_take isl_id *key); -To iterate over all quasipolynomials in a reduction, use +Associative arrays can be printed using the following function. - int isl_qpolynomial_fold_foreach_qpolynomial( - __isl_keep isl_qpolynomial_fold *fold, - int (*fn)(__isl_take isl_qpolynomial *qp, - void *user), void *user); + #include + __isl_give isl_printer *isl_printer_print_id_to_ast_expr( + __isl_take isl_printer *p, + __isl_keep isl_id_to_ast_expr *id2expr); -=head3 Properties of Piecewise Quasipolynomial Reductions +=head2 Vectors -To check whether two union piecewise quasipolynomial reductions are -obviously equal, use +Vectors can be created, copied and freed using the following functions. - int isl_union_pw_qpolynomial_fold_plain_is_equal( - __isl_keep isl_union_pw_qpolynomial_fold *upwf1, - __isl_keep isl_union_pw_qpolynomial_fold *upwf2); + #include + __isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx, + unsigned size); + __isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec); + __isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec); -=head3 Operations on Piecewise Quasipolynomial Reductions +Note that the elements of a newly created vector may have arbitrary values. +The elements can be changed and inspected using the following functions. - __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale( - __isl_take isl_qpolynomial_fold *fold, isl_int v); - __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val( - __isl_take isl_qpolynomial_fold *fold, - __isl_take isl_val *v); - __isl_give isl_pw_qpolynomial_fold * - isl_pw_qpolynomial_fold_scale_val( - __isl_take isl_pw_qpolynomial_fold *pwf, - __isl_take isl_val *v); - __isl_give isl_union_pw_qpolynomial_fold * - isl_union_pw_qpolynomial_fold_scale_val( - __isl_take isl_union_pw_qpolynomial_fold *upwf, + int isl_vec_size(__isl_keep isl_vec *vec); + __isl_give isl_val *isl_vec_get_element_val( + __isl_keep isl_vec *vec, int pos); + __isl_give isl_vec *isl_vec_set_element_si( + __isl_take isl_vec *vec, int pos, int v); + __isl_give isl_vec *isl_vec_set_element_val( + __isl_take isl_vec *vec, int pos, __isl_take isl_val *v); + __isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, + int v); + __isl_give isl_vec *isl_vec_set_val( + __isl_take isl_vec *vec, __isl_take isl_val *v); + int isl_vec_cmp_element(__isl_keep isl_vec *vec1, + __isl_keep isl_vec *vec2, int pos); - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( - __isl_take isl_pw_qpolynomial_fold *pwf1, - __isl_take isl_pw_qpolynomial_fold *pwf2); +C will return a negative value if anything went wrong. +In that case, the value of C<*v> is undefined. - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( - __isl_take isl_pw_qpolynomial_fold *pwf1, - __isl_take isl_pw_qpolynomial_fold *pwf2); +The following function can be used to concatenate two vectors. - __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold( - __isl_take isl_union_pw_qpolynomial_fold *upwf1, - __isl_take isl_union_pw_qpolynomial_fold *upwf2); + __isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, + __isl_take isl_vec *vec2); - __isl_give isl_qpolynomial *isl_pw_qpolynomial_fold_eval( - __isl_take isl_pw_qpolynomial_fold *pwf, - __isl_take isl_point *pnt); +=head2 Matrices - __isl_give isl_qpolynomial *isl_union_pw_qpolynomial_fold_eval( - __isl_take isl_union_pw_qpolynomial_fold *upwf, - __isl_take isl_point *pnt); +Matrices can be created, copied and freed using the following functions. - __isl_give isl_pw_qpolynomial_fold * - isl_pw_qpolynomial_fold_intersect_params( - __isl_take isl_pw_qpolynomial_fold *pwf, - __isl_take isl_set *set); + #include + __isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx, + unsigned n_row, unsigned n_col); + __isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat); + __isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat); - __isl_give isl_union_set *isl_union_pw_qpolynomial_fold_domain( - __isl_take isl_union_pw_qpolynomial_fold *upwf); - __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_intersect_domain( - __isl_take isl_union_pw_qpolynomial_fold *upwf, - __isl_take isl_union_set *uset); - __isl_give isl_union_pw_qpolynomial_fold * - isl_union_pw_qpolynomial_fold_intersect_params( - __isl_take isl_union_pw_qpolynomial_fold *upwf, - __isl_take isl_set *set); +Note that the elements of a newly created matrix may have arbitrary values. +The elements can be changed and inspected using the following functions. + + int isl_mat_rows(__isl_keep isl_mat *mat); + int isl_mat_cols(__isl_keep isl_mat *mat); + __isl_give isl_val *isl_mat_get_element_val( + __isl_keep isl_mat *mat, int row, int col); + __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, + int row, int col, int v); + __isl_give isl_mat *isl_mat_set_element_val( + __isl_take isl_mat *mat, int row, int col, + __isl_take isl_val *v); - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_project_domain_on_params( - __isl_take isl_pw_qpolynomial_fold *pwf); +C will return a negative value if anything went wrong. +In that case, the value of C<*v> is undefined. - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_coalesce( - __isl_take isl_pw_qpolynomial_fold *pwf); +The following function can be used to compute the (right) inverse +of a matrix, i.e., a matrix such that the product of the original +and the inverse (in that order) is a multiple of the identity matrix. +The input matrix is assumed to be of full row-rank. - __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_coalesce( - __isl_take isl_union_pw_qpolynomial_fold *upwf); + __isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat); - __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params( - __isl_take isl_qpolynomial_fold *fold, - __isl_take isl_set *context); - __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( - __isl_take isl_qpolynomial_fold *fold, - __isl_take isl_set *context); +The following function can be used to compute the (right) kernel +(or null space) of a matrix, i.e., a matrix such that the product of +the original and the kernel (in that order) is the zero matrix. - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_gist( - __isl_take isl_pw_qpolynomial_fold *pwf, - __isl_take isl_set *context); - __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_gist_params( - __isl_take isl_pw_qpolynomial_fold *pwf, - __isl_take isl_set *context); + __isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat); - __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_gist( - __isl_take isl_union_pw_qpolynomial_fold *upwf, - __isl_take isl_union_set *context); - __isl_give isl_union_pw_qpolynomial_fold * - isl_union_pw_qpolynomial_fold_gist_params( - __isl_take isl_union_pw_qpolynomial_fold *upwf, - __isl_take isl_set *context); +=head2 Bounds on Piecewise Quasipolynomials and Piecewise Quasipolynomial Reductions -The gist operation applies the gist operation to each of -the cells in the domain of the input piecewise quasipolynomial reduction. -In future, the operation will also exploit the context -to simplify the quasipolynomial reductions associated to each cell. +The following functions determine +an upper or lower bound on a quasipolynomial over its domain. __isl_give isl_pw_qpolynomial_fold * - isl_set_apply_pw_qpolynomial_fold( - __isl_take isl_set *set, - __isl_take isl_pw_qpolynomial_fold *pwf, - int *tight); - __isl_give isl_pw_qpolynomial_fold * - isl_map_apply_pw_qpolynomial_fold( - __isl_take isl_map *map, - __isl_take isl_pw_qpolynomial_fold *pwf, - int *tight); - __isl_give isl_union_pw_qpolynomial_fold * - isl_union_set_apply_union_pw_qpolynomial_fold( - __isl_take isl_union_set *uset, - __isl_take isl_union_pw_qpolynomial_fold *upwf, - int *tight); + isl_pw_qpolynomial_bound( + __isl_take isl_pw_qpolynomial *pwqp, + enum isl_fold type, int *tight); + __isl_give isl_union_pw_qpolynomial_fold * - isl_union_map_apply_union_pw_qpolynomial_fold( - __isl_take isl_union_map *umap, - __isl_take isl_union_pw_qpolynomial_fold *upwf, - int *tight); + isl_union_pw_qpolynomial_bound( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_fold type, int *tight); -The functions taking a map -compose the given map with the given piecewise quasipolynomial reduction. -That is, compute a bound (of the same type as C or C itself) -over all elements in the intersection of the range of the map -and the domain of the piecewise quasipolynomial reduction -as a function of an element in the domain of the map. -The functions taking a set compute a bound over all elements in the -intersection of the set and the domain of the -piecewise quasipolynomial reduction. +The C argument may be either C or C. +If C is not C, then C<*tight> is set to C<1> +is the returned bound is known be tight, i.e., for each value +of the parameters there is at least +one element in the domain that reaches the bound. +If the domain of C is not wrapping, then the bound is computed +over all elements in that domain and the result has a purely parametric +domain. If the domain of C is wrapping, then the bound is +computed over the range of the wrapped relation. The domain of the +wrapped relation becomes the domain of the result. =head2 Parametric Vertex Enumeration @@ -5268,48 +7276,42 @@ the vertices or iterating over all the chambers or cells and then iterating over all vertices that are active on the chamber. - int isl_vertices_foreach_vertex( + isl_stat isl_vertices_foreach_vertex( __isl_keep isl_vertices *vertices, - int (*fn)(__isl_take isl_vertex *vertex, void *user), - void *user); + isl_stat (*fn)(__isl_take isl_vertex *vertex, + void *user), void *user); - int isl_vertices_foreach_cell( + isl_stat isl_vertices_foreach_cell( __isl_keep isl_vertices *vertices, - int (*fn)(__isl_take isl_cell *cell, void *user), - void *user); - int isl_cell_foreach_vertex(__isl_keep isl_cell *cell, - int (*fn)(__isl_take isl_vertex *vertex, void *user), - void *user); + isl_stat (*fn)(__isl_take isl_cell *cell, + void *user), void *user); + isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, + isl_stat (*fn)(__isl_take isl_vertex *vertex, + void *user), void *user); Other operations that can be performed on an C object are the following. - isl_ctx *isl_vertices_get_ctx( - __isl_keep isl_vertices *vertices); int isl_vertices_get_n_vertices( __isl_keep isl_vertices *vertices); void isl_vertices_free(__isl_take isl_vertices *vertices); Vertices can be inspected and destroyed using the following functions. - isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex); int isl_vertex_get_id(__isl_keep isl_vertex *vertex); __isl_give isl_basic_set *isl_vertex_get_domain( __isl_keep isl_vertex *vertex); - __isl_give isl_basic_set *isl_vertex_get_expr( + __isl_give isl_multi_aff *isl_vertex_get_expr( __isl_keep isl_vertex *vertex); void isl_vertex_free(__isl_take isl_vertex *vertex); -C returns a singleton parametric set describing -the vertex, while C returns the activity domain +C returns a multiple quasi-affine expression +describing the vertex in terms of the parameters, +while C returns the activity domain of the vertex. -Note that C and C return -B basic sets, so they should mainly be used for inspection -and should not be mixed with integer sets. Chambers can be inspected and destroyed using the following functions. - isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell); __isl_give isl_basic_set *isl_cell_get_domain( __isl_keep isl_cell *cell); void isl_cell_free(__isl_take isl_cell *cell); @@ -5319,6 +7321,907 @@ This section collects functionality in C that has been specifically designed for use during polyhedral compilation. +=head2 Schedule Trees + +A schedule tree is a structured representation of a schedule, +assigning a relative order to a set of domain elements. +The relative order expressed by the schedule tree is +defined recursively. In particular, the order between +two domain elements is determined by the node that is closest +to the root that refers to both elements and that orders them apart. +Each node in the tree is of one of several types. +The root node is always of type C +(or C) +and it describes the (extra) domain elements to which the schedule applies. +The other types of nodes are as follows. + +=over + +=item C + +A band of schedule dimensions. Each schedule dimension is represented +by a union piecewise quasi-affine expression. If this expression +assigns a different value to two domain elements, while all previous +schedule dimensions in the same band assign them the same value, +then the two domain elements are ordered according to these two +different values. + +=item C + +An expansion node maps each of the domain elements that reach the node +to one or more domain elements. The image of this mapping forms +the set of domain elements that reach the child of the expansion node. +The function that maps each of the expanded domain elements +to the original domain element from which it was expanded +is called the contraction. + +=item C + +A filter node does not impose any ordering, but rather intersects +the set of domain elements that the current subtree refers to +with a given union set. The subtree of the filter node only +refers to domain elements in the intersection. +A filter node is typically only used a child of a sequence or +set node. + +=item C + +A leaf of the schedule tree. Leaf nodes do not impose any ordering. + +=item C + +A mark node can be used to attach any kind of information to a subtree +of the schedule tree. + +=item C + +A sequence node has one or more children, each of which is a filter node. +The filters on these filter nodes form a partition of +the domain elements that the current subtree refers to. +If two domain elements appear in distinct filters then the sequence +node orders them according to the child positions of the corresponding +filter nodes. + +=item C + +A set node is similar to a sequence node, except that +it expresses that domain elements appearing in distinct filters +may have any order. The order of the children of a set node +is therefore also immaterial. + +=back + +The following node types are only supported by the AST generator. + +=over + +=item C + +The context describes constraints on the parameters and +the schedule dimensions of outer +bands that the AST generator may assume to hold. It is also the only +kind of node that may introduce additional parameters. +The space of the context is that of the flat product of the outer +band nodes. In particular, if there are no outer band nodes, then +this space is the unnamed zero-dimensional space. +Since a context node references the outer band nodes, any tree +containing a context node is considered to be anchored. + +=item C + +An extension node instructs the AST generator to add additional +domain elements that need to be scheduled. +The additional domain elements are described by the range of +the extension map in terms of the outer schedule dimensions, +i.e., the flat product of the outer band nodes. +Note that domain elements are added whenever the AST generator +reaches the extension node, meaning that there are still some +active domain elements for which an AST needs to be generated. +The conditions under which some domain elements are still active +may however not be completely described by the outer AST nodes +generated at that point. + +An extension node may also appear as the root of a schedule tree, +when it is intended to be inserted into another tree +using C or C. +In this case, the domain of the extension node should +correspond to the flat product of the outer band nodes +in this other schedule tree at the point where the extension tree +will be inserted. + +=item C + +The guard describes constraints on the parameters and +the schedule dimensions of outer +bands that need to be enforced by the outer nodes +in the generated AST. +The space of the guard is that of the flat product of the outer +band nodes. In particular, if there are no outer band nodes, then +this space is the unnamed zero-dimensional space. +Since a guard node references the outer band nodes, any tree +containing a guard node is considered to be anchored. + +=back + +Except for the C nodes, +none of the nodes may introduce any parameters that were not +already present in the root domain node. + +A schedule tree is encapsulated in an C object. +The simplest such objects, those with a tree consisting of single domain node, +can be created using the following functions with either an empty +domain or a given domain. + + #include + __isl_give isl_schedule *isl_schedule_empty( + __isl_take isl_space *space); + __isl_give isl_schedule *isl_schedule_from_domain( + __isl_take isl_union_set *domain); + +The function C described +in L can also be used to construct schedules. + +C objects may be copied and freed using the following functions. + + #include + __isl_give isl_schedule *isl_schedule_copy( + __isl_keep isl_schedule *sched); + __isl_null isl_schedule *isl_schedule_free( + __isl_take isl_schedule *sched); + +The following functions checks whether two C objects +are obviously the same. + + #include + isl_bool isl_schedule_plain_is_equal( + __isl_keep isl_schedule *schedule1, + __isl_keep isl_schedule *schedule2); + +The domain of the schedule, i.e., the domain described by the root node, +can be obtained using the following function. + + #include + __isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule); + +An extra top-level band node (right underneath the domain node) can +be introduced into the schedule using the following function. +The schedule tree is assumed not to have any anchored nodes. + + #include + __isl_give isl_schedule * + isl_schedule_insert_partial_schedule( + __isl_take isl_schedule *schedule, + __isl_take isl_multi_union_pw_aff *partial); + +A top-level context node (right underneath the domain node) can +be introduced into the schedule using the following function. + + #include + __isl_give isl_schedule *isl_schedule_insert_context( + __isl_take isl_schedule *schedule, + __isl_take isl_set *context) + +A top-level guard node (right underneath the domain node) can +be introduced into the schedule using the following function. + + #include + __isl_give isl_schedule *isl_schedule_insert_guard( + __isl_take isl_schedule *schedule, + __isl_take isl_set *guard) + +A schedule that combines two schedules either in the given +order or in an arbitrary order, i.e., with an C +or an C node, +can be created using the following functions. + + #include + __isl_give isl_schedule *isl_schedule_sequence( + __isl_take isl_schedule *schedule1, + __isl_take isl_schedule *schedule2); + __isl_give isl_schedule *isl_schedule_set( + __isl_take isl_schedule *schedule1, + __isl_take isl_schedule *schedule2); + +The domains of the two input schedules need to be disjoint. + +The following function can be used to restrict the domain +of a schedule with a domain node as root to be a subset of the given union set. +This operation may remove nodes in the tree that have become +redundant. + + #include + __isl_give isl_schedule *isl_schedule_intersect_domain( + __isl_take isl_schedule *schedule, + __isl_take isl_union_set *domain); + +The following function resets the user pointers on all parameter +and tuple identifiers referenced by the nodes of the given schedule. + + #include + __isl_give isl_schedule *isl_schedule_reset_user( + __isl_take isl_schedule *schedule); + +The following function aligns the parameters of all nodes +in the given schedule to the given space. + + #include + __isl_give isl_schedule *isl_schedule_align_params( + __isl_take isl_schedule *schedule, + __isl_take isl_space *space); + +The following function allows the user to plug in a given function +in the iteration domains. The input schedule is not allowed to contain +any expansion nodes. + + #include + __isl_give isl_schedule * + isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma); + +An C representation of the schedule can be obtained +from an C using the following function. + + #include + __isl_give isl_union_map *isl_schedule_get_map( + __isl_keep isl_schedule *sched); + +The resulting relation encodes the same relative ordering as +the schedule by mapping the domain elements to a common schedule space. +If the schedule_separate_components option is set, then the order +of the children of a set node is explicitly encoded in the result. +If the tree contains any expansion nodes, then the relation +is formulated in terms of the expanded domain elements. + +Schedules can be read from input using the following functions. + + #include + __isl_give isl_schedule *isl_schedule_read_from_file( + isl_ctx *ctx, FILE *input); + __isl_give isl_schedule *isl_schedule_read_from_str( + isl_ctx *ctx, const char *str); + +A representation of the schedule can be printed using + + #include + __isl_give isl_printer *isl_printer_print_schedule( + __isl_take isl_printer *p, + __isl_keep isl_schedule *schedule); + +The schedule tree can be traversed through the use of +C objects that point to a particular +position in the schedule tree. Whenever a C +is use to modify a node in the schedule tree, the original schedule +tree is left untouched and the modifications are performed to a copy +of the tree. The returned C then points to +this modified copy of the tree. + +The root of the schedule tree can be obtained using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_get_root( + __isl_keep isl_schedule *schedule); + +A pointer to a newly created schedule tree with a single domain +node can be created using the following functions. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_from_domain( + __isl_take isl_union_set *domain); + __isl_give isl_schedule_node * + isl_schedule_node_from_extension( + __isl_take isl_union_map *extension); + +C creates a tree with an extension +node as root. + +Schedule nodes can be copied and freed using the following functions. + + #include + __isl_give isl_schedule_node *isl_schedule_node_copy( + __isl_keep isl_schedule_node *node); + __isl_null isl_schedule_node *isl_schedule_node_free( + __isl_take isl_schedule_node *node); + +The following functions can be used to check if two schedule +nodes point to the same position in the same schedule. + + #include + isl_bool isl_schedule_node_is_equal( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +The following properties can be obtained from a schedule node. + + #include + enum isl_schedule_node_type isl_schedule_node_get_type( + __isl_keep isl_schedule_node *node); + enum isl_schedule_node_type + isl_schedule_node_get_parent_type( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule *isl_schedule_node_get_schedule( + __isl_keep isl_schedule_node *node); + +The function C returns the type of +the node, while C returns +type of the parent of the node, which is required to exist. +The function C returns a copy +to the schedule to which the node belongs. + +The following functions can be used to move the schedule node +to a different position in the tree or to check if such a position +exists. + + #include + isl_bool isl_schedule_node_has_parent( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_parent( + __isl_take isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_root( + __isl_take isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_ancestor( + __isl_take isl_schedule_node *node, + int generation); + int isl_schedule_node_n_children( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_child( + __isl_take isl_schedule_node *node, int pos); + isl_bool isl_schedule_node_has_children( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node *isl_schedule_node_first_child( + __isl_take isl_schedule_node *node); + isl_bool isl_schedule_node_has_previous_sibling( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_previous_sibling( + __isl_take isl_schedule_node *node); + isl_bool isl_schedule_node_has_next_sibling( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_next_sibling( + __isl_take isl_schedule_node *node); + +For C, the ancestor of generation 0 +is the node itself, the ancestor of generation 1 is its parent and so on. + +It is also possible to query the number of ancestors of a node, +the position of the current node +within the children of its parent, the position of the subtree +containing a node within the children of an ancestor +or to obtain a copy of a given +child without destroying the current node. +Given two nodes that point to the same schedule, their closest +shared ancestor can be obtained using +C. + + #include + int isl_schedule_node_get_tree_depth( + __isl_keep isl_schedule_node *node); + int isl_schedule_node_get_child_position( + __isl_keep isl_schedule_node *node); + int isl_schedule_node_get_ancestor_child_position( + __isl_keep isl_schedule_node *node, + __isl_keep isl_schedule_node *ancestor); + __isl_give isl_schedule_node *isl_schedule_node_get_child( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_get_shared_ancestor( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +All nodes in a schedule tree or +all descendants of a specific node (including the node) can be visited +in depth-first pre-order using the following functions. + + #include + isl_stat isl_schedule_foreach_schedule_node_top_down( + __isl_keep isl_schedule *sched, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, + void *user), void *user); + + #include + isl_stat isl_schedule_node_foreach_descendant_top_down( + __isl_keep isl_schedule_node *node, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, + void *user), void *user); + +The callback function is slightly different from the usual +callbacks in that it not only indicates success (non-negative result) +or failure (negative result), but also indicates whether the children +of the given node should be visited. In particular, if the callback +returns a positive value, then the children are visited, but if +the callback returns zero, then the children are not visited. + +The ancestors of a node in a schedule tree can be visited from +the root down to and including the parent of the node using +the following function. + + #include + isl_stat isl_schedule_node_foreach_ancestor_top_down( + __isl_keep isl_schedule_node *node, + isl_stat (*fn)(__isl_keep isl_schedule_node *node, + void *user), void *user); + +The following functions allows for a depth-first post-order +traversal of the nodes in a schedule tree or +of the descendants of a specific node (including the node +itself), where the user callback is allowed to modify the +visited node. + + #include + __isl_give isl_schedule * + isl_schedule_map_schedule_node_bottom_up( + __isl_take isl_schedule *schedule, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, + void *user), void *user); + + #include + __isl_give isl_schedule_node * + isl_schedule_node_map_descendant_bottom_up( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, + void *user), void *user); + +The traversal continues from the node returned by the callback function. +It is the responsibility of the user to ensure that this does not +lead to an infinite loop. It is safest to always return a pointer +to the same position (same ancestors and child positions) as the input node. + +The following function removes a node (along with its descendants) +from a schedule tree and returns a pointer to the leaf at the +same position in the updated tree. +It is not allowed to remove the root of a schedule tree or +a child of a set or sequence node. + + #include + __isl_give isl_schedule_node *isl_schedule_node_cut( + __isl_take isl_schedule_node *node); + +The following function removes a single node +from a schedule tree and returns a pointer to the child +of the node, now located at the position of the original node +or to a leaf node at that position if there was no child. +It is not allowed to remove the root of a schedule tree, +a set or sequence node, a child of a set or sequence node or +a band node with an anchored subtree. + + #include + __isl_give isl_schedule_node *isl_schedule_node_delete( + __isl_take isl_schedule_node *node); + +Most nodes in a schedule tree only contain local information. +In some cases, however, a node may also refer to outer band nodes. +This means that the position of the node within the tree should +not be changed, or at least that no changes are performed to the +outer band nodes. The following function can be used to test +whether the subtree rooted at a given node contains any such nodes. + + #include + isl_bool isl_schedule_node_is_subtree_anchored( + __isl_keep isl_schedule_node *node); + +The following function resets the user pointers on all parameter +and tuple identifiers referenced by the given schedule node. + + #include + __isl_give isl_schedule_node *isl_schedule_node_reset_user( + __isl_take isl_schedule_node *node); + +The following function aligns the parameters of the given schedule +node to the given space. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_align_params( + __isl_take isl_schedule_node *node, + __isl_take isl_space *space); + +Several node types have their own functions for querying +(and in some cases setting) some node type specific properties. + + #include + __isl_give isl_space *isl_schedule_node_band_get_space( + __isl_keep isl_schedule_node *node); + __isl_give isl_multi_union_pw_aff * + isl_schedule_node_band_get_partial_schedule( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_band_get_partial_schedule_union_map( + __isl_keep isl_schedule_node *node); + unsigned isl_schedule_node_band_n_member( + __isl_keep isl_schedule_node *node); + isl_bool isl_schedule_node_band_member_get_coincident( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_band_member_set_coincident( + __isl_take isl_schedule_node *node, int pos, + int coincident); + isl_bool isl_schedule_node_band_get_permutable( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_band_set_permutable( + __isl_take isl_schedule_node *node, int permutable); + enum isl_ast_loop_type + isl_schedule_node_band_member_get_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_band_member_set_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); + __isl_give isl_union_set * + enum isl_ast_loop_type + isl_schedule_node_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); + __isl_give isl_schedule_node * + isl_schedule_node_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); + isl_schedule_node_band_get_ast_build_options( + __isl_keep isl_schedule_node *node); + __isl_give isl_schedule_node * + isl_schedule_node_band_set_ast_build_options( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *options); + +The function C returns the space +of the partial schedule of the band. +The function C +returns a representation of the partial schedule of the band node +in the form of an C. +The coincident and permutable properties are set by +C on the schedule tree +it produces. +A scheduling dimension is considered to be ``coincident'' +if it satisfies the coincidence constraints within its band. +That is, if the dependence distances of the coincidence +constraints are all zero in that direction (for fixed +iterations of outer bands). +A band is marked permutable if it was produced using the Pluto-like scheduler. +Note that the scheduler may have to resort to a Feautrier style scheduling +step even if the default scheduler is used. +An C is one of C, +C, C or C. +For the meaning of these loop AST generation types and the difference +between the regular loop AST generation type and the isolate +loop AST generation type, see L. +The functions C +and C +may return C if an error occurs. +The AST build options govern how an AST is generated for +the individual schedule dimensions during AST generation. +See L. + + #include + __isl_give isl_set * + isl_schedule_node_context_get_context( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_set * + isl_schedule_node_domain_get_domain( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_map * + isl_schedule_node_expansion_get_expansion( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_pw_multi_aff * + isl_schedule_node_expansion_get_contraction( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_map * + isl_schedule_node_extension_get_extension( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_union_set * + isl_schedule_node_filter_get_filter( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_set *isl_schedule_node_guard_get_guard( + __isl_keep isl_schedule_node *node); + + #include + __isl_give isl_id *isl_schedule_node_mark_get_id( + __isl_keep isl_schedule_node *node); + +The following functions can be used to obtain an C, +an C or C representation of +partial schedules related to the node. + + #include + __isl_give isl_multi_union_pw_aff * + isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_pw_multi_aff * + isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_get_prefix_schedule_union_map( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_get_prefix_schedule_relation( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_map * + isl_schedule_node_get_subtree_schedule_union_map( + __isl_keep isl_schedule_node *node); + +In particular, the functions +C, +C +and C +return a relative ordering on the domain elements that reach the given +node determined by its ancestors. +The function C +additionally includes the domain constraints in the result. +The function C +returns a representation of the partial schedule defined by the +subtree rooted at the given node. +If the tree contains any expansion nodes, then the subtree schedule +is formulated in terms of the expanded domain elements. +The tree passed to functions returning a prefix schedule +may only contain extension nodes if these would not affect +the result of these functions. That is, if one of the ancestors +is an extension node, then all of the domain elements that were +added by the extension node need to have been filtered out +by filter nodes between the extension node and the input node. +The tree passed to C +may not contain in extension nodes in the selected subtree. + +The expansion/contraction defined by an entire subtree, combining +the expansions/contractions +on the expansion nodes in the subtree, can be obtained using +the following functions. + + #include + __isl_give isl_union_map * + isl_schedule_node_get_subtree_expansion( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_pw_multi_aff * + isl_schedule_node_get_subtree_contraction( + __isl_keep isl_schedule_node *node); + +The total number of outer band members of given node, i.e., +the shared output dimension of the maps in the result +of C can be obtained +using the following function. + + #include + int isl_schedule_node_get_schedule_depth( + __isl_keep isl_schedule_node *node); + +The following functions return the elements that reach the given node +or the union of universes in the spaces that contain these elements. + + #include + __isl_give isl_union_set * + isl_schedule_node_get_domain( + __isl_keep isl_schedule_node *node); + __isl_give isl_union_set * + isl_schedule_node_get_universe_domain( + __isl_keep isl_schedule_node *node); + +The input tree of C +may only contain extension nodes if these would not affect +the result of this function. That is, if one of the ancestors +is an extension node, then all of the domain elements that were +added by the extension node need to have been filtered out +by filter nodes between the extension node and the input node. + +The following functions can be used to introduce additional nodes +in the schedule tree. The new node is introduced at the point +in the tree where the C points to and +the results points to the new node. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_partial_schedule( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *schedule); + +This function inserts a new band node with (the greatest integer +part of) the given partial schedule. +The subtree rooted at the given node is assumed not to have +any anchored nodes. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_context( + __isl_take isl_schedule_node *node, + __isl_take isl_set *context); + +This function inserts a new context node with the given context constraints. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_filter( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *filter); + +This function inserts a new filter node with the given filter. +If the original node already pointed to a filter node, then the +two filter nodes are merged into one. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_guard( + __isl_take isl_schedule_node *node, + __isl_take isl_set *guard); + +This function inserts a new guard node with the given guard constraints. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_mark( + __isl_take isl_schedule_node *node, + __isl_take isl_id *mark); + +This function inserts a new mark node with the give mark identifier. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_insert_sequence( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); + __isl_give isl_schedule_node * + isl_schedule_node_insert_set( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); + +These functions insert a new sequence or set node with the given +filters as children. + + #include + __isl_give isl_schedule_node *isl_schedule_node_group( + __isl_take isl_schedule_node *node, + __isl_take isl_id *group_id); + +This function introduces an expansion node in between the current +node and its parent that expands instances of a space with tuple +identifier C to the original domain elements that reach +the node. The group instances are identified by the prefix schedule +of those domain elements. The ancestors of the node are adjusted +to refer to the group instances instead of the original domain +elements. The return value points to the same node in the updated +schedule tree as the input node, i.e., to the child of the newly +introduced expansion node. Grouping instances of different statements +ensures that they will be treated as a single statement by the +AST generator up to the point of the expansion node. + +The partial schedule of a band node can be scaled (down) using +the following functions. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *mv); + __isl_give isl_schedule_node * + isl_schedule_node_band_scale_down( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *mv); + +The spaces of the two arguments need to match. +After scaling, the partial schedule is replaced by its greatest +integer part to ensure that the schedule remains integral. + +A band node can be tiled using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_node_band_tile( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_val *sizes); + + isl_stat isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, + int val); + int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx); + isl_stat isl_options_set_tile_shift_point_loops(isl_ctx *ctx, + int val); + int isl_options_get_tile_shift_point_loops(isl_ctx *ctx); + +The C function tiles +the band using the given tile sizes inside its schedule. +A new child band node is created to represent the point loops and it is +inserted between the modified band and its children. +The subtree rooted at the given node is assumed not to have +any anchored nodes. +The C option specifies whether the tile +loops iterators should be scaled by the tile sizes. +If the C option is set, then the point loops +are shifted to start at zero. + +A band node can be split into two nested band nodes +using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_node_band_split( + __isl_take isl_schedule_node *node, int pos); + +The resulting outer band node contains the first C dimensions of +the schedule of C while the inner band contains the remaining dimensions. +The schedules of the two band nodes live in anonymous spaces. + +A band node can be moved down to the leaves of the subtree rooted +at the band node using the following function. + + #include + __isl_give isl_schedule_node *isl_schedule_node_band_sink( + __isl_take isl_schedule_node *node); + +The subtree rooted at the given node is assumed not to have +any anchored nodes. +The result points to the node in the resulting tree that is in the same +position as the node pointed to by C in the original tree. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_order_after( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set *filter); + +This function splits the domain elements that reach C +into those that satisfy C and those that do not and +arranges for the elements that do satisfy the filter to be +executed after those that do not. The order is imposed by +a sequence node, possibly reusing the grandparent of C +on two copies of the subtree attached to the original C. +Both copies are simplified with respect to their filter. + +Return a pointer to the copy of the subtree that does not +satisfy C. If there is no such copy (because all +reaching domain elements satisfy the filter), then return +the original pointer. + + #include + __isl_give isl_schedule_node * + isl_schedule_node_graft_before( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); + __isl_give isl_schedule_node * + isl_schedule_node_graft_after( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); + +This function inserts the C tree into the tree containing C +such that it is executed before (in case of C) +or after (in case of C) C. +The root node of C +should be an extension node where the domain of the extension +is the flat product of all outer band nodes of C. +The root node may also be a domain node. +The elements of the domain or the range of the extension may not +intersect with the domain elements that reach "node". +The schedule tree of C may not be anchored. + +The schedule tree of C is modified to include an extension node +corresponding to the root node of C as a child of the original +parent of C. The original node that C points to and the +child of the root node of C are attached to this extension node +through a sequence, with appropriate filters and with the child +of C appearing before or after the original C. + +If C already appears inside a sequence that is the child of +an extension node and if the spaces of the new domain elements +do not overlap with those of the original domain elements, +then that extension node is extended with the new extension +rather than introducing a new segment of extension and sequence nodes. + +Return a pointer to the same node in the modified tree that +C pointed to in the original tree. + +A representation of the schedule node can be printed using + + #include + __isl_give isl_printer *isl_printer_print_schedule_node( + __isl_take isl_printer *p, + __isl_keep isl_schedule_node *node); + =head2 Dependence Analysis C contains specialized functionality for performing @@ -5342,6 +8245,99 @@ If, on the other hand, all sources are I accesses, then value based dependence analysis is performed. +=head3 High-level Interface + +A high-level interface to dependence analysis is provided +by the following function. + + #include + __isl_give isl_union_flow * + isl_union_access_info_compute_flow( + __isl_take isl_union_access_info *access); + +The input C object describes the sink +access relations, the source access relations and a schedule, +while the output C object describes +the resulting dependence relations and the subsets of the +sink relations for which no source was found. + +An C is created, modified, copied and freed using +the following functions. + + #include + __isl_give isl_union_access_info * + isl_union_access_info_from_sink( + __isl_take isl_union_map *sink); + __isl_give isl_union_access_info * + isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source); + __isl_give isl_union_access_info * + isl_union_access_info_set_may_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *may_source); + __isl_give isl_union_access_info * + isl_union_access_info_set_schedule( + __isl_take isl_union_access_info *access, + __isl_take isl_schedule *schedule); + __isl_give isl_union_access_info * + isl_union_access_info_set_schedule_map( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *schedule_map); + __isl_give isl_union_access_info * + isl_union_access_info_copy( + __isl_keep isl_union_access_info *access); + __isl_null isl_union_access_info * + isl_union_access_info_free( + __isl_take isl_union_access_info *access); + +The may sources set by C +do not need to include the must sources set by +C as a subset. +The user is free not to call one (or both) of these functions, +in which case the corresponding set is kept to its empty default. +Similarly, the default schedule initialized by +C is empty. +The current schedule is determined by the last call to either +C or +C. +The domain of the schedule corresponds to the domains of +the access relations. In particular, the domains of the access +relations are effectively intersected with the domain of the schedule +and only the resulting accesses are considered by the dependence analysis. + +The output of C can be examined +and freed using the following functions. + + #include + __isl_give isl_union_map *isl_union_flow_get_must_dependence( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map *isl_union_flow_get_may_dependence( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map *isl_union_flow_get_must_no_source( + __isl_keep isl_union_flow *flow); + __isl_give isl_union_map *isl_union_flow_get_may_no_source( + __isl_keep isl_union_flow *flow); + __isl_null isl_union_flow *isl_union_flow_free( + __isl_take isl_union_flow *flow); + +The relation returned by C +relates domain elements of must sources to domain elements of the sink. +The relation returned by C +relates domain elements of must or may sources to domain elements of the sink +and includes the previous relation as a subset. +The relation returned by C is the subset +of the sink relation for which no dependences have been found. +The relation returned by C is the subset +of the sink relation for which no definite dependences have been found. +That is, it contains those sink access that do not contribute to any +of the elements in the relation returned +by C. + +=head3 Low-level Interface + +A lower-level interface is provided by the following functions. + #include typedef int (*isl_access_level_before)(void *first, void *second); @@ -5354,13 +8350,14 @@ __isl_take isl_access_info *acc, __isl_take isl_map *source, int must, void *source_user); - void *isl_access_info_free(__isl_take isl_access_info *acc); + __isl_null isl_access_info *isl_access_info_free( + __isl_take isl_access_info *acc); __isl_give isl_flow *isl_access_info_compute_flow( __isl_take isl_access_info *acc); - int isl_flow_foreach(__isl_keep isl_flow *deps, - int (*fn)(__isl_take isl_map *dep, int must, + isl_stat isl_flow_foreach(__isl_keep isl_flow *deps, + isl_stat (*fn)(__isl_take isl_map *dep, int must, void *dep_user, void *user), void *user); __isl_give isl_map *isl_flow_get_no_source( @@ -5426,31 +8423,7 @@ After finishing with an C, the user should call C to free all associated memory. -A higher-level interface to dependence analysis is provided -by the following function. - - #include - - int isl_union_map_compute_flow(__isl_take isl_union_map *sink, - __isl_take isl_union_map *must_source, - __isl_take isl_union_map *may_source, - __isl_take isl_union_map *schedule, - __isl_give isl_union_map **must_dep, - __isl_give isl_union_map **may_dep, - __isl_give isl_union_map **must_no_source, - __isl_give isl_union_map **may_no_source); - -The arrays are identified by the tuple names of the ranges -of the accesses. The iteration domains by the tuple names -of the domains of the accesses and of the schedule. -The relative order of the iteration domains is given by the -schedule. The relations returned through C -and C are subsets of C. -Any of C, C, C -or C may be C, but a C value for -any of the other arguments is treated as an error. - -=head3 Interaction with Dependence Analysis +=head3 Interaction with the Low-level Interface During the dependence analysis, we frequently need to perform the following operation. Given a relation between sink iterations @@ -5508,10 +8481,8 @@ __isl_take isl_map *source_map); __isl_give isl_restriction *isl_restriction_empty( __isl_take isl_map *source_map); - void *isl_restriction_free( + __isl_null isl_restriction *isl_restriction_free( __isl_take isl_restriction *restr); - isl_ctx *isl_restriction_get_ctx( - __isl_keep isl_restriction *restr); C and C are special cases of C. C @@ -5534,179 +8505,185 @@ B -The following function can be used to compute a schedule -for a union of domains. + #include + __isl_give isl_schedule * + isl_schedule_constraints_compute_schedule( + __isl_take isl_schedule_constraints *sc); + +The function C can be +used to compute a schedule that satisfies the given schedule constraints. +These schedule constraints include the iteration domain for which +a schedule should be computed and dependences between pairs of +iterations. In particular, these dependences include +I dependences and I dependences. By default, the algorithm used to construct the schedule is similar to that of C. Alternatively, Feautrier's multi-dimensional scheduling algorithm can be selected. -The generated schedule respects all C dependences. +The generated schedule respects all validity dependences. That is, all dependence distances over these dependences in the scheduled space are lexicographically positive. -The default algorithm tries to minimize the dependence distances over -C dependences. + +The default algorithm tries to ensure that the dependence distances +over coincidence constraints are zero and to minimize the +dependence distances over proximity dependences. Moreover, it tries to obtain sequences (bands) of schedule dimensions -for groups of domains where the dependence distances have only -non-negative values. -When using Feautrier's algorithm, the C dependence -distances are only minimized during the extension to a +for groups of domains where the dependence distances over validity +dependences have only non-negative values. +Note that when minimizing the maximal dependence distance +over proximity dependences, a single affine expression in the parameters +is constructed that bounds all dependence distances. If no such expression +exists, then the algorithm will fail and resort to an alternative +scheduling algorithm. In particular, this means that adding proximity +dependences may eliminate valid solutions. A typical example where this +phenomenon may occur is when some subset of the proximity dependences +has no restriction on some parameter, forcing the coefficient of that +parameter to be zero, while some other subset forces the dependence +distance to depend on that parameter, requiring the same coefficient +to be non-zero. +When using Feautrier's algorithm, the coincidence and proximity constraints +are only taken into account during the extension to a full-dimensional schedule. +An C object can be constructed +and manipulated using the following functions. + #include - __isl_give isl_schedule *isl_union_set_compute_schedule( - __isl_take isl_union_set *domain, - __isl_take isl_union_map *validity, + __isl_give isl_schedule_constraints * + isl_schedule_constraints_copy( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_on_domain( + __isl_take isl_union_set *domain); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_context( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_set *context); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *validity); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_coincidence( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *coincidence); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_proximity( + __isl_take isl_schedule_constraints *sc, __isl_take isl_union_map *proximity); - void *isl_schedule_free(__isl_take isl_schedule *sched); - -A mapping from the domains to the scheduled space can be obtained -from an C using the following function. - - __isl_give isl_union_map *isl_schedule_get_map( - __isl_keep isl_schedule *sched); - -A representation of the schedule can be printed using - - __isl_give isl_printer *isl_printer_print_schedule( - __isl_take isl_printer *p, - __isl_keep isl_schedule *schedule); - -A representation of the schedule as a forest of bands can be obtained -using the following function. - - __isl_give isl_band_list *isl_schedule_get_band_forest( - __isl_keep isl_schedule *schedule); + __isl_give isl_schedule_constraints * + isl_schedule_constraints_set_conditional_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *condition, + __isl_take isl_union_map *validity); + __isl_null isl_schedule_constraints * + isl_schedule_constraints_free( + __isl_take isl_schedule_constraints *sc); + +The initial C object created by +C does not impose any constraints. +That is, it has an empty set of dependences. +The function C allows the user +to specify additional constraints on the parameters that may +be assumed to hold during the construction of the schedule. +The function C replaces the +validity dependences, mapping domain elements I to domain +elements that should be scheduled after I. +The function C replaces the +coincidence dependences, mapping domain elements I to domain +elements that should be scheduled together with I, if possible. +The function C replaces the +proximity dependences, mapping domain elements I to domain +elements that should be scheduled either before I +or as early as possible after I. + +The function C +replaces the conditional validity constraints. +A conditional validity constraint is only imposed when any of the corresponding +conditions is satisfied, i.e., when any of them is non-zero. +That is, the scheduler ensures that within each band if the dependence +distances over the condition constraints are not all zero +then all corresponding conditional validity constraints are respected. +A conditional validity constraint corresponds to a condition +if the two are adjacent, i.e., if the domain of one relation intersect +the range of the other relation. +The typical use case of conditional validity constraints is +to allow order constraints between live ranges to be violated +as long as the live ranges themselves are local to the band. +To allow more fine-grained control over which conditions correspond +to which conditional validity constraints, the domains and ranges +of these relations may include I. That is, the domains and +ranges of those relation may themselves be wrapped relations +where the iteration domain appears in the domain of those wrapped relations +and the range of the wrapped relations can be arbitrarily chosen +by the user. Conditions and conditional validity constraints are only +considered adjacent to each other if the entire wrapped relation matches. +In particular, a relation with a tag will never be considered adjacent +to a relation without a tag. -The individual bands can be visited in depth-first post-order -using the following function. +An C object can be inspected +using the following functions. #include - int isl_schedule_foreach_band( - __isl_keep isl_schedule *sched, - int (*fn)(__isl_keep isl_band *band, void *user), - void *user); - -The list can be manipulated as explained in L<"Lists">. -The bands inside the list can be copied and freed using the following -functions. - - #include - __isl_give isl_band *isl_band_copy( - __isl_keep isl_band *band); - void *isl_band_free(__isl_take isl_band *band); - -Each band contains zero or more scheduling dimensions. -These are referred to as the members of the band. -The section of the schedule that corresponds to the band is -referred to as the partial schedule of the band. -For those nodes that participate in a band, the outer scheduling -dimensions form the prefix schedule, while the inner scheduling -dimensions form the suffix schedule. -That is, if we take a cut of the band forest, then the union of -the concatenations of the prefix, partial and suffix schedules of -each band in the cut is equal to the entire schedule (modulo -some possible padding at the end with zero scheduling dimensions). -The properties of a band can be inspected using the following functions. - - #include - isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band); - - int isl_band_has_children(__isl_keep isl_band *band); - __isl_give isl_band_list *isl_band_get_children( - __isl_keep isl_band *band); - - __isl_give isl_union_map *isl_band_get_prefix_schedule( - __isl_keep isl_band *band); - __isl_give isl_union_map *isl_band_get_partial_schedule( - __isl_keep isl_band *band); - __isl_give isl_union_map *isl_band_get_suffix_schedule( - __isl_keep isl_band *band); - - int isl_band_n_member(__isl_keep isl_band *band); - int isl_band_member_is_zero_distance( - __isl_keep isl_band *band, int pos); - - int isl_band_list_foreach_band( - __isl_keep isl_band_list *list, - int (*fn)(__isl_keep isl_band *band, void *user), - void *user); - -Note that a scheduling dimension is considered to be ``zero -distance'' if it does not carry any proximity dependences -within its band. -That is, if the dependence distances of the proximity -dependences are all zero in that direction (for fixed -iterations of outer bands). -Like C, -the function C calls C on the bands -in depth-first post-order. - -A band can be tiled using the following function. - - #include - int isl_band_tile(__isl_keep isl_band *band, - __isl_take isl_vec *sizes); - - int isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, - int val); - int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx); - int isl_options_set_tile_shift_point_loops(isl_ctx *ctx, - int val); - int isl_options_get_tile_shift_point_loops(isl_ctx *ctx); - -The C function tiles the band using the given tile sizes -inside its schedule. -A new child band is created to represent the point loops and it is -inserted between the modified band and its children. -The C option specifies whether the tile -loops iterators should be scaled by the tile sizes. -If the C option is set, then the point loops -are shifted to start at zero. - -A band can be split into two nested bands using the following function. - - int isl_band_split(__isl_keep isl_band *band, int pos); + __isl_give isl_union_map * + isl_schedule_constraints_get_validity( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_coincidence( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_conditional_validity( + __isl_keep isl_schedule_constraints *sc); + __isl_give isl_union_map * + isl_schedule_constraints_get_conditional_validity_condition( + __isl_keep isl_schedule_constraints *sc); -The resulting outer band contains the first C dimensions of C -while the inner band contains the remaining dimensions. +The following function computes a schedule directly from +an iteration domain and validity and proximity dependences +and is implemented in terms of the functions described above. +The use of C is discouraged. -A representation of the band can be printed using + #include + __isl_give isl_schedule *isl_union_set_compute_schedule( + __isl_take isl_union_set *domain, + __isl_take isl_union_map *validity, + __isl_take isl_union_map *proximity); - #include - __isl_give isl_printer *isl_printer_print_band( - __isl_take isl_printer *p, - __isl_keep isl_band *band); +The generated schedule represents a schedule tree. +For more information on schedule trees, see +L. =head3 Options #include - int isl_options_set_schedule_max_coefficient( + isl_stat isl_options_set_schedule_max_coefficient( isl_ctx *ctx, int val); int isl_options_get_schedule_max_coefficient( isl_ctx *ctx); - int isl_options_set_schedule_max_constant_term( + isl_stat isl_options_set_schedule_max_constant_term( isl_ctx *ctx, int val); int isl_options_get_schedule_max_constant_term( isl_ctx *ctx); - int isl_options_set_schedule_fuse(isl_ctx *ctx, int val); - int isl_options_get_schedule_fuse(isl_ctx *ctx); - int isl_options_set_schedule_maximize_band_depth( + isl_stat isl_options_set_schedule_serialize_sccs( + isl_ctx *ctx, int val); + int isl_options_get_schedule_serialize_sccs(isl_ctx *ctx); + isl_stat isl_options_set_schedule_maximize_band_depth( isl_ctx *ctx, int val); int isl_options_get_schedule_maximize_band_depth( isl_ctx *ctx); - int isl_options_set_schedule_outer_zero_distance( + isl_stat isl_options_set_schedule_outer_coincidence( isl_ctx *ctx, int val); - int isl_options_get_schedule_outer_zero_distance( + int isl_options_get_schedule_outer_coincidence( isl_ctx *ctx); - int isl_options_set_schedule_split_scaled( + isl_stat isl_options_set_schedule_split_scaled( isl_ctx *ctx, int val); int isl_options_get_schedule_split_scaled( isl_ctx *ctx); - int isl_options_set_schedule_algorithm( + isl_stat isl_options_set_schedule_algorithm( isl_ctx *ctx, int val); int isl_options_get_schedule_algorithm( isl_ctx *ctx); - int isl_options_set_schedule_separate_components( + isl_stat isl_options_set_schedule_separate_components( isl_ctx *ctx, int val); int isl_options_get_schedule_separate_components( isl_ctx *ctx); @@ -5730,13 +8707,14 @@ unrelated dimensions. A value of -1 means that this option does not introduce bounds on the constant coefficients. -=item * schedule_fuse +=item * schedule_serialize_sccs -This option controls the level of fusion. -If this option is set to C, then loops in the -resulting schedule will be distributed as much as possible. -If this option is set to C, then C will -try to fuse loops in the resulting schedule. +If this option is set, then all strongly connected components +in the dependence graph are serialized as soon as they are detected. +This means in particular that instances of statements will only +appear in the same band node if these statements belong +to the same strongly connected component at the point where +the band node is constructed. =item * schedule_maximize_band_depth @@ -5745,16 +8723,15 @@ backtrack and split bands as early as possible. This reduces the number of splits and maximizes the width of the bands. Wider bands give more possibilities for tiling. -Note that if the C option is set to C, +Note that if the C options is set, then bands will be split as early as possible, even if there is no need. The C option therefore has no effect in this case. -=item * schedule_outer_zero_distance +=item * schedule_outer_coincidence If this option is set, then we try to construct schedules where the outermost scheduling dimension in each band -results in a zero dependence distance over the proximity -dependences. +satisfies the coincidence constraints. =item * schedule_split_scaled @@ -5773,12 +8750,8 @@ =item * schedule_separate_components -If at any point the dependence graph contains any (weakly connected) components, -then these components are scheduled separately. -If this option is not set, then some iterations of the domains -in these components may be scheduled together. -If this option is set, then the components are given consecutive -schedules. +If this option is set then the function C +will treat set nodes in the same way as sequence nodes. =back @@ -5786,40 +8759,51 @@ This section describes the C functionality for generating ASTs that visit all the elements -in a domain in an order specified by a schedule. -In particular, given a C, an AST is generated +in a domain in an order specified by a schedule tree or +a schedule map. +In case the schedule given as a C, an AST is generated that visits all the elements in the domain of the C according to the lexicographic order of the corresponding image element(s). If the range of the C consists of elements in more than one space, then each of these spaces is handled separately in an arbitrary order. -It should be noted that the image elements only specify the I +It should be noted that the schedule tree or the image elements +in a schedule map only specify the I in which the corresponding domain elements should be visited. -No direct relation between the image elements and the loop iterators -in the generated AST should be assumed. +No direct relation between the partial schedule values +or the image elements on the one hand and the loop iterators +in the generated AST on the other hand should be assumed. Each AST is generated within a build. The initial build simply specifies the constraints on the parameters (if any) and can be created, inspected, copied and freed using the following functions. #include + __isl_give isl_ast_build *isl_ast_build_alloc( + isl_ctx *ctx); __isl_give isl_ast_build *isl_ast_build_from_context( __isl_take isl_set *set); - isl_ctx *isl_ast_build_get_ctx( - __isl_keep isl_ast_build *build); __isl_give isl_ast_build *isl_ast_build_copy( __isl_keep isl_ast_build *build); - void *isl_ast_build_free( + __isl_null isl_ast_build *isl_ast_build_free( __isl_take isl_ast_build *build); The C argument is usually a parameter set with zero or more parameters. +In fact, when creating an AST using C, +this set is required to be a parameter set. +An C created using C does not +specify any parameter constraints. More C functions are described in L and L. -Finally, the AST itself can be constructed using the following -function. +Finally, the AST itself can be constructed using one of the following +functions. #include - __isl_give isl_ast_node *isl_ast_build_ast_from_schedule( + __isl_give isl_ast_node *isl_ast_build_node_from_schedule( + __isl_keep isl_ast_build *build, + __isl_take isl_schedule *schedule); + __isl_give isl_ast_node * + isl_ast_build_node_from_schedule_map( __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule); @@ -5828,19 +8812,19 @@ The basic properties of an AST node can be obtained as follows. #include - isl_ctx *isl_ast_node_get_ctx( - __isl_keep isl_ast_node *node); enum isl_ast_node_type isl_ast_node_get_type( __isl_keep isl_ast_node *node); The type of an AST node is one of C, C, -C or +C, +C or C. An C represents a for node. An C represents an if node. An C represents a compound node. +An C introduces a mark in the AST. An C represents an expression statement. An expression statement typically corresponds to a domain element, i.e., one of the elements that is visited by the AST. @@ -5858,7 +8842,7 @@ __isl_keep isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_for_get_body( __isl_keep isl_ast_node *node); - int isl_ast_node_for_is_degenerate( + isl_bool isl_ast_node_for_is_degenerate( __isl_keep isl_ast_node *node); An C is considered degenerate if it is known to execute @@ -5869,7 +8853,7 @@ __isl_keep isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_if_get_then( __isl_keep isl_ast_node *node); - int isl_ast_node_if_has_else( + isl_bool isl_ast_node_if_has_else( __isl_keep isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_if_get_else( __isl_keep isl_ast_node *node); @@ -5878,6 +8862,15 @@ isl_ast_node_block_get_children( __isl_keep isl_ast_node *node); + __isl_give isl_id *isl_ast_node_mark_get_id( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_node *isl_ast_node_mark_get_node( + __isl_keep isl_ast_node *node); + +C returns the identifier of the mark. +C returns the child node that is being marked. + + #include __isl_give isl_ast_expr *isl_ast_node_user_get_expr( __isl_keep isl_ast_node *node); @@ -5885,8 +8878,6 @@ the following functions. #include - isl_ctx *isl_ast_expr_get_ctx( - __isl_keep isl_ast_expr *expr); enum isl_ast_expr_type isl_ast_expr_get_type( __isl_keep isl_ast_expr *expr); @@ -5906,10 +8897,10 @@ int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr); __isl_give isl_ast_expr *isl_ast_expr_get_op_arg( __isl_keep isl_ast_expr *expr, int pos); - int isl_ast_node_foreach_ast_op_type( + isl_stat isl_ast_node_foreach_ast_op_type( __isl_keep isl_ast_node *node, - int (*fn)(enum isl_ast_op_type type, void *user), - void *user); + isl_stat (*fn)(enum isl_ast_op_type type, + void *user), void *user); C returns the type of the operation performed. C returns the number of @@ -5982,6 +8973,10 @@ Remainder of integer division, where dividend is known to be non-negative. +=item C + +Equal to zero iff the remainder on integer division is zero. + =item C Conditional operator defined on three arguments. @@ -6029,6 +9024,19 @@ the number of arguments in the function call, the first argument representing the function being called. +=item C + +An array access. +The number of arguments of the C is one more than +the number of index expressions in the array access, the first argument +representing the array being accessed. + +=item C + +A member access. +This operation has two arguments, a structure and the name of +the member of the structure being accessed. + =back #include @@ -6038,16 +9046,19 @@ Return the identifier represented by the AST expression. #include - int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, - isl_int *v); __isl_give isl_val *isl_ast_expr_get_val( __isl_keep isl_ast_expr *expr); Return the integer represented by the AST expression. -Note that the integer is returned by C -through the C argument. -The return value of this function itself indicates whether the -operation was performed successfully. + +=head3 Properties of ASTs + + #include + isl_bool isl_ast_expr_is_equal( + __isl_keep isl_ast_expr *expr1, + __isl_keep isl_ast_expr *expr2); + +Check if two Cs are equal to each other. =head3 Manipulating and printing the AST @@ -6056,14 +9067,16 @@ #include __isl_give isl_ast_node *isl_ast_node_copy( __isl_keep isl_ast_node *node); - void *isl_ast_node_free(__isl_take isl_ast_node *node); + __isl_null isl_ast_node *isl_ast_node_free( + __isl_take isl_ast_node *node); AST expressions can be copied and freed using the following functions. #include __isl_give isl_ast_expr *isl_ast_expr_copy( __isl_keep isl_ast_expr *expr); - void *isl_ast_expr_free(__isl_take isl_ast_expr *expr); + __isl_null isl_ast_expr *isl_ast_expr_free( + __isl_take isl_ast_expr *expr); New AST expressions can be created either directly or within the context of an C. @@ -6075,6 +9088,8 @@ __isl_take isl_id *id); __isl_give isl_ast_expr *isl_ast_expr_neg( __isl_take isl_ast_expr *expr); + __isl_give isl_ast_expr *isl_ast_expr_address_of( + __isl_take isl_ast_expr *expr); __isl_give isl_ast_expr *isl_ast_expr_add( __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2); @@ -6087,25 +9102,104 @@ __isl_give isl_ast_expr *isl_ast_expr_div( __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_pdiv_q( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_pdiv_r( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); __isl_give isl_ast_expr *isl_ast_expr_and( __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_and_then( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) __isl_give isl_ast_expr *isl_ast_expr_or( __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_or_else( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) + __isl_give isl_ast_expr *isl_ast_expr_eq( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_le( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_lt( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_ge( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_gt( + __isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); + __isl_give isl_ast_expr *isl_ast_expr_access( + __isl_take isl_ast_expr *array, + __isl_take isl_ast_expr_list *indices); + __isl_give isl_ast_expr *isl_ast_expr_call( + __isl_take isl_ast_expr *function, + __isl_take isl_ast_expr_list *arguments); + +The function C can be applied to an +C of type C only. It is meant +to represent the address of the C. The function +C as well as C are short-circuit +versions of C and C, respectively. #include + __isl_give isl_ast_expr *isl_ast_build_expr_from_set( + __isl_keep isl_ast_build *build, + __isl_take isl_set *set); __isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff( __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa); __isl_give isl_ast_expr * + isl_ast_build_access_from_pw_multi_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_ast_expr * + isl_ast_build_access_from_multi_pw_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_multi_pw_aff *mpa); + __isl_give isl_ast_expr * isl_ast_build_call_from_pw_multi_aff( __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma); + __isl_give isl_ast_expr * + isl_ast_build_call_from_multi_pw_aff( + __isl_keep isl_ast_build *build, + __isl_take isl_multi_pw_aff *mpa); -The domains of C and C should correspond +The set and +the domains of C, C and C should correspond to the schedule space of C. -The tuple id of C is used as the function being called. +The tuple id of C or C is used as the array being accessed or +the function being called. +If the accessed space is a nested relation, then it is taken +to represent an access of the member specified by the range +of this nested relation of the structure specified by the domain +of the nested relation. + +The following functions can be used to modify an C. + + #include + __isl_give isl_ast_expr *isl_ast_expr_set_op_arg( + __isl_take isl_ast_expr *expr, int pos, + __isl_take isl_ast_expr *arg); + +Replace the argument of C at position C by C. + + #include + __isl_give isl_ast_expr *isl_ast_expr_substitute_ids( + __isl_take isl_ast_expr *expr, + __isl_take isl_id_to_ast_expr *id2expr); + +The function C replaces the +subexpressions of C of type C +by the corresponding expression in C, if there is any. + User specified data can be attached to an C and obtained from the same C using the following functions. @@ -6126,6 +9220,8 @@ __isl_give isl_printer *isl_printer_print_ast_node( __isl_take isl_printer *p, __isl_keep isl_ast_node *node); + __isl_give char *isl_ast_expr_to_str( + __isl_keep isl_ast_expr *expr); More advanced printing can be performed using the following functions. @@ -6172,7 +9268,8 @@ __isl_give isl_ast_print_options * isl_ast_print_options_copy( __isl_keep isl_ast_print_options *options); - void *isl_ast_print_options_free( + __isl_null isl_ast_print_options * + isl_ast_print_options_free( __isl_take isl_ast_print_options *options); __isl_give isl_ast_print_options * @@ -6208,37 +9305,47 @@ The following option determines the type to be used for iterators while printing the AST. - int isl_options_set_ast_iterator_type( + isl_stat isl_options_set_ast_iterator_type( isl_ctx *ctx, const char *val); const char *isl_options_get_ast_iterator_type( isl_ctx *ctx); +The AST printer only prints body nodes as blocks if these +blocks cannot be safely omitted. +For example, a C node with one body node will not be +surrounded with braces in C. +A block will always be printed by setting the following option. + + isl_stat isl_options_set_ast_always_print_block(isl_ctx *ctx, + int val); + int isl_options_get_ast_always_print_block(isl_ctx *ctx); + =head3 Options #include - int isl_options_set_ast_build_atomic_upper_bound( + isl_stat isl_options_set_ast_build_atomic_upper_bound( isl_ctx *ctx, int val); int isl_options_get_ast_build_atomic_upper_bound( isl_ctx *ctx); - int isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, + isl_stat isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, int val); int isl_options_get_ast_build_prefer_pdiv(isl_ctx *ctx); - int isl_options_set_ast_build_exploit_nested_bounds( + isl_stat isl_options_set_ast_build_exploit_nested_bounds( isl_ctx *ctx, int val); int isl_options_get_ast_build_exploit_nested_bounds( isl_ctx *ctx); - int isl_options_set_ast_build_group_coscheduled( + isl_stat isl_options_set_ast_build_group_coscheduled( isl_ctx *ctx, int val); int isl_options_get_ast_build_group_coscheduled( isl_ctx *ctx); - int isl_options_set_ast_build_scale_strides( + isl_stat isl_options_set_ast_build_scale_strides( isl_ctx *ctx, int val); int isl_options_get_ast_build_scale_strides( isl_ctx *ctx); - int isl_options_set_ast_build_allow_else(isl_ctx *ctx, + isl_stat isl_options_set_ast_build_allow_else(isl_ctx *ctx, int val); int isl_options_get_ast_build_allow_else(isl_ctx *ctx); - int isl_options_set_ast_build_allow_or(isl_ctx *ctx, + isl_stat isl_options_set_ast_build_allow_or(isl_ctx *ctx, int val); int isl_options_get_ast_build_allow_or(isl_ctx *ctx); @@ -6346,13 +9453,223 @@ =back -=head3 Fine-grained Control over AST Generation +=head3 AST Generation Options (Schedule Tree) + +In case of AST construction from a schedule tree, the options +that control how an AST is created from the individual schedule +dimensions are stored in the band nodes of the tree +(see L). + +In particular, a schedule dimension can be handled in four +different ways, atomic, separate, unroll or the default. +This loop AST generation type can be set using +C. +Alternatively, +the first three can be selected by including a one-dimensional +element with as value the position of the schedule dimension +within the band and as name one of C, C +or C in the options +set by C. +Only one of these three may be specified for +any given schedule dimension within a band node. +If none of these is specified, then the default +is used. The meaning of the options is as follows. + +=over + +=item C + +When this option is specified, the AST generator will make +sure that a given domains space only appears in a single +loop at the specified level. + +For example, for the schedule tree + + domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" + child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ atomic[x] }" + +the following AST will be generated + + for (int c0 = 0; c0 <= 10; c0 += 1) { + if (c0 >= 1) + b(c0 - 1); + if (c0 <= 9) + a(c0); + } + +On the other hand, for the schedule tree + + domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" + child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ separate[x] }" + +the following AST will be generated + + { + a(0); + for (int c0 = 1; c0 <= 9; c0 += 1) { + b(c0 - 1); + a(c0); + } + b(9); + } + +If neither C nor C is specified, then the AST generator +may produce either of these two results or some intermediate form. + +=item C + +When this option is specified, the AST generator will +split the domain of the specified schedule dimension +into pieces with a fixed set of statements for which +instances need to be executed by the iterations in +the schedule domain part. This option tends to avoid +the generation of guards inside the corresponding loops. +See also the C option. + +=item C + +When this option is specified, the AST generator will +I unroll the corresponding schedule dimension. +It is the responsibility of the user to ensure that such +unrolling is possible. +To obtain a partial unrolling, the user should apply an additional +strip-mining to the schedule and fully unroll the inner schedule +dimension. + +=back + +The C option is a bit more involved. It allows the user +to isolate a range of schedule dimension values from smaller and +greater values. Additionally, the user may specify a different +atomic/separate/unroll choice for the isolated part and the remaining +parts. The typical use case of the C option is to isolate +full tiles from partial tiles. +The part that needs to be isolated may depend on outer schedule dimensions. +The option therefore needs to be able to reference those outer schedule +dimensions. In particular, the space of the C option is that +of a wrapped map with as domain the flat product of all outer band nodes +and as range the space of the current band node. +The atomic/separate/unroll choice for the isolated part is determined +by an option that lives in an unnamed wrapped space with as domain +a zero-dimensional C space and as range the regular +C, C or C space. +This option may also be set directly using +C. +The atomic/separate/unroll choice for the remaining part is determined +by the regular C, C or C option. +The use of the C option causes any tree containing the node +to be considered anchored. + +As an example, consider the isolation of full tiles from partial tiles +in a tiling of a triangular domain. The original schedule is as follows. + + domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" + child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + +The output is + + for (int c0 = 0; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + +Isolating the full tiles, we have the following input + + domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" + child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ + 10a+9+10b+9 <= 100 }" + +and output + + { + for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; + c2 <= 10 * c0 + 9; c2 += 1) + for (int c3 = 10 * c1; + c3 <= 10 * c1 + 9; c3 += 1) + A(c2, c3); + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + +We may then additionally unroll the innermost loop of the isolated part + + domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" + child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ + 10a+9+10b+9 <= 100; [isolate[] -> unroll[3]] }" + +to obtain + + { + for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; c2 <= 10 * c0 + 9; c2 += 1) { + A(c2, 10 * c1); + A(c2, 10 * c1 + 1); + A(c2, 10 * c1 + 2); + A(c2, 10 * c1 + 3); + A(c2, 10 * c1 + 4); + A(c2, 10 * c1 + 5); + A(c2, 10 * c1 + 6); + A(c2, 10 * c1 + 7); + A(c2, 10 * c1 + 8); + A(c2, 10 * c1 + 9); + } + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; + c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; + c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } -Besides specifying the constraints on the parameters, -an C object can be used to control -various aspects of the AST generation process. -The most prominent way of control is through ``options'', -which can be set using the following function. + +=head3 AST Generation Options (Schedule Map) + +In case of AST construction using +C, the options +that control how an AST is created from the individual schedule +dimensions are stored in the C. +They can be set using the following function. #include __isl_give isl_ast_build * @@ -6360,9 +9677,10 @@ __isl_take isl_ast_build *control, __isl_take isl_union_map *options); -The options are encoded in an . +The options are encoded in an C. The domain of this union relation refers to the schedule domain, -i.e., the range of the schedule passed to C. +i.e., the range of the schedule passed +to C. In the case of nested AST generation (see L), the domain of C should refer to the extra piece of the schedule. That is, it should be equal to the range of the wrapped relation in the @@ -6381,6 +9699,9 @@ =item C +B + This space is a wrapped relation between two one dimensional spaces. The input space represents the schedule dimension to which the option applies and the output space represents the separation class. @@ -6528,6 +9849,16 @@ =back +=head3 Fine-grained Control over AST Generation + +Besides specifying the constraints on the parameters, +an C object can be used to control +various aspects of the AST generation process. +In case of AST construction using +C, +the most prominent way of control is through ``options'', +as explained above. + Additional control is available through the following functions. #include @@ -6599,6 +9930,19 @@ __isl_take isl_ast_node *node, __isl_keep isl_ast_build *build, void *user), void *user); + __isl_give isl_ast_build * + isl_ast_build_set_before_each_mark( + __isl_take isl_ast_build *build, + isl_stat (*fn)(__isl_keep isl_id *mark, + __isl_keep isl_ast_build *build, + void *user), void *user); + __isl_give isl_ast_build * + isl_ast_build_set_after_each_mark( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, + void *user), void *user); The callback set by C will be called for each domain AST node. @@ -6613,7 +9957,15 @@ In particular, if the user has also specified an C callback, then the annotation can be retrieved from the node passed to that callback using C. -All callbacks should C on failure. +The callbacks set by C +and C will be called for each +mark AST node that is created, i.e., for each mark schedule node +in the input schedule tree. The first will be called in depth-first +pre-order, while the second will be called in depth-first post-order. +Since the callback set by C +is called before the mark AST node is actually constructed, it is passed +the identifier of the mark node. +All callbacks should C (or -1) on failure. The given C can be used to create new C objects using C or C. @@ -6622,8 +9974,8 @@ C allows the user to create an AST within the context of another AST. These nested ASTs are created using the -same C function that is used to create the -outer AST. The C argument should be an C +same C function that is used to create +the outer AST. The C argument should be an C passed to a callback set by C. The space of the range of the C argument should refer diff -Nru isl-0.12.2/GIT_HEAD_ID isl-0.15/GIT_HEAD_ID --- isl-0.12.2/GIT_HEAD_ID 2014-01-12 11:45:44.000000000 +0000 +++ isl-0.15/GIT_HEAD_ID 2015-06-11 10:47:44.000000000 +0000 @@ -1 +1 @@ -isl-0.12.2 +isl-0.15 diff -Nru isl-0.12.2/imath/gmp_compat.c isl-0.15/imath/gmp_compat.c --- isl-0.12.2/imath/gmp_compat.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath/gmp_compat.c 2015-06-02 09:28:14.000000000 +0000 @@ -0,0 +1,862 @@ +/* + Name: gmp_compat.c + Purpose: Provide GMP compatiable routines for imath library + Author: David Peixotto + + Copyright (c) 2012 Qualcomm Innovation Center, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ +#include "gmp_compat.h" +#include +#include +#include +#include + +#ifdef NDEBUG +#define CHECK(res) (res) +#else +#define CHECK(res) assert(((res) == MP_OK) && "expected MP_OK") +#endif + +/************************************************************************* + * + * Functions with direct translations + * + *************************************************************************/ +/* gmp: mpq_clear */ +void GMPQAPI(clear)(mp_rat x) { + mp_rat_clear(x); +} + +/* gmp: mpq_cmp */ +int GMPQAPI(cmp)(mp_rat op1, mp_rat op2) { + return mp_rat_compare(op1, op2); +} + +/* gmp: mpq_init */ +void GMPQAPI(init)(mp_rat x) { + CHECK(mp_rat_init(x)); +} + +/* gmp: mpq_mul */ +void GMPQAPI(mul)(mp_rat product, mp_rat multiplier, mp_rat multiplicand) { + CHECK(mp_rat_mul(multiplier, multiplicand, product)); +} + +/* gmp: mpq_set*/ +void GMPQAPI(set)(mp_rat rop, mp_rat op) { + CHECK(mp_rat_copy(op, rop)); +} + +/* gmp: mpz_abs */ +void GMPZAPI(abs)(mp_int rop, mp_int op) { + CHECK(mp_int_abs(op, rop)); +} + +/* gmp: mpz_add */ +void GMPZAPI(add)(mp_int rop, mp_int op1, mp_int op2) { + CHECK(mp_int_add(op1, op2, rop)); +} + +/* gmp: mpz_clear */ +void GMPZAPI(clear)(mp_int x) { + mp_int_clear(x); +} + +/* gmp: mpz_cmp_si */ +int GMPZAPI(cmp_si)(mp_int op1, long op2) { + return mp_int_compare_value(op1, op2); +} + +/* gmp: mpz_cmpabs */ +int GMPZAPI(cmpabs)(mp_int op1, mp_int op2) { + return mp_int_compare_unsigned(op1, op2); +} + +/* gmp: mpz_cmp */ +int GMPZAPI(cmp)(mp_int op1, mp_int op2) { + return mp_int_compare(op1, op2); +} + +/* gmp: mpz_init */ +void GMPZAPI(init)(mp_int x) { + CHECK(mp_int_init(x)); +} + +/* gmp: mpz_mul */ +void GMPZAPI(mul)(mp_int rop, mp_int op1, mp_int op2) { + CHECK(mp_int_mul(op1, op2, rop)); +} + +/* gmp: mpz_neg */ +void GMPZAPI(neg)(mp_int rop, mp_int op) { + CHECK(mp_int_neg(op, rop)); +} + +/* gmp: mpz_set_si */ +void GMPZAPI(set_si)(mp_int rop, long op) { + CHECK(mp_int_set_value(rop, op)); +} + +/* gmp: mpz_set */ +void GMPZAPI(set)(mp_int rop, mp_int op) { + CHECK(mp_int_copy(op, rop)); +} + +/* gmp: mpz_sub */ +void GMPZAPI(sub)(mp_int rop, mp_int op1, mp_int op2) { + CHECK(mp_int_sub(op1, op2, rop)); +} + +/* gmp: mpz_swap */ +void GMPZAPI(swap)(mp_int rop1, mp_int rop2) { + mp_int_swap(rop1, rop2); +} + +/* gmp: mpq_sgn */ +int GMPQAPI(sgn)(mp_rat op) { + return mp_rat_compare_zero(op); +} + +/* gmp: mpz_sgn */ +int GMPZAPI(sgn)(mp_int op) { + return mp_int_compare_zero(op); +} + +/* gmp: mpq_set_ui */ +void GMPQAPI(set_ui)(mp_rat rop, unsigned long op1, unsigned long op2) { + CHECK(mp_rat_set_uvalue(rop, op1, op2)); +} + +/* gmp: mpz_set_ui */ +void GMPZAPI(set_ui)(mp_int rop, unsigned long op) { + CHECK(mp_int_set_uvalue(rop, op)); +} + +/* gmp: mpq_den_ref */ +mp_int GMPQAPI(denref)(mp_rat op) { + return mp_rat_denom_ref(op); +} + +/* gmp: mpq_num_ref */ +mp_int GMPQAPI(numref)(mp_rat op) { + return mp_rat_numer_ref(op); +} + +/* gmp: mpq_canonicalize */ +void GMPQAPI(canonicalize)(mp_rat op) { + CHECK(mp_rat_reduce(op)); +} + +/************************************************************************* + * + * Functions that can be implemented as a combination of imath functions + * + *************************************************************************/ +/* gmp: mpz_addmul */ +/* gmp: rop = rop + (op1 * op2) */ +void GMPZAPI(addmul)(mp_int rop, mp_int op1, mp_int op2) { + mpz_t tempz; + mp_int temp = &tempz; + mp_int_init(temp); + + CHECK(mp_int_mul(op1, op2, temp)); + CHECK(mp_int_add(rop, temp, rop)); + mp_int_clear(temp); +} + +/* gmp: mpz_divexact */ +/* gmp: only produces correct results when d divides n */ +void GMPZAPI(divexact)(mp_int q, mp_int n, mp_int d) { + CHECK(mp_int_div(n, d, q, NULL)); +} + +/* gmp: mpz_divisible_p */ +/* gmp: return 1 if d divides n, 0 otherwise */ +/* gmp: 0 is considered to divide 0*/ +int GMPZAPI(divisible_p)(mp_int n, mp_int d) { + /* variables to hold remainder */ + mpz_t rz; + mp_int r = &rz; + int r_is_zero; + + /* check for n = 0, d = 0 */ + int n_is_zero = mp_int_compare_zero(n) == 0; + int d_is_zero = mp_int_compare_zero(d) == 0; + if (n_is_zero && d_is_zero) + return 1; + + /* return true if remainder is 0 */ + CHECK(mp_int_init(r)); + CHECK(mp_int_div(n, d, NULL, r)); + r_is_zero = mp_int_compare_zero(r) == 0; + mp_int_clear(r); + + return r_is_zero; +} + +/* gmp: mpz_submul */ +/* gmp: rop = rop - (op1 * op2) */ +void GMPZAPI(submul)(mp_int rop, mp_int op1, mp_int op2) { + mpz_t tempz; + mp_int temp = &tempz; + mp_int_init(temp); + + CHECK(mp_int_mul(op1, op2, temp)); + CHECK(mp_int_sub(rop, temp, rop)); + + mp_int_clear(temp); +} + +/* gmp: mpz_add_ui */ +void GMPZAPI(add_ui)(mp_int rop, mp_int op1, unsigned long op2) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, op2)); + + CHECK(mp_int_add(op1, temp, rop)); + + mp_int_clear(temp); +} + +/* gmp: mpz_divexact_ui */ +/* gmp: only produces correct results when d divides n */ +void GMPZAPI(divexact_ui)(mp_int q, mp_int n, unsigned long d) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, d)); + + CHECK(mp_int_div(n, temp, q, NULL)); + + mp_int_clear(temp); +} + +/* gmp: mpz_mul_ui */ +void GMPZAPI(mul_ui)(mp_int rop, mp_int op1, unsigned long op2) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, op2)); + + CHECK(mp_int_mul(op1, temp, rop)); + + mp_int_clear(temp); +} + +/* gmp: mpz_pow_ui */ +/* gmp: 0^0 = 1 */ +void GMPZAPI(pow_ui)(mp_int rop, mp_int base, unsigned long exp) { + mpz_t tempz; + mp_int temp = &tempz; + + /* check for 0^0 */ + if (exp == 0 && mp_int_compare_zero(base) == 0) { + CHECK(mp_int_set_value(rop, 1)); + return; + } + + /* rop = base^exp */ + CHECK(mp_int_init_uvalue(temp, exp)); + CHECK(mp_int_expt_full(base, temp, rop)); + mp_int_clear(temp); +} + +/* gmp: mpz_sub_ui */ +void GMPZAPI(sub_ui)(mp_int rop, mp_int op1, unsigned long op2) { + mpz_t tempz; + mp_int temp = &tempz; + CHECK(mp_int_init_uvalue(temp, op2)); + + CHECK(mp_int_sub(op1, temp, rop)); + + mp_int_clear(temp); +} + +/************************************************************************* + * + * Functions with different behavior in corner cases + * + *************************************************************************/ + +/* gmp: mpz_gcd */ +void GMPZAPI(gcd)(mp_int rop, mp_int op1, mp_int op2) { + int op1_is_zero = mp_int_compare_zero(op1) == 0; + int op2_is_zero = mp_int_compare_zero(op2) == 0; + + if (op1_is_zero && op2_is_zero) { + mp_int_zero(rop); + return; + } + + CHECK(mp_int_gcd(op1, op2, rop)); +} + +/* gmp: mpz_get_str */ +char* GMPZAPI(get_str)(char *str, int radix, mp_int op) { + int i, r, len; + + /* Support negative radix like gmp */ + r = radix; + if (r < 0) + r = -r; + + /* Compute the length of the string needed to hold the int */ + len = mp_int_string_len(op, r); + if (str == NULL) { + str = malloc(len); + } + + /* Convert to string using imath function */ + CHECK(mp_int_to_string(op, r, str, len)); + + /* Change case to match gmp */ + for (i = 0; i < len - 1; i++) + if (radix < 0) + str[i] = toupper(str[i]); + else + str[i] = tolower(str[i]); + return str; +} + +/* gmp: mpq_get_str */ +char* GMPQAPI(get_str)(char *str, int radix, mp_rat op) { + int i, r, len; + + /* Only print numerator if it is a whole number */ + if (mp_int_compare_value(mp_rat_denom_ref(op), 1) == 0) + return GMPZAPI(get_str)(str, radix, mp_rat_numer_ref(op)); + + /* Support negative radix like gmp */ + r = radix; + if (r < 0) + r = -r; + + /* Compute the length of the string needed to hold the int */ + len = mp_rat_string_len(op, r); + if (str == NULL) { + str = malloc(len); + } + + /* Convert to string using imath function */ + CHECK(mp_rat_to_string(op, r, str, len)); + + /* Change case to match gmp */ + for (i = 0; i < len; i++) + if (radix < 0) + str[i] = toupper(str[i]); + else + str[i] = tolower(str[i]); + + return str; +} + +/* gmp: mpz_set_str */ +int GMPZAPI(set_str)(mp_int rop, char *str, int base) { + mp_result res = mp_int_read_string(rop, base, str); + return ((res == MP_OK) ? 0 : -1); +} + +/* gmp: mpq_set_str */ +int GMPQAPI(set_str)(mp_rat rop, char *s, int base) { + char *slash; + char *str; + mp_result resN; + mp_result resD; + int res = 0; + + /* Copy string to temporary storage so we can modify it below */ + str = malloc(strlen(s)+1); + strcpy(str, s); + + /* Properly format the string as an int by terminating at the / */ + slash = strchr(str, '/'); + if (slash) + *slash = '\0'; + + /* Parse numerator */ + resN = mp_int_read_string(mp_rat_numer_ref(rop), base, str); + + /* Parse denomenator if given or set to 1 if not */ + if (slash) + resD = mp_int_read_string(mp_rat_denom_ref(rop), base, slash+1); + else + resD = mp_int_set_uvalue(mp_rat_denom_ref(rop), 1); + + /* Return failure if either parse failed */ + if (resN != MP_OK || resD != MP_OK) + res = -1; + + free(str); + return res; +} + +static unsigned long get_long_bits(mp_int op) { + /* Deal with integer that does not fit into unsigned long. We want to grab + * the least significant digits that will fit into the long. Read the digits + * into the long starting at the most significant digit that fits into a + * long. The long is shifted over by MP_DIGIT_BIT before each digit is added. + * The shift is decomposed into two steps to follow the patten used in the + * rest of the imath library. The two step shift is used to accomedate + * architectures that don't deal well with 32-bit shifts. */ + mp_size num_digits_in_long = sizeof(unsigned long) / sizeof(mp_digit); + mp_digit *digits = MP_DIGITS(op); + unsigned long out = 0; + int i; + + for (i = num_digits_in_long - 1; i >= 0; i--) { + out <<= (MP_DIGIT_BIT/2); + out <<= (MP_DIGIT_BIT/2); + out |= digits[i]; + } + + return out; +} + +/* gmp: mpz_get_ui */ +unsigned long GMPZAPI(get_ui)(mp_int op) { + unsigned long out; + + /* Try a standard conversion that fits into an unsigned long */ + mp_result res = mp_int_to_uint(op, &out); + if (res == MP_OK) + return out; + + /* Abort the try if we don't have a range error in the conversion. + * The range error indicates that the value cannot fit into a long. */ + CHECK(res == MP_RANGE ? MP_OK : MP_RANGE); + if (res != MP_RANGE) + return 0; + + return get_long_bits(op); +} + +/* gmp: mpz_get_si */ +long GMPZAPI(get_si)(mp_int op) { + long out; + unsigned long uout; + int long_msb; + + /* Try a standard conversion that fits into a long */ + mp_result res = mp_int_to_int(op, &out); + if (res == MP_OK) + return out; + + /* Abort the try if we don't have a range error in the conversion. + * The range error indicates that the value cannot fit into a long. */ + CHECK(res == MP_RANGE ? MP_OK : MP_RANGE); + if (res != MP_RANGE) + return 0; + + /* get least significant bits into an unsigned long */ + uout = get_long_bits(op); + + /* clear the top bit */ + long_msb = (sizeof(unsigned long) * 8) - 1; + uout &= (~(1UL << long_msb)); + + /* convert to negative if needed based on sign of op */ + if (MP_SIGN(op) == MP_NEG) + uout = 0 - uout; + + out = (long) uout; + return out; +} + +/* gmp: mpz_lcm */ +void GMPZAPI(lcm)(mp_int rop, mp_int op1, mp_int op2) { + int op1_is_zero = mp_int_compare_zero(op1) == 0; + int op2_is_zero = mp_int_compare_zero(op2) == 0; + + if (op1_is_zero || op2_is_zero) { + mp_int_zero(rop); + return; + } + + CHECK(mp_int_lcm(op1, op2, rop)); + CHECK(mp_int_abs(rop, rop)); +} + +/* gmp: mpz_mul_2exp */ +/* gmp: allow big values for op2 when op1 == 0 */ +void GMPZAPI(mul_2exp)(mp_int rop, mp_int op1, unsigned long op2) { + if (mp_int_compare_zero(op1) == 0) + mp_int_zero(rop); + else + CHECK(mp_int_mul_pow2(op1, op2, rop)); +} + +/************************************************************************* + * + * Functions needing expanded functionality + * + *************************************************************************/ +/* [Note]Overview of division implementation + + All division operations (N / D) compute q and r such that + + N = q * D + r, with 0 <= abs(r) < abs(d) + + The q and r values are not uniquely specified by N and D. To specify which q + and r values should be used, GMP implements three different rounding modes + for integer division: + + ceiling - round q twords +infinity, r has opposite sign as d + floor - round q twords -infinity, r has same sign as d + truncate - round q twords zero, r has same sign as n + + The imath library only supports truncate as a rounding mode. We need to + implement the other rounding modes in terms of truncating division. We first + perform the division in trucate mode and then adjust q accordingly. Once we + know q, we can easily compute the correct r according the the formula above + by computing: + + r = N - q * D + + The main task is to compute q. We can compute the correct q from a trucated + version as follows. + + For ceiling rounding mode, if q is less than 0 then the truncated rounding + mode is the same as the ceiling rounding mode. If q is greater than zero + then we need to round q up by one because the truncated version was rounded + down to zero. If q equals zero then check to see if the result of the + divison is positive. A positive result needs to increment q to one. + + For floor rounding mode, if q is greater than 0 then the trucated rounding + mode is the same as the floor rounding mode. If q is less than zero then we + need to round q down by one because the trucated mode rounded q up by one + twords zero. If q is zero then we need to check to see if the result of the + division is negative. A negative result needs to decrement q to negative + one. + */ + +/* gmp: mpz_cdiv_q */ +void GMPZAPI(cdiv_q)(mp_int q, mp_int n, mp_int d) { + mpz_t rz; + mp_int r = &rz; + int qsign, rsign, nsign, dsign; + CHECK(mp_int_init(r)); + + /* save signs before division because q can alias with n or d */ + nsign = mp_int_compare_zero(n); + dsign = mp_int_compare_zero(d); + + /* truncating division */ + CHECK(mp_int_div(n, d, q, r)); + + /* see: [Note]Overview of division implementation */ + qsign = mp_int_compare_zero(q); + rsign = mp_int_compare_zero(r); + if (qsign > 0) { /* q > 0 */ + if (rsign != 0) { /* r != 0 */ + CHECK(mp_int_add_value(q, 1, q)); + } + } + else if (qsign == 0) { /* q == 0 */ + if (rsign != 0) { /* r != 0 */ + if ((nsign > 0 && dsign > 0) || (nsign < 0 && dsign < 0)) { + CHECK(mp_int_set_value(q, 1)); + } + } + } + mp_int_clear(r); +} + +/* gmp: mpz_fdiv_q */ +void GMPZAPI(fdiv_q)(mp_int q, mp_int n, mp_int d) { + mpz_t rz; + mp_int r = &rz; + int qsign, rsign, nsign, dsign; + CHECK(mp_int_init(r)); + + /* save signs before division because q can alias with n or d */ + nsign = mp_int_compare_zero(n); + dsign = mp_int_compare_zero(d); + + /* truncating division */ + CHECK(mp_int_div(n, d, q, r)); + + /* see: [Note]Overview of division implementation */ + qsign = mp_int_compare_zero(q); + rsign = mp_int_compare_zero(r); + if (qsign < 0) { /* q < 0 */ + if (rsign != 0) { /* r != 0 */ + CHECK(mp_int_sub_value(q, 1, q)); + } + } + else if (qsign == 0) { /* q == 0 */ + if (rsign != 0) { /* r != 0 */ + if ((nsign < 0 && dsign > 0) || (nsign > 0 && dsign < 0)) { + CHECK(mp_int_set_value(q, -1)); + } + } + } + mp_int_clear(r); +} + +/* gmp: mpz_fdiv_r */ +void GMPZAPI(fdiv_r)(mp_int r, mp_int n, mp_int d) { + mpz_t qz; + mpz_t tempz; + mpz_t orig_dz; + mpz_t orig_nz; + mp_int q = &qz; + mp_int temp = &tempz; + mp_int orig_d = &orig_dz; + mp_int orig_n = &orig_nz; + CHECK(mp_int_init(q)); + CHECK(mp_int_init(temp)); + /* Make a copy of n in case n and d in case they overlap with q */ + CHECK(mp_int_init_copy(orig_d, d)); + CHECK(mp_int_init_copy(orig_n, n)); + + /* floor division */ + GMPZAPI(fdiv_q)(q, n, d); + + /* see: [Note]Overview of division implementation */ + /* n = q * d + r ==> r = n - q * d */ + mp_int_mul(q, orig_d, temp); + mp_int_sub(orig_n, temp, r); + + mp_int_clear(q); + mp_int_clear(temp); + mp_int_clear(orig_d); + mp_int_clear(orig_n); +} + +/* gmp: mpz_tdiv_q */ +void GMPZAPI(tdiv_q)(mp_int q, mp_int n, mp_int d) { + /* truncating division*/ + CHECK(mp_int_div(n, d, q, NULL)); +} + +/* gmp: mpz_fdiv_q_ui */ +unsigned long GMPZAPI(fdiv_q_ui)(mp_int q, mp_int n, unsigned long d) { + mpz_t tempz; + mp_int temp = &tempz; + mpz_t rz; + mp_int r = &rz; + mpz_t orig_nz; + mp_int orig_n = &orig_nz; + unsigned long rl; + CHECK(mp_int_init_uvalue(temp, d)); + CHECK(mp_int_init(r)); + /* Make a copy of n in case n and q overlap */ + CHECK(mp_int_init_copy(orig_n, n)); + + /* use floor division mode to compute q and r */ + GMPZAPI(fdiv_q)(q, n, temp); + GMPZAPI(fdiv_r)(r, orig_n, temp); + CHECK(mp_int_to_uint(r, &rl)); + + mp_int_clear(temp); + mp_int_clear(r); + mp_int_clear(orig_n); + + return rl; +} + +/* gmp: mpz_export */ +void* GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int op) { + int i; + int num_used_bytes; + size_t num_words, num_missing_bytes; + unsigned char* dst; + unsigned char* src; + + /* We do not have a complete implementation. Assert to ensure our + * restrictions are in place, We do not support big endian output, but do not + * check that native endian is little endian. */ + assert(nails == 0 && "Do not support non-full words"); + assert((endian == 0 || endian == -1) && "Do not support big endian"); + + /* The gmp API requires that order must be -1 or 1. + Not sure how gmp behaves when order is not 1 or -1, so force all non-one + values to -1 for now. */ + if (order != 1) order = -1; + + /* Test for zero */ + if (mp_int_compare_zero(op) == 0) { + if (countp) + *countp = 0; + return rop; + } + + /* Calculate how many words we need */ + num_used_bytes = mp_int_unsigned_len(op); + num_words = (num_used_bytes + (size-1)) / size; /* ceil division */ + assert(num_used_bytes > 0); + + /* Check to see if we will have missing bytes in the last word. + + Missing bytes can only occur when the size of words we output is + greater than the size of words used internally by imath. The number of + missing bytes is the number of bytes needed to fill out the last word. If + this number is greater than the size of a single mp_digit, then we need to + pad the word with extra zeros. Otherwise, the missing bytes can be filled + directly from the zeros in the last digit in the number. + */ + num_missing_bytes = (size * num_words) - num_used_bytes; + assert(num_missing_bytes < size); + + /* Allocate space for the result if needed */ + if (rop == NULL) { + rop = malloc(num_words * size); + } + + /* Initialize dst and src pointers */ + dst = (unsigned char *)rop; + src = (unsigned char *)MP_DIGITS(op); + + /* Most significant word first */ + if (order == 1) { + size_t words_written = 0; + src += (num_words-1) * size; + + /* Handle write of first word specially */ + for (i = 0; i < size - num_missing_bytes; i++) + dst[i] = src[i]; + for (; i < size; i++) + dst[i] = 0; + dst += size; + src -= size; + words_written++; + + for (; words_written < num_words; words_written++) { + for (i = 0; i < size; i++) + dst[i] = src[i]; + dst += size; + src -= size; + } + } + /* Least significant word first */ + else { + size_t words_written = 0; + for (; words_written < num_words - 1; words_written++) { + for (i = 0; i < size; i++) + dst[i] = src[i]; + dst += size; + src += size; + } + + /* Handle write of last word specially */ + for (i = 0; i < size - num_missing_bytes; i++) + dst[i] = src[i]; + + for (; i < size; i++) + dst[i] = 0; + } + + if (countp) + *countp = num_words; + return rop; +} + +/* gmp: mpz_import */ +void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op) { + mpz_t tmpz; + mp_int tmp = &tmpz; + size_t total_size; + size_t num_digits; + const char *src; + char *dst; + int i; + if (count == 0 || op == NULL) + return; + + /* We do not have a complete implementation. Assert to ensure our + * restrictions are in place, We do not support big endian output, but do not + * check that native endian is little endian. */ + assert(nails == 0 && "Do not support non-full words"); + assert((endian == 0 || endian == -1) && "Do not support big endian"); + + /* Compute number of needed digits by ceil division */ + total_size = count * size; + num_digits = (total_size + sizeof(mp_digit) - 1) / sizeof(mp_digit); + + /* Init temporary */ + mp_int_init_size(tmp, num_digits); + for (i = 0; i < num_digits; i++) + tmp->digits[i] = 0; + + /* Copy bytes */ + src = (const char *) op; + dst = (char *)MP_DIGITS(tmp); + + /* Most significant word is first */ + if (order == 1) { + size_t word; + dst += (count - 1) * size; + for (word = 0; word < count; word++) { + for (i = 0; i < size; i++) + dst[i] = src[i]; + dst -= size; + src += size; + } + } + /* Least significant word is first */ + else { + size_t word; + for (word = 0; word < count; word++) { + for (i = 0; i < size; i++) + dst[i] = src[i]; + dst += size; + src += size; + } + } + MP_USED(tmp) = num_digits; + + /* Remove leading zeros from number */ + { + mp_size uz_ = MP_USED(tmp); + mp_digit *dz_ = MP_DIGITS(tmp) + uz_ -1; + while (uz_ > 1 && (*dz_-- == 0)) + --uz_; + MP_USED(tmp) = uz_; + } + + /* Copy to destination */ + mp_int_copy(tmp, rop); + mp_int_clear(tmp); +} + +/* gmp: mpz_sizeinbase */ +size_t GMPZAPI(sizeinbase)(mp_int op, int base) { + mp_result res; + size_t size; + + /* If op == 0, return 1 */ + if (mp_int_compare_zero(op) == 0) + return 1; + + /* Compute string length in base */ + res = mp_int_string_len(op, base); + CHECK((res > 0) == MP_OK); + + /* Now adjust the final size by getting rid of string artifacts */ + size = res; + + /* subtract one for the null terminator */ + size -= 1; + + /* subtract one for the negative sign */ + if (mp_int_compare_zero(op) < 0) + size -= 1; + + return size; +} diff -Nru isl-0.12.2/imath/gmp_compat.h isl-0.15/imath/gmp_compat.h --- isl-0.12.2/imath/gmp_compat.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath/gmp_compat.h 2014-05-28 13:11:37.000000000 +0000 @@ -0,0 +1,229 @@ +/* + Name: gmp_compat.h + Purpose: Provide GMP compatiable routines for imath library + Author: David Peixotto + + Copyright (c) 2012 Qualcomm Innovation Center, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#ifndef IMATH_GMP_COMPAT_H_ +#define IMATH_GMP_COMPAT_H_ +#include "imath.h" +#include "imrat.h" +#include + +#define GMPZAPI(fun) impz_ ## fun +#define GMPQAPI(fun) impq_ ## fun + +#ifdef __cplusplus +extern "C" { +#endif +/************************************************************************* + * + * Functions with direct translations + * + *************************************************************************/ +/* gmp: mpq_clear */ +void GMPQAPI(clear)(mp_rat x); + +/* gmp: mpq_cmp */ +int GMPQAPI(cmp)(mp_rat op1, mp_rat op2); + +/* gmp: mpq_init */ +void GMPQAPI(init)(mp_rat x); + +/* gmp: mpq_mul */ +void GMPQAPI(mul)(mp_rat product, mp_rat multiplier, mp_rat multiplicand); + +/* gmp: mpq_set */ +void GMPQAPI(set)(mp_rat rop, mp_rat op); + +/* gmp: mpz_abs */ +void GMPZAPI(abs)(mp_int rop, mp_int op); + +/* gmp: mpz_add */ +void GMPZAPI(add)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_clear */ +void GMPZAPI(clear)(mp_int x); + +/* gmp: mpz_cmp_si */ +int GMPZAPI(cmp_si)(mp_int op1, long op2); + +/* gmp: mpz_cmpabs */ +int GMPZAPI(cmpabs)(mp_int op1, mp_int op2); + +/* gmp: mpz_cmp */ +int GMPZAPI(cmp)(mp_int op1, mp_int op2); + +/* gmp: mpz_init */ +void GMPZAPI(init)(mp_int x); + +/* gmp: mpz_mul */ +void GMPZAPI(mul)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_neg */ +void GMPZAPI(neg)(mp_int rop, mp_int op); + +/* gmp: mpz_set_si */ +void GMPZAPI(set_si)(mp_int rop, long op); + +/* gmp: mpz_set */ +void GMPZAPI(set)(mp_int rop, mp_int op); + +/* gmp: mpz_sub */ +void GMPZAPI(sub)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_swap */ +void GMPZAPI(swap)(mp_int rop1, mp_int rop2); + +/* gmp: mpq_sgn */ +int GMPQAPI(sgn)(mp_rat op); + +/* gmp: mpz_sgn */ +int GMPZAPI(sgn)(mp_int op); + +/* gmp: mpq_set_ui */ +void GMPQAPI(set_ui)(mp_rat rop, unsigned long op1, unsigned long op2); + +/* gmp: mpz_set_ui */ +void GMPZAPI(set_ui)(mp_int rop, unsigned long op); + +/* gmp: mpq_den_ref */ +mp_int GMPQAPI(denref)(mp_rat op); + +/* gmp: mpq_num_ref */ +mp_int GMPQAPI(numref)(mp_rat op); + +/* gmp: mpq_canonicalize */ +void GMPQAPI(canonicalize)(mp_rat op); + +/************************************************************************* + * + * Functions that can be implemented as a combination of imath functions + * + *************************************************************************/ +/* gmp: mpz_addmul */ +void GMPZAPI(addmul)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_divexact */ +void GMPZAPI(divexact)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_divisible_p */ +int GMPZAPI(divisible_p)(mp_int n, mp_int d); + +/* gmp: mpz_submul */ +void GMPZAPI(submul)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_add_ui */ +void GMPZAPI(add_ui)(mp_int rop, mp_int op1, unsigned long op2); + +/* gmp: mpz_divexact_ui */ +void GMPZAPI(divexact_ui)(mp_int q, mp_int n, unsigned long d); + +/* gmp: mpz_mul_ui */ +void GMPZAPI(mul_ui)(mp_int rop, mp_int op1, unsigned long op2); + +/* gmp: mpz_pow_ui */ +void GMPZAPI(pow_ui)(mp_int rop, mp_int base, unsigned long exp); + +/* gmp: mpz_sub_ui */ +void GMPZAPI(sub_ui)(mp_int rop, mp_int op1, unsigned long op2); + +/* gmp: mpz_fdiv_q_ui */ +unsigned long GMPZAPI(fdiv_q_ui)(mp_int q, mp_int n, unsigned long d); + +/* gmp: mpz_sizeinbase */ +size_t GMPZAPI(sizeinbase)(mp_int op, int base); + +/************************************************************************* + * + * Functions with different behavior in corner cases + * + *************************************************************************/ +/* gmp: mpz_gcd */ +/* gmp: When op1 = 0 and op2 = 0, return 0.*/ +void GMPZAPI(gcd)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_get_str */ +/* gmp: If str is NULL then allocate space using the default allocator. */ +char* GMPZAPI(get_str)(char *str, int radix, mp_int op); + +/* gmp: mpq_get_str */ +/* gmp: If str is NULL then allocate space using the default allocator. */ +/* gmp: If value is a whole number do not print denomenator. */ +/* TODO: Need to handle 0 values better. GMP prints 0/4 instead of 0.*/ +char* GMPQAPI(get_str)(char *str, int radix, mp_rat op); + +/* gmp: mpz_set_str */ +/* gmp: Allow and ignore spaces in string. */ +int GMPZAPI(set_str)(mp_int rop, char *str, int base); + +/* gmp: mpq_set_str */ +int GMPQAPI(set_str)(mp_rat rop, char *str, int base); + +/* gmp: mpz_get_ui */ +/* gmp: Return least significant bits if value is too big for a long. */ +unsigned long GMPZAPI(get_ui)(mp_int op); + +/* gmp: mpz_get_si */ +/* gmp: Return least significant bits if value is too bit for a long. */ +/* gmp: If value is too big for long, return the least significant + (8*sizeof(long)-1) bits from the op and set the sign bit according to + the sign of the op. */ +long GMPZAPI(get_si)(mp_int op); + +/* gmp: mpz_lcm */ +/* gmp: When op1 = 0 or op2 = 0, return 0.*/ +/* gmp: The resutl of lcm(a,b) is always positive. */ +void GMPZAPI(lcm)(mp_int rop, mp_int op1, mp_int op2); + +/* gmp: mpz_mul_2exp */ +/* gmp: allow big values for op2 when op1 == 0 */ +void GMPZAPI(mul_2exp)(mp_int rop, mp_int op1, unsigned long op2); + +/************************************************************************* + * + * Functions needing expanded functionality + * + *************************************************************************/ +/* gmp: mpz_cdiv_q */ +void GMPZAPI(cdiv_q)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_fdiv_q */ +void GMPZAPI(fdiv_q)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_fdiv_r */ +void GMPZAPI(fdiv_r)(mp_int r, mp_int n, mp_int d); + +/* gmp: mpz_tdiv_q */ +void GMPZAPI(tdiv_q)(mp_int q, mp_int n, mp_int d); + +/* gmp: mpz_export */ +void* GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int op); + +/* gmp: mpz_import */ +void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op); + +#ifdef __cplusplus +} +#endif +#endif /* end IMATH_GMP_COMPAT_H_ */ diff -Nru isl-0.12.2/imath/imath.c isl-0.15/imath/imath.c --- isl-0.12.2/imath/imath.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath/imath.c 2015-06-02 09:28:14.000000000 +0000 @@ -0,0 +1,3256 @@ +/* + Name: imath.c + Purpose: Arbitrary precision integer arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#include "imath.h" + +#if DEBUG +#include +#endif + +#include +#include +#include + +#include + +#if DEBUG +#define STATIC /* public */ +#else +#define STATIC static +#endif + +const mp_result MP_OK = 0; /* no error, all is well */ +const mp_result MP_FALSE = 0; /* boolean false */ +const mp_result MP_TRUE = -1; /* boolean true */ +const mp_result MP_MEMORY = -2; /* out of memory */ +const mp_result MP_RANGE = -3; /* argument out of range */ +const mp_result MP_UNDEF = -4; /* result undefined */ +const mp_result MP_TRUNC = -5; /* output truncated */ +const mp_result MP_BADARG = -6; /* invalid null argument */ +const mp_result MP_MINERR = -6; + +const mp_sign MP_NEG = 1; /* value is strictly negative */ +const mp_sign MP_ZPOS = 0; /* value is non-negative */ + +STATIC const char *s_unknown_err = "unknown result code"; +STATIC const char *s_error_msg[] = { + "error code 0", + "boolean true", + "out of memory", + "argument out of range", + "result undefined", + "output truncated", + "invalid argument", + NULL +}; + +/* Argument checking macros + Use CHECK() where a return value is required; NRCHECK() elsewhere */ +#define CHECK(TEST) assert(TEST) +#define NRCHECK(TEST) assert(TEST) + +/* The ith entry of this table gives the value of log_i(2). + + An integer value n requires ceil(log_i(n)) digits to be represented + in base i. Since it is easy to compute lg(n), by counting bits, we + can compute log_i(n) = lg(n) * log_i(2). + + The use of this table eliminates a dependency upon linkage against + the standard math libraries. + + If MP_MAX_RADIX is increased, this table should be expanded too. + */ +STATIC const double s_log2[] = { + 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* (D)(D) 2 3 */ + 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ + 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ + 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ + 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ + 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ + 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ + 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ + 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ + 0.193426404, /* 36 */ +}; + + + +/* Return the number of digits needed to represent a static value */ +#define MP_VALUE_DIGITS(V) \ +((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit)) + +/* Round precision P to nearest word boundary */ +#define ROUND_PREC(P) ((mp_size)(2*(((P)+1)/2))) + +/* Set array P of S digits to zero */ +#define ZERO(P, S) \ +do{ \ + mp_size i__ = (S) * sizeof(mp_digit); \ + mp_digit *p__ = (P); \ + memset(p__, 0, i__); \ +} while(0) + +/* Copy S digits from array P to array Q */ +#define COPY(P, Q, S) \ +do{ \ + mp_size i__ = (S) * sizeof(mp_digit); \ + mp_digit *p__ = (P), *q__ = (Q); \ + memcpy(q__, p__, i__); \ +} while(0) + +/* Reverse N elements of type T in array A */ +#define REV(T, A, N) \ +do{ \ + T *u_ = (A), *v_ = u_ + (N) - 1; \ + while (u_ < v_) { \ + T xch = *u_; \ + *u_++ = *v_; \ + *v_-- = xch; \ + } \ +} while(0) + +#define CLAMP(Z) \ +do{ \ + mp_int z_ = (Z); \ + mp_size uz_ = MP_USED(z_); \ + mp_digit *dz_ = MP_DIGITS(z_) + uz_ -1; \ + while (uz_ > 1 && (*dz_-- == 0)) \ + --uz_; \ + MP_USED(z_) = uz_; \ +} while(0) + +/* Select min/max. Do not provide expressions for which multiple + evaluation would be problematic, e.g. x++ */ +#define MIN(A, B) ((B)<(A)?(B):(A)) +#define MAX(A, B) ((B)>(A)?(B):(A)) + +/* Exchange lvalues A and B of type T, e.g. + SWAP(int, x, y) where x and y are variables of type int. */ +#define SWAP(T, A, B) \ +do{ \ + T t_ = (A); \ + A = (B); \ + B = t_; \ +} while(0) + +/* Used to set up and access simple temp stacks within functions. */ +#define DECLARE_TEMP(N) \ + mpz_t temp[(N)]; \ + int last__ = 0 +#define CLEANUP_TEMP() \ + CLEANUP: \ + while (--last__ >= 0) \ + mp_int_clear(TEMP(last__)) +#define TEMP(K) (temp + (K)) +#define LAST_TEMP() TEMP(last__) +#define SETUP(E) \ +do{ \ + if ((res = (E)) != MP_OK) \ + goto CLEANUP; \ + ++(last__); \ +} while(0) + +/* Compare value to zero. */ +#define CMPZ(Z) \ +(((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1) + +/* Multiply X by Y into Z, ignoring signs. Requires that Z have + enough storage preallocated to hold the result. */ +#define UMUL(X, Y, Z) \ +do{ \ + mp_size ua_ = MP_USED(X), ub_ = MP_USED(Y); \ + mp_size o_ = ua_ + ub_; \ + ZERO(MP_DIGITS(Z), o_); \ + (void) s_kmul(MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); \ + MP_USED(Z) = o_; \ + CLAMP(Z); \ +} while(0) + +/* Square X into Z. Requires that Z have enough storage to hold the + result. */ +#define USQR(X, Z) \ +do{ \ + mp_size ua_ = MP_USED(X), o_ = ua_ + ua_; \ + ZERO(MP_DIGITS(Z), o_); \ + (void) s_ksqr(MP_DIGITS(X), MP_DIGITS(Z), ua_); \ + MP_USED(Z) = o_; \ + CLAMP(Z); \ +} while(0) + +#define UPPER_HALF(W) ((mp_word)((W) >> MP_DIGIT_BIT)) +#define LOWER_HALF(W) ((mp_digit)(W)) +#define HIGH_BIT_SET(W) ((W) >> (MP_WORD_BIT - 1)) +#define ADD_WILL_OVERFLOW(W, V) ((MP_WORD_MAX - (V)) < (W)) + + + +/* Default number of digits allocated to a new mp_int */ +#if IMATH_TEST +mp_size default_precision = MP_DEFAULT_PREC; +#else +STATIC const mp_size default_precision = MP_DEFAULT_PREC; +#endif + +/* Minimum number of digits to invoke recursive multiply */ +#if IMATH_TEST +mp_size multiply_threshold = MP_MULT_THRESH; +#else +STATIC const mp_size multiply_threshold = MP_MULT_THRESH; +#endif + +/* Allocate a buffer of (at least) num digits, or return + NULL if that couldn't be done. */ +STATIC mp_digit *s_alloc(mp_size num); + +/* Release a buffer of digits allocated by s_alloc(). */ +STATIC void s_free(void *ptr); + +/* Insure that z has at least min digits allocated, resizing if + necessary. Returns true if successful, false if out of memory. */ +STATIC int s_pad(mp_int z, mp_size min); + +/* Fill in a "fake" mp_int on the stack with a given value */ +STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); +STATIC void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]); + +/* Compare two runs of digits of given length, returns <0, 0, >0 */ +STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len); + +/* Pack the unsigned digits of v into array t */ +STATIC int s_uvpack(mp_usmall v, mp_digit t[]); + +/* Compare magnitudes of a and b, returns <0, 0, >0 */ +STATIC int s_ucmp(mp_int a, mp_int b); + +/* Compare magnitudes of a and v, returns <0, 0, >0 */ +STATIC int s_vcmp(mp_int a, mp_small v); +STATIC int s_uvcmp(mp_int a, mp_usmall uv); + +/* Unsigned magnitude addition; assumes dc is big enough. + Carry out is returned (no memory allocated). */ +STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b); + +/* Unsigned magnitude subtraction. Assumes dc is big enough. */ +STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b); + +/* Unsigned recursive multiplication. Assumes dc is big enough. */ +STATIC int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b); + +/* Unsigned magnitude multiplication. Assumes dc is big enough. */ +STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b); + +/* Unsigned recursive squaring. Assumes dc is big enough. */ +STATIC int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a); + +/* Unsigned magnitude squaring. Assumes dc is big enough. */ +STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a); + +/* Single digit addition. Assumes a is big enough. */ +STATIC void s_dadd(mp_int a, mp_digit b); + +/* Single digit multiplication. Assumes a is big enough. */ +STATIC void s_dmul(mp_int a, mp_digit b); + +/* Single digit multiplication on buffers; assumes dc is big enough. */ +STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, + mp_size size_a); + +/* Single digit division. Replaces a with the quotient, + returns the remainder. */ +STATIC mp_digit s_ddiv(mp_int a, mp_digit b); + +/* Quick division by a power of 2, replaces z (no allocation) */ +STATIC void s_qdiv(mp_int z, mp_size p2); + +/* Quick remainder by a power of 2, replaces z (no allocation) */ +STATIC void s_qmod(mp_int z, mp_size p2); + +/* Quick multiplication by a power of 2, replaces z. + Allocates if necessary; returns false in case this fails. */ +STATIC int s_qmul(mp_int z, mp_size p2); + +/* Quick subtraction from a power of 2, replaces z. + Allocates if necessary; returns false in case this fails. */ +STATIC int s_qsub(mp_int z, mp_size p2); + +/* Return maximum k such that 2^k divides z. */ +STATIC int s_dp2k(mp_int z); + +/* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */ +STATIC int s_isp2(mp_int z); + +/* Set z to 2^k. May allocate; returns false in case this fails. */ +STATIC int s_2expt(mp_int z, mp_small k); + +/* Normalize a and b for division, returns normalization constant */ +STATIC int s_norm(mp_int a, mp_int b); + +/* Compute constant mu for Barrett reduction, given modulus m, result + replaces z, m is untouched. */ +STATIC mp_result s_brmu(mp_int z, mp_int m); + +/* Reduce a modulo m, using Barrett's algorithm. */ +STATIC int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2); + +/* Modular exponentiation, using Barrett reduction */ +STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); + +/* Unsigned magnitude division. Assumes |a| > |b|. Allocates temporaries; + overwrites a with quotient, b with remainder. */ +STATIC mp_result s_udiv_knuth(mp_int a, mp_int b); + +/* Compute the number of digits in radix r required to represent the given + value. Does not account for sign flags, terminators, etc. */ +STATIC int s_outlen(mp_int z, mp_size r); + +/* Guess how many digits of precision will be needed to represent a radix r + value of the specified number of digits. Returns a value guaranteed to be + no smaller than the actual number required. */ +STATIC mp_size s_inlen(int len, mp_size r); + +/* Convert a character to a digit value in radix r, or + -1 if out of range */ +STATIC int s_ch2val(char c, int r); + +/* Convert a digit value to a character */ +STATIC char s_val2ch(int v, int caps); + +/* Take 2's complement of a buffer in place */ +STATIC void s_2comp(unsigned char *buf, int len); + +/* Convert a value to binary, ignoring sign. On input, *limpos is the bound on + how many bytes should be written to buf; on output, *limpos is set to the + number of bytes actually written. */ +STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad); + +#if DEBUG +/* Dump a representation of the mp_int to standard output */ +void s_print(char *tag, mp_int z); +void s_print_buf(char *tag, mp_digit *buf, mp_size num); +#endif + +mp_result mp_int_init(mp_int z) +{ + if (z == NULL) + return MP_BADARG; + + z->single = 0; + z->digits = &(z->single); + z->alloc = 1; + z->used = 1; + z->sign = MP_ZPOS; + + return MP_OK; +} + +mp_int mp_int_alloc(void) +{ + mp_int out = malloc(sizeof(mpz_t)); + + if (out != NULL) + mp_int_init(out); + + return out; +} + +mp_result mp_int_init_size(mp_int z, mp_size prec) +{ + CHECK(z != NULL); + + if (prec == 0) + prec = default_precision; + else if (prec == 1) + return mp_int_init(z); + else + prec = (mp_size) ROUND_PREC(prec); + + if ((MP_DIGITS(z) = s_alloc(prec)) == NULL) + return MP_MEMORY; + + z->digits[0] = 0; + MP_USED(z) = 1; + MP_ALLOC(z) = prec; + MP_SIGN(z) = MP_ZPOS; + + return MP_OK; +} + +mp_result mp_int_init_copy(mp_int z, mp_int old) +{ + mp_result res; + mp_size uold; + + CHECK(z != NULL && old != NULL); + + uold = MP_USED(old); + if (uold == 1) { + mp_int_init(z); + } + else { + mp_size target = MAX(uold, default_precision); + + if ((res = mp_int_init_size(z, target)) != MP_OK) + return res; + } + + MP_USED(z) = uold; + MP_SIGN(z) = MP_SIGN(old); + COPY(MP_DIGITS(old), MP_DIGITS(z), uold); + + return MP_OK; +} + +mp_result mp_int_init_value(mp_int z, mp_small value) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + return mp_int_init_copy(z, &vtmp); +} + +mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; + + s_ufake(&vtmp, uvalue, vbuf); + return mp_int_init_copy(z, &vtmp); +} + +mp_result mp_int_set_value(mp_int z, mp_small value) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + return mp_int_copy(&vtmp, z); +} + +mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; + + s_ufake(&vtmp, uvalue, vbuf); + return mp_int_copy(&vtmp, z); +} + +void mp_int_clear(mp_int z) +{ + if (z == NULL) + return; + + if (MP_DIGITS(z) != NULL) { + if (MP_DIGITS(z) != &(z->single)) + s_free(MP_DIGITS(z)); + + MP_DIGITS(z) = NULL; + } +} + +void mp_int_free(mp_int z) +{ + NRCHECK(z != NULL); + + mp_int_clear(z); + free(z); /* note: NOT s_free() */ +} + +mp_result mp_int_copy(mp_int a, mp_int c) +{ + CHECK(a != NULL && c != NULL); + + if (a != c) { + mp_size ua = MP_USED(a); + mp_digit *da, *dc; + + if (!s_pad(c, ua)) + return MP_MEMORY; + + da = MP_DIGITS(a); dc = MP_DIGITS(c); + COPY(da, dc, ua); + + MP_USED(c) = ua; + MP_SIGN(c) = MP_SIGN(a); + } + + return MP_OK; +} + +void mp_int_swap(mp_int a, mp_int c) +{ + if (a != c) { + mpz_t tmp = *a; + + *a = *c; + *c = tmp; + + if (MP_DIGITS(a) == &(c->single)) + MP_DIGITS(a) = &(a->single); + if (MP_DIGITS(c) == &(a->single)) + MP_DIGITS(c) = &(c->single); + } +} + +void mp_int_zero(mp_int z) +{ + NRCHECK(z != NULL); + + z->digits[0] = 0; + MP_USED(z) = 1; + MP_SIGN(z) = MP_ZPOS; +} + +mp_result mp_int_abs(mp_int a, mp_int c) +{ + mp_result res; + + CHECK(a != NULL && c != NULL); + + if ((res = mp_int_copy(a, c)) != MP_OK) + return res; + + MP_SIGN(c) = MP_ZPOS; + return MP_OK; +} + +mp_result mp_int_neg(mp_int a, mp_int c) +{ + mp_result res; + + CHECK(a != NULL && c != NULL); + + if ((res = mp_int_copy(a, c)) != MP_OK) + return res; + + if (CMPZ(c) != 0) + MP_SIGN(c) = 1 - MP_SIGN(a); + + return MP_OK; +} + +mp_result mp_int_add(mp_int a, mp_int b, mp_int c) +{ + mp_size ua, ub, uc, max; + + CHECK(a != NULL && b != NULL && c != NULL); + + ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c); + max = MAX(ua, ub); + + if (MP_SIGN(a) == MP_SIGN(b)) { + /* Same sign -- add magnitudes, preserve sign of addends */ + mp_digit carry; + + if (!s_pad(c, max)) + return MP_MEMORY; + + carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + uc = max; + + if (carry) { + if (!s_pad(c, max + 1)) + return MP_MEMORY; + + c->digits[max] = carry; + ++uc; + } + + MP_USED(c) = uc; + MP_SIGN(c) = MP_SIGN(a); + + } + else { + /* Different signs -- subtract magnitudes, preserve sign of greater */ + mp_int x, y; + int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */ + + /* Set x to max(a, b), y to min(a, b) to simplify later code. + A special case yields zero for equal magnitudes. + */ + if (cmp == 0) { + mp_int_zero(c); + return MP_OK; + } + else if (cmp < 0) { + x = b; y = a; + } + else { + x = a; y = b; + } + + if (!s_pad(c, MP_USED(x))) + return MP_MEMORY; + + /* Subtract smaller from larger */ + s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); + MP_USED(c) = MP_USED(x); + CLAMP(c); + + /* Give result the sign of the larger */ + MP_SIGN(c) = MP_SIGN(x); + } + + return MP_OK; +} + +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_add(a, &vtmp, c); +} + +mp_result mp_int_sub(mp_int a, mp_int b, mp_int c) +{ + mp_size ua, ub, uc, max; + + CHECK(a != NULL && b != NULL && c != NULL); + + ua = MP_USED(a); ub = MP_USED(b); uc = MP_USED(c); + max = MAX(ua, ub); + + if (MP_SIGN(a) != MP_SIGN(b)) { + /* Different signs -- add magnitudes and keep sign of a */ + mp_digit carry; + + if (!s_pad(c, max)) + return MP_MEMORY; + + carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + uc = max; + + if (carry) { + if (!s_pad(c, max + 1)) + return MP_MEMORY; + + c->digits[max] = carry; + ++uc; + } + + MP_USED(c) = uc; + MP_SIGN(c) = MP_SIGN(a); + + } + else { + /* Same signs -- subtract magnitudes */ + mp_int x, y; + mp_sign osign; + int cmp = s_ucmp(a, b); + + if (!s_pad(c, max)) + return MP_MEMORY; + + if (cmp >= 0) { + x = a; y = b; osign = MP_ZPOS; + } + else { + x = b; y = a; osign = MP_NEG; + } + + if (MP_SIGN(a) == MP_NEG && cmp != 0) + osign = 1 - osign; + + s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); + MP_USED(c) = MP_USED(x); + CLAMP(c); + + MP_SIGN(c) = osign; + } + + return MP_OK; +} + +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_sub(a, &vtmp, c); +} + +mp_result mp_int_mul(mp_int a, mp_int b, mp_int c) +{ + mp_digit *out; + mp_size osize, ua, ub, p = 0; + mp_sign osign; + + CHECK(a != NULL && b != NULL && c != NULL); + + /* If either input is zero, we can shortcut multiplication */ + if (mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) { + mp_int_zero(c); + return MP_OK; + } + + /* Output is positive if inputs have same sign, otherwise negative */ + osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; + + /* If the output is not identical to any of the inputs, we'll write the + results directly; otherwise, allocate a temporary space. */ + ua = MP_USED(a); ub = MP_USED(b); + osize = MAX(ua, ub); + osize = 4 * ((osize + 1) / 2); + + if (c == a || c == b) { + p = ROUND_PREC(osize); + p = MAX(p, default_precision); + + if ((out = s_alloc(p)) == NULL) + return MP_MEMORY; + } + else { + if (!s_pad(c, osize)) + return MP_MEMORY; + + out = MP_DIGITS(c); + } + ZERO(out, osize); + + if (!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub)) + return MP_MEMORY; + + /* If we allocated a new buffer, get rid of whatever memory c was already + using, and fix up its fields to reflect that. + */ + if (out != MP_DIGITS(c)) { + if ((void *) MP_DIGITS(c) != (void *) c) + s_free(MP_DIGITS(c)); + MP_DIGITS(c) = out; + MP_ALLOC(c) = p; + } + + MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ + CLAMP(c); /* ... right here */ + MP_SIGN(c) = osign; + + return MP_OK; +} + +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_mul(a, &vtmp, c); +} + +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c) +{ + mp_result res; + CHECK(a != NULL && c != NULL && p2 >= 0); + + if ((res = mp_int_copy(a, c)) != MP_OK) + return res; + + if (s_qmul(c, (mp_size) p2)) + return MP_OK; + else + return MP_MEMORY; +} + +mp_result mp_int_sqr(mp_int a, mp_int c) +{ + mp_digit *out; + mp_size osize, p = 0; + + CHECK(a != NULL && c != NULL); + + /* Get a temporary buffer big enough to hold the result */ + osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); + if (a == c) { + p = ROUND_PREC(osize); + p = MAX(p, default_precision); + + if ((out = s_alloc(p)) == NULL) + return MP_MEMORY; + } + else { + if (!s_pad(c, osize)) + return MP_MEMORY; + + out = MP_DIGITS(c); + } + ZERO(out, osize); + + s_ksqr(MP_DIGITS(a), out, MP_USED(a)); + + /* Get rid of whatever memory c was already using, and fix up its fields to + reflect the new digit array it's using + */ + if (out != MP_DIGITS(c)) { + if ((void *) MP_DIGITS(c) != (void *) c) + s_free(MP_DIGITS(c)); + MP_DIGITS(c) = out; + MP_ALLOC(c) = p; + } + + MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ + CLAMP(c); /* ... right here */ + MP_SIGN(c) = MP_ZPOS; + + return MP_OK; +} + +mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) +{ + int cmp, lg; + mp_result res = MP_OK; + mp_int qout, rout; + mp_sign sa = MP_SIGN(a), sb = MP_SIGN(b); + DECLARE_TEMP(2); + + CHECK(a != NULL && b != NULL && q != r); + + if (CMPZ(b) == 0) + return MP_UNDEF; + else if ((cmp = s_ucmp(a, b)) < 0) { + /* If |a| < |b|, no division is required: + q = 0, r = a + */ + if (r && (res = mp_int_copy(a, r)) != MP_OK) + return res; + + if (q) + mp_int_zero(q); + + return MP_OK; + } + else if (cmp == 0) { + /* If |a| = |b|, no division is required: + q = 1 or -1, r = 0 + */ + if (r) + mp_int_zero(r); + + if (q) { + mp_int_zero(q); + q->digits[0] = 1; + + if (sa != sb) + MP_SIGN(q) = MP_NEG; + } + + return MP_OK; + } + + /* When |a| > |b|, real division is required. We need someplace to store + quotient and remainder, but q and r are allowed to be NULL or to overlap + with the inputs. + */ + if ((lg = s_isp2(b)) < 0) { + if (q && b != q) { + if ((res = mp_int_copy(a, q)) != MP_OK) + goto CLEANUP; + else + qout = q; + } + else { + qout = LAST_TEMP(); + SETUP(mp_int_init_copy(LAST_TEMP(), a)); + } + + if (r && a != r) { + if ((res = mp_int_copy(b, r)) != MP_OK) + goto CLEANUP; + else + rout = r; + } + else { + rout = LAST_TEMP(); + SETUP(mp_int_init_copy(LAST_TEMP(), b)); + } + + if ((res = s_udiv_knuth(qout, rout)) != MP_OK) goto CLEANUP; + } + else { + if (q && (res = mp_int_copy(a, q)) != MP_OK) goto CLEANUP; + if (r && (res = mp_int_copy(a, r)) != MP_OK) goto CLEANUP; + + if (q) s_qdiv(q, (mp_size) lg); qout = q; + if (r) s_qmod(r, (mp_size) lg); rout = r; + } + + /* Recompute signs for output */ + if (rout) { + MP_SIGN(rout) = sa; + if (CMPZ(rout) == 0) + MP_SIGN(rout) = MP_ZPOS; + } + if (qout) { + MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG; + if (CMPZ(qout) == 0) + MP_SIGN(qout) = MP_ZPOS; + } + + if (q && (res = mp_int_copy(qout, q)) != MP_OK) goto CLEANUP; + if (r && (res = mp_int_copy(rout, r)) != MP_OK) goto CLEANUP; + + CLEANUP_TEMP(); + return res; +} + +mp_result mp_int_mod(mp_int a, mp_int m, mp_int c) +{ + mp_result res; + mpz_t tmp; + mp_int out; + + if (m == c) { + mp_int_init(&tmp); + out = &tmp; + } + else { + out = c; + } + + if ((res = mp_int_div(a, m, NULL, out)) != MP_OK) + goto CLEANUP; + + if (CMPZ(out) < 0) + res = mp_int_add(out, m, c); + else + res = mp_int_copy(out, c); + + CLEANUP: + if (out != c) + mp_int_clear(&tmp); + + return res; +} + +mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r) +{ + mpz_t vtmp, rtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + mp_result res; + + mp_int_init(&rtmp); + s_fake(&vtmp, value, vbuf); + + if ((res = mp_int_div(a, &vtmp, q, &rtmp)) != MP_OK) + goto CLEANUP; + + if (r) + (void) mp_int_to_int(&rtmp, r); /* can't fail */ + + CLEANUP: + mp_int_clear(&rtmp); + return res; +} + +mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r) +{ + mp_result res = MP_OK; + + CHECK(a != NULL && p2 >= 0 && q != r); + + if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK) + s_qdiv(q, (mp_size) p2); + + if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK) + s_qmod(r, (mp_size) p2); + + return res; +} + +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c) +{ + mpz_t t; + mp_result res; + unsigned int v = abs(b); + + CHECK(c != NULL); + if (b < 0) + return MP_RANGE; + + if ((res = mp_int_init_copy(&t, a)) != MP_OK) + return res; + + (void) mp_int_set_value(c, 1); + while (v != 0) { + if (v & 1) { + if ((res = mp_int_mul(c, &t, c)) != MP_OK) + goto CLEANUP; + } + + v >>= 1; + if (v == 0) break; + + if ((res = mp_int_sqr(&t, &t)) != MP_OK) + goto CLEANUP; + } + + CLEANUP: + mp_int_clear(&t); + return res; +} + +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c) +{ + mpz_t t; + mp_result res; + unsigned int v = abs(b); + + CHECK(c != NULL); + if (b < 0) + return MP_RANGE; + + if ((res = mp_int_init_value(&t, a)) != MP_OK) + return res; + + (void) mp_int_set_value(c, 1); + while (v != 0) { + if (v & 1) { + if ((res = mp_int_mul(c, &t, c)) != MP_OK) + goto CLEANUP; + } + + v >>= 1; + if (v == 0) break; + + if ((res = mp_int_sqr(&t, &t)) != MP_OK) + goto CLEANUP; + } + + CLEANUP: + mp_int_clear(&t); + return res; +} + +mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c) +{ + mpz_t t; + mp_result res; + unsigned ix, jx; + + CHECK(a != NULL && b != NULL && c != NULL); + if (MP_SIGN(b) == MP_NEG) + return MP_RANGE; + + if ((res = mp_int_init_copy(&t, a)) != MP_OK) + return res; + + (void) mp_int_set_value(c, 1); + for (ix = 0; ix < MP_USED(b); ++ix) { + mp_digit d = b->digits[ix]; + + for (jx = 0; jx < MP_DIGIT_BIT; ++jx) { + if (d & 1) { + if ((res = mp_int_mul(c, &t, c)) != MP_OK) + goto CLEANUP; + } + + d >>= 1; + if (d == 0 && ix + 1 == MP_USED(b)) + break; + if ((res = mp_int_sqr(&t, &t)) != MP_OK) + goto CLEANUP; + } + } + + CLEANUP: + mp_int_clear(&t); + return res; +} + +int mp_int_compare(mp_int a, mp_int b) +{ + mp_sign sa; + + CHECK(a != NULL && b != NULL); + + sa = MP_SIGN(a); + if (sa == MP_SIGN(b)) { + int cmp = s_ucmp(a, b); + + /* If they're both zero or positive, the normal comparison applies; if both + negative, the sense is reversed. */ + if (sa == MP_ZPOS) + return cmp; + else + return -cmp; + + } + else { + if (sa == MP_ZPOS) + return 1; + else + return -1; + } +} + +int mp_int_compare_unsigned(mp_int a, mp_int b) +{ + NRCHECK(a != NULL && b != NULL); + + return s_ucmp(a, b); +} + +int mp_int_compare_zero(mp_int z) +{ + NRCHECK(z != NULL); + + if (MP_USED(z) == 1 && z->digits[0] == 0) + return 0; + else if (MP_SIGN(z) == MP_ZPOS) + return 1; + else + return -1; +} + +int mp_int_compare_value(mp_int z, mp_small value) +{ + mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; + int cmp; + + CHECK(z != NULL); + + if (vsign == MP_SIGN(z)) { + cmp = s_vcmp(z, value); + + return (vsign == MP_ZPOS) ? cmp : -cmp; + } + else { + return (value < 0) ? 1 : -1; + } +} + +int mp_int_compare_uvalue(mp_int z, mp_usmall uv) +{ + CHECK(z != NULL); + + if (MP_SIGN(z) == MP_NEG) + return -1; + else + return s_uvcmp(z, uv); +} + +mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) +{ + mp_result res; + mp_size um; + mp_int s; + DECLARE_TEMP(3); + + CHECK(a != NULL && b != NULL && c != NULL && m != NULL); + + /* Zero moduli and negative exponents are not considered. */ + if (CMPZ(m) == 0) + return MP_UNDEF; + if (CMPZ(b) < 0) + return MP_RANGE; + + um = MP_USED(m); + SETUP(mp_int_init_size(TEMP(0), 2 * um)); + SETUP(mp_int_init_size(TEMP(1), 2 * um)); + + if (c == b || c == m) { + SETUP(mp_int_init_size(TEMP(2), 2 * um)); + s = TEMP(2); + } + else { + s = c; + } + + if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP; + + if ((res = s_brmu(TEMP(1), m)) != MP_OK) goto CLEANUP; + + if ((res = s_embar(TEMP(0), b, m, TEMP(1), s)) != MP_OK) + goto CLEANUP; + + res = mp_int_copy(s, c); + + CLEANUP_TEMP(); + return res; +} + +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_exptmod(a, &vtmp, m, c); +} + +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, + mp_int m, mp_int c) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; + + s_fake(&vtmp, value, vbuf); + + return mp_int_exptmod(&vtmp, b, m, c); +} + +mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) +{ + mp_result res; + mp_size um; + mp_int s; + DECLARE_TEMP(2); + + CHECK(a && b && m && c); + + /* Zero moduli and negative exponents are not considered. */ + if (CMPZ(m) == 0) + return MP_UNDEF; + if (CMPZ(b) < 0) + return MP_RANGE; + + um = MP_USED(m); + SETUP(mp_int_init_size(TEMP(0), 2 * um)); + + if (c == b || c == m) { + SETUP(mp_int_init_size(TEMP(1), 2 * um)); + s = TEMP(1); + } + else { + s = c; + } + + if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) goto CLEANUP; + + if ((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK) + goto CLEANUP; + + res = mp_int_copy(s, c); + + CLEANUP_TEMP(); + return res; +} + +mp_result mp_int_redux_const(mp_int m, mp_int c) +{ + CHECK(m != NULL && c != NULL && m != c); + + return s_brmu(c, m); +} + +mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c) +{ + mp_result res; + mp_sign sa; + DECLARE_TEMP(2); + + CHECK(a != NULL && m != NULL && c != NULL); + + if (CMPZ(a) == 0 || CMPZ(m) <= 0) + return MP_RANGE; + + sa = MP_SIGN(a); /* need this for the result later */ + + for (last__ = 0; last__ < 2; ++last__) + mp_int_init(LAST_TEMP()); + + if ((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK) + goto CLEANUP; + + if (mp_int_compare_value(TEMP(0), 1) != 0) { + res = MP_UNDEF; + goto CLEANUP; + } + + /* It is first necessary to constrain the value to the proper range */ + if ((res = mp_int_mod(TEMP(1), m, TEMP(1))) != MP_OK) + goto CLEANUP; + + /* Now, if 'a' was originally negative, the value we have is actually the + magnitude of the negative representative; to get the positive value we + have to subtract from the modulus. Otherwise, the value is okay as it + stands. + */ + if (sa == MP_NEG) + res = mp_int_sub(m, TEMP(1), c); + else + res = mp_int_copy(TEMP(1), c); + + CLEANUP_TEMP(); + return res; +} + +/* Binary GCD algorithm due to Josef Stein, 1961 */ +mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c) +{ + int ca, cb, k = 0; + mpz_t u, v, t; + mp_result res; + + CHECK(a != NULL && b != NULL && c != NULL); + + ca = CMPZ(a); + cb = CMPZ(b); + if (ca == 0 && cb == 0) + return MP_UNDEF; + else if (ca == 0) + return mp_int_abs(b, c); + else if (cb == 0) + return mp_int_abs(a, c); + + mp_int_init(&t); + if ((res = mp_int_init_copy(&u, a)) != MP_OK) + goto U; + if ((res = mp_int_init_copy(&v, b)) != MP_OK) + goto V; + + MP_SIGN(&u) = MP_ZPOS; MP_SIGN(&v) = MP_ZPOS; + + { /* Divide out common factors of 2 from u and v */ + int div2_u = s_dp2k(&u), div2_v = s_dp2k(&v); + + k = MIN(div2_u, div2_v); + s_qdiv(&u, (mp_size) k); + s_qdiv(&v, (mp_size) k); + } + + if (mp_int_is_odd(&u)) { + if ((res = mp_int_neg(&v, &t)) != MP_OK) + goto CLEANUP; + } + else { + if ((res = mp_int_copy(&u, &t)) != MP_OK) + goto CLEANUP; + } + + for (;;) { + s_qdiv(&t, s_dp2k(&t)); + + if (CMPZ(&t) > 0) { + if ((res = mp_int_copy(&t, &u)) != MP_OK) + goto CLEANUP; + } + else { + if ((res = mp_int_neg(&t, &v)) != MP_OK) + goto CLEANUP; + } + + if ((res = mp_int_sub(&u, &v, &t)) != MP_OK) + goto CLEANUP; + + if (CMPZ(&t) == 0) + break; + } + + if ((res = mp_int_abs(&u, c)) != MP_OK) + goto CLEANUP; + if (!s_qmul(c, (mp_size) k)) + res = MP_MEMORY; + + CLEANUP: + mp_int_clear(&v); + V: mp_int_clear(&u); + U: mp_int_clear(&t); + + return res; +} + +/* This is the binary GCD algorithm again, but this time we keep track of the + elementary matrix operations as we go, so we can get values x and y + satisfying c = ax + by. + */ +mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, + mp_int x, mp_int y) +{ + int k, ca, cb; + mp_result res; + DECLARE_TEMP(8); + + CHECK(a != NULL && b != NULL && c != NULL && + (x != NULL || y != NULL)); + + ca = CMPZ(a); + cb = CMPZ(b); + if (ca == 0 && cb == 0) + return MP_UNDEF; + else if (ca == 0) { + if ((res = mp_int_abs(b, c)) != MP_OK) return res; + mp_int_zero(x); (void) mp_int_set_value(y, 1); return MP_OK; + } + else if (cb == 0) { + if ((res = mp_int_abs(a, c)) != MP_OK) return res; + (void) mp_int_set_value(x, 1); mp_int_zero(y); return MP_OK; + } + + /* Initialize temporaries: + A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */ + for (last__ = 0; last__ < 4; ++last__) + mp_int_init(LAST_TEMP()); + TEMP(0)->digits[0] = 1; + TEMP(3)->digits[0] = 1; + + SETUP(mp_int_init_copy(TEMP(4), a)); + SETUP(mp_int_init_copy(TEMP(5), b)); + + /* We will work with absolute values here */ + MP_SIGN(TEMP(4)) = MP_ZPOS; + MP_SIGN(TEMP(5)) = MP_ZPOS; + + { /* Divide out common factors of 2 from u and v */ + int div2_u = s_dp2k(TEMP(4)), div2_v = s_dp2k(TEMP(5)); + + k = MIN(div2_u, div2_v); + s_qdiv(TEMP(4), k); + s_qdiv(TEMP(5), k); + } + + SETUP(mp_int_init_copy(TEMP(6), TEMP(4))); + SETUP(mp_int_init_copy(TEMP(7), TEMP(5))); + + for (;;) { + while (mp_int_is_even(TEMP(4))) { + s_qdiv(TEMP(4), 1); + + if (mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) { + if ((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK) + goto CLEANUP; + } + + s_qdiv(TEMP(0), 1); + s_qdiv(TEMP(1), 1); + } + + while (mp_int_is_even(TEMP(5))) { + s_qdiv(TEMP(5), 1); + + if (mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) { + if ((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK) + goto CLEANUP; + } + + s_qdiv(TEMP(2), 1); + s_qdiv(TEMP(3), 1); + } + + if (mp_int_compare(TEMP(4), TEMP(5)) >= 0) { + if ((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK) goto CLEANUP; + if ((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK) goto CLEANUP; + if ((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK) goto CLEANUP; + } + else { + if ((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK) goto CLEANUP; + if ((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) goto CLEANUP; + if ((res = mp_int_sub(TEMP(3), TEMP(1), TEMP(3))) != MP_OK) goto CLEANUP; + } + + if (CMPZ(TEMP(4)) == 0) { + if (x && (res = mp_int_copy(TEMP(2), x)) != MP_OK) goto CLEANUP; + if (y && (res = mp_int_copy(TEMP(3), y)) != MP_OK) goto CLEANUP; + if (c) { + if (!s_qmul(TEMP(5), k)) { + res = MP_MEMORY; + goto CLEANUP; + } + + res = mp_int_copy(TEMP(5), c); + } + + break; + } + } + + CLEANUP_TEMP(); + return res; +} + +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c) +{ + mpz_t lcm; + mp_result res; + + CHECK(a != NULL && b != NULL && c != NULL); + + /* Since a * b = gcd(a, b) * lcm(a, b), we can compute + lcm(a, b) = (a / gcd(a, b)) * b. + + This formulation insures everything works even if the input + variables share space. + */ + if ((res = mp_int_init(&lcm)) != MP_OK) + return res; + if ((res = mp_int_gcd(a, b, &lcm)) != MP_OK) + goto CLEANUP; + if ((res = mp_int_div(a, &lcm, &lcm, NULL)) != MP_OK) + goto CLEANUP; + if ((res = mp_int_mul(&lcm, b, &lcm)) != MP_OK) + goto CLEANUP; + + res = mp_int_copy(&lcm, c); + + CLEANUP: + mp_int_clear(&lcm); + + return res; +} + +int mp_int_divisible_value(mp_int a, mp_small v) +{ + mp_small rem = 0; + + if (mp_int_div_value(a, v, NULL, &rem) != MP_OK) + return 0; + + return rem == 0; +} + +int mp_int_is_pow2(mp_int z) +{ + CHECK(z != NULL); + + return s_isp2(z); +} + +/* Implementation of Newton's root finding method, based loosely on a patch + contributed by Hal Finkel + modified by M. J. Fromberger. + */ +mp_result mp_int_root(mp_int a, mp_small b, mp_int c) +{ + mp_result res = MP_OK; + int flips = 0; + DECLARE_TEMP(5); + + CHECK(a != NULL && c != NULL && b > 0); + + if (b == 1) { + return mp_int_copy(a, c); + } + if (MP_SIGN(a) == MP_NEG) { + if (b % 2 == 0) + return MP_UNDEF; /* root does not exist for negative a with even b */ + else + flips = 1; + } + + SETUP(mp_int_init_copy(LAST_TEMP(), a)); + SETUP(mp_int_init_copy(LAST_TEMP(), a)); + SETUP(mp_int_init(LAST_TEMP())); + SETUP(mp_int_init(LAST_TEMP())); + SETUP(mp_int_init(LAST_TEMP())); + + (void) mp_int_abs(TEMP(0), TEMP(0)); + (void) mp_int_abs(TEMP(1), TEMP(1)); + + for (;;) { + if ((res = mp_int_expt(TEMP(1), b, TEMP(2))) != MP_OK) + goto CLEANUP; + + if (mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) + break; + + if ((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_expt(TEMP(1), b - 1, TEMP(3))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_mul_value(TEMP(3), b, TEMP(3))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL)) != MP_OK) + goto CLEANUP; + if ((res = mp_int_sub(TEMP(1), TEMP(4), TEMP(4))) != MP_OK) + goto CLEANUP; + + if (mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) { + if ((res = mp_int_sub_value(TEMP(4), 1, TEMP(4))) != MP_OK) + goto CLEANUP; + } + if ((res = mp_int_copy(TEMP(4), TEMP(1))) != MP_OK) + goto CLEANUP; + } + + if ((res = mp_int_copy(TEMP(1), c)) != MP_OK) + goto CLEANUP; + + /* If the original value of a was negative, flip the output sign. */ + if (flips) + (void) mp_int_neg(c, c); /* cannot fail */ + + CLEANUP_TEMP(); + return res; +} + +mp_result mp_int_to_int(mp_int z, mp_small *out) +{ + mp_usmall uv = 0; + mp_size uz; + mp_digit *dz; + mp_sign sz; + + CHECK(z != NULL); + + /* Make sure the value is representable as a small integer */ + sz = MP_SIGN(z); + if ((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || + mp_int_compare_value(z, MP_SMALL_MIN) < 0) + return MP_RANGE; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; + + while (uz > 0) { + uv <<= MP_DIGIT_BIT/2; + uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; + --uz; + } + + if (out) + *out = (sz == MP_NEG) ? -(mp_small)uv : (mp_small)uv; + + return MP_OK; +} + +mp_result mp_int_to_uint(mp_int z, mp_usmall *out) +{ + mp_usmall uv = 0; + mp_size uz; + mp_digit *dz; + mp_sign sz; + + CHECK(z != NULL); + + /* Make sure the value is representable as an unsigned small integer */ + sz = MP_SIGN(z); + if (sz == MP_NEG || mp_int_compare_uvalue(z, MP_USMALL_MAX) > 0) + return MP_RANGE; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; + + while (uz > 0) { + uv <<= MP_DIGIT_BIT/2; + uv = (uv << (MP_DIGIT_BIT/2)) | *dz--; + --uz; + } + + if (out) + *out = uv; + + return MP_OK; +} + +mp_result mp_int_to_string(mp_int z, mp_size radix, + char *str, int limit) +{ + mp_result res; + int cmp = 0; + + CHECK(z != NULL && str != NULL && limit >= 2); + + if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + return MP_RANGE; + + if (CMPZ(z) == 0) { + *str++ = s_val2ch(0, 1); + } + else { + mpz_t tmp; + char *h, *t; + + if ((res = mp_int_init_copy(&tmp, z)) != MP_OK) + return res; + + if (MP_SIGN(z) == MP_NEG) { + *str++ = '-'; + --limit; + } + h = str; + + /* Generate digits in reverse order until finished or limit reached */ + for (/* */; limit > 0; --limit) { + mp_digit d; + + if ((cmp = CMPZ(&tmp)) == 0) + break; + + d = s_ddiv(&tmp, (mp_digit)radix); + *str++ = s_val2ch(d, 1); + } + t = str - 1; + + /* Put digits back in correct output order */ + while (h < t) { + char tc = *h; + *h++ = *t; + *t-- = tc; + } + + mp_int_clear(&tmp); + } + + *str = '\0'; + if (cmp == 0) + return MP_OK; + else + return MP_TRUNC; +} + +mp_result mp_int_string_len(mp_int z, mp_size radix) +{ + int len; + + CHECK(z != NULL); + + if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + return MP_RANGE; + + len = s_outlen(z, radix) + 1; /* for terminator */ + + /* Allow for sign marker on negatives */ + if (MP_SIGN(z) == MP_NEG) + len += 1; + + return len; +} + +/* Read zero-terminated string into z */ +mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str) +{ + return mp_int_read_cstring(z, radix, str, NULL); +} + +mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end) +{ + int ch; + + CHECK(z != NULL && str != NULL); + + if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + return MP_RANGE; + + /* Skip leading whitespace */ + while (isspace((int)*str)) + ++str; + + /* Handle leading sign tag (+/-, positive default) */ + switch (*str) { + case '-': + MP_SIGN(z) = MP_NEG; + ++str; + break; + case '+': + ++str; /* fallthrough */ + default: + MP_SIGN(z) = MP_ZPOS; + break; + } + + /* Skip leading zeroes */ + while ((ch = s_ch2val(*str, radix)) == 0) + ++str; + + /* Make sure there is enough space for the value */ + if (!s_pad(z, s_inlen(strlen(str), radix))) + return MP_MEMORY; + + MP_USED(z) = 1; z->digits[0] = 0; + + while (*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) { + s_dmul(z, (mp_digit)radix); + s_dadd(z, (mp_digit)ch); + ++str; + } + + CLAMP(z); + + /* Override sign for zero, even if negative specified. */ + if (CMPZ(z) == 0) + MP_SIGN(z) = MP_ZPOS; + + if (end != NULL) + *end = (char *)str; + + /* Return a truncation error if the string has unprocessed characters + remaining, so the caller can tell if the whole string was done */ + if (*str != '\0') + return MP_TRUNC; + else + return MP_OK; +} + +mp_result mp_int_count_bits(mp_int z) +{ + mp_size nbits = 0, uz; + mp_digit d; + + CHECK(z != NULL); + + uz = MP_USED(z); + if (uz == 1 && z->digits[0] == 0) + return 1; + + --uz; + nbits = uz * MP_DIGIT_BIT; + d = z->digits[uz]; + + while (d != 0) { + d >>= 1; + ++nbits; + } + + return nbits; +} + +mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit) +{ + static const int PAD_FOR_2C = 1; + + mp_result res; + int limpos = limit; + + CHECK(z != NULL && buf != NULL); + + res = s_tobin(z, buf, &limpos, PAD_FOR_2C); + + if (MP_SIGN(z) == MP_NEG) + s_2comp(buf, limpos); + + return res; +} + +mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len) +{ + mp_size need, i; + unsigned char *tmp; + mp_digit *dz; + + CHECK(z != NULL && buf != NULL && len > 0); + + /* Figure out how many digits are needed to represent this value */ + need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if (!s_pad(z, need)) + return MP_MEMORY; + + mp_int_zero(z); + + /* If the high-order bit is set, take the 2's complement before reading the + value (it will be restored afterward) */ + if (buf[0] >> (CHAR_BIT - 1)) { + MP_SIGN(z) = MP_NEG; + s_2comp(buf, len); + } + + dz = MP_DIGITS(z); + for (tmp = buf, i = len; i > 0; --i, ++tmp) { + s_qmul(z, (mp_size) CHAR_BIT); + *dz |= *tmp; + } + + /* Restore 2's complement if we took it before */ + if (MP_SIGN(z) == MP_NEG) + s_2comp(buf, len); + + return MP_OK; +} + +mp_result mp_int_binary_len(mp_int z) +{ + mp_result res = mp_int_count_bits(z); + int bytes = mp_int_unsigned_len(z); + + if (res <= 0) + return res; + + bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + + /* If the highest-order bit falls exactly on a byte boundary, we need to pad + with an extra byte so that the sign will be read correctly when reading it + back in. */ + if (bytes * CHAR_BIT == res) + ++bytes; + + return bytes; +} + +mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit) +{ + static const int NO_PADDING = 0; + + CHECK(z != NULL && buf != NULL); + + return s_tobin(z, buf, &limit, NO_PADDING); +} + +mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len) +{ + mp_size need, i; + unsigned char *tmp; + + CHECK(z != NULL && buf != NULL && len > 0); + + /* Figure out how many digits are needed to represent this value */ + need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if (!s_pad(z, need)) + return MP_MEMORY; + + mp_int_zero(z); + + for (tmp = buf, i = len; i > 0; --i, ++tmp) { + (void) s_qmul(z, CHAR_BIT); + *MP_DIGITS(z) |= *tmp; + } + + return MP_OK; +} + +mp_result mp_int_unsigned_len(mp_int z) +{ + mp_result res = mp_int_count_bits(z); + int bytes; + + if (res <= 0) + return res; + + bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + + return bytes; +} + +const char *mp_error_string(mp_result res) +{ + int ix; + if (res > 0) + return s_unknown_err; + + res = -res; + for (ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix) + ; + + if (s_error_msg[ix] != NULL) + return s_error_msg[ix]; + else + return s_unknown_err; +} + +/*------------------------------------------------------------------------*/ +/* Private functions for internal use. These make assumptions. */ + +STATIC mp_digit *s_alloc(mp_size num) +{ + mp_digit *out = malloc(num * sizeof(mp_digit)); + + assert(out != NULL); /* for debugging */ +#if DEBUG > 1 + { + mp_digit v = (mp_digit) 0xdeadbeef; + int ix; + + for (ix = 0; ix < num; ++ix) + out[ix] = v; + } +#endif + + return out; +} + +STATIC mp_digit *s_realloc(mp_digit *old, mp_size osize, mp_size nsize) +{ +#if DEBUG > 1 + mp_digit *new = s_alloc(nsize); + int ix; + + for (ix = 0; ix < nsize; ++ix) + new[ix] = (mp_digit) 0xdeadbeef; + + memcpy(new, old, osize * sizeof(mp_digit)); +#else + mp_digit *new = realloc(old, nsize * sizeof(mp_digit)); + + assert(new != NULL); /* for debugging */ +#endif + return new; +} + +STATIC void s_free(void *ptr) +{ + free(ptr); +} + +STATIC int s_pad(mp_int z, mp_size min) +{ + if (MP_ALLOC(z) < min) { + mp_size nsize = ROUND_PREC(min); + mp_digit *tmp; + + if ((void *)z->digits == (void *)z) { + if ((tmp = s_alloc(nsize)) == NULL) + return 0; + + COPY(MP_DIGITS(z), tmp, MP_USED(z)); + } + else if ((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) + return 0; + + MP_DIGITS(z) = tmp; + MP_ALLOC(z) = nsize; + } + + return 1; +} + +/* Note: This will not work correctly when value == MP_SMALL_MIN */ +STATIC void s_fake(mp_int z, mp_small value, mp_digit vbuf[]) +{ + mp_usmall uv = (mp_usmall) (value < 0) ? -value : value; + s_ufake(z, uv, vbuf); + if (value < 0) + z->sign = MP_NEG; +} + +STATIC void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]) +{ + mp_size ndig = (mp_size) s_uvpack(value, vbuf); + + z->used = ndig; + z->alloc = MP_VALUE_DIGITS(value); + z->sign = MP_ZPOS; + z->digits = vbuf; +} + +STATIC int s_cdig(mp_digit *da, mp_digit *db, mp_size len) +{ + mp_digit *dat = da + len - 1, *dbt = db + len - 1; + + for (/* */; len != 0; --len, --dat, --dbt) { + if (*dat > *dbt) + return 1; + else if (*dat < *dbt) + return -1; + } + + return 0; +} + +STATIC int s_uvpack(mp_usmall uv, mp_digit t[]) +{ + int ndig = 0; + + if (uv == 0) + t[ndig++] = 0; + else { + while (uv != 0) { + t[ndig++] = (mp_digit) uv; + uv >>= MP_DIGIT_BIT/2; + uv >>= MP_DIGIT_BIT/2; + } + } + + return ndig; +} + +STATIC int s_ucmp(mp_int a, mp_int b) +{ + mp_size ua = MP_USED(a), ub = MP_USED(b); + + if (ua > ub) + return 1; + else if (ub > ua) + return -1; + else + return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua); +} + +STATIC int s_vcmp(mp_int a, mp_small v) +{ + mp_usmall uv = (mp_usmall) (v < 0) ? -v : v; + return s_uvcmp(a, uv); +} + +STATIC int s_uvcmp(mp_int a, mp_usmall uv) +{ + mpz_t vtmp; + mp_digit vdig[MP_VALUE_DIGITS(uv)]; + + s_ufake(&vtmp, uv, vdig); + return s_ucmp(a, &vtmp); +} + +STATIC mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b) +{ + mp_size pos; + mp_word w = 0; + + /* Insure that da is the longer of the two to simplify later code */ + if (size_b > size_a) { + SWAP(mp_digit *, da, db); + SWAP(mp_size, size_a, size_b); + } + + /* Add corresponding digits until the shorter number runs out */ + for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { + w = w + (mp_word) *da + (mp_word) *db; + *dc = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + /* Propagate carries as far as necessary */ + for (/* */; pos < size_a; ++pos, ++da, ++dc) { + w = w + *da; + + *dc = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + /* Return carry out */ + return (mp_digit)w; +} + +STATIC void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b) +{ + mp_size pos; + mp_word w = 0; + + /* We assume that |a| >= |b| so this should definitely hold */ + assert(size_a >= size_b); + + /* Subtract corresponding digits and propagate borrow */ + for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { + w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ + (mp_word)*da) - w - (mp_word)*db; + + *dc = LOWER_HALF(w); + w = (UPPER_HALF(w) == 0); + } + + /* Finish the subtraction for remaining upper digits of da */ + for (/* */; pos < size_a; ++pos, ++da, ++dc) { + w = ((mp_word)MP_DIGIT_MAX + 1 + /* MP_RADIX */ + (mp_word)*da) - w; + + *dc = LOWER_HALF(w); + w = (UPPER_HALF(w) == 0); + } + + /* If there is a borrow out at the end, it violates the precondition */ + assert(w == 0); +} + +STATIC int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b) +{ + mp_size bot_size; + + /* Make sure b is the smaller of the two input values */ + if (size_b > size_a) { + SWAP(mp_digit *, da, db); + SWAP(mp_size, size_a, size_b); + } + + /* Insure that the bottom is the larger half in an odd-length split; the code + below relies on this being true. + */ + bot_size = (size_a + 1) / 2; + + /* If the values are big enough to bother with recursion, use the Karatsuba + algorithm to compute the product; otherwise use the normal multiplication + algorithm + */ + if (multiply_threshold && + size_a >= multiply_threshold && + size_b > bot_size) { + + mp_digit *t1, *t2, *t3, carry; + + mp_digit *a_top = da + bot_size; + mp_digit *b_top = db + bot_size; + + mp_size at_size = size_a - bot_size; + mp_size bt_size = size_b - bot_size; + mp_size buf_size = 2 * bot_size; + + /* Do a single allocation for all three temporary buffers needed; each + buffer must be big enough to hold the product of two bottom halves, and + one buffer needs space for the completed product; twice the space is + plenty. + */ + if ((t1 = s_alloc(4 * buf_size)) == NULL) return 0; + t2 = t1 + buf_size; + t3 = t2 + buf_size; + ZERO(t1, 4 * buf_size); + + /* t1 and t2 are initially used as temporaries to compute the inner product + (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0 + */ + carry = s_uadd(da, a_top, t1, bot_size, at_size); /* t1 = a1 + a0 */ + t1[bot_size] = carry; + + carry = s_uadd(db, b_top, t2, bot_size, bt_size); /* t2 = b1 + b0 */ + t2[bot_size] = carry; + + (void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1); /* t3 = t1 * t2 */ + + /* Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so that + we're left with only the pieces we want: t3 = a1b0 + a0b1 + */ + ZERO(t1, buf_size); + ZERO(t2, buf_size); + (void) s_kmul(da, db, t1, bot_size, bot_size); /* t1 = a0 * b0 */ + (void) s_kmul(a_top, b_top, t2, at_size, bt_size); /* t2 = a1 * b1 */ + + /* Subtract out t1 and t2 to get the inner product */ + s_usub(t3, t1, t3, buf_size + 2, buf_size); + s_usub(t3, t2, t3, buf_size + 2, buf_size); + + /* Assemble the output value */ + COPY(t1, dc, buf_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, + buf_size + 1, buf_size); + assert(carry == 0); + + carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, + buf_size, buf_size); + assert(carry == 0); + + s_free(t1); /* note t2 and t3 are just internal pointers to t1 */ + } + else { + s_umul(da, db, dc, size_a, size_b); + } + + return 1; +} + +STATIC void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, + mp_size size_a, mp_size size_b) +{ + mp_size a, b; + mp_word w; + + for (a = 0; a < size_a; ++a, ++dc, ++da) { + mp_digit *dct = dc; + mp_digit *dbt = db; + + if (*da == 0) + continue; + + w = 0; + for (b = 0; b < size_b; ++b, ++dbt, ++dct) { + w = (mp_word)*da * (mp_word)*dbt + w + (mp_word)*dct; + + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + *dct = (mp_digit)w; + } +} + +STATIC int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) +{ + if (multiply_threshold && size_a > multiply_threshold) { + mp_size bot_size = (size_a + 1) / 2; + mp_digit *a_top = da + bot_size; + mp_digit *t1, *t2, *t3, carry; + mp_size at_size = size_a - bot_size; + mp_size buf_size = 2 * bot_size; + + if ((t1 = s_alloc(4 * buf_size)) == NULL) return 0; + t2 = t1 + buf_size; + t3 = t2 + buf_size; + ZERO(t1, 4 * buf_size); + + (void) s_ksqr(da, t1, bot_size); /* t1 = a0 ^ 2 */ + (void) s_ksqr(a_top, t2, at_size); /* t2 = a1 ^ 2 */ + + (void) s_kmul(da, a_top, t3, bot_size, at_size); /* t3 = a0 * a1 */ + + /* Quick multiply t3 by 2, shifting left (can't overflow) */ + { + int i, top = bot_size + at_size; + mp_word w, save = 0; + + for (i = 0; i < top; ++i) { + w = t3[i]; + w = (w << 1) | save; + t3[i] = LOWER_HALF(w); + save = UPPER_HALF(w); + } + t3[i] = LOWER_HALF(save); + } + + /* Assemble the output value */ + COPY(t1, dc, 2 * bot_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, + buf_size + 1, buf_size); + assert(carry == 0); + + carry = s_uadd(t2, dc + 2*bot_size, dc + 2*bot_size, + buf_size, buf_size); + assert(carry == 0); + + s_free(t1); /* note that t2 and t2 are internal pointers only */ + + } + else { + s_usqr(da, dc, size_a); + } + + return 1; +} + +STATIC void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) +{ + mp_size i, j; + mp_word w; + + for (i = 0; i < size_a; ++i, dc += 2, ++da) { + mp_digit *dct = dc, *dat = da; + + if (*da == 0) + continue; + + /* Take care of the first digit, no rollover */ + w = (mp_word)*dat * (mp_word)*dat + (mp_word)*dct; + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + ++dat; ++dct; + + for (j = i + 1; j < size_a; ++j, ++dat, ++dct) { + mp_word t = (mp_word)*da * (mp_word)*dat; + mp_word u = w + (mp_word)*dct, ov = 0; + + /* Check if doubling t will overflow a word */ + if (HIGH_BIT_SET(t)) + ov = 1; + + w = t + t; + + /* Check if adding u to w will overflow a word */ + if (ADD_WILL_OVERFLOW(w, u)) + ov = 1; + + w += u; + + *dct = LOWER_HALF(w); + w = UPPER_HALF(w); + if (ov) { + w += MP_DIGIT_MAX; /* MP_RADIX */ + ++w; + } + } + + w = w + *dct; + *dct = (mp_digit)w; + while ((w = UPPER_HALF(w)) != 0) { + ++dct; w = w + *dct; + *dct = LOWER_HALF(w); + } + + assert(w == 0); + } +} + +STATIC void s_dadd(mp_int a, mp_digit b) +{ + mp_word w = 0; + mp_digit *da = MP_DIGITS(a); + mp_size ua = MP_USED(a); + + w = (mp_word)*da + b; + *da++ = LOWER_HALF(w); + w = UPPER_HALF(w); + + for (ua -= 1; ua > 0; --ua, ++da) { + w = (mp_word)*da + w; + + *da = LOWER_HALF(w); + w = UPPER_HALF(w); + } + + if (w) { + *da = (mp_digit)w; + MP_USED(a) += 1; + } +} + +STATIC void s_dmul(mp_int a, mp_digit b) +{ + mp_word w = 0; + mp_digit *da = MP_DIGITS(a); + mp_size ua = MP_USED(a); + + while (ua > 0) { + w = (mp_word)*da * b + w; + *da++ = LOWER_HALF(w); + w = UPPER_HALF(w); + --ua; + } + + if (w) { + *da = (mp_digit)w; + MP_USED(a) += 1; + } +} + +STATIC void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) +{ + mp_word w = 0; + + while (size_a > 0) { + w = (mp_word)*da++ * (mp_word)b + w; + + *dc++ = LOWER_HALF(w); + w = UPPER_HALF(w); + --size_a; + } + + if (w) + *dc = LOWER_HALF(w); +} + +STATIC mp_digit s_ddiv(mp_int a, mp_digit b) +{ + mp_word w = 0, qdigit; + mp_size ua = MP_USED(a); + mp_digit *da = MP_DIGITS(a) + ua - 1; + + for (/* */; ua > 0; --ua, --da) { + w = (w << MP_DIGIT_BIT) | *da; + + if (w >= b) { + qdigit = w / b; + w = w % b; + } + else { + qdigit = 0; + } + + *da = (mp_digit)qdigit; + } + + CLAMP(a); + return (mp_digit)w; +} + +STATIC void s_qdiv(mp_int z, mp_size p2) +{ + mp_size ndig = p2 / MP_DIGIT_BIT, nbits = p2 % MP_DIGIT_BIT; + mp_size uz = MP_USED(z); + + if (ndig) { + mp_size mark; + mp_digit *to, *from; + + if (ndig >= uz) { + mp_int_zero(z); + return; + } + + to = MP_DIGITS(z); from = to + ndig; + + for (mark = ndig; mark < uz; ++mark) + *to++ = *from++; + + MP_USED(z) = uz - ndig; + } + + if (nbits) { + mp_digit d = 0, *dz, save; + mp_size up = MP_DIGIT_BIT - nbits; + + uz = MP_USED(z); + dz = MP_DIGITS(z) + uz - 1; + + for (/* */; uz > 0; --uz, --dz) { + save = *dz; + + *dz = (*dz >> nbits) | (d << up); + d = save; + } + + CLAMP(z); + } + + if (MP_USED(z) == 1 && z->digits[0] == 0) + MP_SIGN(z) = MP_ZPOS; +} + +STATIC void s_qmod(mp_int z, mp_size p2) +{ + mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT; + mp_size uz = MP_USED(z); + mp_digit mask = (1 << rest) - 1; + + if (start <= uz) { + MP_USED(z) = start; + z->digits[start - 1] &= mask; + CLAMP(z); + } +} + +STATIC int s_qmul(mp_int z, mp_size p2) +{ + mp_size uz, need, rest, extra, i; + mp_digit *from, *to, d; + + if (p2 == 0) + return 1; + + uz = MP_USED(z); + need = p2 / MP_DIGIT_BIT; rest = p2 % MP_DIGIT_BIT; + + /* Figure out if we need an extra digit at the top end; this occurs if the + topmost `rest' bits of the high-order digit of z are not zero, meaning + they will be shifted off the end if not preserved */ + extra = 0; + if (rest != 0) { + mp_digit *dz = MP_DIGITS(z) + uz - 1; + + if ((*dz >> (MP_DIGIT_BIT - rest)) != 0) + extra = 1; + } + + if (!s_pad(z, uz + need + extra)) + return 0; + + /* If we need to shift by whole digits, do that in one pass, then + to back and shift by partial digits. + */ + if (need > 0) { + from = MP_DIGITS(z) + uz - 1; + to = from + need; + + for (i = 0; i < uz; ++i) + *to-- = *from--; + + ZERO(MP_DIGITS(z), need); + uz += need; + } + + if (rest) { + d = 0; + for (i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from) { + mp_digit save = *from; + + *from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest)); + d = save; + } + + d >>= (MP_DIGIT_BIT - rest); + if (d != 0) { + *from = d; + uz += extra; + } + } + + MP_USED(z) = uz; + CLAMP(z); + + return 1; +} + +/* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z| + The sign of the result is always zero/positive. + */ +STATIC int s_qsub(mp_int z, mp_size p2) +{ + mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), *zp; + mp_size tdig = (p2 / MP_DIGIT_BIT), pos; + mp_word w = 0; + + if (!s_pad(z, tdig + 1)) + return 0; + + for (pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp) { + w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word)*zp; + + *zp = LOWER_HALF(w); + w = UPPER_HALF(w) ? 0 : 1; + } + + w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word)*zp; + *zp = LOWER_HALF(w); + + assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */ + + MP_SIGN(z) = MP_ZPOS; + CLAMP(z); + + return 1; +} + +STATIC int s_dp2k(mp_int z) +{ + int k = 0; + mp_digit *dp = MP_DIGITS(z), d; + + if (MP_USED(z) == 1 && *dp == 0) + return 1; + + while (*dp == 0) { + k += MP_DIGIT_BIT; + ++dp; + } + + d = *dp; + while ((d & 1) == 0) { + d >>= 1; + ++k; + } + + return k; +} + +STATIC int s_isp2(mp_int z) +{ + mp_size uz = MP_USED(z), k = 0; + mp_digit *dz = MP_DIGITS(z), d; + + while (uz > 1) { + if (*dz++ != 0) + return -1; + k += MP_DIGIT_BIT; + --uz; + } + + d = *dz; + while (d > 1) { + if (d & 1) + return -1; + ++k; d >>= 1; + } + + return (int) k; +} + +STATIC int s_2expt(mp_int z, mp_small k) +{ + mp_size ndig, rest; + mp_digit *dz; + + ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT; + rest = k % MP_DIGIT_BIT; + + if (!s_pad(z, ndig)) + return 0; + + dz = MP_DIGITS(z); + ZERO(dz, ndig); + *(dz + ndig - 1) = (1 << rest); + MP_USED(z) = ndig; + + return 1; +} + +STATIC int s_norm(mp_int a, mp_int b) +{ + mp_digit d = b->digits[MP_USED(b) - 1]; + int k = 0; + + while (d < (mp_digit) (1 << (MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */ + d <<= 1; + ++k; + } + + /* These multiplications can't fail */ + if (k != 0) { + (void) s_qmul(a, (mp_size) k); + (void) s_qmul(b, (mp_size) k); + } + + return k; +} + +STATIC mp_result s_brmu(mp_int z, mp_int m) +{ + mp_size um = MP_USED(m) * 2; + + if (!s_pad(z, um)) + return MP_MEMORY; + + s_2expt(z, MP_DIGIT_BIT * um); + return mp_int_div(z, m, z, NULL); +} + +STATIC int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) +{ + mp_size um = MP_USED(m), umb_p1, umb_m1; + + umb_p1 = (um + 1) * MP_DIGIT_BIT; + umb_m1 = (um - 1) * MP_DIGIT_BIT; + + if (mp_int_copy(x, q1) != MP_OK) + return 0; + + /* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */ + s_qdiv(q1, umb_m1); + UMUL(q1, mu, q2); + s_qdiv(q2, umb_p1); + + /* Set x = x mod b^(k+1) */ + s_qmod(x, umb_p1); + + /* Now, q is a guess for the quotient a / m. + Compute x - q * m mod b^(k+1), replacing x. This may be off + by a factor of 2m, but no more than that. + */ + UMUL(q2, m, q1); + s_qmod(q1, umb_p1); + (void) mp_int_sub(x, q1, x); /* can't fail */ + + /* The result may be < 0; if it is, add b^(k+1) to pin it in the proper + range. */ + if ((CMPZ(x) < 0) && !s_qsub(x, umb_p1)) + return 0; + + /* If x > m, we need to back it off until it is in range. This will be + required at most twice. */ + if (mp_int_compare(x, m) >= 0) { + (void) mp_int_sub(x, m, x); + if (mp_int_compare(x, m) >= 0) + (void) mp_int_sub(x, m, x); + } + + /* At this point, x has been properly reduced. */ + return 1; +} + +/* Perform modular exponentiation using Barrett's method, where mu is the + reduction constant for m. Assumes a < m, b > 0. */ +STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) +{ + mp_digit *db, *dbt, umu, d; + mp_result res; + DECLARE_TEMP(3); + + umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1; + + while (last__ < 3) { + SETUP(mp_int_init_size(LAST_TEMP(), 4 * umu)); + ZERO(MP_DIGITS(TEMP(last__ - 1)), MP_ALLOC(TEMP(last__ - 1))); + } + + (void) mp_int_set_value(c, 1); + + /* Take care of low-order digits */ + while (db < dbt) { + int i; + + for (d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) { + if (d & 1) { + /* The use of a second temporary avoids allocation */ + UMUL(c, a, TEMP(0)); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + mp_int_copy(TEMP(0), c); + } + + + USQR(a, TEMP(0)); + assert(MP_SIGN(TEMP(0)) == MP_ZPOS); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + assert(MP_SIGN(TEMP(0)) == MP_ZPOS); + mp_int_copy(TEMP(0), a); + } + + ++db; + } + + /* Take care of highest-order digit */ + d = *dbt; + for (;;) { + if (d & 1) { + UMUL(c, a, TEMP(0)); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + mp_int_copy(TEMP(0), c); + } + + d >>= 1; + if (!d) break; + + USQR(a, TEMP(0)); + if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { + res = MP_MEMORY; goto CLEANUP; + } + (void) mp_int_copy(TEMP(0), a); + } + + CLEANUP_TEMP(); + return res; +} + +#if 0 +/* + The s_udiv function produces incorrect results. For example, with test + div:11141460315522012760862883825:48318382095:0,230584300062375935 + commenting out the function for now and using s_udiv_knuth instead. + STATIC mp_result s_udiv(mp_int a, mp_int b); +*/ +/* Precondition: a >= b and b > 0 + Postcondition: a' = a / b, b' = a % b + */ +STATIC mp_result s_udiv(mp_int a, mp_int b) +{ + mpz_t q, r, t; + mp_size ua, ub, qpos = 0; + mp_digit *da, btop; + mp_result res = MP_OK; + int k, skip = 0; + + /* Force signs to positive */ + MP_SIGN(a) = MP_ZPOS; + MP_SIGN(b) = MP_ZPOS; + + /* Normalize, per Knuth */ + k = s_norm(a, b); + + ua = MP_USED(a); ub = MP_USED(b); btop = b->digits[ub - 1]; + if ((res = mp_int_init_size(&q, ua)) != MP_OK) return res; + if ((res = mp_int_init_size(&t, ua + 1)) != MP_OK) goto CLEANUP; + + da = MP_DIGITS(a); + r.digits = da + ua - 1; /* The contents of r are shared with a */ + r.used = 1; + r.sign = MP_ZPOS; + r.alloc = MP_ALLOC(a); + ZERO(t.digits, t.alloc); + + /* Solve for quotient digits, store in q.digits in reverse order */ + while (r.digits >= da) { + assert(qpos <= q.alloc); + + if (s_ucmp(b, &r) > 0) { + r.digits -= 1; + r.used += 1; + + if (++skip > 1 && qpos > 0) + q.digits[qpos++] = 0; + + CLAMP(&r); + } + else { + mp_word pfx = r.digits[r.used - 1]; + mp_word qdigit; + + if (r.used > 1 && pfx < btop) { + pfx <<= MP_DIGIT_BIT / 2; + pfx <<= MP_DIGIT_BIT / 2; + pfx |= r.digits[r.used - 2]; + } + + qdigit = pfx / btop; + if (qdigit > MP_DIGIT_MAX) { + qdigit = MP_DIGIT_MAX; + } + + s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub); + t.used = ub + 1; CLAMP(&t); + while (s_ucmp(&t, &r) > 0) { + --qdigit; + (void) mp_int_sub(&t, b, &t); /* cannot fail */ + } + + s_usub(r.digits, t.digits, r.digits, r.used, t.used); + CLAMP(&r); + + q.digits[qpos++] = (mp_digit) qdigit; + ZERO(t.digits, t.used); + skip = 0; + } + } + + /* Put quotient digits in the correct order, and discard extra zeroes */ + q.used = qpos; + REV(mp_digit, q.digits, qpos); + CLAMP(&q); + + /* Denormalize the remainder */ + CLAMP(a); + if (k != 0) + s_qdiv(a, k); + + mp_int_copy(a, b); /* ok: 0 <= r < b */ + mp_int_copy(&q, a); /* ok: q <= a */ + + mp_int_clear(&t); + CLEANUP: + mp_int_clear(&q); + return res; +} +#endif + +/* Division of nonnegative integers + + This function implements division algorithm for unsigned multi-precision + integers. The algorithm is based on Algorithm D from Knuth's "The Art of + Computer Programming", 3rd ed. 1998, pg 272-273. + + We diverge from Knuth's algorithm in that we do not perform the subtraction + from the remainder until we have determined that we have the correct + quotient digit. This makes our algorithm less efficient that Knuth because + we might have to perform multiple multiplication and comparison steps before + the subtraction. The advantage is that it is easy to implement and ensure + correctness without worrying about underflow from the subtraction. + + inputs: u a n+m digit integer in base b (b is 2^MP_DIGIT_BIT) + v a n digit integer in base b (b is 2^MP_DIGIT_BIT) + n >= 1 + m >= 0 + outputs: u / v stored in u + u % v stored in v + */ +STATIC mp_result s_udiv_knuth(mp_int u, mp_int v) { + mpz_t q, r, t; + mp_result + res = MP_OK; + int k,j; + mp_size m,n; + + /* Force signs to positive */ + MP_SIGN(u) = MP_ZPOS; + MP_SIGN(v) = MP_ZPOS; + + /* Use simple division algorithm when v is only one digit long */ + if (MP_USED(v) == 1) { + mp_digit d, rem; + d = v->digits[0]; + rem = s_ddiv(u, d); + mp_int_set_value(v, rem); + return MP_OK; + } + + /************************************************************/ + /* Algorithm D */ + /************************************************************/ + /* The n and m variables are defined as used by Knuth. + u is an n digit number with digits u_{n-1}..u_0. + v is an n+m digit number with digits from v_{m+n-1}..v_0. + We require that n > 1 and m >= 0 */ + n = MP_USED(v); + m = MP_USED(u) - n; + assert(n > 1); + assert(m >= 0); + + /************************************************************/ + /* D1: Normalize. + The normalization step provides the necessary condition for Theorem B, + which states that the quotient estimate for q_j, call it qhat + + qhat = u_{j+n}u_{j+n-1} / v_{n-1} + + is bounded by + + qhat - 2 <= q_j <= qhat. + + That is, qhat is always greater than the actual quotient digit q, + and it is never more than two larger than the actual quotient digit. */ + k = s_norm(u, v); + + /* Extend size of u by one if needed. + + The algorithm begins with a value of u that has one more digit of input. + The normalization step sets u_{m+n}..u_0 = 2^k * u_{m+n-1}..u_0. If the + multiplication did not increase the number of digits of u, we need to add + a leading zero here. + */ + if (k == 0 || MP_USED(u) != m + n + 1) { + if (!s_pad(u, m+n+1)) + return MP_MEMORY; + u->digits[m+n] = 0; + u->used = m+n+1; + } + + /* Add a leading 0 to v. + + The multiplication in step D4 multiplies qhat * 0v_{n-1}..v_0. We need to + add the leading zero to v here to ensure that the multiplication will + produce the full n+1 digit result. */ + if (!s_pad(v, n+1)) return MP_MEMORY; v->digits[n] = 0; + + /* Initialize temporary variables q and t. + q allocates space for m+1 digits to store the quotient digits + t allocates space for n+1 digits to hold the result of q_j*v */ + if ((res = mp_int_init_size(&q, m + 1)) != MP_OK) return res; + if ((res = mp_int_init_size(&t, n + 1)) != MP_OK) goto CLEANUP; + + /************************************************************/ + /* D2: Initialize j */ + j = m; + r.digits = MP_DIGITS(u) + j; /* The contents of r are shared with u */ + r.used = n + 1; + r.sign = MP_ZPOS; + r.alloc = MP_ALLOC(u); + ZERO(t.digits, t.alloc); + + /* Calculate the m+1 digits of the quotient result */ + for (; j >= 0; j--) { + /************************************************************/ + /* D3: Calculate q' */ + /* r->digits is aligned to position j of the number u */ + mp_word pfx, qhat; + pfx = r.digits[n]; + pfx <<= MP_DIGIT_BIT / 2; + pfx <<= MP_DIGIT_BIT / 2; + pfx |= r.digits[n-1]; /* pfx = u_{j+n}{j+n-1} */ + + qhat = pfx / v->digits[n-1]; + /* Check to see if qhat > b, and decrease qhat if so. + Theorem B guarantess that qhat is at most 2 larger than the + actual value, so it is possible that qhat is greater than + the maximum value that will fit in a digit */ + if (qhat > MP_DIGIT_MAX) + qhat = MP_DIGIT_MAX; + + /************************************************************/ + /* D4,D5,D6: Multiply qhat * v and test for a correct value of q + + We proceed a bit different than the way described by Knuth. This way is + simpler but less efficent. Instead of doing the multiply and subtract + then checking for underflow, we first do the multiply of qhat * v and + see if it is larger than the current remainder r. If it is larger, we + decrease qhat by one and try again. We may need to decrease qhat one + more time before we get a value that is smaller than r. + + This way is less efficent than Knuth becuase we do more multiplies, but + we do not need to worry about underflow this way. */ + /* t = qhat * v */ + s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1); t.used = n + 1; + CLAMP(&t); + + /* Clamp r for the comparison. Comparisons do not like leading zeros. */ + CLAMP(&r); + if (s_ucmp(&t, &r) > 0) { /* would the remainder be negative? */ + qhat -= 1; /* try a smaller q */ + s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1); + t.used = n + 1; CLAMP(&t); + if (s_ucmp(&t, &r) > 0) { /* would the remainder be negative? */ + assert(qhat > 0); + qhat -= 1; /* try a smaller q */ + s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1); + t.used = n + 1; CLAMP(&t); + } + assert(s_ucmp(&t, &r) <= 0 && "The mathematics failed us."); + } + /* Unclamp r. The D algorithm expects r = u_{j+n}..u_j to always be n+1 + digits long. */ + r.used = n + 1; + + /************************************************************/ + /* D4: Multiply and subtract */ + /* note: The multiply was completed above so we only need to subtract here. + **/ + s_usub(r.digits, t.digits, r.digits, r.used, t.used); + + /************************************************************/ + /* D5: Test remainder */ + /* note: Not needed because we always check that qhat is the correct value + * before performing the subtract. + * Value cast to mp_digit to prevent warning, qhat has been clamped to MP_DIGIT_MAX */ + q.digits[j] = (mp_digit)qhat; + + /************************************************************/ + /* D6: Add back */ + /* note: Not needed because we always check that qhat is the correct value + * before performing the subtract. */ + + /************************************************************/ + /* D7: Loop on j */ + r.digits--; + ZERO(t.digits, t.alloc); + } + + /* Get rid of leading zeros in q */ + q.used = m + 1; + CLAMP(&q); + + /* Denormalize the remainder */ + CLAMP(u); /* use u here because the r.digits pointer is off-by-one */ + if (k != 0) + s_qdiv(u, k); + + mp_int_copy(u, v); /* ok: 0 <= r < v */ + mp_int_copy(&q, u); /* ok: q <= u */ + + mp_int_clear(&t); + CLEANUP: + mp_int_clear(&q); + return res; +} + +STATIC int s_outlen(mp_int z, mp_size r) +{ + mp_result bits; + double raw; + + assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); + + bits = mp_int_count_bits(z); + raw = (double)bits * s_log2[r]; + + return (int)(raw + 0.999999); +} + +STATIC mp_size s_inlen(int len, mp_size r) +{ + double raw = (double)len / s_log2[r]; + mp_size bits = (mp_size)(raw + 0.5); + + return (mp_size)((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT) + 1; +} + +STATIC int s_ch2val(char c, int r) +{ + int out; + + if (isdigit((unsigned char) c)) + out = c - '0'; + else if (r > 10 && isalpha((unsigned char) c)) + out = toupper(c) - 'A' + 10; + else + return -1; + + return (out >= r) ? -1 : out; +} + +STATIC char s_val2ch(int v, int caps) +{ + assert(v >= 0); + + if (v < 10) + return v + '0'; + else { + char out = (v - 10) + 'a'; + + if (caps) + return toupper(out); + else + return out; + } +} + +STATIC void s_2comp(unsigned char *buf, int len) +{ + int i; + unsigned short s = 1; + + for (i = len - 1; i >= 0; --i) { + unsigned char c = ~buf[i]; + + s = c + s; + c = s & UCHAR_MAX; + s >>= CHAR_BIT; + + buf[i] = c; + } + + /* last carry out is ignored */ +} + +STATIC mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) +{ + mp_size uz; + mp_digit *dz; + int pos = 0, limit = *limpos; + + uz = MP_USED(z); dz = MP_DIGITS(z); + while (uz > 0 && pos < limit) { + mp_digit d = *dz++; + int i; + + for (i = sizeof(mp_digit); i > 0 && pos < limit; --i) { + buf[pos++] = (unsigned char)d; + d >>= CHAR_BIT; + + /* Don't write leading zeroes */ + if (d == 0 && uz == 1) + i = 0; /* exit loop without signaling truncation */ + } + + /* Detect truncation (loop exited with pos >= limit) */ + if (i > 0) break; + + --uz; + } + + if (pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) { + if (pos < limit) + buf[pos++] = 0; + else + uz = 1; + } + + /* Digits are in reverse order, fix that */ + REV(unsigned char, buf, pos); + + /* Return the number of bytes actually written */ + *limpos = pos; + + return (uz == 0) ? MP_OK : MP_TRUNC; +} + +#if DEBUG +void s_print(char *tag, mp_int z) +{ + int i; + + fprintf(stderr, "%s: %c ", tag, + (MP_SIGN(z) == MP_NEG) ? '-' : '+'); + + for (i = MP_USED(z) - 1; i >= 0; --i) + fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), z->digits[i]); + + fputc('\n', stderr); + +} + +void s_print_buf(char *tag, mp_digit *buf, mp_size num) +{ + int i; + + fprintf(stderr, "%s: ", tag); + + for (i = num - 1; i >= 0; --i) + fprintf(stderr, "%0*X", (int)(MP_DIGIT_BIT / 4), buf[i]); + + fputc('\n', stderr); +} +#endif + +/* Here there be dragons */ diff -Nru isl-0.12.2/imath/imath.h isl-0.15/imath/imath.h --- isl-0.12.2/imath/imath.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath/imath.h 2014-05-28 13:11:37.000000000 +0000 @@ -0,0 +1,232 @@ +/* + Name: imath.h + Purpose: Arbitrary precision integer arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#ifndef IMATH_H_ +#define IMATH_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char mp_sign; +typedef unsigned int mp_size; +typedef int mp_result; +typedef long mp_small; /* must be a signed type */ +typedef unsigned long mp_usmall; /* must be an unsigned type */ + +/* Force building with uint64_t so that the library builds consistently + * whether we build from the makefile or by embedding imath in another project. + */ +#undef USE_64BIT_WORDS +#define USE_64BIT_WORDS +#ifdef USE_64BIT_WORDS +typedef uint32_t mp_digit; +typedef uint64_t mp_word; +#else +typedef uint16_t mp_digit; +typedef uint32_t mp_word; +#endif + +typedef struct mpz { + mp_digit single; + mp_digit *digits; + mp_size alloc; + mp_size used; + mp_sign sign; +} mpz_t, *mp_int; + +#define MP_DIGITS(Z) ((Z)->digits) +#define MP_ALLOC(Z) ((Z)->alloc) +#define MP_USED(Z) ((Z)->used) +#define MP_SIGN(Z) ((Z)->sign) + +extern const mp_result MP_OK; +extern const mp_result MP_FALSE; +extern const mp_result MP_TRUE; +extern const mp_result MP_MEMORY; +extern const mp_result MP_RANGE; +extern const mp_result MP_UNDEF; +extern const mp_result MP_TRUNC; +extern const mp_result MP_BADARG; +extern const mp_result MP_MINERR; + +#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) +#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) +#define MP_SMALL_MIN LONG_MIN +#define MP_SMALL_MAX LONG_MAX +#define MP_USMALL_MIN ULONG_MIN +#define MP_USMALL_MAX ULONG_MAX + +#ifdef USE_64BIT_WORDS +# define MP_DIGIT_MAX (UINT32_MAX * UINT64_C(1)) +# define MP_WORD_MAX (UINT64_MAX) +#else +# define MP_DIGIT_MAX (UINT16_MAX * 1UL) +# define MP_WORD_MAX (UINT32_MAX * 1UL) +#endif + +#define MP_MIN_RADIX 2 +#define MP_MAX_RADIX 36 + +/* Values with fewer than this many significant digits use the standard + multiplication algorithm; otherwise, a recursive algorithm is used. + Choose a value to suit your platform. + */ +#define MP_MULT_THRESH 22 + +#define MP_DEFAULT_PREC 8 /* default memory allocation, in digits */ + +extern const mp_sign MP_NEG; +extern const mp_sign MP_ZPOS; + +#define mp_int_is_odd(Z) ((Z)->digits[0] & 1) +#define mp_int_is_even(Z) !((Z)->digits[0] & 1) + +mp_result mp_int_init(mp_int z); +mp_int mp_int_alloc(void); +mp_result mp_int_init_size(mp_int z, mp_size prec); +mp_result mp_int_init_copy(mp_int z, mp_int old); +mp_result mp_int_init_value(mp_int z, mp_small value); +mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue); +mp_result mp_int_set_value(mp_int z, mp_small value); +mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue); +void mp_int_clear(mp_int z); +void mp_int_free(mp_int z); + +mp_result mp_int_copy(mp_int a, mp_int c); /* c = a */ +void mp_int_swap(mp_int a, mp_int c); /* swap a, c */ +void mp_int_zero(mp_int z); /* z = 0 */ +mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */ +mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */ +mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */ +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c); +mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */ +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c); +mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */ +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c); +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c); +mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */ +mp_result mp_int_div(mp_int a, mp_int b, /* q = a / b */ + mp_int q, mp_int r); /* r = a % b */ +mp_result mp_int_div_value(mp_int a, mp_small value, /* q = a / value */ + mp_int q, mp_small *r); /* r = a % value */ +mp_result mp_int_div_pow2(mp_int a, mp_small p2, /* q = a / 2^p2 */ + mp_int q, mp_int r); /* r = q % 2^p2 */ +mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */ +#define mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R)) +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c); /* c = a^b */ +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); /* c = a^b */ +mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c); /* c = a^b */ + +int mp_int_compare(mp_int a, mp_int b); /* a <=> b */ +int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */ +int mp_int_compare_zero(mp_int z); /* a <=> 0 */ +int mp_int_compare_value(mp_int z, mp_small v); /* a <=> v */ +int mp_int_compare_uvalue(mp_int z, mp_usmall uv); /* a <=> uv */ + +/* Returns true if v|a, false otherwise (including errors) */ +int mp_int_divisible_value(mp_int a, mp_small v); + +/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */ +int mp_int_is_pow2(mp_int z); + +mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, + mp_int c); /* c = a^b (mod m) */ +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, + mp_int m, mp_int c); /* c = a^v (mod m) */ +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, + mp_int m, mp_int c); /* c = v^b (mod m) */ +mp_result mp_int_exptmod_known(mp_int a, mp_int b, + mp_int m, mp_int mu, + mp_int c); /* c = a^b (mod m) */ +mp_result mp_int_redux_const(mp_int m, mp_int c); + +mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */ + +mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */ + +mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */ + mp_int x, mp_int y); /* c = ax + by */ + +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c); /* c = lcm(a, b) */ + +mp_result mp_int_root(mp_int a, mp_small b, mp_int c); /* c = floor(a^{1/b}) */ +#define mp_int_sqrt(a, c) mp_int_root(a, 2, c) /* c = floor(sqrt(a)) */ + +/* Convert to a small int, if representable; else MP_RANGE */ +mp_result mp_int_to_int(mp_int z, mp_small *out); +mp_result mp_int_to_uint(mp_int z, mp_usmall *out); + +/* Convert to nul-terminated string with the specified radix, writing at + most limit characters including the nul terminator */ +mp_result mp_int_to_string(mp_int z, mp_size radix, + char *str, int limit); + +/* Return the number of characters required to represent + z in the given radix. May over-estimate. */ +mp_result mp_int_string_len(mp_int z, mp_size radix); + +/* Read zero-terminated string into z */ +mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str); +mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, + char **end); + +/* Return the number of significant bits in z */ +mp_result mp_int_count_bits(mp_int z); + +/* Convert z to two's complement binary, writing at most limit bytes */ +mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit); + +/* Read a two's complement binary value into z from the given buffer */ +mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len); + +/* Return the number of bytes required to represent z in binary. */ +mp_result mp_int_binary_len(mp_int z); + +/* Convert z to unsigned binary, writing at most limit bytes */ +mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit); + +/* Read an unsigned binary value into z from the given buffer */ +mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len); + +/* Return the number of bytes required to represent z as unsigned output */ +mp_result mp_int_unsigned_len(mp_int z); + +/* Return a statically allocated string describing error code res */ +const char *mp_error_string(mp_result res); + +#if DEBUG +void s_print(char *tag, mp_int z); +void s_print_buf(char *tag, mp_digit *buf, mp_size num); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* end IMATH_H_ */ diff -Nru isl-0.12.2/imath/imrat.c isl-0.15/imath/imrat.c --- isl-0.12.2/imath/imrat.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath/imrat.c 2015-06-02 09:28:14.000000000 +0000 @@ -0,0 +1,958 @@ +/* + Name: imrat.c + Purpose: Arbitrary precision rational arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#include "imrat.h" +#include +#include +#include +#include + +#define TEMP(K) (temp + (K)) +#define SETUP(E, C) \ +do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0) + +/* Argument checking: + Use CHECK() where a return value is required; NRCHECK() elsewhere */ +#define CHECK(TEST) assert(TEST) +#define NRCHECK(TEST) assert(TEST) + +/* Reduce the given rational, in place, to lowest terms and canonical form. + Zero is represented as 0/1, one as 1/1. Signs are adjusted so that the sign + of the numerator is definitive. */ +static mp_result s_rat_reduce(mp_rat r); + +/* Common code for addition and subtraction operations on rationals. */ +static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c, + mp_result (*comb_f)(mp_int, mp_int, mp_int)); + +mp_result mp_rat_init(mp_rat r) +{ + mp_result res; + + if ((res = mp_int_init(MP_NUMER_P(r))) != MP_OK) + return res; + if ((res = mp_int_init(MP_DENOM_P(r))) != MP_OK) { + mp_int_clear(MP_NUMER_P(r)); + return res; + } + + return mp_int_set_value(MP_DENOM_P(r), 1); +} + +mp_rat mp_rat_alloc(void) +{ + mp_rat out = malloc(sizeof(*out)); + + if (out != NULL) { + if (mp_rat_init(out) != MP_OK) { + free(out); + return NULL; + } + } + + return out; +} + +mp_result mp_rat_reduce(mp_rat r) { + return s_rat_reduce(r); +} + +mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec) +{ + mp_result res; + + if ((res = mp_int_init_size(MP_NUMER_P(r), n_prec)) != MP_OK) + return res; + if ((res = mp_int_init_size(MP_DENOM_P(r), d_prec)) != MP_OK) { + mp_int_clear(MP_NUMER_P(r)); + return res; + } + + return mp_int_set_value(MP_DENOM_P(r), 1); +} + +mp_result mp_rat_init_copy(mp_rat r, mp_rat old) +{ + mp_result res; + + if ((res = mp_int_init_copy(MP_NUMER_P(r), MP_NUMER_P(old))) != MP_OK) + return res; + if ((res = mp_int_init_copy(MP_DENOM_P(r), MP_DENOM_P(old))) != MP_OK) + mp_int_clear(MP_NUMER_P(r)); + + return res; +} + +mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom) +{ + mp_result res; + + if (denom == 0) + return MP_UNDEF; + + if ((res = mp_int_set_value(MP_NUMER_P(r), numer)) != MP_OK) + return res; + if ((res = mp_int_set_value(MP_DENOM_P(r), denom)) != MP_OK) + return res; + + return s_rat_reduce(r); +} + +mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom) +{ + mp_result res; + + if (denom == 0) + return MP_UNDEF; + + if ((res = mp_int_set_uvalue(MP_NUMER_P(r), numer)) != MP_OK) + return res; + if ((res = mp_int_set_uvalue(MP_DENOM_P(r), denom)) != MP_OK) + return res; + + return s_rat_reduce(r); +} + +void mp_rat_clear(mp_rat r) +{ + mp_int_clear(MP_NUMER_P(r)); + mp_int_clear(MP_DENOM_P(r)); + +} + +void mp_rat_free(mp_rat r) +{ + NRCHECK(r != NULL); + + if (r->num.digits != NULL) + mp_rat_clear(r); + + free(r); +} + +mp_result mp_rat_numer(mp_rat r, mp_int z) +{ + return mp_int_copy(MP_NUMER_P(r), z); +} + +mp_int mp_rat_numer_ref(mp_rat r) +{ + return MP_NUMER_P(r); +} + + +mp_result mp_rat_denom(mp_rat r, mp_int z) +{ + return mp_int_copy(MP_DENOM_P(r), z); +} + +mp_int mp_rat_denom_ref(mp_rat r) +{ + return MP_DENOM_P(r); +} + +mp_sign mp_rat_sign(mp_rat r) +{ + return MP_SIGN(MP_NUMER_P(r)); +} + +mp_result mp_rat_copy(mp_rat a, mp_rat c) +{ + mp_result res; + + if ((res = mp_int_copy(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) + return res; + + res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c)); + return res; +} + +void mp_rat_zero(mp_rat r) +{ + mp_int_zero(MP_NUMER_P(r)); + mp_int_set_value(MP_DENOM_P(r), 1); + +} + +mp_result mp_rat_abs(mp_rat a, mp_rat c) +{ + mp_result res; + + if ((res = mp_int_abs(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) + return res; + + res = mp_int_abs(MP_DENOM_P(a), MP_DENOM_P(c)); + return res; +} + +mp_result mp_rat_neg(mp_rat a, mp_rat c) +{ + mp_result res; + + if ((res = mp_int_neg(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK) + return res; + + res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c)); + return res; +} + +mp_result mp_rat_recip(mp_rat a, mp_rat c) +{ + mp_result res; + + if (mp_rat_compare_zero(a) == 0) + return MP_UNDEF; + + if ((res = mp_rat_copy(a, c)) != MP_OK) + return res; + + mp_int_swap(MP_NUMER_P(c), MP_DENOM_P(c)); + + /* Restore the signs of the swapped elements */ + { + mp_sign tmp = MP_SIGN(MP_NUMER_P(c)); + + MP_SIGN(MP_NUMER_P(c)) = MP_SIGN(MP_DENOM_P(c)); + MP_SIGN(MP_DENOM_P(c)) = tmp; + } + + return MP_OK; +} + +mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c) +{ + return s_rat_combine(a, b, c, mp_int_add); + +} + +mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c) +{ + return s_rat_combine(a, b, c, mp_int_sub); + +} + +mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c) +{ + mp_result res; + + if ((res = mp_int_mul(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK) + return res; + + if (mp_int_compare_zero(MP_NUMER_P(c)) != 0) { + if ((res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c))) != MP_OK) + return res; + } + + return s_rat_reduce(c); +} + +mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c) +{ + mp_result res = MP_OK; + + if (mp_rat_compare_zero(b) == 0) + return MP_UNDEF; + + if (c == a || c == b) { + mpz_t tmp; + + if ((res = mp_int_init(&tmp)) != MP_OK) return res; + if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) + goto CLEANUP; + if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != MP_OK) + goto CLEANUP; + res = mp_int_copy(&tmp, MP_NUMER_P(c)); + + CLEANUP: + mp_int_clear(&tmp); + } + else { + if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), MP_NUMER_P(c))) != MP_OK) + return res; + if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != MP_OK) + return res; + } + + if (res != MP_OK) + return res; + else + return s_rat_reduce(c); +} + +mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c) +{ + mpz_t tmp; + mp_result res; + + if ((res = mp_int_init_copy(&tmp, b)) != MP_OK) + return res; + + if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK) + goto CLEANUP; + + if ((res = mp_rat_copy(a, c)) != MP_OK) + goto CLEANUP; + + if ((res = mp_int_add(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) + goto CLEANUP; + + res = s_rat_reduce(c); + + CLEANUP: + mp_int_clear(&tmp); + return res; +} + +mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c) +{ + mpz_t tmp; + mp_result res; + + if ((res = mp_int_init_copy(&tmp, b)) != MP_OK) + return res; + + if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK) + goto CLEANUP; + + if ((res = mp_rat_copy(a, c)) != MP_OK) + goto CLEANUP; + + if ((res = mp_int_sub(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK) + goto CLEANUP; + + res = s_rat_reduce(c); + + CLEANUP: + mp_int_clear(&tmp); + return res; +} + +mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c) +{ + mp_result res; + + if ((res = mp_rat_copy(a, c)) != MP_OK) + return res; + + if ((res = mp_int_mul(MP_NUMER_P(c), b, MP_NUMER_P(c))) != MP_OK) + return res; + + return s_rat_reduce(c); +} + +mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c) +{ + mp_result res; + + if (mp_int_compare_zero(b) == 0) + return MP_UNDEF; + + if ((res = mp_rat_copy(a, c)) != MP_OK) + return res; + + if ((res = mp_int_mul(MP_DENOM_P(c), b, MP_DENOM_P(c))) != MP_OK) + return res; + + return s_rat_reduce(c); +} + +mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c) +{ + mp_result res; + + /* Special cases for easy powers. */ + if (b == 0) + return mp_rat_set_value(c, 1, 1); + else if(b == 1) + return mp_rat_copy(a, c); + + /* Since rationals are always stored in lowest terms, it is not necessary to + reduce again when raising to an integer power. */ + if ((res = mp_int_expt(MP_NUMER_P(a), b, MP_NUMER_P(c))) != MP_OK) + return res; + + return mp_int_expt(MP_DENOM_P(a), b, MP_DENOM_P(c)); +} + +int mp_rat_compare(mp_rat a, mp_rat b) +{ + /* Quick check for opposite signs. Works because the sign of the numerator + is always definitive. */ + if (MP_SIGN(MP_NUMER_P(a)) != MP_SIGN(MP_NUMER_P(b))) { + if (MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS) + return 1; + else + return -1; + } + else { + /* Compare absolute magnitudes; if both are positive, the answer stands, + otherwise it needs to be reflected about zero. */ + int cmp = mp_rat_compare_unsigned(a, b); + + if (MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS) + return cmp; + else + return -cmp; + } +} + +int mp_rat_compare_unsigned(mp_rat a, mp_rat b) +{ + /* If the denominators are equal, we can quickly compare numerators without + multiplying. Otherwise, we actually have to do some work. */ + if (mp_int_compare_unsigned(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) + return mp_int_compare_unsigned(MP_NUMER_P(a), MP_NUMER_P(b)); + + else { + mpz_t temp[2]; + mp_result res; + int cmp = INT_MAX, last = 0; + + /* t0 = num(a) * den(b), t1 = num(b) * den(a) */ + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last); + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last); + + if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK || + (res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) + goto CLEANUP; + + cmp = mp_int_compare_unsigned(TEMP(0), TEMP(1)); + + CLEANUP: + while (--last >= 0) + mp_int_clear(TEMP(last)); + + return cmp; + } +} + +int mp_rat_compare_zero(mp_rat r) +{ + return mp_int_compare_zero(MP_NUMER_P(r)); +} + +int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d) +{ + mpq_t tmp; + mp_result res; + int out = INT_MAX; + + if ((res = mp_rat_init(&tmp)) != MP_OK) + return out; + if ((res = mp_rat_set_value(&tmp, n, d)) != MP_OK) + goto CLEANUP; + + out = mp_rat_compare(r, &tmp); + + CLEANUP: + mp_rat_clear(&tmp); + return out; +} + +int mp_rat_is_integer(mp_rat r) +{ + return (mp_int_compare_value(MP_DENOM_P(r), 1) == 0); +} + +mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den) +{ + mp_result res; + + if ((res = mp_int_to_int(MP_NUMER_P(r), num)) != MP_OK) + return res; + + res = mp_int_to_int(MP_DENOM_P(r), den); + return res; +} + +mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit) +{ + char *start; + int len; + mp_result res; + + /* Write the numerator. The sign of the rational number is written by the + underlying integer implementation. */ + if ((res = mp_int_to_string(MP_NUMER_P(r), radix, str, limit)) != MP_OK) + return res; + + /* If the value is zero, don't bother writing any denominator */ + if (mp_int_compare_zero(MP_NUMER_P(r)) == 0) + return MP_OK; + + /* Locate the end of the numerator, and make sure we are not going to exceed + the limit by writing a slash. */ + len = strlen(str); + start = str + len; + limit -= len; + if(limit == 0) + return MP_TRUNC; + + *start++ = '/'; + limit -= 1; + + res = mp_int_to_string(MP_DENOM_P(r), radix, start, limit); + return res; +} + +mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec, + mp_round_mode round, char *str, int limit) +{ + mpz_t temp[3]; + mp_result res; + char *start = str; + int len, lead_0, left = limit, last = 0; + + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(r)), last); + SETUP(mp_int_init(TEMP(last)), last); + SETUP(mp_int_init(TEMP(last)), last); + + /* Get the unsigned integer part by dividing denominator into the absolute + value of the numerator. */ + mp_int_abs(TEMP(0), TEMP(0)); + if ((res = mp_int_div(TEMP(0), MP_DENOM_P(r), TEMP(0), TEMP(1))) != MP_OK) + goto CLEANUP; + + /* Now: T0 = integer portion, unsigned; + T1 = remainder, from which fractional part is computed. */ + + /* Count up leading zeroes after the radix point. */ + for (lead_0 = 0; lead_0 < prec && mp_int_compare(TEMP(1), MP_DENOM_P(r)) < 0; + ++lead_0) { + if ((res = mp_int_mul_value(TEMP(1), radix, TEMP(1))) != MP_OK) + goto CLEANUP; + } + + /* Multiply remainder by a power of the radix sufficient to get the right + number of significant figures. */ + if (prec > lead_0) { + if ((res = mp_int_expt_value(radix, prec - lead_0, TEMP(2))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_mul(TEMP(1), TEMP(2), TEMP(1))) != MP_OK) + goto CLEANUP; + } + if ((res = mp_int_div(TEMP(1), MP_DENOM_P(r), TEMP(1), TEMP(2))) != MP_OK) + goto CLEANUP; + + /* Now: T1 = significant digits of fractional part; + T2 = leftovers, to use for rounding. + + At this point, what we do depends on the rounding mode. The default is + MP_ROUND_DOWN, for which everything is as it should be already. + */ + switch (round) { + int cmp; + + case MP_ROUND_UP: + if (mp_int_compare_zero(TEMP(2)) != 0) { + if (prec == 0) + res = mp_int_add_value(TEMP(0), 1, TEMP(0)); + else + res = mp_int_add_value(TEMP(1), 1, TEMP(1)); + } + break; + + case MP_ROUND_HALF_UP: + case MP_ROUND_HALF_DOWN: + if ((res = mp_int_mul_pow2(TEMP(2), 1, TEMP(2))) != MP_OK) + goto CLEANUP; + + cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r)); + + if (round == MP_ROUND_HALF_UP) + cmp += 1; + + if (cmp > 0) { + if (prec == 0) + res = mp_int_add_value(TEMP(0), 1, TEMP(0)); + else + res = mp_int_add_value(TEMP(1), 1, TEMP(1)); + } + break; + + case MP_ROUND_DOWN: + break; /* No action required */ + + default: + return MP_BADARG; /* Invalid rounding specifier */ + } + + /* The sign of the output should be the sign of the numerator, but if all the + displayed digits will be zero due to the precision, a negative shouldn't + be shown. */ + if (MP_SIGN(MP_NUMER_P(r)) == MP_NEG && + (mp_int_compare_zero(TEMP(0)) != 0 || + mp_int_compare_zero(TEMP(1)) != 0)) { + *start++ = '-'; + left -= 1; + } + + if ((res = mp_int_to_string(TEMP(0), radix, start, left)) != MP_OK) + goto CLEANUP; + + len = strlen(start); + start += len; + left -= len; + + if (prec == 0) + goto CLEANUP; + + *start++ = '.'; + left -= 1; + + if (left < prec + 1) { + res = MP_TRUNC; + goto CLEANUP; + } + + memset(start, '0', lead_0 - 1); + left -= lead_0; + start += lead_0 - 1; + + res = mp_int_to_string(TEMP(1), radix, start, left); + + CLEANUP: + while (--last >= 0) + mp_int_clear(TEMP(last)); + + return res; +} + +mp_result mp_rat_string_len(mp_rat r, mp_size radix) +{ + mp_result n_len, d_len = 0; + + n_len = mp_int_string_len(MP_NUMER_P(r), radix); + + if (mp_int_compare_zero(MP_NUMER_P(r)) != 0) + d_len = mp_int_string_len(MP_DENOM_P(r), radix); + + /* Though simplistic, this formula is correct. Space for the sign flag is + included in n_len, and the space for the NUL that is counted in n_len + counts for the separator here. The space for the NUL counted in d_len + counts for the final terminator here. */ + + return n_len + d_len; + +} + +mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec) +{ + int z_len, f_len; + + z_len = mp_int_string_len(MP_NUMER_P(r), radix); + + if (prec == 0) + f_len = 1; /* terminator only */ + else + f_len = 1 + prec + 1; /* decimal point, digits, terminator */ + + return z_len + f_len; +} + +mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str) +{ + return mp_rat_read_cstring(r, radix, str, NULL); +} + +mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str, + char **end) +{ + mp_result res; + char *endp; + + if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK && + (res != MP_TRUNC)) + return res; + + /* Skip whitespace between numerator and (possible) separator */ + while (isspace((unsigned char) *endp)) + ++endp; + + /* If there is no separator, we will stop reading at this point. */ + if (*endp != '/') { + mp_int_set_value(MP_DENOM_P(r), 1); + if (end != NULL) + *end = endp; + return res; + } + + ++endp; /* skip separator */ + if ((res = mp_int_read_cstring(MP_DENOM_P(r), radix, endp, end)) != MP_OK) + return res; + + /* Make sure the value is well-defined */ + if (mp_int_compare_zero(MP_DENOM_P(r)) == 0) + return MP_UNDEF; + + /* Reduce to lowest terms */ + return s_rat_reduce(r); +} + +/* Read a string and figure out what format it's in. The radix may be supplied + as zero to use "default" behaviour. + + This function will accept either a/b notation or decimal notation. + */ +mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str, + char **end) +{ + char *endp; + mp_result res; + + if (radix == 0) + radix = 10; /* default to decimal input */ + + if ((res = mp_rat_read_cstring(r, radix, str, &endp)) != MP_OK) { + if (res == MP_TRUNC) { + if (*endp == '.') + res = mp_rat_read_cdecimal(r, radix, str, &endp); + } + else + return res; + } + + if (end != NULL) + *end = endp; + + return res; +} + +mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str) +{ + return mp_rat_read_cdecimal(r, radix, str, NULL); +} + +mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str, + char **end) +{ + mp_result res; + mp_sign osign; + char *endp; + + while (isspace((unsigned char) *str)) + ++str; + + switch (*str) { + case '-': + osign = MP_NEG; + break; + default: + osign = MP_ZPOS; + } + + if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK && + (res != MP_TRUNC)) + return res; + + /* This needs to be here. */ + (void) mp_int_set_value(MP_DENOM_P(r), 1); + + if (*endp != '.') { + if (end != NULL) + *end = endp; + return res; + } + + /* If the character following the decimal point is whitespace or a sign flag, + we will consider this a truncated value. This special case is because + mp_int_read_string() will consider whitespace or sign flags to be valid + starting characters for a value, and we do not want them following the + decimal point. + + Once we have done this check, it is safe to read in the value of the + fractional piece as a regular old integer. + */ + ++endp; + if (*endp == '\0') { + if (end != NULL) + *end = endp; + return MP_OK; + } + else if(isspace((unsigned char) *endp) || *endp == '-' || *endp == '+') { + return MP_TRUNC; + } + else { + mpz_t frac; + mp_result save_res; + char *save = endp; + int num_lz = 0; + + /* Make a temporary to hold the part after the decimal point. */ + if ((res = mp_int_init(&frac)) != MP_OK) + return res; + + if ((res = mp_int_read_cstring(&frac, radix, endp, &endp)) != MP_OK && + (res != MP_TRUNC)) + goto CLEANUP; + + /* Save this response for later. */ + save_res = res; + + if (mp_int_compare_zero(&frac) == 0) + goto FINISHED; + + /* Discard trailing zeroes (somewhat inefficiently) */ + while (mp_int_divisible_value(&frac, radix)) + if ((res = mp_int_div_value(&frac, radix, &frac, NULL)) != MP_OK) + goto CLEANUP; + + /* Count leading zeros after the decimal point */ + while (save[num_lz] == '0') + ++num_lz; + + /* Find the least power of the radix that is at least as large as the + significant value of the fractional part, ignoring leading zeroes. */ + (void) mp_int_set_value(MP_DENOM_P(r), radix); + + while (mp_int_compare(MP_DENOM_P(r), &frac) < 0) { + if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != MP_OK) + goto CLEANUP; + } + + /* Also shift by enough to account for leading zeroes */ + while (num_lz > 0) { + if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != MP_OK) + goto CLEANUP; + + --num_lz; + } + + /* Having found this power, shift the numerator leftward that many, digits, + and add the nonzero significant digits of the fractional part to get the + result. */ + if ((res = mp_int_mul(MP_NUMER_P(r), MP_DENOM_P(r), MP_NUMER_P(r))) != MP_OK) + goto CLEANUP; + + { /* This addition needs to be unsigned. */ + MP_SIGN(MP_NUMER_P(r)) = MP_ZPOS; + if ((res = mp_int_add(MP_NUMER_P(r), &frac, MP_NUMER_P(r))) != MP_OK) + goto CLEANUP; + + MP_SIGN(MP_NUMER_P(r)) = osign; + } + if ((res = s_rat_reduce(r)) != MP_OK) + goto CLEANUP; + + /* At this point, what we return depends on whether reading the fractional + part was truncated or not. That information is saved from when we + called mp_int_read_string() above. */ + FINISHED: + res = save_res; + if (end != NULL) + *end = endp; + + CLEANUP: + mp_int_clear(&frac); + + return res; + } +} + +/* Private functions for internal use. Make unchecked assumptions about format + and validity of inputs. */ + +static mp_result s_rat_reduce(mp_rat r) +{ + mpz_t gcd; + mp_result res = MP_OK; + + if (mp_int_compare_zero(MP_NUMER_P(r)) == 0) { + mp_int_set_value(MP_DENOM_P(r), 1); + return MP_OK; + } + + /* If the greatest common divisor of the numerator and denominator is greater + than 1, divide it out. */ + if ((res = mp_int_init(&gcd)) != MP_OK) + return res; + + if ((res = mp_int_gcd(MP_NUMER_P(r), MP_DENOM_P(r), &gcd)) != MP_OK) + goto CLEANUP; + + if (mp_int_compare_value(&gcd, 1) != 0) { + if ((res = mp_int_div(MP_NUMER_P(r), &gcd, MP_NUMER_P(r), NULL)) != MP_OK) + goto CLEANUP; + if ((res = mp_int_div(MP_DENOM_P(r), &gcd, MP_DENOM_P(r), NULL)) != MP_OK) + goto CLEANUP; + } + + /* Fix up the signs of numerator and denominator */ + if (MP_SIGN(MP_NUMER_P(r)) == MP_SIGN(MP_DENOM_P(r))) + MP_SIGN(MP_NUMER_P(r)) = MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS; + else { + MP_SIGN(MP_NUMER_P(r)) = MP_NEG; + MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS; + } + + CLEANUP: + mp_int_clear(&gcd); + + return res; +} + +static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c, + mp_result (*comb_f)(mp_int, mp_int, mp_int)) +{ + mp_result res; + + /* Shortcut when denominators are already common */ + if (mp_int_compare(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) { + if ((res = (comb_f)(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK) + return res; + if ((res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK) + return res; + + return s_rat_reduce(c); + } + else { + mpz_t temp[2]; + int last = 0; + + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last); + SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last); + + if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK) + goto CLEANUP; + if ((res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK) + goto CLEANUP; + if ((res = (comb_f)(TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK) + goto CLEANUP; + + res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c)); + + CLEANUP: + while (--last >= 0) + mp_int_clear(TEMP(last)); + + if (res == MP_OK) + return s_rat_reduce(c); + else + return res; + } +} + +/* Here there be dragons */ diff -Nru isl-0.12.2/imath/imrat.h isl-0.15/imath/imrat.h --- isl-0.12.2/imath/imrat.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath/imrat.h 2014-05-28 13:11:37.000000000 +0000 @@ -0,0 +1,124 @@ +/* + Name: imrat.h + Purpose: Arbitrary precision rational arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +#ifndef IMRAT_H_ +#define IMRAT_H_ + +#include "imath.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct mpq { + mpz_t num; /* Numerator */ + mpz_t den; /* Denominator, <> 0 */ +} mpq_t, *mp_rat; + +#define MP_NUMER_P(Q) (&((Q)->num)) /* Pointer to numerator */ +#define MP_DENOM_P(Q) (&((Q)->den)) /* Pointer to denominator */ + +/* Rounding constants */ +typedef enum { + MP_ROUND_DOWN, + MP_ROUND_HALF_UP, + MP_ROUND_UP, + MP_ROUND_HALF_DOWN +} mp_round_mode; + +mp_result mp_rat_init(mp_rat r); +mp_rat mp_rat_alloc(void); +mp_result mp_rat_reduce(mp_rat r); +mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec); +mp_result mp_rat_init_copy(mp_rat r, mp_rat old); +mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom); +mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom); +void mp_rat_clear(mp_rat r); +void mp_rat_free(mp_rat r); +mp_result mp_rat_numer(mp_rat r, mp_int z); /* z = num(r) */ +mp_int mp_rat_numer_ref(mp_rat r); /* &num(r) */ +mp_result mp_rat_denom(mp_rat r, mp_int z); /* z = den(r) */ +mp_int mp_rat_denom_ref(mp_rat r); /* &den(r) */ +mp_sign mp_rat_sign(mp_rat r); + +mp_result mp_rat_copy(mp_rat a, mp_rat c); /* c = a */ +void mp_rat_zero(mp_rat r); /* r = 0 */ +mp_result mp_rat_abs(mp_rat a, mp_rat c); /* c = |a| */ +mp_result mp_rat_neg(mp_rat a, mp_rat c); /* c = -a */ +mp_result mp_rat_recip(mp_rat a, mp_rat c); /* c = 1 / a */ +mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c); /* c = a + b */ +mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c); /* c = a - b */ +mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c); /* c = a * b */ +mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c); /* c = a / b */ + +mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c); /* c = a + b */ +mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c); /* c = a - b */ +mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c); /* c = a * b */ +mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c); /* c = a / b */ +mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c); /* c = a ^ b */ + +int mp_rat_compare(mp_rat a, mp_rat b); /* a <=> b */ +int mp_rat_compare_unsigned(mp_rat a, mp_rat b); /* |a| <=> |b| */ +int mp_rat_compare_zero(mp_rat r); /* r <=> 0 */ +int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d); /* r <=> n/d */ +int mp_rat_is_integer(mp_rat r); + +/* Convert to integers, if representable (returns MP_RANGE if not). */ +mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den); + +/* Convert to nul-terminated string with the specified radix, writing + at most limit characters including the nul terminator. */ +mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit); + +/* Convert to decimal format in the specified radix and precision, + writing at most limit characters including a nul terminator. */ +mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec, + mp_round_mode round, char *str, int limit); + +/* Return the number of characters required to represent r in the given + radix. May over-estimate. */ +mp_result mp_rat_string_len(mp_rat r, mp_size radix); + +/* Return the number of characters required to represent r in decimal + format with the given radix and precision. May over-estimate. */ +mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec); + +/* Read zero-terminated string into r */ +mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str); +mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str, + char **end); +mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str, + char **end); + +/* Read zero-terminated string in decimal format into r */ +mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str); +mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str, + char **end); + +#ifdef __cplusplus +} +#endif +#endif /* IMRAT_H_ */ diff -Nru isl-0.12.2/imath_wrap/gmp_compat.c isl-0.15/imath_wrap/gmp_compat.c --- isl-0.12.2/imath_wrap/gmp_compat.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/gmp_compat.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/gmp_compat.c" diff -Nru isl-0.12.2/imath_wrap/gmp_compat.h isl-0.15/imath_wrap/gmp_compat.h --- isl-0.12.2/imath_wrap/gmp_compat.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/gmp_compat.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/gmp_compat.h" diff -Nru isl-0.12.2/imath_wrap/imath.c isl-0.15/imath_wrap/imath.c --- isl-0.12.2/imath_wrap/imath.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/imath.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imath.c" diff -Nru isl-0.12.2/imath_wrap/imath.h isl-0.15/imath_wrap/imath.h --- isl-0.12.2/imath_wrap/imath.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/imath.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imath.h" diff -Nru isl-0.12.2/imath_wrap/imrat.c isl-0.15/imath_wrap/imrat.c --- isl-0.12.2/imath_wrap/imrat.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/imrat.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imrat.c" diff -Nru isl-0.12.2/imath_wrap/imrat.h isl-0.15/imath_wrap/imrat.h --- isl-0.12.2/imath_wrap/imrat.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/imrat.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,2 @@ +#include "wrap.h" +#include "../imath/imrat.h" diff -Nru isl-0.12.2/imath_wrap/wrap.h isl-0.15/imath_wrap/wrap.h --- isl-0.12.2/imath_wrap/wrap.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/imath_wrap/wrap.h 2015-04-19 12:02:52.000000000 +0000 @@ -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 -Nru isl-0.12.2/include/isl/aff.h isl-0.15/include/isl/aff.h --- isl-0.12.2/include/isl/aff.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/aff.h 2015-06-02 09:28:08.000000000 +0000 @@ -15,16 +15,19 @@ #endif __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls); +__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls, + __isl_take isl_val *val); __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos); +__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls); __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff); -void *isl_aff_free(__isl_take isl_aff *aff); +__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff); isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff); int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type); -int isl_aff_involves_dims(__isl_keep isl_aff *aff, +isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff); @@ -35,55 +38,50 @@ const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, enum isl_dim_type type, unsigned pos); -int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v); __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff); -int isl_aff_get_coefficient(__isl_keep isl_aff *aff, - enum isl_dim_type type, int pos, isl_int *v); __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff, enum isl_dim_type type, int pos); -int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v); +int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos); __isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff); -__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v); __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v); __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v); -__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff, - enum isl_dim_type type, int pos, isl_int v); __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, int v); __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, __isl_take isl_val *v); -__isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v); -__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v); __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v); __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v); -__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, - isl_int v); __isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v); -__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff, - enum isl_dim_type type, int pos, isl_int v); __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, int v); __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, __isl_take isl_val *v); -int isl_aff_is_cst(__isl_keep isl_aff *aff); +isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff); +__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff, + enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff, enum isl_dim_type type, unsigned pos, const char *s); __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2); -int isl_aff_plain_is_zero(__isl_keep isl_aff *aff); +int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type, + const char *name); + +isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, + __isl_keep isl_aff *aff2); +isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff); +isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff); __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos); __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff); __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff); __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff); -__isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int mod); __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, __isl_take isl_val *mod); @@ -96,10 +94,8 @@ __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2); -__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f); __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, __isl_take isl_val *v); -__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f); __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f); __isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff, __isl_take isl_val *v); @@ -108,6 +104,9 @@ enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff, enum isl_dim_type type, unsigned n); +__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff); @@ -120,6 +119,8 @@ __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff, __isl_take isl_set *context); +__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff, __isl_take isl_multi_aff *ma); @@ -148,21 +149,31 @@ __isl_take isl_local_space *ls); __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos); +__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls); +__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain, + __isl_take isl_val *v); __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set); const char *isl_pw_aff_get_dim_name(__isl_keep isl_pw_aff *pa, enum isl_dim_type type, unsigned pos); -int isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, +isl_bool isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_pw_aff_get_dim_id(__isl_keep isl_pw_aff *pa, enum isl_dim_type type, unsigned pos); __isl_give isl_pw_aff *isl_pw_aff_set_dim_id(__isl_take isl_pw_aff *pma, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); -int isl_pw_aff_plain_is_equal(__isl_keep isl_pw_aff *pwaff1, +int isl_pw_aff_find_dim_by_name(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type, const char *name); + +isl_bool isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); +isl_bool isl_pw_aff_involves_nan(__isl_keep isl_pw_aff *pa); +int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2); +isl_bool isl_pw_aff_plain_is_equal(__isl_keep isl_pw_aff *pwaff1, __isl_keep isl_pw_aff *pwaff2); +int isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, __isl_keep isl_pw_aff *pa2); __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2); @@ -172,23 +183,30 @@ __isl_take isl_pw_aff *pwaff2); __isl_give isl_pw_aff *isl_pw_aff_copy(__isl_keep isl_pw_aff *pwaff); -void *isl_pw_aff_free(__isl_take isl_pw_aff *pwaff); +__isl_null isl_pw_aff *isl_pw_aff_free(__isl_take isl_pw_aff *pwaff); unsigned isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff, enum isl_dim_type type); -int isl_pw_aff_involves_dims(__isl_keep isl_pw_aff *pwaff, +isl_bool isl_pw_aff_involves_dims(__isl_keep isl_pw_aff *pwaff, enum isl_dim_type type, unsigned first, unsigned n); -int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); +isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); __isl_give isl_pw_aff *isl_pw_aff_align_params(__isl_take isl_pw_aff *pwaff, __isl_take isl_space *model); +isl_bool isl_pw_aff_has_tuple_id(__isl_keep isl_pw_aff *pa, + enum isl_dim_type type); __isl_give isl_id *isl_pw_aff_get_tuple_id(__isl_keep isl_pw_aff *pa, enum isl_dim_type type); __isl_give isl_pw_aff *isl_pw_aff_set_tuple_id(__isl_take isl_pw_aff *pwaff, enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_pw_aff *isl_pw_aff_reset_tuple_id(__isl_take isl_pw_aff *pa, + enum isl_dim_type type); +__isl_give isl_pw_aff *isl_pw_aff_reset_user(__isl_take isl_pw_aff *pa); +__isl_give isl_set *isl_pw_aff_params(__isl_take isl_pw_aff *pwa); __isl_give isl_set *isl_pw_aff_domain(__isl_take isl_pw_aff *pwaff); +__isl_give isl_pw_aff *isl_pw_aff_from_range(__isl_take isl_pw_aff *pwa); __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2); @@ -205,8 +223,6 @@ __isl_give isl_pw_aff *isl_pw_aff_neg(__isl_take isl_pw_aff *pwaff); __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff); __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff); -__isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, - isl_int mod); __isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa, __isl_take isl_val *mod); __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1, @@ -218,16 +234,14 @@ __isl_take isl_set *set); __isl_give isl_pw_aff *isl_pw_aff_intersect_domain(__isl_take isl_pw_aff *pa, __isl_take isl_set *set); +__isl_give isl_pw_aff *isl_pw_aff_subtract_domain(__isl_take isl_pw_aff *pa, + __isl_take isl_set *set); __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond, __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false); -__isl_give isl_pw_aff *isl_pw_aff_scale(__isl_take isl_pw_aff *pwaff, - isl_int f); __isl_give isl_pw_aff *isl_pw_aff_scale_val(__isl_take isl_pw_aff *pa, __isl_take isl_val *v); -__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff, - isl_int f); __isl_give isl_pw_aff *isl_pw_aff_scale_down_val(__isl_take isl_pw_aff *pa, __isl_take isl_val *f); @@ -235,6 +249,9 @@ enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff, enum isl_dim_type type, unsigned n); +__isl_give isl_pw_aff *isl_pw_aff_move_dims(__isl_take isl_pw_aff *pa, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); __isl_give isl_pw_aff *isl_pw_aff_drop_dims(__isl_take isl_pw_aff *pwaff, enum isl_dim_type type, unsigned first, unsigned n); @@ -248,15 +265,18 @@ __isl_take isl_pw_aff *pa, __isl_take isl_multi_aff *ma); __isl_give isl_pw_aff *isl_pw_aff_pullback_pw_multi_aff( __isl_take isl_pw_aff *pa, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa); int isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); -int isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff, - int (*fn)(__isl_take isl_set *set, __isl_take isl_aff *aff, +isl_stat isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user), void *user); __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff); __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff); +__isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa); __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff); __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff); __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff); @@ -274,6 +294,13 @@ __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2); +__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); +__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2); + __isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str); __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p, __isl_keep isl_pw_aff *pwaff); @@ -296,20 +323,25 @@ __isl_take isl_pw_aff_list *list2); ISL_DECLARE_MULTI(aff) +ISL_DECLARE_MULTI_NEG(aff) +ISL_DECLARE_MULTI_DIMS(aff) +ISL_DECLARE_MULTI_WITH_DOMAIN(aff) __isl_give isl_multi_aff *isl_multi_aff_from_aff(__isl_take isl_aff *aff); __isl_give isl_multi_aff *isl_multi_aff_identity(__isl_take isl_space *space); +__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space); +__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space); +__isl_give isl_multi_aff *isl_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n); -int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1, - __isl_keep isl_multi_aff *maff2); +__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space( + __isl_take isl_space *space, __isl_take isl_multi_val *mv); + +__isl_give isl_multi_aff *isl_multi_aff_floor(__isl_take isl_multi_aff *ma); __isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2); -__isl_give isl_multi_aff *isl_multi_aff_sub(__isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2); - -__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff, - isl_int f); __isl_give isl_multi_aff *isl_multi_aff_product( __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); @@ -325,11 +357,16 @@ __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); +__isl_give isl_multi_aff *isl_multi_aff_move_dims(__isl_take isl_multi_aff *ma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + __isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); __isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); +__isl_give char *isl_multi_aff_to_str(__isl_keep isl_multi_aff *aff); __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p, __isl_keep isl_multi_aff *maff); @@ -338,16 +375,28 @@ void isl_multi_aff_dump(__isl_keep isl_multi_aff *maff); ISL_DECLARE_MULTI(pw_aff) +ISL_DECLARE_MULTI_NEG(pw_aff) +ISL_DECLARE_MULTI_DIMS(pw_aff) +ISL_DECLARE_MULTI_WITH_DOMAIN(pw_aff) +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( + __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff( __isl_take isl_multi_aff *ma); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc(__isl_take isl_set *set, __isl_take isl_multi_aff *maff); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( __isl_keep isl_pw_multi_aff *pma); -void *isl_pw_multi_aff_free(__isl_take isl_pw_multi_aff *pma); +__isl_null isl_pw_multi_aff *isl_pw_multi_aff_free( + __isl_take isl_pw_multi_aff *pma); unsigned isl_pw_multi_aff_dim(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); @@ -362,17 +411,24 @@ __isl_keep isl_pw_multi_aff *pma); __isl_give isl_space *isl_pw_multi_aff_get_space( __isl_keep isl_pw_multi_aff *pma); -int isl_pw_multi_aff_has_tuple_name(__isl_keep isl_pw_multi_aff *pma, +isl_bool isl_pw_multi_aff_has_tuple_name(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); const char *isl_pw_multi_aff_get_tuple_name(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( __isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); -int isl_pw_multi_aff_has_tuple_id(__isl_keep isl_pw_multi_aff *pma, +isl_bool isl_pw_multi_aff_has_tuple_id(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, __isl_take isl_id *id); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_tuple_id( + __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user( + __isl_take isl_pw_multi_aff *pma); + +int isl_pw_multi_aff_find_dim_by_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, const char *name); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_dims( __isl_take isl_pw_multi_aff *pma, @@ -384,6 +440,9 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( __isl_take isl_set *set); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain( + __isl_take isl_set *domain, __isl_take isl_multi_val *mv); + const char *isl_pw_multi_aff_get_dim_name(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_pw_multi_aff_get_dim_id( @@ -393,12 +452,19 @@ __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_pw_multi_aff_plain_is_equal(__isl_keep isl_pw_multi_aff *pma1, +isl_bool isl_pw_multi_aff_plain_is_equal(__isl_keep isl_pw_multi_aff *pma1, __isl_keep isl_pw_multi_aff *pma2); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_fix_si( + __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, + unsigned pos, int value); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_neg( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( @@ -406,6 +472,8 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_val( __isl_take isl_pw_multi_aff *pma, __isl_take isl_val *v); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_val( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_val *v); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val( __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv); @@ -416,6 +484,9 @@ __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); +__isl_give isl_multi_aff *isl_multi_aff_flatten_domain( + __isl_take isl_multi_aff *ma); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product( __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product( @@ -427,6 +498,8 @@ __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain( __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_subtract_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_domain_on_params( __isl_take isl_pw_multi_aff *pma); @@ -446,8 +519,8 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_pullback_pw_multi_aff( __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); -int isl_pw_multi_aff_foreach_piece(__isl_keep isl_pw_multi_aff *pma, - int (*fn)(__isl_take isl_set *set, __isl_take isl_multi_aff *maff, +isl_stat isl_pw_multi_aff_foreach_piece(__isl_keep isl_pw_multi_aff *pma, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_multi_aff *maff, void *user), void *user); __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); @@ -466,11 +539,24 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_empty( __isl_take isl_space *space); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff( + __isl_take isl_aff *aff); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain( __isl_take isl_union_set *uset); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_copy( __isl_keep isl_union_pw_multi_aff *upma); -void *isl_union_pw_multi_aff_free(__isl_take isl_union_pw_multi_aff *upma); +__isl_null isl_union_pw_multi_aff *isl_union_pw_multi_aff_free( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff *isl_union_set_identity_union_pw_multi_aff( + __isl_take isl_union_set *uset); + +__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff( + __isl_keep isl_union_pw_multi_aff *upma, int pos); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add_pw_multi_aff( __isl_take isl_union_pw_multi_aff *upma, @@ -481,20 +567,72 @@ __isl_give isl_space *isl_union_pw_multi_aff_get_space( __isl_keep isl_union_pw_multi_aff *upma); -int isl_union_pw_multi_aff_foreach_pw_multi_aff( +unsigned isl_union_pw_multi_aff_dim(__isl_keep isl_union_pw_multi_aff *upma, + enum isl_dim_type type); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_set_dim_name( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_union_pw_multi_aff_find_dim_by_name( + __isl_keep isl_union_pw_multi_aff *upma, enum isl_dim_type type, + const char *name); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_drop_dims( + __isl_take isl_union_pw_multi_aff *upma, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_reset_user( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_coalesce( + __isl_take isl_union_pw_multi_aff *upma); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_gist_params( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_set *context); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_gist( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *context); + +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_align_params( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *model); + +int isl_union_pw_multi_aff_n_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma); + +isl_stat isl_union_pw_multi_aff_foreach_pw_multi_aff( __isl_keep isl_union_pw_multi_aff *upma, - int (*fn)(__isl_take isl_pw_multi_aff *pma, void *user), void *user); + isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user), + void *user); +__isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_extract_pw_multi_aff( + __isl_keep isl_union_pw_multi_aff *upma, __isl_take isl_space *space); + +isl_bool isl_union_pw_multi_aff_plain_is_equal( + __isl_keep isl_union_pw_multi_aff *upma1, + __isl_keep isl_union_pw_multi_aff *upma2); __isl_give isl_union_set *isl_union_pw_multi_aff_domain( __isl_take isl_union_pw_multi_aff *upma); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_neg( + __isl_take isl_union_pw_multi_aff *upma); + __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add( __isl_take isl_union_pw_multi_aff *upma1, __isl_take isl_union_pw_multi_aff *upma2); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_union_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_sub( __isl_take isl_union_pw_multi_aff *upma1, __isl_take isl_union_pw_multi_aff *upma2); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_val( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_val *val); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_down_val( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_val *val); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val( __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv); @@ -502,9 +640,14 @@ __isl_take isl_union_pw_multi_aff *upma1, __isl_take isl_union_pw_multi_aff *upma2); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_intersect_params( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_set *set); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_intersect_domain( __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_union_set *uset); +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_subtract_domain( + __isl_take isl_union_pw_multi_aff *upma, + __isl_take isl_union_set *uset); __isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff( __isl_take isl_union_pw_multi_aff *upma); @@ -525,17 +668,249 @@ __isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity( __isl_take isl_space *space); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff( __isl_take isl_pw_aff *pa); +__isl_give isl_set *isl_multi_pw_aff_domain(__isl_take isl_multi_pw_aff *mpa); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_intersect_params( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_intersect_domain( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *domain); + +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce( + __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist_params( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); + +isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2); + +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); + +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_dims( + __isl_take isl_multi_pw_aff *pma, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +__isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa); +__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + +__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_map *isl_multi_pw_aff_lex_lt_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_map *isl_multi_pw_aff_lex_gt_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2); +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str(isl_ctx *ctx, + const char *str); __isl_give isl_printer *isl_printer_print_multi_pw_aff( __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa); void isl_multi_pw_aff_dump(__isl_keep isl_multi_pw_aff *mpa); +__isl_give isl_union_pw_aff *isl_union_pw_aff_copy( + __isl_keep isl_union_pw_aff *upa); +__isl_null isl_union_pw_aff *isl_union_pw_aff_free( + __isl_take isl_union_pw_aff *upa); + +isl_ctx *isl_union_pw_aff_get_ctx(__isl_keep isl_union_pw_aff *upa); +__isl_give isl_space *isl_union_pw_aff_get_space( + __isl_keep isl_union_pw_aff *upa); + +unsigned isl_union_pw_aff_dim(__isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type); +__isl_give isl_union_pw_aff *isl_union_pw_aff_set_dim_name( + __isl_take isl_union_pw_aff *upa, enum isl_dim_type type, + unsigned pos, const char *s); + +int isl_union_pw_aff_find_dim_by_name(__isl_keep isl_union_pw_aff *upa, + enum isl_dim_type type, const char *name); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_drop_dims( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_empty( + __isl_take isl_space *space); +__isl_give isl_union_pw_aff *isl_union_pw_aff_from_pw_aff( + __isl_take isl_pw_aff *pa); +__isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_val *v); +__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_aff *aff); +__isl_give isl_union_pw_aff *isl_union_pw_aff_add_pw_aff( + __isl_take isl_union_pw_aff *upa, __isl_take isl_pw_aff *pa); + +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + +int isl_union_pw_aff_n_pw_aff(__isl_keep isl_union_pw_aff *upa); + +isl_stat isl_union_pw_aff_foreach_pw_aff(__isl_keep isl_union_pw_aff *upa, + isl_stat (*fn)(__isl_take isl_pw_aff *ma, void *user), void *user); +__isl_give isl_pw_aff *isl_union_pw_aff_extract_pw_aff( + __isl_keep isl_union_pw_aff *upa, __isl_take isl_space *space); + +isl_bool isl_union_pw_aff_plain_is_equal(__isl_keep isl_union_pw_aff *upa1, + __isl_keep isl_union_pw_aff *upa2); + +__isl_give isl_union_set *isl_union_pw_aff_domain( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_neg( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_add( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2); +__isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2); +__isl_give isl_union_pw_aff *isl_union_pw_aff_sub( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_coalesce( + __isl_take isl_union_pw_aff *upa); +__isl_give isl_union_pw_aff *isl_union_pw_aff_gist( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *context); +__isl_give isl_union_pw_aff *isl_union_pw_aff_gist_params( + __isl_take isl_union_pw_aff *upa, __isl_take isl_set *context); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_floor( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *v); +__isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *v); +__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *f); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_align_params( + __isl_take isl_union_pw_aff *upa, __isl_take isl_space *model); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_params( + __isl_take isl_union_pw_aff *upa, __isl_take isl_set *set); +__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); +__isl_give isl_union_pw_aff *isl_union_pw_aff_subtract_domain( + __isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset); + +__isl_give isl_union_pw_aff *isl_union_pw_aff_set_dim_name( + __isl_take isl_union_pw_aff *upa, + enum isl_dim_type type, unsigned pos, const char *s); + +__isl_give isl_union_set *isl_union_pw_aff_zero_union_set( + __isl_take isl_union_pw_aff *upa); + +__isl_give isl_union_map *isl_union_map_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); + +__isl_give char *isl_union_pw_aff_to_str(__isl_keep isl_union_pw_aff *upa); +__isl_give isl_printer *isl_printer_print_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa); + +ISL_DECLARE_MULTI(union_pw_aff) +ISL_DECLARE_MULTI_NEG(union_pw_aff) + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma); + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_floor( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_domain( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_set *uset); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_params( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *params); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *set); + +__isl_give isl_union_set *isl_multi_union_pw_aff_domain( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist( + __isl_take isl_multi_union_pw_aff *aff, + __isl_take isl_union_set *context); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist_params( + __isl_take isl_multi_union_pw_aff *aff, __isl_take isl_set *context); + +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma); +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma); + +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2); + +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set( + __isl_take isl_multi_union_pw_aff *mupa); + +__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space); + +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); +__isl_give char *isl_multi_union_pw_aff_to_str( + __isl_keep isl_multi_union_pw_aff *mupa); +__isl_give isl_printer *isl_printer_print_multi_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa); +void isl_multi_union_pw_aff_dump(__isl_keep isl_multi_union_pw_aff *mupa); + +ISL_DECLARE_LIST_FN(union_pw_aff) +ISL_DECLARE_LIST_FN(union_pw_multi_aff) + #if defined(__cplusplus) } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/aff_type.h isl-0.15/include/isl/aff_type.h --- isl-0.12.2/include/isl/aff_type.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/include/isl/aff_type.h 2015-06-02 09:28:08.000000000 +0000 @@ -17,6 +17,11 @@ ISL_DECLARE_LIST(pw_aff) +struct isl_union_pw_aff; +typedef struct isl_union_pw_aff isl_union_pw_aff; + +ISL_DECLARE_LIST_TYPE(union_pw_aff) + struct isl_multi_aff; typedef struct isl_multi_aff isl_multi_aff; @@ -26,9 +31,14 @@ struct isl_union_pw_multi_aff; typedef struct isl_union_pw_multi_aff isl_union_pw_multi_aff; +ISL_DECLARE_LIST_TYPE(union_pw_multi_aff) + struct isl_multi_pw_aff; typedef struct isl_multi_pw_aff isl_multi_pw_aff; +struct isl_multi_union_pw_aff; +typedef struct isl_multi_union_pw_aff isl_multi_union_pw_aff; + #if defined(__cplusplus) } #endif diff -Nru isl-0.12.2/include/isl/arg.h isl-0.15/include/isl/arg.h --- isl-0.12.2/include/isl/arg.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/arg.h 2015-06-10 18:25:32.000000000 +0000 @@ -148,6 +148,16 @@ .u = { .choice = { .choice = c, .default_value = d, \ .default_selected = ds, .set = NULL } } \ }, +#define ISL_ARG_PHANTOM_USER_CHOICE_F(s,l,c,setter,d,h,fl) { \ + .type = isl_arg_choice, \ + .short_name = s, \ + .long_name = l, \ + .offset = -1, \ + .help_msg = h, \ + .flags = fl, \ + .u = { .choice = { .choice = c, .default_value = d, \ + .default_selected = d, .set = setter } } \ +}, #define ISL_ARG_USER_OPT_CHOICE(st,f,s,l,c,setter,d,ds,h) { \ .type = isl_arg_choice, \ .short_name = s, \ @@ -252,10 +262,10 @@ }, #define ISL_ARG_CHILD(st,f,l,c,h) \ _ISL_ARG_CHILD(offsetof(st, f),l,c,h,0) -#define ISL_ARG_GROUP_F(c,h,fl) \ - _ISL_ARG_CHILD(-1,NULL,c,h,fl) -#define ISL_ARG_GROUP(c,h) \ - ISL_ARG_GROUP_F(c,h,0) +#define ISL_ARG_GROUP_F(l,c,h,fl) \ + _ISL_ARG_CHILD(-1,l,c,h,fl) +#define ISL_ARG_GROUP(l,c,h) \ + ISL_ARG_GROUP_F(l,c,h,0) #define ISL_ARG_FLAGS(st,f,s,l,c,d,h) { \ .type = isl_arg_flags, \ .short_name = s, \ diff -Nru isl-0.12.2/include/isl/ast_build.h isl-0.15/include/isl/ast_build.h --- isl-0.12.2/include/isl/ast_build.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/ast_build.h 2015-06-02 09:28:08.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -13,34 +14,35 @@ typedef struct isl_ast_build isl_ast_build; -int isl_options_set_ast_build_atomic_upper_bound(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_atomic_upper_bound(isl_ctx *ctx, int val); int isl_options_get_ast_build_atomic_upper_bound(isl_ctx *ctx); -int isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, int val); int isl_options_get_ast_build_prefer_pdiv(isl_ctx *ctx); -int isl_options_set_ast_build_exploit_nested_bounds(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_exploit_nested_bounds(isl_ctx *ctx, int val); int isl_options_get_ast_build_exploit_nested_bounds(isl_ctx *ctx); -int isl_options_set_ast_build_group_coscheduled(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_group_coscheduled(isl_ctx *ctx, int val); int isl_options_get_ast_build_group_coscheduled(isl_ctx *ctx); #define ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT 0 #define ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT 1 -int isl_options_set_ast_build_separation_bounds(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_separation_bounds(isl_ctx *ctx, int val); int isl_options_get_ast_build_separation_bounds(isl_ctx *ctx); -int isl_options_set_ast_build_scale_strides(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_scale_strides(isl_ctx *ctx, int val); int isl_options_get_ast_build_scale_strides(isl_ctx *ctx); -int isl_options_set_ast_build_allow_else(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_allow_else(isl_ctx *ctx, int val); int isl_options_get_ast_build_allow_else(isl_ctx *ctx); -int isl_options_set_ast_build_allow_or(isl_ctx *ctx, int val); +isl_stat isl_options_set_ast_build_allow_or(isl_ctx *ctx, int val); int isl_options_get_ast_build_allow_or(isl_ctx *ctx); isl_ctx *isl_ast_build_get_ctx(__isl_keep isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_alloc(isl_ctx *ctx); __isl_give isl_ast_build *isl_ast_build_from_context(__isl_take isl_set *set); __isl_give isl_space *isl_ast_build_get_schedule_space( @@ -53,7 +55,8 @@ __isl_give isl_ast_build *isl_ast_build_copy( __isl_keep isl_ast_build *build); -void *isl_ast_build_free(__isl_take isl_ast_build *build); +__isl_null isl_ast_build *isl_ast_build_free( + __isl_take isl_ast_build *build); __isl_give isl_ast_build *isl_ast_build_set_options( __isl_take isl_ast_build *build, @@ -73,16 +76,36 @@ __isl_take isl_ast_build *build, __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, __isl_keep isl_ast_build *build, void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_before_each_mark( + __isl_take isl_ast_build *build, + isl_stat (*fn)(__isl_keep isl_id *mark, __isl_keep isl_ast_build *build, + void *user), void *user); +__isl_give isl_ast_build *isl_ast_build_set_after_each_mark( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user); __isl_give isl_ast_build *isl_ast_build_set_create_leaf( __isl_take isl_ast_build *build, __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_build *build, void *user), void *user); +__isl_give isl_ast_expr *isl_ast_build_expr_from_set( + __isl_keep isl_ast_build *build, __isl_take isl_set *set); __isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff( __isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa); +__isl_give isl_ast_expr *isl_ast_build_access_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_ast_expr *isl_ast_build_access_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa); __isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff( __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_ast_expr *isl_ast_build_call_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_ast_node *isl_ast_build_node_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_schedule *schedule); +__isl_give isl_ast_node *isl_ast_build_node_from_schedule_map( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule); __isl_give isl_ast_node *isl_ast_build_ast_from_schedule( __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule); diff -Nru isl-0.12.2/include/isl/ast.h isl-0.15/include/isl/ast.h --- isl-0.12.2/include/isl/ast.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/ast.h 2015-06-02 09:28:08.000000000 +0000 @@ -2,7 +2,9 @@ #define ISL_AST_H #include +#include #include +#include #include #include #include @@ -11,62 +13,12 @@ extern "C" { #endif -struct isl_ast_expr; -typedef struct isl_ast_expr isl_ast_expr; - -struct isl_ast_node; -typedef struct isl_ast_node isl_ast_node; - -enum isl_ast_op_type { - isl_ast_op_error = -1, - isl_ast_op_and, - isl_ast_op_and_then, - isl_ast_op_or, - isl_ast_op_or_else, - isl_ast_op_max, - isl_ast_op_min, - isl_ast_op_minus, - isl_ast_op_add, - isl_ast_op_sub, - isl_ast_op_mul, - isl_ast_op_div, - isl_ast_op_fdiv_q, /* Round towards -infty */ - isl_ast_op_pdiv_q, /* Dividend is non-negative */ - isl_ast_op_pdiv_r, /* Dividend is non-negative */ - isl_ast_op_cond, - isl_ast_op_select, - isl_ast_op_eq, - isl_ast_op_le, - isl_ast_op_lt, - isl_ast_op_ge, - isl_ast_op_gt, - isl_ast_op_call -}; - -enum isl_ast_expr_type { - isl_ast_expr_error = -1, - isl_ast_expr_op, - isl_ast_expr_id, - isl_ast_expr_int -}; - -enum isl_ast_node_type { - isl_ast_node_error = -1, - isl_ast_node_for = 1, - isl_ast_node_if, - isl_ast_node_block, - isl_ast_node_user -}; - -struct isl_ast_print_options; -typedef struct isl_ast_print_options isl_ast_print_options; - -ISL_DECLARE_LIST(ast_expr) -ISL_DECLARE_LIST(ast_node) - -int isl_options_set_ast_iterator_type(isl_ctx *ctx, const char *val); +isl_stat isl_options_set_ast_iterator_type(isl_ctx *ctx, const char *val); const char *isl_options_get_ast_iterator_type(isl_ctx *ctx); +isl_stat isl_options_set_ast_always_print_block(isl_ctx *ctx, int val); +int isl_options_get_ast_always_print_block(isl_ctx *ctx); + __isl_give isl_ast_expr *isl_ast_expr_from_val(__isl_take isl_val *v); __isl_give isl_ast_expr *isl_ast_expr_from_id(__isl_take isl_id *id); __isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *expr); @@ -78,17 +30,39 @@ __isl_take isl_ast_expr *expr2); __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2); +__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array, + __isl_take isl_ast_expr_list *indices); +__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function, + __isl_take isl_ast_expr_list *arguments); +__isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr); __isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr); -void *isl_ast_expr_free(__isl_take isl_ast_expr *expr); +__isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr); isl_ctx *isl_ast_expr_get_ctx(__isl_keep isl_ast_expr *expr); enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr); -int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v); __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr); __isl_give isl_id *isl_ast_expr_get_id(__isl_keep isl_ast_expr *expr); @@ -96,6 +70,14 @@ int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr); __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, int pos); +__isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr, + int pos, __isl_take isl_ast_expr *arg); + +isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1, + __isl_keep isl_ast_expr *expr2); + +__isl_give isl_ast_expr *isl_ast_expr_substitute_ids( + __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr); __isl_give isl_printer *isl_printer_print_ast_expr(__isl_take isl_printer *p, __isl_keep isl_ast_expr *expr); @@ -104,7 +86,7 @@ __isl_give isl_ast_node *isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr); __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node); -void *isl_ast_node_free(__isl_take isl_ast_node *node); +__isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node); isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node); enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node); @@ -123,19 +105,23 @@ __isl_keep isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_for_get_body( __isl_keep isl_ast_node *node); -int isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node); +isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node); __isl_give isl_ast_expr *isl_ast_node_if_get_cond( __isl_keep isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_if_get_then( __isl_keep isl_ast_node *node); -int isl_ast_node_if_has_else(__isl_keep isl_ast_node *node); +isl_bool isl_ast_node_if_has_else(__isl_keep isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_if_get_else( __isl_keep isl_ast_node *node); __isl_give isl_ast_node_list *isl_ast_node_block_get_children( __isl_keep isl_ast_node *node); +__isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node); +__isl_give isl_ast_node *isl_ast_node_mark_get_node( + __isl_keep isl_ast_node *node); + __isl_give isl_ast_expr *isl_ast_node_user_get_expr( __isl_keep isl_ast_node *node); @@ -146,7 +132,8 @@ __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx); __isl_give isl_ast_print_options *isl_ast_print_options_copy( __isl_keep isl_ast_print_options *options); -void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options); +__isl_null isl_ast_print_options *isl_ast_print_options_free( + __isl_take isl_ast_print_options *options); isl_ctx *isl_ast_print_options_get_ctx( __isl_keep isl_ast_print_options *options); @@ -163,8 +150,8 @@ __isl_keep isl_ast_node *node, void *user), void *user); -int isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, - int (*fn)(enum isl_ast_op_type type, void *user), void *user); +isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user); __isl_give isl_printer *isl_ast_op_type_print_macro( enum isl_ast_op_type type, __isl_take isl_printer *p); __isl_give isl_printer *isl_ast_node_print_macros( diff -Nru isl-0.12.2/include/isl/ast_type.h isl-0.15/include/isl/ast_type.h --- isl-0.12.2/include/isl/ast_type.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/ast_type.h 2015-06-02 09:28:08.000000000 +0000 @@ -0,0 +1,80 @@ +#ifndef ISL_AST_TYPE_H +#define ISL_AST_TYPE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_ast_expr; +typedef struct isl_ast_expr isl_ast_expr; + +struct isl_ast_node; +typedef struct isl_ast_node isl_ast_node; + +enum isl_ast_op_type { + isl_ast_op_error = -1, + isl_ast_op_and, + isl_ast_op_and_then, + isl_ast_op_or, + isl_ast_op_or_else, + isl_ast_op_max, + isl_ast_op_min, + isl_ast_op_minus, + isl_ast_op_add, + isl_ast_op_sub, + isl_ast_op_mul, + isl_ast_op_div, + isl_ast_op_fdiv_q, /* Round towards -infty */ + isl_ast_op_pdiv_q, /* Dividend is non-negative */ + isl_ast_op_pdiv_r, /* Dividend is non-negative */ + isl_ast_op_zdiv_r, /* Result only compared against zero */ + isl_ast_op_cond, + isl_ast_op_select, + isl_ast_op_eq, + isl_ast_op_le, + isl_ast_op_lt, + isl_ast_op_ge, + isl_ast_op_gt, + isl_ast_op_call, + isl_ast_op_access, + isl_ast_op_member, + isl_ast_op_address_of +}; + +enum isl_ast_expr_type { + isl_ast_expr_error = -1, + isl_ast_expr_op, + isl_ast_expr_id, + isl_ast_expr_int +}; + +enum isl_ast_node_type { + isl_ast_node_error = -1, + isl_ast_node_for = 1, + isl_ast_node_if, + isl_ast_node_block, + isl_ast_node_mark, + isl_ast_node_user +}; + +enum isl_ast_loop_type { + isl_ast_loop_error = -1, + isl_ast_loop_default = 0, + isl_ast_loop_atomic, + isl_ast_loop_unroll, + isl_ast_loop_separate +}; + +struct isl_ast_print_options; +typedef struct isl_ast_print_options isl_ast_print_options; + +ISL_DECLARE_LIST(ast_expr) +ISL_DECLARE_LIST(ast_node) + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/band.h isl-0.15/include/isl/band.h --- isl-0.12.2/include/isl/band.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/band.h 2015-06-02 09:28:08.000000000 +0000 @@ -16,7 +16,7 @@ ISL_DECLARE_LIST(band) __isl_give isl_band *isl_band_copy(__isl_keep isl_band *band); -void *isl_band_free(__isl_take isl_band *band); +__isl_null isl_band *isl_band_free(__isl_take isl_band *band); isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band); @@ -31,16 +31,16 @@ __isl_give isl_union_map *isl_band_get_suffix_schedule( __isl_keep isl_band *band); -int isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, int val); +isl_stat isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, int val); int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx); -int isl_options_set_tile_shift_point_loops(isl_ctx *ctx, int val); +isl_stat isl_options_set_tile_shift_point_loops(isl_ctx *ctx, int val); int isl_options_get_tile_shift_point_loops(isl_ctx *ctx); int isl_band_tile(__isl_keep isl_band *band, __isl_take isl_vec *sizes); int isl_band_split(__isl_keep isl_band *band, int pos); int isl_band_n_member(__isl_keep isl_band *band); -int isl_band_member_is_zero_distance(__isl_keep isl_band *band, int pos); +int isl_band_member_is_coincident(__isl_keep isl_band *band, int pos); int isl_band_list_foreach_band(__isl_keep isl_band_list *list, int (*fn)(__isl_keep isl_band *band, void *user), void *user); diff -Nru isl-0.12.2/include/isl/blk.h isl-0.15/include/isl/blk.h --- isl-0.12.2/include/isl/blk.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/blk.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - * 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_BLK_H -#define ISL_BLK_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -struct isl_blk { - size_t size; - isl_int *data; -}; - -#define ISL_BLK_CACHE_SIZE 20 - -struct isl_ctx; - -struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n); -struct isl_blk isl_blk_empty(void); -int isl_blk_is_error(struct isl_blk block); -struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block, - size_t new_n); -void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block); -void isl_blk_clear_cache(struct isl_ctx *ctx); - -#if defined(__cplusplus) -} -#endif - -#endif diff -Nru isl-0.12.2/include/isl/config.h.in isl-0.15/include/isl/config.h.in --- isl-0.12.2/include/isl/config.h.in 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/config.h.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#undef GCC_WARN_UNUSED_RESULT - -#undef ISL_PIPLIB diff -Nru isl-0.12.2/include/isl/constraint.h isl-0.15/include/isl/constraint.h --- isl-0.12.2/include/isl/constraint.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/constraint.h 2015-06-10 18:25:32.000000000 +0000 @@ -29,24 +29,33 @@ isl_ctx *isl_constraint_get_ctx(__isl_keep isl_constraint *c); +__isl_give isl_constraint *isl_constraint_alloc_equality( + __isl_take isl_local_space *ls); +__isl_give isl_constraint *isl_constraint_alloc_inequality( + __isl_take isl_local_space *ls); __isl_give isl_constraint *isl_equality_alloc(__isl_take isl_local_space *ls); __isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls); struct isl_constraint *isl_constraint_cow(struct isl_constraint *c); struct isl_constraint *isl_constraint_copy(struct isl_constraint *c); -void *isl_constraint_free(__isl_take isl_constraint *c); +__isl_null isl_constraint *isl_constraint_free(__isl_take isl_constraint *c); +int isl_basic_map_n_constraint(__isl_keep isl_basic_map *bmap); int isl_basic_set_n_constraint(__isl_keep isl_basic_set *bset); -int isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap, - int (*fn)(__isl_take isl_constraint *c, void *user), void *user); -int isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, - int (*fn)(__isl_take isl_constraint *c, void *user), void *user); +isl_stat isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user); +isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user); +__isl_give isl_constraint_list *isl_basic_map_get_constraint_list( + __isl_keep isl_basic_map *bmap); +__isl_give isl_constraint_list *isl_basic_set_get_constraint_list( + __isl_keep isl_basic_set *bset); int isl_constraint_is_equal(struct isl_constraint *constraint1, struct isl_constraint *constraint2); -int isl_basic_set_foreach_bound_pair(__isl_keep isl_basic_set *bset, +isl_stat isl_basic_set_foreach_bound_pair(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos, - int (*fn)(__isl_take isl_constraint *lower, + isl_stat (*fn)(__isl_take isl_constraint *lower, __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, void *user), void *user); @@ -77,46 +86,37 @@ int isl_constraint_dim(struct isl_constraint *constraint, enum isl_dim_type type); -int isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, +isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned first, unsigned n); const char *isl_constraint_get_dim_name(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos); -void isl_constraint_get_constant(__isl_keep isl_constraint *constraint, - isl_int *v); __isl_give isl_val *isl_constraint_get_constant_val( __isl_keep isl_constraint *constraint); -void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_int *v); __isl_give isl_val *isl_constraint_get_coefficient_val( __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos); -__isl_give isl_constraint *isl_constraint_set_constant( - __isl_take isl_constraint *constraint, isl_int v); __isl_give isl_constraint *isl_constraint_set_constant_si( __isl_take isl_constraint *constraint, int v); __isl_give isl_constraint *isl_constraint_set_constant_val( __isl_take isl_constraint *constraint, __isl_take isl_val *v); -__isl_give isl_constraint *isl_constraint_set_coefficient( - __isl_take isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_int v); __isl_give isl_constraint *isl_constraint_set_coefficient_si( __isl_take isl_constraint *constraint, enum isl_dim_type type, int pos, int v); __isl_give isl_constraint *isl_constraint_set_coefficient_val( __isl_take isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_val *v); + enum isl_dim_type type, int pos, __isl_take isl_val *v); __isl_give isl_aff *isl_constraint_get_div(__isl_keep isl_constraint *constraint, int pos); struct isl_constraint *isl_constraint_negate(struct isl_constraint *constraint); -int isl_constraint_is_equality(__isl_keep isl_constraint *constraint); +isl_bool isl_constraint_is_equality(__isl_keep isl_constraint *constraint); int isl_constraint_is_div_constraint(__isl_keep isl_constraint *constraint); -int isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, +isl_bool isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos); -int isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint, +isl_bool isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos); __isl_give isl_basic_map *isl_basic_map_from_constraint( @@ -134,6 +134,11 @@ __isl_give isl_basic_set *isl_basic_set_drop_constraint( __isl_take isl_basic_set *bset, __isl_take isl_constraint *constraint); +int isl_constraint_plain_cmp(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); +int isl_constraint_cmp_last_non_zero(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2); + __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p, __isl_keep isl_constraint *c); void isl_constraint_dump(__isl_keep isl_constraint *c); @@ -142,6 +147,4 @@ } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/ctx.h isl-0.15/include/isl/ctx.h --- isl-0.12.2/include/isl/ctx.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/ctx.h 2015-06-02 09:28:08.000000000 +0000 @@ -13,11 +13,7 @@ #include #include -#include -#include #include -#include -#include #ifndef __isl_give #define __isl_give @@ -28,6 +24,9 @@ #ifndef __isl_keep #define __isl_keep #endif +#ifndef __isl_null +#define __isl_null +#endif #ifndef __isl_export #define __isl_export #endif @@ -38,12 +37,6 @@ #define __isl_subclass(super) #endif -#ifdef GCC_WARN_UNUSED_RESULT -#define WARN_UNUSED GCC_WARN_UNUSED_RESULT -#else -#define WARN_UNUSED -#endif - #if defined(__cplusplus) extern "C" { #endif @@ -78,16 +71,33 @@ enum isl_error { isl_error_none = 0, isl_error_abort, + isl_error_alloc, isl_error_unknown, isl_error_internal, isl_error_invalid, + isl_error_quota, isl_error_unsupported }; +typedef enum { + isl_stat_error = -1, + isl_stat_ok = 0, +} isl_stat; +typedef enum { + isl_bool_error = -1, + isl_bool_false = 0, + isl_bool_true = 1 +} isl_bool; struct isl_ctx; typedef struct isl_ctx isl_ctx; /* Some helper macros */ +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define ISL_DEPRECATED __attribute__((__deprecated__)) +#else +#define ISL_DEPRECATED +#endif + #define ISL_FL_INIT(l, f) (l) = (f) /* Specific flags location. */ #define ISL_FL_SET(l, f) ((l) |= (f)) #define ISL_FL_CLR(l, f) ((l) &= ~(f)) @@ -98,24 +108,21 @@ #define ISL_F_CLR(p, f) ISL_FL_CLR((p)->flags, f) #define ISL_F_ISSET(p, f) ISL_FL_ISSET((p)->flags, f) -/* isl_check_ctx() checks at compile time if 'ctx' is of type 'isl_ctx *' and - * returns the value of 'expr'. It is used to ensure, that always an isl_ctx is - * passed to the following macros, even if they currently do not use it. - */ -#define isl_check_ctx(ctx, expr) ((ctx != (isl_ctx *) 0) ? expr : NULL) - -#define isl_alloc(ctx,type,size) ((type *)isl_check_ctx(ctx,\ - malloc(size))) -#define isl_calloc(ctx,type,size) ((type *)isl_check_ctx(ctx,\ - calloc(1, size))) -#define isl_realloc(ctx,ptr,type,size) ((type *)isl_check_ctx(ctx,\ - realloc(ptr,size))) +void *isl_malloc_or_die(isl_ctx *ctx, size_t size); +void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size); +void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size); + +#define isl_alloc(ctx,type,size) ((type *)isl_malloc_or_die(ctx, size)) +#define isl_calloc(ctx,type,size) ((type *)isl_calloc_or_die(ctx,\ + 1, size)) +#define isl_realloc(ctx,ptr,type,size) ((type *)isl_realloc_or_die(ctx,\ + ptr, size)) #define isl_alloc_type(ctx,type) isl_alloc(ctx,type,sizeof(type)) #define isl_calloc_type(ctx,type) isl_calloc(ctx,type,sizeof(type)) #define isl_realloc_type(ctx,ptr,type) isl_realloc(ctx,ptr,type,sizeof(type)) #define isl_alloc_array(ctx,type,n) isl_alloc(ctx,type,(n)*sizeof(type)) -#define isl_calloc_array(ctx,type,n) ((type *)isl_check_ctx(ctx,\ - calloc(n, sizeof(type)))) +#define isl_calloc_array(ctx,type,n) ((type *)isl_calloc_or_die(ctx,\ + n, sizeof(type))) #define isl_realloc_array(ctx,ptr,type,n) \ isl_realloc(ctx,ptr,type,(n)*sizeof(type)) @@ -156,6 +163,10 @@ void isl_ctx_resume(isl_ctx *ctx); int isl_ctx_aborted(isl_ctx *ctx); +void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations); +unsigned long isl_ctx_get_max_operations(isl_ctx *ctx); +void isl_ctx_reset_operations(isl_ctx *ctx); + #define ISL_ARG_CTX_DECL(prefix,st,args) \ st *isl_ctx_peek_ ## prefix(isl_ctx *ctx); @@ -178,16 +189,16 @@ } #define ISL_CTX_SET_INT_DEF(prefix,st,args,field) \ -int prefix ## _set_ ## field(isl_ctx *ctx, int val) \ +isl_stat prefix ## _set_ ## field(isl_ctx *ctx, int val) \ { \ st *options; \ options = isl_ctx_peek_ ## prefix(ctx); \ if (!options) \ isl_die(ctx, isl_error_invalid, \ "isl_ctx does not reference " #prefix, \ - return -1); \ + return isl_stat_error); \ options->field = val; \ - return 0; \ + return isl_stat_ok; \ } #define ISL_CTX_GET_STR_DEF(prefix,st,args,field) \ @@ -203,21 +214,21 @@ } #define ISL_CTX_SET_STR_DEF(prefix,st,args,field) \ -int prefix ## _set_ ## field(isl_ctx *ctx, const char *val) \ +isl_stat prefix ## _set_ ## field(isl_ctx *ctx, const char *val) \ { \ st *options; \ options = isl_ctx_peek_ ## prefix(ctx); \ if (!options) \ isl_die(ctx, isl_error_invalid, \ "isl_ctx does not reference " #prefix, \ - return -1); \ + return isl_stat_error); \ if (!val) \ - return -1; \ + return isl_stat_error; \ free(options->field); \ options->field = strdup(val); \ if (!options->field) \ - return -1; \ - return 0; \ + return isl_stat_error; \ + return isl_stat_ok; \ } #define ISL_CTX_GET_BOOL_DEF(prefix,st,args,field) \ diff -Nru isl-0.12.2/include/isl/deprecated/aff_int.h isl-0.15/include/isl/deprecated/aff_int.h --- isl-0.12.2/include/isl/deprecated/aff_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/aff_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,45 @@ +#ifndef ISL_DEPRECATED_AFF_INT_H +#define ISL_DEPRECATED_AFF_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v); +int isl_aff_get_coefficient(__isl_keep isl_aff *aff, + enum isl_dim_type type, int pos, isl_int *v); +int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v); +__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v); +__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, isl_int v); +__isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v); +__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v); +__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, + isl_int v); +__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, isl_int v); + +__isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int mod); + +__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f); +__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f); + +__isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, + isl_int mod); + +__isl_give isl_pw_aff *isl_pw_aff_scale(__isl_take isl_pw_aff *pwaff, + isl_int f); +__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff, + isl_int f); + +__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff, + isl_int f); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/ast_int.h isl-0.15/include/isl/deprecated/ast_int.h --- isl-0.12.2/include/isl/deprecated/ast_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/ast_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,17 @@ +#ifndef ISL_DEPRECATED_AST_INT_H +#define ISL_DEPRECATED_AST_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/constraint_int.h isl-0.15/include/isl/deprecated/constraint_int.h --- isl-0.12.2/include/isl/deprecated/constraint_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/constraint_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,25 @@ +#ifndef ISL_DEPRECATED_CONSTRAINT_INT_H +#define ISL_DEPRECATED_CONSTRAINT_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +void isl_constraint_get_constant(__isl_keep isl_constraint *constraint, + isl_int *v); +void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, int pos, isl_int *v); +__isl_give isl_constraint *isl_constraint_set_constant( + __isl_take isl_constraint *constraint, isl_int v); +__isl_give isl_constraint *isl_constraint_set_coefficient( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, isl_int v); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/ilp_int.h isl-0.15/include/isl/deprecated/ilp_int.h --- isl-0.12.2/include/isl/deprecated/ilp_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/ilp_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,23 @@ +#ifndef ISL_DEPRECATED_ILP_INT_H +#define ISL_DEPRECATED_ILP_INT_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +enum isl_lp_result isl_basic_set_max(__isl_keep isl_basic_set *bset, + __isl_keep isl_aff *obj, isl_int *opt); +enum isl_lp_result isl_set_min(__isl_keep isl_set *set, + __isl_keep isl_aff *obj, isl_int *opt); +enum isl_lp_result isl_set_max(__isl_keep isl_set *set, + __isl_keep isl_aff *obj, isl_int *opt); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/int.h isl-0.15/include/isl/deprecated/int.h --- isl-0.12.2/include/isl/deprecated/int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,136 @@ +/* + * 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_DEPRECATED_INT_H +#define ISL_DEPRECATED_INT_H + +#include +#include +#include +#if defined(__cplusplus) +#include +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#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_get_si(r) mpz_get_si(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_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_submul(r,i,j) mpz_submul(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) + +#if defined(__cplusplus) +} +#endif + +#if defined(__cplusplus) +extern "C" { typedef void (*isl_gmp_free_t)(void *, size_t); } + +static inline std::ostream &operator<<(std::ostream &os, isl_int i) +{ + char *s; + s = mpz_get_str(0, 10, i); + os << s; + isl_int_free_str(s); + return os; +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/map_int.h isl-0.15/include/isl/deprecated/map_int.h --- isl-0.12.2/include/isl/deprecated/map_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/map_int.h 2015-06-02 09:28:08.000000000 +0000 @@ -0,0 +1,25 @@ +#ifndef ISL_DEPRECATED_MAP_INT_H +#define ISL_DEPRECATED_MAP_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, isl_int *val); + +__isl_give isl_map *isl_map_fix(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int value); +int isl_map_plain_is_fixed(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int *val); + +__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/mat_int.h isl-0.15/include/isl/deprecated/mat_int.h --- isl-0.12.2/include/isl/deprecated/mat_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/mat_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,19 @@ +#ifndef ISL_DEPRECATED_MAT_INT_H +#define ISL_DEPRECATED_MAT_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v); +__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat, + int row, int col, isl_int v); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/point_int.h isl-0.15/include/isl/deprecated/point_int.h --- isl-0.12.2/include/isl/deprecated/point_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/point_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,20 @@ +#ifndef ISL_DEPRECATED_POINT_INT_H +#define ISL_DEPRECATED_POINT_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int isl_point_get_coordinate(__isl_keep isl_point *pnt, + enum isl_dim_type type, int pos, isl_int *v); +__isl_give isl_point *isl_point_set_coordinate(__isl_take isl_point *pnt, + enum isl_dim_type type, int pos, isl_int v); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/polynomial_int.h isl-0.15/include/isl/deprecated/polynomial_int.h --- isl-0.12.2/include/isl/deprecated/polynomial_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/polynomial_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,32 @@ +#ifndef ISL_DEPRECATED_POLYNOMIAL_INT_H +#define ISL_DEPRECATED_POLYNOMIAL_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain( + __isl_take isl_space *space, const isl_int n, const isl_int d); +int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp, + isl_int *n, isl_int *d); +__isl_give isl_qpolynomial *isl_qpolynomial_scale( + __isl_take isl_qpolynomial *qp, isl_int v); + +void isl_term_get_num(__isl_keep isl_term *term, isl_int *n); +void isl_term_get_den(__isl_keep isl_term *term, isl_int *d); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale( + __isl_take isl_qpolynomial_fold *fold, isl_int v); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fix_dim( + __isl_take isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, unsigned n, isl_int v); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/set_int.h isl-0.15/include/isl/deprecated/set_int.h --- isl-0.12.2/include/isl/deprecated/set_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/set_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,27 @@ +#ifndef ISL_DEPRECATED_SET_INT_H +#define ISL_DEPRECATED_SET_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, isl_int value); +__isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value); +__isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value); +__isl_give isl_set *isl_set_fix(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value); + +int isl_set_plain_is_fixed(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int *val); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/union_map_int.h isl-0.15/include/isl/deprecated/union_map_int.h --- isl-0.12.2/include/isl/deprecated/union_map_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/union_map_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,18 @@ +#ifndef ISL_DEPRECATED_UNION_MAP_INT_H +#define ISL_DEPRECATED_UNION_MAP_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_union_map *isl_union_map_fixed_power( + __isl_take isl_union_map *umap, isl_int exp); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/val_int.h isl-0.15/include/isl/deprecated/val_int.h --- isl-0.12.2/include/isl/deprecated/val_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/val_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,18 @@ +#ifndef ISL_DEPRECATED_VAL_INT_H +#define ISL_DEPRECATED_VAL_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n); +int isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/deprecated/vec_int.h isl-0.15/include/isl/deprecated/vec_int.h --- isl-0.12.2/include/isl/deprecated/vec_int.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/deprecated/vec_int.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,22 @@ +#ifndef ISL_DEPRECATED_VEC_INT_H +#define ISL_DEPRECATED_VEC_INT_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +int isl_vec_get_element(__isl_keep isl_vec *vec, int pos, isl_int *v); +__isl_give isl_vec *isl_vec_set_element(__isl_take isl_vec *vec, + int pos, isl_int v); + +__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v); +__isl_give isl_vec *isl_vec_fdiv_r(__isl_take isl_vec *vec, isl_int m); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/dim.h isl-0.15/include/isl/dim.h --- isl-0.12.2/include/isl/dim.h 2013-01-08 11:20:43.000000000 +0000 +++ isl-0.15/include/isl/dim.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -#ifndef ISL_DIM_H -#define ISL_DIM_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -#define isl_dim isl_space - -isl_ctx *isl_dim_get_ctx(__isl_keep isl_space *dim); -__isl_give isl_space *isl_dim_alloc(isl_ctx *ctx, - unsigned nparam, unsigned n_in, unsigned n_out); -__isl_give isl_space *isl_dim_set_alloc(isl_ctx *ctx, - unsigned nparam, unsigned dim); -__isl_give isl_space *isl_dim_copy(__isl_keep isl_space *dim); -void isl_dim_free(__isl_take isl_space *dim); - -unsigned isl_dim_size(__isl_keep isl_space *dim, enum isl_dim_type type); - -__isl_give isl_space *isl_dim_set_dim_id(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_dim_has_dim_id(__isl_keep isl_space *dim, - enum isl_dim_type type, unsigned pos); -__isl_give isl_id *isl_dim_get_dim_id(__isl_keep isl_space *dim, - enum isl_dim_type type, unsigned pos); - -int isl_dim_find_dim_by_id(__isl_keep isl_space *dim, - enum isl_dim_type type, __isl_keep isl_id *id); - -__isl_give isl_space *isl_dim_set_tuple_id(__isl_take isl_space *dim, - enum isl_dim_type type, __isl_take isl_id *id); -__isl_give isl_space *isl_dim_reset_tuple_id(__isl_take isl_space *dim, - enum isl_dim_type type); -int isl_dim_has_tuple_id(__isl_keep isl_space *dim, enum isl_dim_type type); -__isl_give isl_id *isl_dim_get_tuple_id(__isl_keep isl_space *dim, - enum isl_dim_type type); - -__isl_give isl_space *isl_dim_set_name(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned pos, __isl_keep const char *name); -__isl_keep const char *isl_dim_get_name(__isl_keep isl_space *dim, - enum isl_dim_type type, unsigned pos); - -__isl_give isl_space *isl_dim_set_tuple_name(__isl_take isl_space *dim, - enum isl_dim_type type, const char *s); -const char *isl_dim_get_tuple_name(__isl_keep isl_space *dim, - enum isl_dim_type type); - -int isl_dim_is_wrapping(__isl_keep isl_space *dim); -__isl_give isl_space *isl_dim_wrap(__isl_take isl_space *dim); -__isl_give isl_space *isl_dim_unwrap(__isl_take isl_space *dim); - -__isl_give isl_space *isl_dim_domain(__isl_take isl_space *dim); -__isl_give isl_space *isl_dim_from_domain(__isl_take isl_space *dim); -__isl_give isl_space *isl_dim_range(__isl_take isl_space *dim); -__isl_give isl_space *isl_dim_from_range(__isl_take isl_space *dim); -__isl_give isl_space *isl_dim_reverse(__isl_take isl_space *dim); -__isl_give isl_space *isl_dim_join(__isl_take isl_space *left, - __isl_take isl_space *right); -__isl_give isl_space *isl_dim_align_params(__isl_take isl_space *dim1, - __isl_take isl_space *dim2); -__isl_give isl_space *isl_dim_insert(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned pos, unsigned n); -__isl_give isl_space *isl_dim_add(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned n); -__isl_give isl_space *isl_dim_drop(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned first, unsigned n); -__isl_give isl_space *isl_dim_move(__isl_take isl_space *dim, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, unsigned n); -__isl_give isl_space *isl_dim_map_from_set( - __isl_take isl_space *dim); -__isl_give isl_space *isl_dim_zip(__isl_take isl_space *dim); - -__isl_give isl_local_space *isl_local_space_from_dim( - __isl_take isl_space *dim); -__isl_give isl_space *isl_local_space_get_dim( - __isl_keep isl_local_space *ls); - -__isl_give isl_space *isl_aff_get_dim(__isl_keep isl_aff *aff); -__isl_give isl_space *isl_pw_aff_get_dim(__isl_keep isl_pw_aff *pwaff); - -__isl_give isl_space *isl_constraint_get_dim( - __isl_keep isl_constraint *constraint); - -__isl_give isl_space *isl_basic_map_get_dim(__isl_keep isl_basic_map *bmap); -__isl_give isl_space *isl_map_get_dim(__isl_keep isl_map *map); -__isl_give isl_space *isl_union_map_get_dim(__isl_keep isl_union_map *umap); - -__isl_give isl_space *isl_basic_set_get_dim(__isl_keep isl_basic_set *bset); -__isl_give isl_space *isl_set_get_dim(__isl_keep isl_set *set); -__isl_give isl_space *isl_union_set_get_dim(__isl_keep isl_union_set *uset); - -__isl_give isl_space *isl_point_get_dim(__isl_keep isl_point *pnt); - -__isl_give isl_space *isl_qpolynomial_get_dim(__isl_keep isl_qpolynomial *qp); -__isl_give isl_space *isl_pw_qpolynomial_get_dim( - __isl_keep isl_pw_qpolynomial *pwqp); -__isl_give isl_space *isl_qpolynomial_fold_get_dim( - __isl_keep isl_qpolynomial_fold *fold); -__isl_give isl_space *isl_pw_qpolynomial_fold_get_dim( - __isl_keep isl_pw_qpolynomial_fold *pwf); -__isl_give isl_space *isl_union_pw_qpolynomial_get_dim( - __isl_keep isl_union_pw_qpolynomial *upwqp); -__isl_give isl_space *isl_union_pw_qpolynomial_fold_get_dim( - __isl_keep isl_union_pw_qpolynomial_fold *upwf); - -#if defined(__cplusplus) -} -#endif - -#endif diff -Nru isl-0.12.2/include/isl/flow.h isl-0.15/include/isl/flow.h --- isl-0.12.2/include/isl/flow.h 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/include/isl/flow.h 2015-06-11 07:55:31.000000000 +0000 @@ -5,6 +5,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -19,7 +20,8 @@ struct isl_restriction; typedef struct isl_restriction isl_restriction; -void *isl_restriction_free(__isl_take isl_restriction *restr); +__isl_null isl_restriction *isl_restriction_free( + __isl_take isl_restriction *restr); __isl_give isl_restriction *isl_restriction_empty( __isl_take isl_map *source_map); __isl_give isl_restriction *isl_restriction_none( @@ -47,19 +49,62 @@ __isl_give isl_access_info *isl_access_info_add_source( __isl_take isl_access_info *acc, __isl_take isl_map *source, int must, void *source_user); -void *isl_access_info_free(__isl_take isl_access_info *acc); +__isl_null isl_access_info *isl_access_info_free( + __isl_take isl_access_info *acc); isl_ctx *isl_access_info_get_ctx(__isl_keep isl_access_info *acc); __isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc); -int isl_flow_foreach(__isl_keep isl_flow *deps, - int (*fn)(__isl_take isl_map *dep, int must, void *dep_user, void *user), +isl_stat isl_flow_foreach(__isl_keep isl_flow *deps, + isl_stat (*fn)(__isl_take isl_map *dep, int must, void *dep_user, + void *user), void *user); __isl_give isl_map *isl_flow_get_no_source(__isl_keep isl_flow *deps, int must); void isl_flow_free(__isl_take isl_flow *deps); isl_ctx *isl_flow_get_ctx(__isl_keep isl_flow *deps); +struct isl_union_access_info; +typedef struct isl_union_access_info isl_union_access_info; +struct isl_union_flow; +typedef struct isl_union_flow isl_union_flow; + +__isl_give isl_union_access_info *isl_union_access_info_from_sink( + __isl_take isl_union_map *sink); +__isl_give isl_union_access_info *isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source); +__isl_give isl_union_access_info *isl_union_access_info_set_may_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *may_source); +__isl_give isl_union_access_info *isl_union_access_info_set_schedule( + __isl_take isl_union_access_info *access, + __isl_take isl_schedule *schedule); +__isl_give isl_union_access_info *isl_union_access_info_set_schedule_map( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *schedule_map); +__isl_give isl_union_access_info *isl_union_access_info_copy( + __isl_keep isl_union_access_info *access); +__isl_null isl_union_access_info *isl_union_access_info_free( + __isl_take isl_union_access_info *access); + +isl_ctx *isl_union_access_info_get_ctx( + __isl_keep isl_union_access_info *access); + +__isl_give isl_union_flow *isl_union_access_info_compute_flow( + __isl_take isl_union_access_info *access); + +isl_ctx *isl_union_flow_get_ctx(__isl_keep isl_union_flow *flow); +__isl_give isl_union_map *isl_union_flow_get_must_dependence( + __isl_keep isl_union_flow *flow); +__isl_give isl_union_map *isl_union_flow_get_may_dependence( + __isl_keep isl_union_flow *flow); +__isl_give isl_union_map *isl_union_flow_get_must_no_source( + __isl_keep isl_union_flow *flow); +__isl_give isl_union_map *isl_union_flow_get_may_no_source( + __isl_keep isl_union_flow *flow); +__isl_null isl_union_flow *isl_union_flow_free(__isl_take isl_union_flow *flow); + int isl_union_map_compute_flow(__isl_take isl_union_map *sink, __isl_take isl_union_map *must_source, __isl_take isl_union_map *may_source, diff -Nru isl-0.12.2/include/isl/hash.h isl-0.15/include/isl/hash.h --- isl-0.12.2/include/isl/hash.h 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/include/isl/hash.h 2015-06-02 09:28:08.000000000 +0000 @@ -12,6 +12,7 @@ #include #include +#include #if defined(__cplusplus) extern "C" { @@ -52,8 +53,6 @@ struct isl_hash_table_entry *entries; }; -struct isl_ctx; - struct isl_hash_table *isl_hash_table_alloc(struct isl_ctx *ctx, int min_size); void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table); @@ -65,9 +64,8 @@ uint32_t key_hash, int (*eq)(const void *entry, const void *val), const void *val, int reserve); -int isl_hash_table_foreach(struct isl_ctx *ctx, - struct isl_hash_table *table, - int (*fn)(void **entry, void *user), void *user); +isl_stat isl_hash_table_foreach(isl_ctx *ctx, struct isl_hash_table *table, + isl_stat (*fn)(void **entry, void *user), void *user); void isl_hash_table_remove(struct isl_ctx *ctx, struct isl_hash_table *table, struct isl_hash_table_entry *entry); diff -Nru isl-0.12.2/include/isl/hmap.h isl-0.15/include/isl/hmap.h --- isl-0.12.2/include/isl/hmap.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/hmap.h 2015-06-02 09:28:08.000000000 +0000 @@ -0,0 +1,58 @@ +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#define ISL_xCAT(A,B) A ## B +#define ISL_CAT(A,B) ISL_xCAT(A,B) +#define ISL_KEY ISL_CAT(isl_,ISL_KEY_BASE) +#define ISL_VAL ISL_CAT(isl_,ISL_VAL_BASE) +#define ISL_xFN(TYPE,NAME) TYPE ## _ ## NAME +#define ISL_FN(TYPE,NAME) ISL_xFN(TYPE,NAME) +#define ISL_xHMAP(KEY,VAL_BASE) KEY ## _to_ ## VAL_BASE +#define ISL_yHMAP(KEY,VAL_BASE) ISL_xHMAP(KEY,VAL_BASE) +#define ISL_HMAP ISL_yHMAP(ISL_KEY,ISL_VAL_BASE) +#define ISL_HMAP_BASE ISL_yHMAP(ISL_KEY_BASE,ISL_VAL_BASE) + +struct ISL_HMAP; +typedef struct ISL_HMAP ISL_HMAP; + +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,alloc)(isl_ctx *ctx, int min_size); +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,copy)(__isl_keep ISL_HMAP *hmap); +__isl_null ISL_HMAP *ISL_FN(ISL_HMAP,free)(__isl_take ISL_HMAP *hmap); + +isl_ctx *ISL_FN(ISL_HMAP,get_ctx)(__isl_keep ISL_HMAP *hmap); + +isl_bool ISL_FN(ISL_HMAP,has)(__isl_keep ISL_HMAP *hmap, + __isl_keep ISL_KEY *key); +__isl_give ISL_VAL *ISL_FN(ISL_HMAP,get)(__isl_keep ISL_HMAP *hmap, + __isl_take ISL_KEY *key); +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,set)(__isl_take ISL_HMAP *hmap, + __isl_take ISL_KEY *key, __isl_take ISL_VAL *val); +__isl_give ISL_HMAP *ISL_FN(ISL_HMAP,drop)(__isl_take ISL_HMAP *hmap, + __isl_take ISL_KEY *key); + +isl_stat ISL_FN(ISL_HMAP,foreach)(__isl_keep ISL_HMAP *hmap, + isl_stat (*fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, + void *user), + void *user); + +__isl_give isl_printer *ISL_FN(isl_printer_print,ISL_HMAP_BASE)( + __isl_take isl_printer *p, __isl_keep ISL_HMAP *hmap); +void ISL_FN(ISL_HMAP,dump)(__isl_keep ISL_HMAP *hmap); + +#undef ISL_xCAT +#undef ISL_CAT +#undef ISL_KEY +#undef ISL_VAL +#undef ISL_xFN +#undef ISL_FN +#undef ISL_xHMAP +#undef ISL_yHMAP +#undef ISL_HMAP + +#if defined(__cplusplus) +} +#endif diff -Nru isl-0.12.2/include/isl/id.h isl-0.15/include/isl/id.h --- isl-0.12.2/include/isl/id.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/id.h 2015-06-02 09:28:08.000000000 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -15,11 +16,12 @@ ISL_DECLARE_LIST(id) isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); +uint32_t isl_id_get_hash(__isl_keep isl_id *id); __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, __isl_keep const char *name, void *user); __isl_give isl_id *isl_id_copy(isl_id *id); -void *isl_id_free(__isl_take isl_id *id); +__isl_null isl_id *isl_id_free(__isl_take isl_id *id); void *isl_id_get_user(__isl_keep isl_id *id); __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); diff -Nru isl-0.12.2/include/isl/id_to_ast_expr.h isl-0.15/include/isl/id_to_ast_expr.h --- isl-0.12.2/include/isl/id_to_ast_expr.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/id_to_ast_expr.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,13 @@ +#ifndef ISL_ID_TO_AST_EXPR_H +#define ISL_ID_TO_AST_EXPR_H + +#include +#include + +#define ISL_KEY_BASE id +#define ISL_VAL_BASE ast_expr +#include +#undef ISL_KEY_BASE +#undef ISL_VAL_BASE + +#endif diff -Nru isl-0.12.2/include/isl/id_to_pw_aff.h isl-0.15/include/isl/id_to_pw_aff.h --- isl-0.12.2/include/isl/id_to_pw_aff.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/id_to_pw_aff.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,13 @@ +#ifndef ISL_ID_TO_PW_AFF_H +#define ISL_ID_TO_PW_AFF_H + +#include +#include + +#define ISL_KEY_BASE id +#define ISL_VAL_BASE pw_aff +#include +#undef ISL_KEY_BASE +#undef ISL_VAL_BASE + +#endif diff -Nru isl-0.12.2/include/isl/ilp.h isl-0.15/include/isl/ilp.h --- isl-0.12.2/include/isl/ilp.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/ilp.h 2015-04-19 12:02:52.000000000 +0000 @@ -11,24 +11,16 @@ #define ISL_ILP_H #include -#include +#include #include +#include #if defined(__cplusplus) extern "C" { #endif -enum isl_lp_result isl_basic_set_solve_ilp(struct isl_basic_set *bset, int max, - isl_int *f, isl_int *opt, - struct isl_vec **sol_p); -enum isl_lp_result isl_basic_set_max(__isl_keep isl_basic_set *bset, - __isl_keep isl_aff *obj, isl_int *opt); __isl_give isl_val *isl_basic_set_max_val(__isl_keep isl_basic_set *bset, __isl_keep isl_aff *obj); -enum isl_lp_result isl_set_min(__isl_keep isl_set *set, - __isl_keep isl_aff *obj, isl_int *opt); -enum isl_lp_result isl_set_max(__isl_keep isl_set *set, - __isl_keep isl_aff *obj, isl_int *opt); __isl_give isl_val *isl_set_min_val(__isl_keep isl_set *set, __isl_keep isl_aff *obj); __isl_give isl_val *isl_set_max_val(__isl_keep isl_set *set, diff -Nru isl-0.12.2/include/isl/int.h isl-0.15/include/isl/int.h --- isl-0.12.2/include/isl/int.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/int.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -/* - * 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 - -#include -#include -#include -#if defined(__cplusplus) -#include -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -#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_get_si(r) mpz_get_si(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_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_submul(r,i,j) mpz_submul(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) - -#if defined(__cplusplus) -} -#endif - -#if defined(__cplusplus) -extern "C" { typedef void (*isl_gmp_free_t)(void *, size_t); } - -static inline std::ostream &operator<<(std::ostream &os, isl_int i) -{ - char *s; - s = mpz_get_str(0, 10, i); - os << s; - isl_int_free_str(s); - return os; -} -#endif - -#endif diff -Nru isl-0.12.2/include/isl/list.h isl-0.15/include/isl/list.h --- isl-0.12.2/include/isl/list.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/include/isl/list.h 2015-06-02 09:28:08.000000000 +0000 @@ -28,7 +28,8 @@ __isl_give isl_##EL##_list *isl_##EL##_list_alloc(isl_ctx *ctx, int n); \ __isl_give isl_##EL##_list *isl_##EL##_list_copy( \ __isl_keep isl_##EL##_list *list); \ -void *isl_##EL##_list_free(__isl_take isl_##EL##_list *list); \ +__isl_null isl_##EL##_list *isl_##EL##_list_free( \ + __isl_take isl_##EL##_list *list); \ __isl_give isl_##EL##_list *isl_##EL##_list_add( \ __isl_take isl_##EL##_list *list, \ __isl_take struct isl_##EL *el); \ @@ -46,19 +47,19 @@ __isl_give struct isl_##EL##_list *isl_##EL##_list_set_##EL( \ __isl_take struct isl_##EL##_list *list, int index, \ __isl_take struct isl_##EL *el); \ -int isl_##EL##_list_foreach(__isl_keep isl_##EL##_list *list, \ - int (*fn)(__isl_take struct isl_##EL *el, void *user), \ +isl_stat isl_##EL##_list_foreach(__isl_keep isl_##EL##_list *list, \ + isl_stat (*fn)(__isl_take struct isl_##EL *el, void *user), \ void *user); \ __isl_give isl_##EL##_list *isl_##EL##_list_sort( \ __isl_take isl_##EL##_list *list, \ int (*cmp)(__isl_keep struct isl_##EL *a, \ __isl_keep struct isl_##EL *b, \ void *user), void *user); \ -int isl_##EL##_list_foreach_scc(__isl_keep isl_##EL##_list *list, \ - int (*follows)(__isl_keep struct isl_##EL *a, \ +isl_stat isl_##EL##_list_foreach_scc(__isl_keep isl_##EL##_list *list, \ + isl_bool (*follows)(__isl_keep struct isl_##EL *a, \ __isl_keep struct isl_##EL *b, void *user), \ void *follows_user, \ - int (*fn)(__isl_take isl_##EL##_list *scc, void *user), \ + isl_stat (*fn)(__isl_take isl_##EL##_list *scc, void *user), \ void *fn_user); \ __isl_give isl_printer *isl_printer_print_##EL##_list( \ __isl_take isl_printer *p, __isl_keep isl_##EL##_list *list); \ diff -Nru isl-0.12.2/include/isl/local_space.h isl-0.15/include/isl/local_space.h --- isl-0.12.2/include/isl/local_space.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/local_space.h 2015-06-02 09:28:08.000000000 +0000 @@ -19,20 +19,26 @@ __isl_give isl_local_space *isl_local_space_copy( __isl_keep isl_local_space *ls); -void *isl_local_space_free(__isl_take isl_local_space *ls); +__isl_null isl_local_space *isl_local_space_free( + __isl_take isl_local_space *ls); + +isl_bool isl_local_space_is_params(__isl_keep isl_local_space *ls); +isl_bool isl_local_space_is_set(__isl_keep isl_local_space *ls); -int isl_local_space_is_set(__isl_keep isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_set_tuple_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, __isl_take isl_id *id); int isl_local_space_dim(__isl_keep isl_local_space *ls, enum isl_dim_type type); -int isl_local_space_has_dim_name(__isl_keep isl_local_space *ls, +isl_bool isl_local_space_has_dim_name(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); const char *isl_local_space_get_dim_name(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); __isl_give isl_local_space *isl_local_space_set_dim_name( __isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos, const char *s); -int isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, +isl_bool isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_local_space_get_dim_id(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos); @@ -43,6 +49,9 @@ __isl_give isl_aff *isl_local_space_get_div(__isl_keep isl_local_space *ls, int pos); +int isl_local_space_find_dim_by_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, const char *name); + __isl_give isl_local_space *isl_local_space_domain( __isl_take isl_local_space *ls); __isl_give isl_local_space *isl_local_space_range( @@ -61,12 +70,20 @@ __isl_give isl_local_space *isl_local_space_intersect( __isl_take isl_local_space *ls1, __isl_take isl_local_space *ls2); -int isl_local_space_is_equal(__isl_keep isl_local_space *ls1, +__isl_give isl_local_space *isl_local_space_wrap( + __isl_take isl_local_space *ls); + +isl_bool isl_local_space_is_equal(__isl_keep isl_local_space *ls1, __isl_keep isl_local_space *ls2); __isl_give isl_basic_map *isl_local_space_lifting( __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_flatten_domain( + __isl_take isl_local_space *ls); +__isl_give isl_local_space *isl_local_space_flatten_range( + __isl_take isl_local_space *ls); + __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p, __isl_keep isl_local_space *ls); void isl_local_space_dump(__isl_keep isl_local_space *ls); diff -Nru isl-0.12.2/include/isl/lp.h isl-0.15/include/isl/lp.h --- isl-0.12.2/include/isl/lp.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/lp.h 2015-04-19 12:02:52.000000000 +0000 @@ -12,9 +12,6 @@ #include #include -#include -#include -#include #include enum isl_lp_result { @@ -28,22 +25,6 @@ extern "C" { #endif -enum isl_lp_result isl_basic_map_solve_lp(struct isl_basic_map *bmap, int max, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **sol); -enum isl_lp_result isl_basic_set_solve_lp(struct isl_basic_set *bset, int max, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **sol); -enum isl_lp_result isl_map_solve_lp(__isl_keep isl_map *map, int max, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **sol); -enum isl_lp_result isl_set_solve_lp(__isl_keep isl_set *set, int max, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **sol); __isl_give isl_val *isl_basic_set_min_lp_val(__isl_keep isl_basic_set *bset, __isl_keep isl_aff *obj); __isl_give isl_val *isl_basic_set_max_lp_val(__isl_keep isl_basic_set *bset, diff -Nru isl-0.12.2/include/isl/map.h isl-0.15/include/isl/map.h --- isl-0.12.2/include/isl/map.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/map.h 2015-06-11 07:55:31.000000000 +0000 @@ -12,9 +12,7 @@ #include -#include #include -#include #include #include #include @@ -24,6 +22,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -71,14 +70,15 @@ __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s); const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap, enum isl_dim_type type); -int isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type); +isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, + enum isl_dim_type type); const char *isl_map_get_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type); __isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map, enum isl_dim_type type, const char *s); const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos); -int isl_map_has_dim_name(__isl_keep isl_map *map, +isl_bool isl_map_has_dim_name(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos); const char *isl_map_get_dim_name(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos); @@ -88,11 +88,14 @@ __isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map, enum isl_dim_type type, unsigned pos, const char *s); +__isl_give isl_basic_map *isl_basic_map_set_tuple_id( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos); -int isl_map_has_dim_id(__isl_keep isl_map *map, +isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos); @@ -100,10 +103,13 @@ enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map, enum isl_dim_type type); -int isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type); +isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type); __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type); +__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map); +int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, const char *name); int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type, __isl_keep isl_id *id); int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type, @@ -111,19 +117,9 @@ int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap); -struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx, - unsigned nparam, unsigned in, unsigned out, unsigned extra, - unsigned n_eq, unsigned n_ineq); __isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *dim); -struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model); -struct isl_basic_map *isl_basic_map_finalize(struct isl_basic_map *bmap); -void *isl_basic_map_free(__isl_take isl_basic_map *bmap); +__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap); __isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap); -struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base, - unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra, - unsigned n_eq, unsigned n_ineq); -struct isl_basic_map *isl_basic_map_extend_constraints( - struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq); __isl_give isl_basic_map *isl_basic_map_equal( __isl_take isl_space *dim, unsigned n_equal); __isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *dim, @@ -131,18 +127,16 @@ __isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *dim, unsigned pos); __isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *dim); -struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model); -struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model); __isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *dim); __isl_give isl_basic_map *isl_basic_map_nat_universe(__isl_take isl_space *dim); -__isl_give isl_basic_map *isl_basic_map_universe_like( - __isl_keep isl_basic_map *bmap); __isl_give isl_basic_map *isl_basic_map_remove_redundancies( __isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_remove_redundancies(__isl_take isl_map *map); __isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map); __isl_give isl_basic_map *isl_map_unshifted_simple_hull( __isl_take isl_map *map); +__isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list( + __isl_take isl_map *map, __isl_take isl_map_list *list); __isl_export __isl_give isl_basic_map *isl_basic_map_intersect_domain( @@ -156,6 +150,8 @@ __isl_give isl_basic_map *isl_basic_map_intersect( __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_give isl_basic_map *isl_basic_map_list_intersect( + __isl_take isl_basic_map_list *list); __isl_export __isl_give isl_map *isl_basic_map_union( __isl_take isl_basic_map *bmap1, @@ -171,6 +167,10 @@ __isl_export __isl_give isl_basic_map *isl_basic_map_affine_hull( __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma); +__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma); __isl_export __isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap); __isl_give isl_basic_set *isl_basic_map_domain(__isl_take isl_basic_map *bmap); @@ -187,10 +187,8 @@ enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_basic_map *isl_basic_map_from_basic_set( __isl_take isl_basic_set *bset, __isl_take isl_space *dim); -struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap); __isl_export __isl_give isl_basic_map *isl_basic_map_sample(__isl_take isl_basic_map *bmap); -struct isl_basic_map *isl_basic_map_simplify(struct isl_basic_map *bmap); __isl_export __isl_give isl_basic_map *isl_basic_map_detect_equalities( __isl_take isl_basic_map *bmap); @@ -203,13 +201,10 @@ __isl_constructor __isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, const char *str); void isl_basic_map_dump(__isl_keep isl_basic_map *bmap); -void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent, - const char *prefix, const char *suffix, unsigned output_format); void isl_map_dump(__isl_keep isl_map *map); -void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent, - unsigned output_format); __isl_give isl_printer *isl_printer_print_basic_map( __isl_take isl_printer *printer, __isl_keep isl_basic_map *bmap); +__isl_give char *isl_map_to_str(__isl_keep isl_map *map); __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *printer, __isl_keep isl_map *map); __isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap, @@ -226,19 +221,17 @@ struct isl_basic_map *isl_basic_map_sum( struct isl_basic_map *bmap1, struct isl_basic_map *bmap2); struct isl_basic_map *isl_basic_map_neg(struct isl_basic_map *bmap); -struct isl_basic_map *isl_basic_map_floordiv(struct isl_basic_map *bmap, - isl_int d); struct isl_map *isl_map_sum(struct isl_map *map1, struct isl_map *map2); struct isl_map *isl_map_neg(struct isl_map *map); -struct isl_map *isl_map_floordiv(struct isl_map *map, isl_int d); __isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map, __isl_take isl_val *d); __isl_export -int isl_basic_map_is_equal( - __isl_keep isl_basic_map *bmap1, - __isl_keep isl_basic_map *bmap2); +isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); +isl_bool isl_basic_map_is_disjoint(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2); __isl_give isl_map *isl_basic_map_partial_lexmax( __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, @@ -280,38 +273,25 @@ __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map, __isl_keep isl_basic_map *bmap); -int isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap, - enum isl_dim_type type, unsigned pos, isl_int *val); __isl_give isl_val *isl_basic_map_plain_get_val_if_fixed( __isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos); int isl_basic_map_image_is_bounded(__isl_keep isl_basic_map *bmap); -int isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap); -int isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap); -int isl_basic_map_fast_is_empty(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap); __isl_export -int isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap); __isl_export -int isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1, +isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2); -int isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1, +isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2); -struct isl_map *isl_map_alloc(struct isl_ctx *ctx, - unsigned nparam, unsigned in, unsigned out, int n, - unsigned flags); __isl_give isl_map *isl_map_universe(__isl_take isl_space *dim); __isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *dim); __isl_give isl_map *isl_map_empty(__isl_take isl_space *dim); -struct isl_map *isl_map_empty_like(struct isl_map *model); -struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model); -struct isl_map *isl_map_dup(struct isl_map *map); -__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map, - __isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_identity(__isl_take isl_space *dim); -struct isl_map *isl_map_identity_like(struct isl_map *model); -struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model); __isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *dim, unsigned n); __isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *dim, unsigned n); __isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_dim); @@ -320,11 +300,8 @@ __isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *dim, unsigned n); __isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_dim); __isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_dim); -struct isl_map *isl_map_finalize(struct isl_map *map); -void *isl_map_free(__isl_take isl_map *map); +__isl_null isl_map *isl_map_free(__isl_take isl_map *map); __isl_give isl_map *isl_map_copy(__isl_keep isl_map *map); -struct isl_map *isl_map_extend(struct isl_map *base, - unsigned nparam, unsigned n_in, unsigned n_out); __isl_export __isl_give isl_map *isl_map_reverse(__isl_take isl_map *map); __isl_export @@ -351,6 +328,14 @@ __isl_take isl_map *map2); __isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map, __isl_take isl_multi_aff *ma); +__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map, + __isl_take isl_multi_aff *ma); +__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_map *isl_map_preimage_range_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff( + __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa); __isl_give isl_basic_map *isl_basic_map_product( __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); __isl_give isl_map *isl_map_product(__isl_take isl_map *map1, @@ -373,6 +358,14 @@ __isl_take isl_map *map2); __isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1, __isl_take isl_map *map2); +isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map); +isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map); +__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map); +__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map); +__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map); +__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map); +__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map); +__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map); __isl_export __isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1, __isl_take isl_map *map2); @@ -391,8 +384,6 @@ __isl_give isl_map *isl_map_complement(__isl_take isl_map *map); struct isl_map *isl_map_fix_input_si(struct isl_map *map, unsigned input, int value); -__isl_give isl_map *isl_map_fix(__isl_take isl_map *map, - enum isl_dim_type type, unsigned pos, isl_int value); __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, enum isl_dim_type type, unsigned pos, int value); __isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map, @@ -415,7 +406,7 @@ __isl_give isl_basic_map *isl_map_convex_hull(__isl_take isl_map *map); __isl_export __isl_give isl_basic_map *isl_map_polyhedral_hull(__isl_take isl_map *map); -__isl_give isl_basic_map *isl_basic_map_add(__isl_take isl_basic_map *bmap, +__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned n); __isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map, enum isl_dim_type type, unsigned n); @@ -456,6 +447,10 @@ enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); __isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap, enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); +__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); __isl_give isl_map *isl_map_equate(__isl_take isl_map *map, enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, @@ -471,9 +466,9 @@ __isl_give isl_map *isl_set_identity(__isl_take isl_set *set); __isl_export -int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset); __isl_export -int isl_set_is_wrapping(__isl_keep isl_set *set); +isl_bool isl_set_is_wrapping(__isl_keep isl_set *set); __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap); __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map); __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset); @@ -502,6 +497,7 @@ __isl_give isl_set *isl_map_range(__isl_take isl_map *map); __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map); __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map); +__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set); __isl_constructor __isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set); @@ -509,54 +505,54 @@ __isl_take isl_basic_set *bset); __isl_give isl_basic_map *isl_basic_map_from_range( __isl_take isl_basic_set *bset); -struct isl_map *isl_map_from_range(struct isl_set *set); +__isl_give isl_map *isl_map_from_range(__isl_take isl_set *set); __isl_give isl_basic_map *isl_basic_map_from_domain_and_range( __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range); __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain, __isl_take isl_set *range); __isl_give isl_map *isl_map_from_set(__isl_take isl_set *set, __isl_take isl_space *dim); -struct isl_set *isl_set_from_map(struct isl_map *map); __isl_export __isl_give isl_basic_map *isl_map_sample(__isl_take isl_map *map); -int isl_map_plain_is_empty(__isl_keep isl_map *map); -int isl_map_fast_is_empty(__isl_keep isl_map *map); -int isl_map_plain_is_universe(__isl_keep isl_map *map); +isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map); +isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map); __isl_export -int isl_map_is_empty(__isl_keep isl_map *map); +isl_bool isl_map_is_empty(__isl_keep isl_map *map); __isl_export -int isl_map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +isl_bool isl_map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2); __isl_export -int isl_map_is_strict_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); __isl_export -int isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2); __isl_export -int isl_map_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2); -int isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap); -int isl_map_plain_is_single_valued(__isl_keep isl_map *map); +isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); +isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map); __isl_export -int isl_map_is_single_valued(__isl_keep isl_map *map); -int isl_map_plain_is_injective(__isl_keep isl_map *map); +isl_bool isl_map_is_single_valued(__isl_keep isl_map *map); +isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map); __isl_export -int isl_map_is_injective(__isl_keep isl_map *map); +isl_bool isl_map_is_injective(__isl_keep isl_map *map); __isl_export -int isl_map_is_bijective(__isl_keep isl_map *map); +isl_bool isl_map_is_bijective(__isl_keep isl_map *map); int isl_map_is_translation(__isl_keep isl_map *map); int isl_map_has_equal_space(__isl_keep isl_map *map1, __isl_keep isl_map *map2); -int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap); -int isl_map_can_zip(__isl_keep isl_map *map); +isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_can_zip(__isl_keep isl_map *map); __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_zip(__isl_take isl_map *map); -int isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap); -int isl_map_can_curry(__isl_keep isl_map *map); +isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_can_curry(__isl_keep isl_map *map); __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_curry(__isl_take isl_map *map); -int isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap); -int isl_map_can_uncurry(__isl_keep isl_map *map); +isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap); +isl_bool isl_map_can_uncurry(__isl_keep isl_map *map); __isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map); @@ -572,22 +568,18 @@ __isl_take isl_map *map, enum isl_dim_type type, unsigned first, unsigned n); -int isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned first, unsigned n); -int isl_map_involves_dims(__isl_keep isl_map *map, +isl_bool isl_map_involves_dims(__isl_keep isl_map *map, enum isl_dim_type type, unsigned first, unsigned n); void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent); -int isl_map_plain_input_is_fixed(__isl_keep isl_map *map, - unsigned in, isl_int *val); -int isl_map_plain_is_fixed(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos, isl_int *val); -int isl_map_fast_is_fixed(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos, isl_int *val); __isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos); +__isl_give isl_basic_map *isl_basic_map_gist_domain( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *context); __isl_export __isl_give isl_basic_map *isl_basic_map_gist(__isl_take isl_basic_map *bmap, __isl_take isl_basic_map *context); @@ -607,18 +599,18 @@ __isl_export __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map); -int isl_map_plain_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2); -int isl_map_fast_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1, + __isl_keep isl_map *map2); uint32_t isl_map_get_hash(__isl_keep isl_map *map); +int isl_map_n_basic_map(__isl_keep isl_map *map); __isl_export -int isl_map_foreach_basic_map(__isl_keep isl_map *map, - int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user); +isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, + isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user); __isl_give isl_map *isl_set_lifting(__isl_take isl_set *set); -__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp); __isl_give isl_map *isl_map_fixed_power_val(__isl_take isl_map *map, __isl_take isl_val *exp); __isl_give isl_map *isl_map_power(__isl_take isl_map *map, int *exact); @@ -666,10 +658,11 @@ __isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos); +ISL_DECLARE_LIST_FN(basic_map) +ISL_DECLARE_LIST_FN(map) + #if defined(__cplusplus) } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/map_to_basic_set.h isl-0.15/include/isl/map_to_basic_set.h --- isl-0.12.2/include/isl/map_to_basic_set.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/map_to_basic_set.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,13 @@ +#ifndef ISL_MAP_TO_BASIC_SET_H +#define ISL_MAP_TO_BASIC_SET_H + +#include +#include + +#define ISL_KEY_BASE map +#define ISL_VAL_BASE basic_set +#include +#undef ISL_KEY_BASE +#undef ISL_VAL_BASE + +#endif diff -Nru isl-0.12.2/include/isl/map_type.h isl-0.15/include/isl/map_type.h --- isl-0.12.2/include/isl/map_type.h 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/include/isl/map_type.h 2015-06-02 09:28:08.000000000 +0000 @@ -10,8 +10,10 @@ struct __isl_subclass(isl_map) isl_basic_map; typedef struct isl_basic_map isl_basic_map; +ISL_DECLARE_LIST_TYPE(basic_map) struct __isl_subclass(isl_union_map) isl_map; typedef struct isl_map isl_map; +ISL_DECLARE_LIST_TYPE(map) #ifndef isl_basic_set struct __isl_subclass(isl_set) isl_basic_set; diff -Nru isl-0.12.2/include/isl/mat.h isl-0.15/include/isl/mat.h --- isl-0.12.2/include/isl/mat.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/mat.h 2015-04-19 12:02:52.000000000 +0000 @@ -12,9 +12,7 @@ #include -#include #include -#include #include #include @@ -35,15 +33,12 @@ struct isl_mat *isl_mat_identity(struct isl_ctx *ctx, unsigned n_row); __isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat); struct isl_mat *isl_mat_cow(struct isl_mat *mat); -void *isl_mat_free(__isl_take isl_mat *mat); +__isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat); int isl_mat_rows(__isl_keep isl_mat *mat); int isl_mat_cols(__isl_keep isl_mat *mat); -int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v); __isl_give isl_val *isl_mat_get_element_val(__isl_keep isl_mat *mat, int row, int col); -__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat, - int row, int col, isl_int v); __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, int row, int col, int v); __isl_give isl_mat *isl_mat_set_element_val(__isl_take isl_mat *mat, @@ -71,9 +66,6 @@ __isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat); __isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat); -__isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row, - isl_int m); - __isl_give isl_mat *isl_mat_normalize(__isl_take isl_mat *mat); __isl_give isl_mat *isl_mat_normalize_row(__isl_take isl_mat *mat, int row); @@ -96,9 +88,6 @@ __isl_give isl_mat *isl_mat_add_zero_rows(__isl_take isl_mat *mat, unsigned n); void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col); -void isl_mat_col_mul(struct isl_mat *mat, int dst_col, isl_int f, int src_col); -void isl_mat_col_submul(struct isl_mat *mat, - int dst_col, isl_int f, int src_col); struct isl_mat *isl_mat_unimodular_complete(struct isl_mat *M, int row); diff -Nru isl-0.12.2/include/isl/multi.h isl-0.15/include/isl/multi.h --- isl-0.12.2/include/isl/multi.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/multi.h 2015-06-02 09:28:08.000000000 +0000 @@ -3,6 +3,7 @@ #include #include +#include #if defined(__cplusplus) extern "C" { @@ -17,30 +18,48 @@ __isl_keep isl_multi_##BASE *multi); \ __isl_give isl_space *isl_multi_##BASE##_get_domain_space( \ __isl_keep isl_multi_##BASE *multi); \ +int isl_multi_##BASE##_find_dim_by_name( \ + __isl_keep isl_multi_##BASE *multi, \ + enum isl_dim_type type, const char *name); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_from_##BASE##_list( \ __isl_take isl_space *space, __isl_take isl_##BASE##_list *list); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_zero( \ __isl_take isl_space *space); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_copy( \ __isl_keep isl_multi_##BASE *multi); \ -void *isl_multi_##BASE##_free(__isl_take isl_multi_##BASE *multi); \ +__isl_null isl_multi_##BASE *isl_multi_##BASE##_free( \ + __isl_take isl_multi_##BASE *multi); \ +isl_bool isl_multi_##BASE##_plain_is_equal( \ + __isl_keep isl_multi_##BASE *multi1, \ + __isl_keep isl_multi_##BASE *multi2); \ +int isl_multi_##BASE##_find_dim_by_id( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type, \ + __isl_keep isl_id *id); \ +__isl_give isl_id *isl_multi_##BASE##_get_dim_id( \ + __isl_take isl_multi_##BASE *multi, \ + enum isl_dim_type type, unsigned pos); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_dim_name( \ __isl_take isl_multi_##BASE *multi, \ enum isl_dim_type type, unsigned pos, const char *s); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_dim_id( \ + __isl_take isl_multi_##BASE *multi, \ + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); \ const char *isl_multi_##BASE##_get_tuple_name( \ __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ +isl_bool isl_multi_##BASE##_has_tuple_id( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ +__isl_give isl_id *isl_multi_##BASE##_get_tuple_id( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_name( \ __isl_take isl_multi_##BASE *multi, \ enum isl_dim_type type, const char *s); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_id( \ __isl_take isl_multi_##BASE *multi, \ enum isl_dim_type type, __isl_take isl_id *id); \ -__isl_give isl_multi_##BASE *isl_multi_##BASE##_insert_dims( \ - __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ - unsigned first, unsigned n); \ -__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_dims( \ - __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ - unsigned n); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_tuple_id( \ + __isl_take isl_multi_##BASE *multi, enum isl_dim_type type); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_user( \ + __isl_take isl_multi_##BASE *multi); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_drop_dims( \ __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ unsigned first, unsigned n); \ @@ -52,23 +71,64 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_range_splice( \ __isl_take isl_multi_##BASE *multi1, unsigned pos, \ __isl_take isl_multi_##BASE *multi2); \ -__isl_give isl_multi_##BASE *isl_multi_##BASE##_splice( \ - __isl_take isl_multi_##BASE *multi1, unsigned in_pos, \ - unsigned out_pos, __isl_take isl_multi_##BASE *multi2); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_flatten_range( \ + __isl_take isl_multi_##BASE *multi); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_flat_range_product( \ __isl_take isl_multi_##BASE *multi1, \ __isl_take isl_multi_##BASE *multi2); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_range_product( \ __isl_take isl_multi_##BASE *multi1, \ __isl_take isl_multi_##BASE *multi2); \ +isl_bool isl_multi_##BASE##_range_is_wrapping( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_factor_domain( \ + __isl_take isl_multi_##BASE *multi); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_factor_range( \ + __isl_take isl_multi_##BASE *multi); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_val( \ __isl_take isl_multi_##BASE *multi, __isl_take isl_val *v); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_val( \ + __isl_take isl_multi_##BASE *multi, __isl_take isl_val *v); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_multi_val( \ __isl_take isl_multi_##BASE *multi, \ __isl_take isl_multi_val *mv); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_multi_val( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_val *mv); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_mod_multi_val( \ + __isl_take isl_multi_##BASE *multi, \ + __isl_take isl_multi_val *mv); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_sub( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_align_params( \ __isl_take isl_multi_##BASE *multi, \ - __isl_take isl_space *model); + __isl_take isl_space *model); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_from_range( \ + __isl_take isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_NEG(BASE) \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_neg( \ + __isl_take isl_multi_##BASE *multi); + +#define ISL_DECLARE_MULTI_DIMS(BASE) \ +isl_bool isl_multi_##BASE##_involves_dims( \ + __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type, \ + unsigned first, unsigned n); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_insert_dims( \ + __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ + unsigned first, unsigned n); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_dims( \ + __isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \ + unsigned n); + +#define ISL_DECLARE_MULTI_WITH_DOMAIN(BASE) \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_product( \ + __isl_take isl_multi_##BASE *multi1, \ + __isl_take isl_multi_##BASE *multi2); \ +__isl_give isl_multi_##BASE *isl_multi_##BASE##_splice( \ + __isl_take isl_multi_##BASE *multi1, unsigned in_pos, \ + unsigned out_pos, __isl_take isl_multi_##BASE *multi2); #if defined(__cplusplus) } diff -Nru isl-0.12.2/include/isl/obj.h isl-0.15/include/isl/obj.h --- isl-0.12.2/include/isl/obj.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/obj.h 2015-06-02 09:28:08.000000000 +0000 @@ -33,6 +33,8 @@ #define isl_obj_map (&isl_obj_map_vtable) extern struct isl_obj_vtable isl_obj_union_map_vtable; #define isl_obj_union_map (&isl_obj_union_map_vtable) +extern struct isl_obj_vtable isl_obj_pw_multi_aff_vtable; +#define isl_obj_pw_multi_aff (&isl_obj_pw_multi_aff_vtable) extern struct isl_obj_vtable isl_obj_pw_qpolynomial_vtable; #define isl_obj_pw_qpolynomial (&isl_obj_pw_qpolynomial_vtable) extern struct isl_obj_vtable isl_obj_union_pw_qpolynomial_vtable; @@ -41,24 +43,13 @@ #define isl_obj_pw_qpolynomial_fold (&isl_obj_pw_qpolynomial_fold_vtable) extern struct isl_obj_vtable isl_obj_union_pw_qpolynomial_fold_vtable; #define isl_obj_union_pw_qpolynomial_fold (&isl_obj_union_pw_qpolynomial_fold_vtable) +extern struct isl_obj_vtable isl_obj_schedule_vtable; +#define isl_obj_schedule (&isl_obj_schedule_vtable) struct isl_obj { isl_obj_type type; void *v; }; -struct isl_int_obj; -typedef struct isl_int_obj isl_int_obj; - -__isl_give isl_int_obj *isl_int_obj_alloc(isl_ctx *ctx, isl_int v); -void isl_int_obj_free(__isl_take isl_int_obj *i); -__isl_give isl_int_obj *isl_int_obj_add(__isl_take isl_int_obj *i1, - __isl_take isl_int_obj *i2); -__isl_give isl_int_obj *isl_int_obj_sub(__isl_take isl_int_obj *i1, - __isl_take isl_int_obj *i2); -__isl_give isl_int_obj *isl_int_obj_mul(__isl_take isl_int_obj *i1, - __isl_take isl_int_obj *i2); -void isl_int_obj_get_int(__isl_keep isl_int_obj *i, isl_int *v); - #if defined(__cplusplus) } #endif diff -Nru isl-0.12.2/include/isl/options.h isl-0.15/include/isl/options.h --- isl-0.12.2/include/isl/options.h 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/include/isl/options.h 2015-06-02 09:28:08.000000000 +0000 @@ -23,24 +23,24 @@ #define ISL_BOUND_BERNSTEIN 0 #define ISL_BOUND_RANGE 1 -int isl_options_set_bound(isl_ctx *ctx, int val); +isl_stat isl_options_set_bound(isl_ctx *ctx, int val); int isl_options_get_bound(isl_ctx *ctx); #define ISL_ON_ERROR_WARN 0 #define ISL_ON_ERROR_CONTINUE 1 #define ISL_ON_ERROR_ABORT 2 -int isl_options_set_on_error(isl_ctx *ctx, int val); +isl_stat isl_options_set_on_error(isl_ctx *ctx, int val); int isl_options_get_on_error(isl_ctx *ctx); -int isl_options_set_gbr_only_first(isl_ctx *ctx, int val); +isl_stat isl_options_set_gbr_only_first(isl_ctx *ctx, int val); int isl_options_get_gbr_only_first(isl_ctx *ctx); #define ISL_SCHEDULE_ALGORITHM_ISL 0 #define ISL_SCHEDULE_ALGORITHM_FEAUTRIER 1 -int isl_options_set_schedule_algorithm(isl_ctx *ctx, int val); +isl_stat isl_options_set_schedule_algorithm(isl_ctx *ctx, int val); int isl_options_get_schedule_algorithm(isl_ctx *ctx); -int isl_options_set_coalesce_bounded_wrapping(isl_ctx *ctx, int val); +isl_stat isl_options_set_coalesce_bounded_wrapping(isl_ctx *ctx, int val); int isl_options_get_coalesce_bounded_wrapping(isl_ctx *ctx); #if defined(__cplusplus) diff -Nru isl-0.12.2/include/isl/point.h isl-0.15/include/isl/point.h --- isl-0.12.2/include/isl/point.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/point.h 2015-06-02 09:28:08.000000000 +0000 @@ -19,12 +19,8 @@ __isl_give isl_point *isl_point_copy(__isl_keep isl_point *pnt); void isl_point_free(__isl_take isl_point *pnt); -int isl_point_get_coordinate(__isl_keep isl_point *pnt, - enum isl_dim_type type, int pos, isl_int *v); __isl_give isl_val *isl_point_get_coordinate_val(__isl_keep isl_point *pnt, enum isl_dim_type type, int pos); -__isl_give isl_point *isl_point_set_coordinate(__isl_take isl_point *pnt, - enum isl_dim_type type, int pos, isl_int v); __isl_give isl_point *isl_point_set_coordinate_val(__isl_take isl_point *pnt, enum isl_dim_type type, int pos, __isl_take isl_val *v); @@ -34,7 +30,7 @@ enum isl_dim_type type, int pos, unsigned val); __isl_give isl_point *isl_point_void(__isl_take isl_space *dim); -int isl_point_is_void(__isl_keep isl_point *pnt); +isl_bool isl_point_is_void(__isl_keep isl_point *pnt); __isl_give isl_printer *isl_printer_print_point( __isl_take isl_printer *printer, __isl_keep isl_point *pnt); @@ -44,6 +40,4 @@ } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/polynomial.h isl-0.15/include/isl/polynomial.h --- isl-0.12.2/include/isl/polynomial.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/polynomial.h 2015-06-10 18:25:32.000000000 +0000 @@ -22,7 +22,7 @@ __isl_give isl_space *isl_qpolynomial_get_space(__isl_keep isl_qpolynomial *qp); unsigned isl_qpolynomial_dim(__isl_keep isl_qpolynomial *qp, enum isl_dim_type type); -int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp, +isl_bool isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_val *isl_qpolynomial_get_constant_val( @@ -37,25 +37,21 @@ __isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain(__isl_take isl_space *dim); __isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain(__isl_take isl_space *dim); __isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain(__isl_take isl_space *dim); -__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain(__isl_take isl_space *dim, - const isl_int n, const isl_int d); __isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( __isl_take isl_space *space, __isl_take isl_val *val); __isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain(__isl_take isl_space *dim, enum isl_dim_type type, unsigned pos); __isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp); -void *isl_qpolynomial_free(__isl_take isl_qpolynomial *qp); +__isl_null isl_qpolynomial *isl_qpolynomial_free( + __isl_take isl_qpolynomial *qp); -int isl_qpolynomial_plain_is_equal(__isl_keep isl_qpolynomial *qp1, +isl_bool isl_qpolynomial_plain_is_equal(__isl_keep isl_qpolynomial *qp1, __isl_keep isl_qpolynomial *qp2); -int isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp); -int isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp); -int isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp); -int isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp); int isl_qpolynomial_sgn(__isl_keep isl_qpolynomial *qp); -int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp, - isl_int *n, isl_int *d); -void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d); __isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp); __isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1, @@ -66,14 +62,10 @@ __isl_take isl_qpolynomial *qp2); __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_qpolynomial *qp, unsigned power); -__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int( - __isl_take isl_qpolynomial *qp, isl_int v); -__isl_give isl_qpolynomial *isl_qpolynomial_mul_isl_int( - __isl_take isl_qpolynomial *qp, isl_int v); -__isl_give isl_qpolynomial *isl_qpolynomial_scale( - __isl_take isl_qpolynomial *qp, isl_int v); __isl_give isl_qpolynomial *isl_qpolynomial_scale_val( __isl_take isl_qpolynomial *qp, __isl_take isl_val *v); +__isl_give isl_qpolynomial *isl_qpolynomial_scale_down_val( + __isl_take isl_qpolynomial *qp, __isl_take isl_val *v); __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims( __isl_take isl_qpolynomial *qp, enum isl_dim_type type, @@ -112,18 +104,16 @@ void isl_term_free(__isl_take isl_term *term); unsigned isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type); -void isl_term_get_num(__isl_keep isl_term *term, isl_int *n); -void isl_term_get_den(__isl_keep isl_term *term, isl_int *d); __isl_give isl_val *isl_term_get_coefficient_val(__isl_keep isl_term *term); int isl_term_get_exp(__isl_keep isl_term *term, enum isl_dim_type type, unsigned pos); __isl_give isl_aff *isl_term_get_div(__isl_keep isl_term *term, unsigned pos); -int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp, - int (*fn)(__isl_take isl_term *term, void *user), void *user); +isl_stat isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp, + isl_stat (*fn)(__isl_take isl_term *term, void *user), void *user); -__isl_give isl_qpolynomial *isl_qpolynomial_eval( - __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt); +__isl_give isl_val *isl_qpolynomial_eval(__isl_take isl_qpolynomial *qp, + __isl_take isl_point *pnt); __isl_give isl_qpolynomial *isl_qpolynomial_gist_params( __isl_take isl_qpolynomial *qp, __isl_take isl_set *context); @@ -145,7 +135,7 @@ isl_ctx *isl_pw_qpolynomial_get_ctx(__isl_keep isl_pw_qpolynomial *pwqp); -int isl_pw_qpolynomial_plain_is_equal(__isl_keep isl_pw_qpolynomial *pwqp1, +isl_bool isl_pw_qpolynomial_plain_is_equal(__isl_keep isl_pw_qpolynomial *pwqp1, __isl_keep isl_pw_qpolynomial *pwqp2); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero(__isl_take isl_space *dim); @@ -155,9 +145,10 @@ __isl_take isl_qpolynomial *qp); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_copy( __isl_keep isl_pw_qpolynomial *pwqp); -void *isl_pw_qpolynomial_free(__isl_take isl_pw_qpolynomial *pwqp); +__isl_null isl_pw_qpolynomial *isl_pw_qpolynomial_free( + __isl_take isl_pw_qpolynomial *pwqp); -int isl_pw_qpolynomial_is_zero(__isl_keep isl_pw_qpolynomial *pwqp); +isl_bool isl_pw_qpolynomial_is_zero(__isl_keep isl_pw_qpolynomial *pwqp); __isl_give isl_space *isl_pw_qpolynomial_get_domain_space( __isl_keep isl_pw_qpolynomial *pwqp); @@ -167,7 +158,7 @@ __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_space *dim); unsigned isl_pw_qpolynomial_dim(__isl_keep isl_pw_qpolynomial *pwqp, enum isl_dim_type type); -int isl_pw_qpolynomial_involves_dims(__isl_keep isl_pw_qpolynomial *pwqp, +isl_bool isl_pw_qpolynomial_involves_dims(__isl_keep isl_pw_qpolynomial *pwqp, enum isl_dim_type type, unsigned first, unsigned n); int isl_pw_qpolynomial_has_equal_space(__isl_keep isl_pw_qpolynomial *pwqp1, __isl_keep isl_pw_qpolynomial *pwqp2); @@ -176,11 +167,19 @@ __isl_take isl_pw_qpolynomial *pwqp, enum isl_dim_type type, unsigned pos, const char *s); +int isl_pw_qpolynomial_find_dim_by_name(__isl_keep isl_pw_qpolynomial *pwqp, + enum isl_dim_type type, const char *name); + +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_reset_user( + __isl_take isl_pw_qpolynomial *pwqp); + __isl_give isl_set *isl_pw_qpolynomial_domain(__isl_take isl_pw_qpolynomial *pwqp); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_domain( __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_params( __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_subtract_domain( + __isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_project_domain_on_params( __isl_take isl_pw_qpolynomial *pwqp); @@ -205,10 +204,10 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( __isl_take isl_pw_qpolynomial *pwqp1, __isl_take isl_pw_qpolynomial *pwqp2); -__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul_isl_int( - __isl_take isl_pw_qpolynomial *pwqp, isl_int v); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_scale_val( __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_val *v); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_scale_down_val( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_val *v); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( __isl_take isl_pw_qpolynomial *pwqp, unsigned exponent); @@ -223,26 +222,22 @@ enum isl_dim_type dst_type, unsigned dst_pos, enum isl_dim_type src_type, unsigned src_pos, unsigned n); -__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_dim( - __isl_take isl_pw_qpolynomial *pwqp, - enum isl_dim_type type, unsigned n, isl_int v); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_val( __isl_take isl_pw_qpolynomial *pwqp, enum isl_dim_type type, unsigned n, __isl_take isl_val *v); -__isl_give isl_qpolynomial *isl_pw_qpolynomial_eval( +__isl_give isl_val *isl_pw_qpolynomial_eval( __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_point *pnt); -__isl_give isl_qpolynomial *isl_pw_qpolynomial_max( - __isl_take isl_pw_qpolynomial *pwqp); -__isl_give isl_qpolynomial *isl_pw_qpolynomial_min( - __isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_val *isl_pw_qpolynomial_max(__isl_take isl_pw_qpolynomial *pwqp); +__isl_give isl_val *isl_pw_qpolynomial_min(__isl_take isl_pw_qpolynomial *pwqp); -int isl_pw_qpolynomial_foreach_piece(__isl_keep isl_pw_qpolynomial *pwqp, - int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, +isl_stat isl_pw_qpolynomial_foreach_piece(__isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, void *user), void *user); -int isl_pw_qpolynomial_foreach_lifted_piece(__isl_keep isl_pw_qpolynomial *pwqp, - int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, +isl_stat isl_pw_qpolynomial_foreach_lifted_piece( + __isl_keep isl_pw_qpolynomial *pwqp, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, void *user), void *user); __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_pw_aff( @@ -285,6 +280,7 @@ void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold); int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold); +isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold); int isl_qpolynomial_fold_plain_is_equal(__isl_keep isl_qpolynomial_fold *fold1, __isl_keep isl_qpolynomial_fold *fold2); @@ -295,12 +291,10 @@ __isl_take isl_qpolynomial_fold *fold1, __isl_take isl_qpolynomial_fold *fold2); -__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int( - __isl_take isl_qpolynomial_fold *fold, isl_int v); -__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale( - __isl_take isl_qpolynomial_fold *fold, isl_int v); __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_val( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_down_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v); __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims( __isl_take isl_qpolynomial_fold *fold, @@ -312,7 +306,7 @@ enum isl_dim_type type, unsigned first, unsigned n, __isl_keep isl_qpolynomial **subs); -__isl_give isl_qpolynomial *isl_qpolynomial_fold_eval( +__isl_give isl_val *isl_qpolynomial_fold_eval( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt); __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params( @@ -320,9 +314,9 @@ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *context); -int isl_qpolynomial_fold_foreach_qpolynomial( +isl_stat isl_qpolynomial_fold_foreach_qpolynomial( __isl_keep isl_qpolynomial_fold *fold, - int (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user); + isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user); __isl_give isl_printer *isl_printer_print_qpolynomial_fold( __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold); @@ -332,7 +326,7 @@ isl_ctx *isl_pw_qpolynomial_fold_get_ctx(__isl_keep isl_pw_qpolynomial_fold *pwf); -int isl_pw_qpolynomial_fold_plain_is_equal( +isl_bool isl_pw_qpolynomial_fold_plain_is_equal( __isl_keep isl_pw_qpolynomial_fold *pwf1, __isl_keep isl_pw_qpolynomial_fold *pwf2); @@ -344,9 +338,11 @@ __isl_take isl_set *set, __isl_take isl_qpolynomial_fold *fold); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_copy( __isl_keep isl_pw_qpolynomial_fold *pwf); -void *isl_pw_qpolynomial_fold_free(__isl_take isl_pw_qpolynomial_fold *pwf); +__isl_null isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_free( + __isl_take isl_pw_qpolynomial_fold *pwf); -int isl_pw_qpolynomial_fold_is_zero(__isl_keep isl_pw_qpolynomial_fold *pwf); +isl_bool isl_pw_qpolynomial_fold_is_zero( + __isl_keep isl_pw_qpolynomial_fold *pwf); __isl_give isl_space *isl_pw_qpolynomial_fold_get_domain_space( __isl_keep isl_pw_qpolynomial_fold *pwf); @@ -369,12 +365,21 @@ __isl_take isl_pw_qpolynomial_fold *pwf, enum isl_dim_type type, unsigned pos, const char *s); +int isl_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_pw_qpolynomial_fold *pwf, + enum isl_dim_type type, const char *name); + +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_reset_user( + __isl_take isl_pw_qpolynomial_fold *pwf); + __isl_give isl_set *isl_pw_qpolynomial_fold_domain( __isl_take isl_pw_qpolynomial_fold *pwf); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_intersect_domain( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_intersect_params( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( __isl_take isl_pw_qpolynomial_fold *pwf1, @@ -385,10 +390,10 @@ __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add_disjoint( __isl_take isl_pw_qpolynomial_fold *pwf1, __isl_take isl_pw_qpolynomial_fold *pwf2); -__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_mul_isl_int( - __isl_take isl_pw_qpolynomial_fold *pwf, isl_int v); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_scale_val( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_val *v); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_val *v); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_project_domain_on_params( __isl_take isl_pw_qpolynomial_fold *pwf); @@ -400,21 +405,17 @@ enum isl_dim_type dst_type, unsigned dst_pos, enum isl_dim_type src_type, unsigned src_pos, unsigned n); -__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fix_dim( - __isl_take isl_pw_qpolynomial_fold *pwf, - enum isl_dim_type type, unsigned n, isl_int v); - -__isl_give isl_qpolynomial *isl_pw_qpolynomial_fold_eval( +__isl_give isl_val *isl_pw_qpolynomial_fold_eval( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_point *pnt); -int isl_pw_qpolynomial_fold_foreach_piece( +isl_stat isl_pw_qpolynomial_fold_foreach_piece( __isl_keep isl_pw_qpolynomial_fold *pwf, - int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial_fold *fold, - void *user), void *user); -int isl_pw_qpolynomial_fold_foreach_lifted_piece( + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, void *user), void *user); +isl_stat isl_pw_qpolynomial_fold_foreach_lifted_piece( __isl_keep isl_pw_qpolynomial_fold *pwf, - int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial_fold *fold, - void *user), void *user); + isl_stat (*fn)(__isl_take isl_set *set, + __isl_take isl_qpolynomial_fold *fold, void *user), void *user); __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold( __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf); @@ -429,9 +430,9 @@ __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_gist_params( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *context); -__isl_give isl_qpolynomial *isl_pw_qpolynomial_fold_max( +__isl_give isl_val *isl_pw_qpolynomial_fold_max( __isl_take isl_pw_qpolynomial_fold *pwf); -__isl_give isl_qpolynomial *isl_pw_qpolynomial_fold_min( +__isl_give isl_val *isl_pw_qpolynomial_fold_min( __isl_take isl_pw_qpolynomial_fold *pwf); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_bound( @@ -451,7 +452,10 @@ isl_ctx *isl_union_pw_qpolynomial_get_ctx( __isl_keep isl_union_pw_qpolynomial *upwqp); -int isl_union_pw_qpolynomial_plain_is_equal( +unsigned isl_union_pw_qpolynomial_dim( + __isl_keep isl_union_pw_qpolynomial *upwqp, enum isl_dim_type type); + +isl_bool isl_union_pw_qpolynomial_plain_is_equal( __isl_keep isl_union_pw_qpolynomial *upwqp1, __isl_keep isl_union_pw_qpolynomial *upwqp2); @@ -463,12 +467,16 @@ __isl_take isl_pw_qpolynomial *pwqp); __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_copy( __isl_keep isl_union_pw_qpolynomial *upwqp); -void *isl_union_pw_qpolynomial_free(__isl_take isl_union_pw_qpolynomial *upwqp); +__isl_null isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_free( + __isl_take isl_union_pw_qpolynomial *upwqp); __isl_constructor __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_read_from_str( isl_ctx *ctx, const char *str); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg( + __isl_take isl_union_pw_qpolynomial *upwqp); + __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add( __isl_take isl_union_pw_qpolynomial *upwqp1, __isl_take isl_union_pw_qpolynomial *upwqp2); @@ -478,10 +486,10 @@ __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( __isl_take isl_union_pw_qpolynomial *upwqp1, __isl_take isl_union_pw_qpolynomial *upwqp2); -__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul_isl_int( - __isl_take isl_union_pw_qpolynomial *upwqp, isl_int v); __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_scale_val( __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_val *v); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_scale_down_val( + __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_val *v); __isl_give isl_union_set *isl_union_pw_qpolynomial_domain( __isl_take isl_union_pw_qpolynomial *upwqp); @@ -491,11 +499,28 @@ __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_intersect_params( __isl_take isl_union_pw_qpolynomial *upwpq, __isl_take isl_set *set); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_subtract_domain( + __isl_take isl_union_pw_qpolynomial *upwpq, + __isl_take isl_union_set *uset); __isl_give isl_space *isl_union_pw_qpolynomial_get_space( __isl_keep isl_union_pw_qpolynomial *upwqp); -__isl_give isl_qpolynomial *isl_union_pw_qpolynomial_eval( +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_set_dim_name( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_union_pw_qpolynomial_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, const char *name); + +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_drop_dims( + __isl_take isl_union_pw_qpolynomial *upwqp, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_reset_user( + __isl_take isl_union_pw_qpolynomial *upwqp); + +__isl_give isl_val *isl_union_pw_qpolynomial_eval( __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_point *pnt); __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_coalesce( @@ -511,9 +536,12 @@ __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_space *model); -int isl_union_pw_qpolynomial_foreach_pw_qpolynomial( +int isl_union_pw_qpolynomial_n_pw_qpolynomial( + __isl_keep isl_union_pw_qpolynomial *upwqp); +isl_stat isl_union_pw_qpolynomial_foreach_pw_qpolynomial( __isl_keep isl_union_pw_qpolynomial *upwqp, - int (*fn)(__isl_take isl_pw_qpolynomial *pwqp, void *user), void *user); + isl_stat (*fn)(__isl_take isl_pw_qpolynomial *pwqp, void *user), + void *user); __isl_give isl_pw_qpolynomial *isl_union_pw_qpolynomial_extract_pw_qpolynomial( __isl_keep isl_union_pw_qpolynomial *upwqp, __isl_take isl_space *dim); @@ -523,7 +551,10 @@ isl_ctx *isl_union_pw_qpolynomial_fold_get_ctx( __isl_keep isl_union_pw_qpolynomial_fold *upwf); -int isl_union_pw_qpolynomial_fold_plain_is_equal( +unsigned isl_union_pw_qpolynomial_fold_dim( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, enum isl_dim_type type); + +isl_bool isl_union_pw_qpolynomial_fold_plain_is_equal( __isl_keep isl_union_pw_qpolynomial_fold *upwf1, __isl_keep isl_union_pw_qpolynomial_fold *upwf2); @@ -533,7 +564,7 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( __isl_take isl_union_pw_qpolynomial_fold *upwqp, __isl_take isl_pw_qpolynomial_fold *pwqp); -void *isl_union_pw_qpolynomial_fold_free( +__isl_null isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_free( __isl_take isl_union_pw_qpolynomial_fold *upwf); __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_copy( __isl_keep isl_union_pw_qpolynomial_fold *upwf); @@ -544,11 +575,12 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial( __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_union_pw_qpolynomial *upwqp); -__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_mul_isl_int( - __isl_take isl_union_pw_qpolynomial_fold *upwf, isl_int v); __isl_give isl_union_pw_qpolynomial_fold * isl_union_pw_qpolynomial_fold_scale_val( __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_val *v); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_scale_down_val( + __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_val *v); __isl_give isl_union_set *isl_union_pw_qpolynomial_fold_domain( __isl_take isl_union_pw_qpolynomial_fold *upwf); @@ -559,13 +591,34 @@ isl_union_pw_qpolynomial_fold_intersect_params( __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_set *set); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_subtract_domain( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_union_set *uset); enum isl_fold isl_union_pw_qpolynomial_fold_get_type( __isl_keep isl_union_pw_qpolynomial_fold *upwf); __isl_give isl_space *isl_union_pw_qpolynomial_fold_get_space( __isl_keep isl_union_pw_qpolynomial_fold *upwf); -__isl_give isl_qpolynomial *isl_union_pw_qpolynomial_fold_eval( +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_set_dim_name( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, unsigned pos, const char *s); + +int isl_union_pw_qpolynomial_fold_find_dim_by_name( + __isl_keep isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, const char *name); + +__isl_give isl_union_pw_qpolynomial_fold * + isl_union_pw_qpolynomial_fold_drop_dims( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_reset_user( + __isl_take isl_union_pw_qpolynomial_fold *upwf); + +__isl_give isl_val *isl_union_pw_qpolynomial_fold_eval( __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_point *pnt); @@ -583,9 +636,11 @@ __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_space *model); -int isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( +int isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold( + __isl_keep isl_union_pw_qpolynomial_fold *upwf); +isl_stat isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( __isl_keep isl_union_pw_qpolynomial_fold *upwf, - int (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, + isl_stat (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, void *user), void *user); __isl_give isl_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_extract_pw_qpolynomial_fold( __isl_keep isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_space *dim); @@ -611,6 +666,4 @@ } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/printer.h isl-0.15/include/isl/printer.h --- isl-0.12.2/include/isl/printer.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/printer.h 2015-06-02 09:28:08.000000000 +0000 @@ -13,7 +13,7 @@ __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file); __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx); -void *isl_printer_free(__isl_take isl_printer *printer); +__isl_null isl_printer *isl_printer_free(__isl_take isl_printer *printer); isl_ctx *isl_printer_get_ctx(__isl_keep isl_printer *printer); FILE *isl_printer_get_file(__isl_keep isl_printer *printer); @@ -36,6 +36,14 @@ int output_format); int isl_printer_get_output_format(__isl_keep isl_printer *p); +#define ISL_YAML_STYLE_BLOCK 0 +#define ISL_YAML_STYLE_FLOW 1 +__isl_give isl_printer *isl_printer_set_yaml_style(__isl_take isl_printer *p, + int yaml_style); +int isl_printer_get_yaml_style(__isl_keep isl_printer *p); + +__isl_give isl_printer *isl_printer_set_indent_prefix(__isl_take isl_printer *p, + const char *prefix); __isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p, const char *prefix); __isl_give isl_printer *isl_printer_set_suffix(__isl_take isl_printer *p, @@ -48,11 +56,19 @@ __isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p, double d); __isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i); -__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p, - isl_int i); __isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p, const char *s); +__isl_give isl_printer *isl_printer_yaml_start_mapping( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_end_mapping( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_start_sequence( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_end_sequence( + __isl_take isl_printer *p); +__isl_give isl_printer *isl_printer_yaml_next(__isl_take isl_printer *p); + __isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p); #if defined(__cplusplus) diff -Nru isl-0.12.2/include/isl/schedule.h isl-0.15/include/isl/schedule.h --- isl-0.12.2/include/isl/schedule.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/schedule.h 2015-06-10 18:25:32.000000000 +0000 @@ -3,51 +3,139 @@ #include #include +#include +#include #include +#include +#include #include #if defined(__cplusplus) extern "C" { #endif -struct isl_schedule; -typedef struct isl_schedule isl_schedule; +struct isl_schedule_constraints; +typedef struct isl_schedule_constraints isl_schedule_constraints; -int isl_options_set_schedule_max_coefficient(isl_ctx *ctx, int val); +isl_stat isl_options_set_schedule_max_coefficient(isl_ctx *ctx, int val); int isl_options_get_schedule_max_coefficient(isl_ctx *ctx); -int isl_options_set_schedule_max_constant_term(isl_ctx *ctx, int val); +isl_stat isl_options_set_schedule_max_constant_term(isl_ctx *ctx, int val); int isl_options_get_schedule_max_constant_term(isl_ctx *ctx); -int isl_options_set_schedule_maximize_band_depth(isl_ctx *ctx, int val); +isl_stat isl_options_set_schedule_maximize_band_depth(isl_ctx *ctx, int val); int isl_options_get_schedule_maximize_band_depth(isl_ctx *ctx); -int isl_options_set_schedule_outer_zero_distance(isl_ctx *ctx, int val); -int isl_options_get_schedule_outer_zero_distance(isl_ctx *ctx); +isl_stat isl_options_set_schedule_outer_coincidence(isl_ctx *ctx, int val); +int isl_options_get_schedule_outer_coincidence(isl_ctx *ctx); -int isl_options_set_schedule_split_scaled(isl_ctx *ctx, int val); +isl_stat isl_options_set_schedule_split_scaled(isl_ctx *ctx, int val); int isl_options_get_schedule_split_scaled(isl_ctx *ctx); -int isl_options_set_schedule_separate_components(isl_ctx *ctx, int val); +isl_stat isl_options_set_schedule_separate_components(isl_ctx *ctx, int val); int isl_options_get_schedule_separate_components(isl_ctx *ctx); -#define ISL_SCHEDULE_FUSE_MAX 0 -#define ISL_SCHEDULE_FUSE_MIN 1 -int isl_options_set_schedule_fuse(isl_ctx *ctx, int val); -int isl_options_get_schedule_fuse(isl_ctx *ctx); +isl_stat isl_options_set_schedule_serialize_sccs(isl_ctx *ctx, int val); +int isl_options_get_schedule_serialize_sccs(isl_ctx *ctx); + +__isl_give isl_schedule_constraints *isl_schedule_constraints_copy( + __isl_keep isl_schedule_constraints *sc); +__isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain( + __isl_take isl_union_set *domain); +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_context( + __isl_take isl_schedule_constraints *sc, __isl_take isl_set *context); +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *validity); +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_coincidence( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *coincidence); +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_proximity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *proximity); +__isl_give isl_schedule_constraints * +isl_schedule_constraints_set_conditional_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *condition, + __isl_take isl_union_map *validity); +__isl_null isl_schedule_constraints *isl_schedule_constraints_free( + __isl_take isl_schedule_constraints *sc); + +isl_ctx *isl_schedule_constraints_get_ctx( + __isl_keep isl_schedule_constraints *sc); +__isl_give isl_union_map *isl_schedule_constraints_get_validity( + __isl_keep isl_schedule_constraints *sc); +__isl_give isl_union_map *isl_schedule_constraints_get_coincidence( + __isl_keep isl_schedule_constraints *sc); +__isl_give isl_union_map *isl_schedule_constraints_get_conditional_validity( + __isl_keep isl_schedule_constraints *sc); +__isl_give isl_union_map * +isl_schedule_constraints_get_conditional_validity_condition( + __isl_keep isl_schedule_constraints *sc); + +void isl_schedule_constraints_dump(__isl_keep isl_schedule_constraints *sc); + +__isl_give isl_schedule *isl_schedule_constraints_compute_schedule( + __isl_take isl_schedule_constraints *sc); __isl_give isl_schedule *isl_union_set_compute_schedule( __isl_take isl_union_set *domain, __isl_take isl_union_map *validity, __isl_take isl_union_map *proximity); -void *isl_schedule_free(__isl_take isl_schedule *sched); + +__isl_give isl_schedule *isl_schedule_empty(__isl_take isl_space *space); +__isl_give isl_schedule *isl_schedule_from_domain( + __isl_take isl_union_set *domain); +__isl_give isl_schedule *isl_schedule_copy(__isl_keep isl_schedule *sched); +__isl_null isl_schedule *isl_schedule_free(__isl_take isl_schedule *sched); __isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched); isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *sched); +isl_bool isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1, + __isl_keep isl_schedule *schedule2); + +__isl_give isl_schedule_node *isl_schedule_get_root( + __isl_keep isl_schedule *schedule); +__isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule); + +isl_stat isl_schedule_foreach_schedule_node_top_down( + __isl_keep isl_schedule *sched, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user); +__isl_give isl_schedule *isl_schedule_map_schedule_node_bottom_up( + __isl_take isl_schedule *schedule, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, void *user), void *user); + +__isl_give isl_schedule *isl_schedule_insert_context( + __isl_take isl_schedule *schedule, __isl_take isl_set *context); +__isl_give isl_schedule *isl_schedule_insert_partial_schedule( + __isl_take isl_schedule *schedule, + __isl_take isl_multi_union_pw_aff *partial); +__isl_give isl_schedule *isl_schedule_insert_guard( + __isl_take isl_schedule *schedule, __isl_take isl_set *guard); +__isl_give isl_schedule *isl_schedule_sequence( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2); +__isl_give isl_schedule *isl_schedule_set( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2); +__isl_give isl_schedule *isl_schedule_intersect_domain( + __isl_take isl_schedule *schedule, __isl_take isl_union_set *domain); + +__isl_give isl_schedule *isl_schedule_reset_user( + __isl_take isl_schedule *schedule); +__isl_give isl_schedule *isl_schedule_align_params( + __isl_take isl_schedule *schedule, __isl_take isl_space *space); +__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma); __isl_give isl_band_list *isl_schedule_get_band_forest( __isl_keep isl_schedule *schedule); +__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input); +__isl_give isl_schedule *isl_schedule_read_from_str(isl_ctx *ctx, + const char *str); __isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p, __isl_keep isl_schedule *schedule); void isl_schedule_dump(__isl_keep isl_schedule *schedule); diff -Nru isl-0.12.2/include/isl/schedule_node.h isl-0.15/include/isl/schedule_node.h --- isl-0.12.2/include/isl/schedule_node.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/schedule_node.h 2015-06-02 09:28:09.000000000 +0000 @@ -0,0 +1,218 @@ +#ifndef ISL_SCHEDULE_NODE_H +#define ISL_SCHEDULE_NODE_H + +#include +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +__isl_give isl_schedule_node *isl_schedule_node_from_domain( + __isl_take isl_union_set *domain); +__isl_give isl_schedule_node *isl_schedule_node_from_extension( + __isl_take isl_union_map *extension); +__isl_give isl_schedule_node *isl_schedule_node_copy( + __isl_keep isl_schedule_node *node); +__isl_null isl_schedule_node *isl_schedule_node_free( + __isl_take isl_schedule_node *node); + +isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +isl_ctx *isl_schedule_node_get_ctx(__isl_keep isl_schedule_node *node); +enum isl_schedule_node_type isl_schedule_node_get_type( + __isl_keep isl_schedule_node *node); +enum isl_schedule_node_type isl_schedule_node_get_parent_type( + __isl_keep isl_schedule_node *node); +__isl_give isl_schedule *isl_schedule_node_get_schedule( + __isl_keep isl_schedule_node *node); + +isl_stat isl_schedule_node_foreach_descendant_top_down( + __isl_keep isl_schedule_node *node, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user); +isl_stat isl_schedule_node_foreach_ancestor_top_down( + __isl_keep isl_schedule_node *node, + isl_stat (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user); +__isl_give isl_schedule_node *isl_schedule_node_map_descendant_bottom_up( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, + void *user), void *user); + +int isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node); +isl_bool isl_schedule_node_has_parent(__isl_keep isl_schedule_node *node); +isl_bool isl_schedule_node_has_children(__isl_keep isl_schedule_node *node); +isl_bool isl_schedule_node_has_previous_sibling( + __isl_keep isl_schedule_node *node); +isl_bool isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node); +int isl_schedule_node_n_children(__isl_keep isl_schedule_node *node); +int isl_schedule_node_get_child_position(__isl_keep isl_schedule_node *node); +int isl_schedule_node_get_ancestor_child_position( + __isl_keep isl_schedule_node *node, + __isl_keep isl_schedule_node *ancestor); +__isl_give isl_schedule_node *isl_schedule_node_get_child( + __isl_keep isl_schedule_node *node, int pos); +__isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2); + +__isl_give isl_schedule_node *isl_schedule_node_root( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_parent( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_ancestor( + __isl_take isl_schedule_node *node, int generation); +__isl_give isl_schedule_node *isl_schedule_node_child( + __isl_take isl_schedule_node *node, int pos); +__isl_give isl_schedule_node *isl_schedule_node_first_child( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_previous_sibling( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_next_sibling( + __isl_take isl_schedule_node *node); + +isl_bool isl_schedule_node_is_subtree_anchored( + __isl_keep isl_schedule_node *node); + +__isl_give isl_schedule_node *isl_schedule_node_group( + __isl_take isl_schedule_node *node, __isl_take isl_id *group_id); + +__isl_give isl_space *isl_schedule_node_band_get_space( + __isl_keep isl_schedule_node *node); +__isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map( + __isl_keep isl_schedule_node *node); +enum isl_ast_loop_type isl_schedule_node_band_member_get_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); +enum isl_ast_loop_type isl_schedule_node_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos); +__isl_give isl_schedule_node * +isl_schedule_node_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type); +__isl_give isl_union_set *isl_schedule_node_band_get_ast_build_options( + __isl_keep isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_band_set_ast_build_options( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *options); +unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node); +isl_bool isl_schedule_node_band_member_get_coincident( + __isl_keep isl_schedule_node *node, int pos); +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_coincident( + __isl_take isl_schedule_node *node, int pos, int coincident); +isl_bool isl_schedule_node_band_get_permutable( + __isl_keep isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_band_set_permutable( + __isl_take isl_schedule_node *node, int permutable); + +isl_stat isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, int val); +int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx); +isl_stat isl_options_set_tile_shift_point_loops(isl_ctx *ctx, int val); +int isl_options_get_tile_shift_point_loops(isl_ctx *ctx); + +__isl_give isl_schedule_node *isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_node *isl_schedule_node_band_scale_down( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_node *isl_schedule_node_band_tile( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_node *isl_schedule_node_band_sink( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_band_split( + __isl_take isl_schedule_node *node, int pos); + +__isl_give isl_set *isl_schedule_node_context_get_context( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_set *isl_schedule_node_domain_get_domain( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_expansion_get_expansion( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_pw_multi_aff *isl_schedule_node_expansion_get_contraction( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_extension_get_extension( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_set *isl_schedule_node_filter_get_filter( + __isl_keep isl_schedule_node *node); +__isl_give isl_set *isl_schedule_node_guard_get_guard( + __isl_keep isl_schedule_node *node); +__isl_give isl_id *isl_schedule_node_mark_get_id( + __isl_keep isl_schedule_node *node); + +int isl_schedule_node_get_schedule_depth(__isl_keep isl_schedule_node *node); +__isl_give isl_union_set *isl_schedule_node_get_domain( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_set *isl_schedule_node_get_universe_domain( + __isl_keep isl_schedule_node *node); +__isl_give isl_multi_union_pw_aff * +isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_pw_multi_aff * +isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_subtree_schedule_union_map( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_map *isl_schedule_node_get_subtree_expansion( + __isl_keep isl_schedule_node *node); +__isl_give isl_union_pw_multi_aff *isl_schedule_node_get_subtree_contraction( + __isl_keep isl_schedule_node *node); + +__isl_give isl_schedule_node *isl_schedule_node_insert_context( + __isl_take isl_schedule_node *node, __isl_take isl_set *context); +__isl_give isl_schedule_node *isl_schedule_node_insert_partial_schedule( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *schedule); +__isl_give isl_schedule_node *isl_schedule_node_insert_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter); +__isl_give isl_schedule_node *isl_schedule_node_insert_guard( + __isl_take isl_schedule_node *node, __isl_take isl_set *context); +__isl_give isl_schedule_node *isl_schedule_node_insert_mark( + __isl_take isl_schedule_node *node, __isl_take isl_id *mark); +__isl_give isl_schedule_node *isl_schedule_node_insert_sequence( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); +__isl_give isl_schedule_node *isl_schedule_node_insert_set( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters); + +__isl_give isl_schedule_node *isl_schedule_node_cut( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_delete( + __isl_take isl_schedule_node *node); + +__isl_give isl_schedule_node *isl_schedule_node_order_after( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter); + +__isl_give isl_schedule_node *isl_schedule_node_graft_before( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); +__isl_give isl_schedule_node *isl_schedule_node_graft_after( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft); + +__isl_give isl_schedule_node *isl_schedule_node_reset_user( + __isl_take isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_align_params( + __isl_take isl_schedule_node *node, __isl_take isl_space *space); + +__isl_give isl_printer *isl_printer_print_schedule_node( + __isl_take isl_printer *p, __isl_keep isl_schedule_node *node); +void isl_schedule_node_dump(__isl_keep isl_schedule_node *node); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/schedule_type.h isl-0.15/include/isl/schedule_type.h --- isl-0.12.2/include/isl/schedule_type.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/include/isl/schedule_type.h 2015-06-02 09:28:09.000000000 +0000 @@ -0,0 +1,33 @@ +#ifndef ISL_SCHEDULE_TYPE_H +#define ISL_SCHEDULE_TYPE_H + +#if defined(__cplusplus) +extern "C" { +#endif + +enum isl_schedule_node_type { + isl_schedule_node_error = -1, + isl_schedule_node_band, + isl_schedule_node_context, + isl_schedule_node_domain, + isl_schedule_node_expansion, + isl_schedule_node_extension, + isl_schedule_node_filter, + isl_schedule_node_leaf, + isl_schedule_node_guard, + isl_schedule_node_mark, + isl_schedule_node_sequence, + isl_schedule_node_set +}; + +struct isl_schedule_node; +typedef struct isl_schedule_node isl_schedule_node; + +struct isl_schedule; +typedef struct isl_schedule isl_schedule; + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/include/isl/seq.h isl-0.15/include/isl/seq.h --- isl-0.12.2/include/isl/seq.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/seq.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - * 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_SEQ_H -#define ISL_SEQ_H - -#include -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Some common operations on sequences of isl_int's */ - -void isl_seq_clr(isl_int *p, unsigned len); -void isl_seq_set(isl_int *p, isl_int v, unsigned len); -void isl_seq_set_si(isl_int *p, int v, unsigned len); -void isl_seq_neg(isl_int *dat, isl_int *src, unsigned len); -void isl_seq_cpy(isl_int *dst, isl_int *src, unsigned len); -void isl_seq_addmul(isl_int *dst, isl_int f, isl_int *src, unsigned len); -void isl_seq_submul(isl_int *dst, isl_int f, isl_int *src, unsigned len); -void isl_seq_swp_or_cpy(isl_int *dst, isl_int *src, unsigned len); -void isl_seq_scale(isl_int *dst, isl_int *src, isl_int f, unsigned len); -void isl_seq_scale_down(isl_int *dst, isl_int *src, isl_int f, unsigned len); -void isl_seq_cdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len); -void isl_seq_fdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len); -void isl_seq_fdiv_r(isl_int *dst, isl_int *src, isl_int m, unsigned len); -void isl_seq_combine(isl_int *dst, isl_int m1, isl_int *src1, - isl_int m2, isl_int *src2, unsigned len); -void isl_seq_elim(isl_int *dst, isl_int *src, unsigned pos, unsigned len, - isl_int *m); -void isl_seq_abs_max(isl_int *p, unsigned len, isl_int *max); -void isl_seq_gcd(isl_int *p, unsigned len, isl_int *gcd); -void isl_seq_lcm(isl_int *p, unsigned len, isl_int *lcm); -void isl_seq_normalize(struct isl_ctx *ctx, isl_int *p, unsigned len); -void isl_seq_inner_product(isl_int *p1, isl_int *p2, unsigned len, - isl_int *prod); -int isl_seq_first_non_zero(isl_int *p, unsigned len); -int isl_seq_last_non_zero(isl_int *p, unsigned len); -int isl_seq_abs_min_non_zero(isl_int *p, unsigned len); -int isl_seq_eq(isl_int *p1, isl_int *p2, unsigned len); -int isl_seq_cmp(isl_int *p1, isl_int *p2, unsigned len); -int isl_seq_is_neg(isl_int *p1, isl_int *p2, unsigned len); - -uint32_t isl_seq_get_hash(isl_int *p, unsigned len); -uint32_t isl_seq_get_hash_bits(isl_int *p, unsigned len, unsigned bits); - -#if defined(__cplusplus) -} -#endif - -#endif diff -Nru isl-0.12.2/include/isl/set.h isl-0.15/include/isl/set.h --- isl-0.12.2/include/isl/set.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/set.h 2015-06-10 19:13:19.000000000 +0000 @@ -17,6 +17,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -46,7 +47,7 @@ __isl_keep isl_basic_set *bset); const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset); -int isl_set_has_tuple_name(__isl_keep isl_set *set); +isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set); const char *isl_set_get_tuple_name(__isl_keep isl_set *set); __isl_give isl_basic_set *isl_basic_set_set_tuple_name( __isl_take isl_basic_set *set, const char *s); @@ -57,7 +58,7 @@ __isl_give isl_basic_set *isl_basic_set_set_dim_name( __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, const char *s); -int isl_set_has_dim_name(__isl_keep isl_set *set, +isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); const char *isl_set_get_dim_name(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); @@ -66,17 +67,20 @@ __isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos); +__isl_give isl_basic_set *isl_basic_set_set_tuple_id( + __isl_take isl_basic_set *bset, __isl_take isl_id *id); __isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_set_has_dim_id(__isl_keep isl_set *set, +isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); __isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set, __isl_take isl_id *id); __isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set); -int isl_set_has_tuple_id(__isl_keep isl_set *set); +isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set); __isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set); +__isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set); int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type, __isl_keep isl_id *id); @@ -85,27 +89,11 @@ int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset); -struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx, - unsigned nparam, unsigned dim, unsigned extra, - unsigned n_eq, unsigned n_ineq); -struct isl_basic_set *isl_basic_set_extend(struct isl_basic_set *base, - unsigned nparam, unsigned dim, unsigned extra, - unsigned n_eq, unsigned n_ineq); -struct isl_basic_set *isl_basic_set_extend_constraints( - struct isl_basic_set *base, unsigned n_eq, unsigned n_ineq); -struct isl_basic_set *isl_basic_set_finalize(struct isl_basic_set *bset); -void *isl_basic_set_free(__isl_take isl_basic_set *bset); +__isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset); __isl_give isl_basic_set *isl_basic_set_copy(__isl_keep isl_basic_set *bset); -struct isl_basic_set *isl_basic_set_dup(struct isl_basic_set *bset); __isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *dim); -struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *bset); __isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *dim); __isl_give isl_basic_set *isl_basic_set_nat_universe(__isl_take isl_space *dim); -struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *bset); -__isl_give isl_basic_set *isl_basic_set_universe_like_set( - __isl_keep isl_set *model); -struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx, - isl_int min, isl_int max); __isl_give isl_basic_set *isl_basic_set_positive_orthant( __isl_take isl_space *space); void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset, @@ -131,13 +119,14 @@ enum isl_dim_type type, unsigned first, unsigned n); __isl_export __isl_give isl_basic_set *isl_basic_set_sample(__isl_take isl_basic_set *bset); -struct isl_basic_set *isl_basic_set_simplify(struct isl_basic_set *bset); __isl_export __isl_give isl_basic_set *isl_basic_set_detect_equalities( __isl_take isl_basic_set *bset); __isl_give isl_basic_set *isl_basic_set_remove_redundancies( __isl_take isl_basic_set *bset); __isl_give isl_set *isl_set_remove_redundancies(__isl_take isl_set *set); +__isl_give isl_basic_set *isl_basic_set_list_intersect( + __isl_take struct isl_basic_set_list *list); __isl_give isl_basic_set *isl_basic_set_list_product( __isl_take struct isl_basic_set_list *list); @@ -155,12 +144,6 @@ __isl_take isl_printer *printer, __isl_keep isl_basic_set *bset); __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *printer, __isl_keep isl_set *map); -void isl_basic_set_print(__isl_keep isl_basic_set *bset, FILE *out, int indent, - const char *prefix, const char *suffix, unsigned output_format); -void isl_set_print(__isl_keep struct isl_set *set, FILE *out, int indent, - unsigned output_format); -__isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset, - enum isl_dim_type type, unsigned pos, isl_int value); __isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, int value); __isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset, @@ -169,29 +152,21 @@ enum isl_dim_type type, unsigned pos, int value); __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, int value); -__isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, isl_int value); __isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); __isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, int value); -__isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, isl_int value); __isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); __isl_give isl_set *isl_set_equate(__isl_take isl_set *set, enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2); -struct isl_basic_set *isl_basic_set_from_underlying_set( - struct isl_basic_set *bset, struct isl_basic_set *like); -struct isl_set *isl_set_from_underlying_set( - struct isl_set *set, struct isl_basic_set *like); -struct isl_set *isl_set_to_underlying_set(struct isl_set *set); - __isl_export -int isl_basic_set_is_equal( - struct isl_basic_set *bset1, struct isl_basic_set *bset2); +isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); +isl_bool isl_basic_set_is_disjoint(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); __isl_give isl_set *isl_basic_set_partial_lexmin( __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom, @@ -243,31 +218,22 @@ int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos, unsigned n, int *signs); -int isl_basic_set_is_universe(__isl_keep isl_basic_set *bset); -int isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset); -int isl_basic_set_fast_is_empty(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset); __isl_export -int isl_basic_set_is_empty(__isl_keep isl_basic_set *bset); +isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset); int isl_basic_set_is_bounded(__isl_keep isl_basic_set *bset); __isl_export -int isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1, +isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2); +isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2); -struct isl_set *isl_set_alloc(struct isl_ctx *ctx, - unsigned nparam, unsigned dim, int n, unsigned flags); -struct isl_set *isl_set_extend(struct isl_set *base, - unsigned nparam, unsigned dim); __isl_give isl_set *isl_set_empty(__isl_take isl_space *dim); -struct isl_set *isl_set_empty_like(struct isl_set *set); __isl_give isl_set *isl_set_universe(__isl_take isl_space *dim); __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *dim); -__isl_give isl_set *isl_set_universe_like(__isl_keep isl_set *model); -__isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set, - __isl_take isl_basic_set *bset); -struct isl_set *isl_set_finalize(struct isl_set *set); __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set); -void *isl_set_free(__isl_take isl_set *set); -struct isl_set *isl_set_dup(struct isl_set *set); +__isl_null isl_set *isl_set_free(__isl_take isl_set *set); __isl_constructor __isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset); __isl_export @@ -284,6 +250,8 @@ __isl_give isl_basic_set *isl_set_simple_hull(__isl_take isl_set *set); __isl_give isl_basic_set *isl_set_unshifted_simple_hull( __isl_take isl_set *set); +__isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list( + __isl_take isl_set *set, __isl_take isl_set_list *list); struct isl_basic_set *isl_set_bounded_simple_hull(struct isl_set *set); __isl_give isl_set *isl_set_recession_cone(__isl_take isl_set *set); @@ -320,14 +288,12 @@ __isl_take isl_multi_aff *ma); __isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set, __isl_take isl_pw_multi_aff *pma); -__isl_give isl_set *isl_set_fix(__isl_take isl_set *set, - enum isl_dim_type type, unsigned pos, isl_int value); +__isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *mpa); __isl_give isl_set *isl_set_fix_val(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, __isl_take isl_val *v); struct isl_set *isl_set_fix_dim_si(struct isl_set *set, unsigned dim, int value); -struct isl_set *isl_set_lower_bound_dim(struct isl_set *set, - unsigned dim, isl_int value); __isl_give isl_basic_set *isl_basic_set_insert_dims( __isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos, unsigned n); @@ -335,7 +301,7 @@ enum isl_dim_type type, unsigned pos, unsigned n); __isl_give isl_basic_set *isl_basic_set_add_dims(__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned n); -/* deprecated */ +ISL_DEPRECATED __isl_give isl_basic_set *isl_basic_set_add(__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned n); __isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set, @@ -384,29 +350,29 @@ __isl_take isl_set *set, enum isl_dim_type type, unsigned first, unsigned n); -int isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, +isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned first, unsigned n); -int isl_set_involves_dims(__isl_keep isl_set *set, +isl_bool isl_set_involves_dims(__isl_keep isl_set *set, enum isl_dim_type type, unsigned first, unsigned n); void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent); -int isl_set_plain_is_empty(__isl_keep isl_set *set); -int isl_set_fast_is_empty(__isl_keep isl_set *set); -int isl_set_plain_is_universe(__isl_keep isl_set *set); -int isl_set_fast_is_universe(__isl_keep isl_set *set); -int isl_set_is_params(__isl_keep isl_set *set); +isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set); +isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set); +isl_bool isl_set_is_params(__isl_keep isl_set *set); __isl_export -int isl_set_is_empty(__isl_keep isl_set *set); +isl_bool isl_set_is_empty(__isl_keep isl_set *set); int isl_set_is_bounded(__isl_keep isl_set *set); __isl_export -int isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2); +isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2); __isl_export -int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2); +isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); __isl_export -int isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2); +isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2); __isl_export -int isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2); -int isl_set_is_singleton(__isl_keep isl_set *set); +isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, + __isl_keep isl_set *set2); +isl_bool isl_set_is_singleton(__isl_keep isl_set *set); int isl_set_is_box(__isl_keep isl_set *set); int isl_set_has_equal_space(__isl_keep isl_set *set1, __isl_keep isl_set *set2); @@ -424,28 +390,17 @@ struct isl_set *isl_set_drop_basic_set(struct isl_set *set, struct isl_basic_set *bset); -int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset, - unsigned dim, isl_int *val); - -int isl_set_plain_is_fixed(__isl_keep isl_set *set, - enum isl_dim_type type, unsigned pos, isl_int *val); -int isl_set_plain_dim_is_fixed(__isl_keep isl_set *set, - unsigned dim, isl_int *val); -int isl_set_fast_dim_is_fixed(__isl_keep isl_set *set, - unsigned dim, isl_int *val); __isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); -int isl_set_plain_dim_has_fixed_lower_bound(__isl_keep isl_set *set, - unsigned dim, isl_int *val); int isl_set_dim_is_bounded(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); -int isl_set_dim_has_lower_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); -int isl_set_dim_has_upper_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); -int isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); -int isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); __isl_export @@ -458,22 +413,16 @@ __isl_take isl_set *context); __isl_give isl_set *isl_set_gist_params(__isl_take isl_set *set, __isl_take isl_set *context); -int isl_basic_set_dim_residue_class(struct isl_basic_set *bset, - int pos, isl_int *modulo, isl_int *residue); -int isl_set_dim_residue_class(struct isl_set *set, - int pos, isl_int *modulo, isl_int *residue); -int isl_set_dim_residue_class_val(__isl_keep isl_set *set, +isl_stat isl_set_dim_residue_class_val(__isl_keep isl_set *set, int pos, __isl_give isl_val **modulo, __isl_give isl_val **residue); __isl_export __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2); -int isl_set_plain_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2); -int isl_set_fast_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2); -int isl_set_plain_is_disjoint(__isl_keep isl_set *set1, +isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2); -int isl_set_fast_is_disjoint(__isl_keep isl_set *set1, +isl_bool isl_set_plain_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2); uint32_t isl_set_get_hash(struct isl_set *set); @@ -482,16 +431,12 @@ int isl_set_n_basic_set(__isl_keep isl_set *set); __isl_export -int isl_set_foreach_basic_set(__isl_keep isl_set *set, - int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user); +isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user); -int isl_set_foreach_point(__isl_keep isl_set *set, - int (*fn)(__isl_take isl_point *pnt, void *user), void *user); -int isl_set_count(__isl_keep isl_set *set, isl_int *count); +isl_stat isl_set_foreach_point(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user); __isl_give isl_val *isl_set_count_val(__isl_keep isl_set *set); -int isl_basic_set_count_upto(__isl_keep isl_basic_set *bset, - isl_int max, isl_int *count); -int isl_set_count_upto(__isl_keep isl_set *set, isl_int max, isl_int *count); __isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt); __isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt); @@ -548,6 +493,4 @@ } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/space.h isl-0.15/include/isl/space.h --- isl-0.12.2/include/isl/space.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/space.h 2015-06-02 09:28:09.000000000 +0000 @@ -38,15 +38,15 @@ unsigned nparam, unsigned dim); __isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, unsigned nparam); __isl_give isl_space *isl_space_copy(__isl_keep isl_space *dim); -void *isl_space_free(__isl_take isl_space *dim); +__isl_null isl_space *isl_space_free(__isl_take isl_space *space); -int isl_space_is_params(__isl_keep isl_space *space); -int isl_space_is_set(__isl_keep isl_space *space); -int isl_space_is_map(__isl_keep isl_space *space); +isl_bool isl_space_is_params(__isl_keep isl_space *space); +isl_bool isl_space_is_set(__isl_keep isl_space *space); +isl_bool isl_space_is_map(__isl_keep isl_space *space); __isl_give isl_space *isl_space_set_tuple_name(__isl_take isl_space *dim, enum isl_dim_type type, const char *s); -int isl_space_has_tuple_name(__isl_keep isl_space *space, +isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space, enum isl_dim_type type); const char *isl_space_get_tuple_name(__isl_keep isl_space *dim, enum isl_dim_type type); @@ -54,13 +54,15 @@ enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *dim, enum isl_dim_type type); -int isl_space_has_tuple_id(__isl_keep isl_space *dim, enum isl_dim_type type); +isl_bool isl_space_has_tuple_id(__isl_keep isl_space *dim, + enum isl_dim_type type); __isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *dim, enum isl_dim_type type); +__isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space); __isl_give isl_space *isl_space_set_dim_id(__isl_take isl_space *dim, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); -int isl_space_has_dim_id(__isl_keep isl_space *dim, +isl_bool isl_space_has_dim_id(__isl_keep isl_space *dim, enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_space_get_dim_id(__isl_keep isl_space *dim, enum isl_dim_type type, unsigned pos); @@ -70,7 +72,7 @@ int isl_space_find_dim_by_name(__isl_keep isl_space *space, enum isl_dim_type type, const char *name); -int isl_space_has_dim_name(__isl_keep isl_space *space, +isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, enum isl_dim_type type, unsigned pos); __isl_give isl_space *isl_space_set_dim_name(__isl_take isl_space *dim, enum isl_dim_type type, unsigned pos, @@ -95,6 +97,16 @@ __isl_take isl_space *right); __isl_give isl_space *isl_space_range_product(__isl_take isl_space *left, __isl_take isl_space *right); +__isl_give isl_space *isl_space_factor_domain(__isl_take isl_space *space); +__isl_give isl_space *isl_space_factor_range(__isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_factor_domain( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_domain_factor_range( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_range_factor_domain( + __isl_take isl_space *space); +__isl_give isl_space *isl_space_range_factor_range( + __isl_take isl_space *space); __isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *dim); __isl_give isl_space *isl_space_map_from_domain_and_range( __isl_take isl_space *domain, __isl_take isl_space *range); @@ -109,39 +121,48 @@ __isl_give isl_space *isl_space_from_domain(__isl_take isl_space *dim); __isl_give isl_space *isl_space_range(__isl_take isl_space *dim); __isl_give isl_space *isl_space_from_range(__isl_take isl_space *dim); +__isl_give isl_space *isl_space_domain_map(__isl_take isl_space *space); +__isl_give isl_space *isl_space_range_map(__isl_take isl_space *space); __isl_give isl_space *isl_space_params(__isl_take isl_space *space); __isl_give isl_space *isl_space_set_from_params(__isl_take isl_space *space); __isl_give isl_space *isl_space_align_params(__isl_take isl_space *dim1, __isl_take isl_space *dim2); -int isl_space_is_wrapping(__isl_keep isl_space *dim); +isl_bool isl_space_is_wrapping(__isl_keep isl_space *dim); +isl_bool isl_space_domain_is_wrapping(__isl_keep isl_space *space); +isl_bool isl_space_range_is_wrapping(__isl_keep isl_space *space); __isl_give isl_space *isl_space_wrap(__isl_take isl_space *dim); __isl_give isl_space *isl_space_unwrap(__isl_take isl_space *dim); -int isl_space_can_zip(__isl_keep isl_space *dim); +isl_bool isl_space_can_zip(__isl_keep isl_space *dim); __isl_give isl_space *isl_space_zip(__isl_take isl_space *dim); -int isl_space_can_curry(__isl_keep isl_space *space); +isl_bool isl_space_can_curry(__isl_keep isl_space *space); __isl_give isl_space *isl_space_curry(__isl_take isl_space *space); -int isl_space_can_uncurry(__isl_keep isl_space *space); +isl_bool isl_space_can_uncurry(__isl_keep isl_space *space); __isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space); -int isl_space_is_domain(__isl_keep isl_space *space1, +isl_bool isl_space_is_domain(__isl_keep isl_space *space1, __isl_keep isl_space *space2); -int isl_space_is_range(__isl_keep isl_space *space1, +isl_bool isl_space_is_range(__isl_keep isl_space *space1, __isl_keep isl_space *space2); -int isl_space_is_equal(__isl_keep isl_space *space1, +isl_bool isl_space_is_equal(__isl_keep isl_space *space1, __isl_keep isl_space *space2); +isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type type1, __isl_keep isl_space *space2, + enum isl_dim_type type2); int isl_space_match(__isl_keep isl_space *dim1, enum isl_dim_type dim1_type, __isl_keep isl_space *dim2, enum isl_dim_type dim2_type); -int isl_space_tuple_match(__isl_keep isl_space *dim1, enum isl_dim_type dim1_type, - __isl_keep isl_space *dim2, enum isl_dim_type dim2_type); +ISL_DEPRECATED +int isl_space_tuple_match(__isl_keep isl_space *space1, enum isl_dim_type type1, + __isl_keep isl_space *space2, enum isl_dim_type type2); int isl_space_compatible(__isl_keep isl_space *dim1, __isl_keep isl_space *dim2); unsigned isl_space_dim(__isl_keep isl_space *dim, enum isl_dim_type type); +__isl_give char *isl_space_to_str(__isl_keep isl_space *space); __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p, __isl_keep isl_space *dim); void isl_space_dump(__isl_keep isl_space *dim); diff -Nru isl-0.12.2/include/isl/stream.h isl-0.15/include/isl/stream.h --- isl-0.12.2/include/isl/stream.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/stream.h 2015-06-02 09:28:09.000000000 +0000 @@ -15,6 +15,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -39,76 +40,54 @@ ISL_TOKEN_IMPLIES, ISL_TOKEN_LAST }; -struct isl_token { - int type; - - unsigned int on_new_line : 1; - unsigned is_keyword : 1; - int line; - int col; - - union { - isl_int v; - char *s; - isl_map *map; - isl_pw_aff *pwaff; - } u; -}; +struct isl_token; __isl_give isl_val *isl_token_get_val(isl_ctx *ctx, struct isl_token *tok); __isl_give char *isl_token_get_str(isl_ctx *ctx, struct isl_token *tok); int isl_token_get_type(struct isl_token *tok); void isl_token_free(struct isl_token *tok); -struct isl_stream { - struct isl_ctx *ctx; - FILE *file; - const char *str; - int line; - int col; - int eof; - - char *buffer; - size_t size; - size_t len; - int c; - int un[5]; - int n_un; - - struct isl_token *tokens[5]; - int n_token; - - struct isl_hash_table *keywords; - enum isl_token_type next_type; -}; - -struct isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file); -struct isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str); -void isl_stream_free(struct isl_stream *s); - -void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg); - -struct isl_token *isl_stream_next_token(struct isl_stream *s); -struct isl_token *isl_stream_next_token_on_same_line(struct isl_stream *s); -int isl_stream_next_token_is(struct isl_stream *s, int type); -void isl_stream_push_token(struct isl_stream *s, struct isl_token *tok); -void isl_stream_flush_tokens(struct isl_stream *s); -int isl_stream_eat_if_available(struct isl_stream *s, int type); -char *isl_stream_read_ident_if_available(struct isl_stream *s); -int isl_stream_eat(struct isl_stream *s, int type); -int isl_stream_is_empty(struct isl_stream *s); -int isl_stream_skip_line(struct isl_stream *s); +struct isl_stream; +typedef struct isl_stream isl_stream; + +__isl_give isl_stream *isl_stream_new_file(isl_ctx *ctx, FILE *file); +__isl_give isl_stream *isl_stream_new_str(isl_ctx *ctx, const char *str); +void isl_stream_free(__isl_take isl_stream *s); + +isl_ctx *isl_stream_get_ctx(__isl_keep isl_stream *s); + +void isl_stream_error(__isl_keep isl_stream *s, struct isl_token *tok, + char *msg); + +struct isl_token *isl_stream_next_token(__isl_keep isl_stream *s); +struct isl_token *isl_stream_next_token_on_same_line(__isl_keep isl_stream *s); +int isl_stream_next_token_is(__isl_keep isl_stream *s, int type); +void isl_stream_push_token(__isl_keep isl_stream *s, struct isl_token *tok); +void isl_stream_flush_tokens(__isl_keep isl_stream *s); +int isl_stream_eat_if_available(__isl_keep isl_stream *s, int type); +char *isl_stream_read_ident_if_available(__isl_keep isl_stream *s); +int isl_stream_eat(__isl_keep isl_stream *s, int type); +int isl_stream_is_empty(__isl_keep isl_stream *s); +int isl_stream_skip_line(__isl_keep isl_stream *s); -enum isl_token_type isl_stream_register_keyword(struct isl_stream *s, +enum isl_token_type isl_stream_register_keyword(__isl_keep isl_stream *s, const char *name); -struct isl_obj isl_stream_read_obj(struct isl_stream *s); -__isl_give isl_multi_aff *isl_stream_read_multi_aff(struct isl_stream *s); -__isl_give isl_map *isl_stream_read_map(struct isl_stream *s); -__isl_give isl_set *isl_stream_read_set(struct isl_stream *s); +struct isl_obj isl_stream_read_obj(__isl_keep isl_stream *s); +__isl_give isl_val *isl_stream_read_val(__isl_keep isl_stream *s); +__isl_give isl_multi_aff *isl_stream_read_multi_aff(__isl_keep isl_stream *s); +__isl_give isl_map *isl_stream_read_map(__isl_keep isl_stream *s); +__isl_give isl_set *isl_stream_read_set(__isl_keep isl_stream *s); __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial( - struct isl_stream *s); -__isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s); + __isl_keep isl_stream *s); +__isl_give isl_union_map *isl_stream_read_union_map(__isl_keep isl_stream *s); +__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s); + +int isl_stream_yaml_read_start_mapping(__isl_keep isl_stream *s); +int isl_stream_yaml_read_end_mapping(__isl_keep isl_stream *s); +int isl_stream_yaml_read_start_sequence(__isl_keep isl_stream *s); +int isl_stream_yaml_read_end_sequence(__isl_keep isl_stream *s); +int isl_stream_yaml_next(__isl_keep isl_stream *s); #if defined(__cplusplus) } diff -Nru isl-0.12.2/include/isl/union_map.h isl-0.15/include/isl/union_map.h --- isl-0.12.2/include/isl/union_map.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/union_map.h 2015-06-02 09:28:09.000000000 +0000 @@ -2,6 +2,7 @@ #define ISL_UNION_MAP_H #include +#include #include #include #include @@ -11,6 +12,13 @@ extern "C" { #endif +unsigned isl_union_map_dim(__isl_keep isl_union_map *umap, + enum isl_dim_type type); +isl_bool isl_union_map_involves_dims(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_id *isl_union_map_get_dim_id(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned pos); + __isl_constructor __isl_give isl_union_map *isl_union_map_from_basic_map( __isl_take isl_basic_map *bmap); @@ -18,11 +26,17 @@ __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map); __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *dim); __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap); -void *isl_union_map_free(__isl_take isl_union_map *umap); +__isl_null isl_union_map *isl_union_map_free(__isl_take isl_union_map *umap); isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap); __isl_give isl_space *isl_union_map_get_space(__isl_keep isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_reset_user( + __isl_take isl_union_map *umap); + +int isl_union_map_find_dim_by_name(__isl_keep isl_union_map *umap, + enum isl_dim_type type, const char *name); + __isl_give isl_union_map *isl_union_map_universe( __isl_take isl_union_map *umap); __isl_give isl_set *isl_union_map_params(__isl_take isl_union_map *umap); @@ -30,8 +44,12 @@ __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap); __isl_give isl_union_map *isl_union_map_domain_map( __isl_take isl_union_map *umap); +__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff( + __isl_take isl_union_map *umap); __isl_give isl_union_map *isl_union_map_range_map( __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_set_wrapped_domain_map( + __isl_take isl_union_set *uset); __isl_give isl_union_map *isl_union_map_from_domain( __isl_take isl_union_set *uset); __isl_give isl_union_map *isl_union_map_from_range( @@ -43,6 +61,8 @@ __isl_export __isl_give isl_union_map *isl_union_map_polyhedral_hull( __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_remove_redundancies( + __isl_take isl_union_map *umap); __isl_give isl_union_map *isl_union_map_simple_hull( __isl_take isl_union_map *umap); __isl_export @@ -73,10 +93,22 @@ __isl_take isl_union_map *umap2); __isl_give isl_union_map *isl_union_map_domain_product( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_flat_domain_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); __isl_give isl_union_map *isl_union_map_range_product( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); __isl_give isl_union_map *isl_union_map_flat_range_product( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_domain_factor_domain( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_domain_factor_range( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_range_factor_range( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_factor_domain( + __isl_take isl_union_map *umap); +__isl_give isl_union_map *isl_union_map_factor_range( + __isl_take isl_union_map *umap); __isl_export __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap, __isl_take isl_union_map *context); @@ -112,6 +144,20 @@ __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); __isl_give isl_union_map *isl_union_map_preimage_domain_multi_aff( __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma); +__isl_give isl_union_map *isl_union_map_preimage_range_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma); +__isl_give isl_union_map *isl_union_map_preimage_domain_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_union_map *isl_union_map_preimage_range_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_union_map *isl_union_map_preimage_domain_multi_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_pw_aff *mpa); +__isl_give isl_union_map *isl_union_map_preimage_domain_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); +__isl_give isl_union_map *isl_union_map_preimage_range_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma); __isl_export __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap); __isl_give isl_union_map *isl_union_map_from_domain_and_range( @@ -127,30 +173,36 @@ __isl_export __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset); +__isl_give isl_union_map *isl_union_map_project_out( + __isl_take isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n); + __isl_export -int isl_union_map_is_empty(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_is_empty(__isl_keep isl_union_map *umap); __isl_export -int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap); -int isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_is_single_valued(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap); __isl_export -int isl_union_map_is_injective(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_is_injective(__isl_keep isl_union_map *umap); __isl_export -int isl_union_map_is_bijective(__isl_keep isl_union_map *umap); +isl_bool isl_union_map_is_bijective(__isl_keep isl_union_map *umap); __isl_export -int isl_union_map_is_subset(__isl_keep isl_union_map *umap1, +isl_bool isl_union_map_is_subset(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2); __isl_export -int isl_union_map_is_equal(__isl_keep isl_union_map *umap1, +isl_bool isl_union_map_is_equal(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2); +isl_bool isl_union_map_is_disjoint(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2); __isl_export -int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1, +isl_bool isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2); int isl_union_map_n_map(__isl_keep isl_union_map *umap); __isl_export -int isl_union_map_foreach_map(__isl_keep isl_union_map *umap, - int (*fn)(__isl_take isl_map *map, void *user), void *user); +isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap, + isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user); __isl_give int isl_union_map_contains(__isl_keep isl_union_map *umap, __isl_keep isl_space *dim); __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap, @@ -159,8 +211,6 @@ __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap); -__isl_give isl_union_map *isl_union_map_fixed_power( - __isl_take isl_union_map *umap, isl_int exp); __isl_give isl_union_map *isl_union_map_fixed_power_val( __isl_take isl_union_map *umap, __isl_take isl_val *exp); __isl_give isl_union_map *isl_union_map_power(__isl_take isl_union_map *umap, @@ -177,11 +227,22 @@ __isl_give isl_union_map *isl_union_map_lex_ge_union_map( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_eq_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa); + __isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx, FILE *input); __isl_constructor __isl_give isl_union_map *isl_union_map_read_from_str(isl_ctx *ctx, const char *str); +__isl_give char *isl_union_map_to_str(__isl_keep isl_union_map *umap); __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p, __isl_keep isl_union_map *umap); void isl_union_map_dump(__isl_keep isl_union_map *umap); @@ -198,10 +259,10 @@ __isl_give isl_union_set *isl_union_set_align_params( __isl_take isl_union_set *uset, __isl_take isl_space *model); +ISL_DECLARE_LIST_FN(union_map) + #if defined(__cplusplus) } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/union_map_type.h isl-0.15/include/isl/union_map_type.h --- isl-0.12.2/include/isl/union_map_type.h 2013-01-08 11:20:44.000000000 +0000 +++ isl-0.15/include/isl/union_map_type.h 2015-06-02 09:28:09.000000000 +0000 @@ -2,6 +2,7 @@ #define ISL_UNION_MAP_TYPE_H #include +#include #if defined(__cplusplus) extern "C" { @@ -9,9 +10,11 @@ struct __isl_export isl_union_map; typedef struct isl_union_map isl_union_map; +ISL_DECLARE_LIST_TYPE(union_map) #ifndef isl_union_set struct __isl_export isl_union_set; typedef struct isl_union_set isl_union_set; +ISL_DECLARE_LIST_TYPE(union_set) #endif #if defined(__cplusplus) diff -Nru isl-0.12.2/include/isl/union_set.h isl-0.15/include/isl/union_set.h --- isl-0.12.2/include/isl/union_set.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/include/isl/union_set.h 2015-06-02 09:28:09.000000000 +0000 @@ -8,6 +8,9 @@ extern "C" { #endif +unsigned isl_union_set_dim(__isl_keep isl_union_set *uset, + enum isl_dim_type type); + __isl_constructor __isl_give isl_union_set *isl_union_set_from_basic_set( __isl_take isl_basic_set *bset); @@ -15,11 +18,14 @@ __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set); __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *dim); __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset); -void *isl_union_set_free(__isl_take isl_union_set *uset); +__isl_null isl_union_set *isl_union_set_free(__isl_take isl_union_set *uset); isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset); __isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset); +__isl_give isl_union_set *isl_union_set_reset_user( + __isl_take isl_union_set *uset); + __isl_give isl_union_set *isl_union_set_universe( __isl_take isl_union_set *uset); __isl_give isl_set *isl_union_set_params(__isl_take isl_union_set *uset); @@ -33,6 +39,8 @@ __isl_export __isl_give isl_union_set *isl_union_set_polyhedral_hull( __isl_take isl_union_set *uset); +__isl_give isl_union_set *isl_union_set_remove_redundancies( + __isl_take isl_union_set *uset); __isl_give isl_union_set *isl_union_set_simple_hull( __isl_take isl_union_set *uset); __isl_export @@ -70,32 +78,45 @@ __isl_export __isl_give isl_union_set *isl_union_set_apply( __isl_take isl_union_set *uset, __isl_take isl_union_map *umap); +__isl_give isl_union_set *isl_union_set_preimage_multi_aff( + __isl_take isl_union_set *uset, __isl_take isl_multi_aff *ma); +__isl_give isl_union_set *isl_union_set_preimage_pw_multi_aff( + __isl_take isl_union_set *uset, __isl_take isl_pw_multi_aff *pma); +__isl_give isl_union_set *isl_union_set_preimage_union_pw_multi_aff( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_union_set *isl_union_set_project_out( + __isl_take isl_union_set *uset, + enum isl_dim_type type, unsigned first, unsigned n); -int isl_union_set_is_params(__isl_keep isl_union_set *uset); +isl_bool isl_union_set_is_params(__isl_keep isl_union_set *uset); __isl_export -int isl_union_set_is_empty(__isl_keep isl_union_set *uset); +isl_bool isl_union_set_is_empty(__isl_keep isl_union_set *uset); __isl_export -int isl_union_set_is_subset(__isl_keep isl_union_set *uset1, +isl_bool isl_union_set_is_subset(__isl_keep isl_union_set *uset1, __isl_keep isl_union_set *uset2); __isl_export -int isl_union_set_is_equal(__isl_keep isl_union_set *uset1, +isl_bool isl_union_set_is_equal(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2); +isl_bool isl_union_set_is_disjoint(__isl_keep isl_union_set *uset1, __isl_keep isl_union_set *uset2); __isl_export -int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1, +isl_bool isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1, __isl_keep isl_union_set *uset2); int isl_union_set_n_set(__isl_keep isl_union_set *uset); __isl_export -int isl_union_set_foreach_set(__isl_keep isl_union_set *uset, - int (*fn)(__isl_take isl_set *set, void *user), void *user); +isl_stat isl_union_set_foreach_set(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_set *set, void *user), void *user); __isl_give int isl_union_set_contains(__isl_keep isl_union_set *uset, __isl_keep isl_space *dim); __isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset, __isl_take isl_space *dim); __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset); -int isl_union_set_foreach_point(__isl_keep isl_union_set *uset, - int (*fn)(__isl_take isl_point *pnt, void *user), void *user); +isl_stat isl_union_set_foreach_point(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user); __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset); @@ -120,14 +141,18 @@ __isl_constructor __isl_give isl_union_set *isl_union_set_read_from_str(isl_ctx *ctx, const char *str); +__isl_give char *isl_union_set_to_str(__isl_keep isl_union_set *uset); __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p, __isl_keep isl_union_set *uset); void isl_union_set_dump(__isl_keep isl_union_set *uset); +ISL_DECLARE_LIST_FN(union_set) + +__isl_give isl_union_set *isl_union_set_list_union( + __isl_take isl_union_set_list *list); + #if defined(__cplusplus) } #endif -#include - #endif diff -Nru isl-0.12.2/include/isl/val_gmp.h isl-0.15/include/isl/val_gmp.h --- isl-0.12.2/include/isl/val_gmp.h 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/include/isl/val_gmp.h 2015-04-19 12:02:52.000000000 +0000 @@ -4,10 +4,18 @@ #include #include +#if defined(__cplusplus) +extern "C" { +#endif + __isl_give isl_val *isl_val_int_from_gmp(isl_ctx *ctx, mpz_t z); __isl_give isl_val *isl_val_from_gmp(isl_ctx *ctx, const mpz_t n, const mpz_t d); int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z); int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z); +#if defined(__cplusplus) +} +#endif + #endif diff -Nru isl-0.12.2/include/isl/val.h isl-0.15/include/isl/val.h --- isl-0.12.2/include/isl/val.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/val.h 2015-06-02 09:28:09.000000000 +0000 @@ -19,9 +19,13 @@ typedef struct isl_multi_val isl_multi_val; ISL_DECLARE_MULTI(val) +ISL_DECLARE_MULTI_NEG(val) +ISL_DECLARE_MULTI_DIMS(val) +ISL_DECLARE_MULTI_WITH_DOMAIN(val) __isl_give isl_val *isl_val_zero(isl_ctx *ctx); __isl_give isl_val *isl_val_one(isl_ctx *ctx); +__isl_give isl_val *isl_val_negone(isl_ctx *ctx); __isl_give isl_val *isl_val_nan(isl_ctx *ctx); __isl_give isl_val *isl_val_infty(isl_ctx *ctx); __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx); @@ -31,7 +35,7 @@ size_t size, const void *chunks); __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v); -void *isl_val_free(__isl_take isl_val *v); +__isl_null isl_val *isl_val_free(__isl_take isl_val *v); isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val); long isl_val_get_num_si(__isl_keep isl_val *v); @@ -45,6 +49,7 @@ __isl_give isl_val *isl_val_abs(__isl_take isl_val *v); __isl_give isl_val *isl_val_neg(__isl_take isl_val *v); +__isl_give isl_val *isl_val_inv(__isl_take isl_val *v); __isl_give isl_val *isl_val_floor(__isl_take isl_val *v); __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v); __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v); @@ -64,29 +69,31 @@ __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y); int isl_val_sgn(__isl_keep isl_val *v); -int isl_val_is_zero(__isl_keep isl_val *v); -int isl_val_is_one(__isl_keep isl_val *v); -int isl_val_is_negone(__isl_keep isl_val *v); -int isl_val_is_nonneg(__isl_keep isl_val *v); -int isl_val_is_nonpos(__isl_keep isl_val *v); -int isl_val_is_pos(__isl_keep isl_val *v); -int isl_val_is_neg(__isl_keep isl_val *v); -int isl_val_is_int(__isl_keep isl_val *v); -int isl_val_is_rat(__isl_keep isl_val *v); -int isl_val_is_nan(__isl_keep isl_val *v); -int isl_val_is_infty(__isl_keep isl_val *v); -int isl_val_is_neginfty(__isl_keep isl_val *v); +isl_bool isl_val_is_zero(__isl_keep isl_val *v); +isl_bool isl_val_is_one(__isl_keep isl_val *v); +isl_bool isl_val_is_negone(__isl_keep isl_val *v); +isl_bool isl_val_is_nonneg(__isl_keep isl_val *v); +isl_bool isl_val_is_nonpos(__isl_keep isl_val *v); +isl_bool isl_val_is_pos(__isl_keep isl_val *v); +isl_bool isl_val_is_neg(__isl_keep isl_val *v); +isl_bool isl_val_is_int(__isl_keep isl_val *v); +isl_bool isl_val_is_rat(__isl_keep isl_val *v); +isl_bool isl_val_is_nan(__isl_keep isl_val *v); +isl_bool isl_val_is_infty(__isl_keep isl_val *v); +isl_bool isl_val_is_neginfty(__isl_keep isl_val *v); int isl_val_cmp_si(__isl_keep isl_val *v, long i); -int isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); -int isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2); -int isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); -int isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2); -int isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); -int isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2); -int isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2); +isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, + __isl_keep isl_val *v2); __isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx, const char *str); __isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p, @@ -99,6 +106,13 @@ __isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv, __isl_take isl_val *v); +__isl_give isl_multi_val *isl_multi_val_read_from_str(isl_ctx *ctx, + const char *str); +__isl_give isl_printer *isl_printer_print_multi_val(__isl_take isl_printer *p, + __isl_keep isl_multi_val *mv); +void isl_multi_val_dump(__isl_keep isl_multi_val *mv); +__isl_give char *isl_multi_val_to_str(__isl_keep isl_multi_val *mv); + #if defined(__cplusplus) } #endif diff -Nru isl-0.12.2/include/isl/val_int.h isl-0.15/include/isl/val_int.h --- isl-0.12.2/include/isl/val_int.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/val_int.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#ifndef ISL_VAL_INT_H -#define ISL_VAL_INT_H - -#include -#include - -__isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n); -int isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n); - -#endif diff -Nru isl-0.12.2/include/isl/vec.h isl-0.15/include/isl/vec.h --- isl-0.12.2/include/isl/vec.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/include/isl/vec.h 2015-06-02 09:28:09.000000000 +0000 @@ -12,9 +12,7 @@ #include -#include #include -#include #include #include @@ -22,36 +20,23 @@ extern "C" { #endif -struct isl_vec { - int ref; - - struct isl_ctx *ctx; - - unsigned size; - isl_int *el; - - struct isl_blk block; -}; +struct isl_vec; typedef struct isl_vec isl_vec; __isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx, unsigned size); __isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec); -struct isl_vec *isl_vec_cow(struct isl_vec *vec); -void *isl_vec_free(__isl_take isl_vec *vec); +__isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec); isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec); int isl_vec_size(__isl_keep isl_vec *vec); -int isl_vec_get_element(__isl_keep isl_vec *vec, int pos, isl_int *v); __isl_give isl_val *isl_vec_get_element_val(__isl_keep isl_vec *vec, int pos); -__isl_give isl_vec *isl_vec_set_element(__isl_take isl_vec *vec, - int pos, isl_int v); __isl_give isl_vec *isl_vec_set_element_si(__isl_take isl_vec *vec, int pos, int v); __isl_give isl_vec *isl_vec_set_element_val(__isl_take isl_vec *vec, int pos, __isl_take isl_val *v); -int isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2); +isl_bool isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2); int isl_vec_cmp_element(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2, int pos); @@ -59,17 +44,13 @@ __isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer, __isl_keep isl_vec *vec); -void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm); struct isl_vec *isl_vec_ceil(struct isl_vec *vec); struct isl_vec *isl_vec_normalize(struct isl_vec *vec); -__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v); __isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, int v); __isl_give isl_vec *isl_vec_set_val(__isl_take isl_vec *vec, __isl_take isl_val *v); __isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec); __isl_give isl_vec *isl_vec_neg(__isl_take isl_vec *vec); -__isl_give isl_vec *isl_vec_scale(__isl_take isl_vec *vec, isl_int m); -__isl_give isl_vec *isl_vec_fdiv_r(__isl_take isl_vec *vec, isl_int m); __isl_give isl_vec *isl_vec_add(__isl_take isl_vec *vec1, __isl_take isl_vec *vec2); __isl_give isl_vec *isl_vec_extend(__isl_take isl_vec *vec, unsigned size); @@ -87,6 +68,8 @@ unsigned pos, unsigned n); __isl_give isl_vec *isl_vec_insert_zero_els(__isl_take isl_vec *vec, unsigned pos, unsigned n); +__isl_give isl_vec *isl_vec_move_els(__isl_take isl_vec *vec, + unsigned dst_col, unsigned src_col, unsigned n); #if defined(__cplusplus) } diff -Nru isl-0.12.2/include/isl/vertices.h isl-0.15/include/isl/vertices.h --- isl-0.12.2/include/isl/vertices.h 2012-11-29 08:47:32.000000000 +0000 +++ isl-0.15/include/isl/vertices.h 2015-06-02 09:28:09.000000000 +0000 @@ -1,6 +1,7 @@ #ifndef ISL_VERTICES_H #define ISL_VERTICES_H +#include #include #if defined(__cplusplus) @@ -19,25 +20,25 @@ isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex); int isl_vertex_get_id(__isl_keep isl_vertex *vertex); __isl_give isl_basic_set *isl_vertex_get_domain(__isl_keep isl_vertex *vertex); -__isl_give isl_basic_set *isl_vertex_get_expr(__isl_keep isl_vertex *vertex); +__isl_give isl_multi_aff *isl_vertex_get_expr(__isl_keep isl_vertex *vertex); void isl_vertex_free(__isl_take isl_vertex *vertex); __isl_give isl_vertices *isl_basic_set_compute_vertices( __isl_keep isl_basic_set *bset); isl_ctx *isl_vertices_get_ctx(__isl_keep isl_vertices *vertices); int isl_vertices_get_n_vertices(__isl_keep isl_vertices *vertices); -int isl_vertices_foreach_vertex(__isl_keep isl_vertices *vertices, - int (*fn)(__isl_take isl_vertex *vertex, void *user), void *user); +isl_stat isl_vertices_foreach_vertex(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user); void isl_vertices_free(__isl_take isl_vertices *vertices); isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell); __isl_give isl_basic_set *isl_cell_get_domain(__isl_keep isl_cell *cell); -int isl_cell_foreach_vertex(__isl_keep isl_cell *cell, - int (*fn)(__isl_take isl_vertex *vertex, void *user), void *user); +isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user); void isl_cell_free(__isl_take isl_cell *cell); -int isl_vertices_foreach_cell(__isl_keep isl_vertices *vertices, - int (*fn)(__isl_take isl_cell *cell, void *user), void *user); +isl_stat isl_vertices_foreach_cell(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, void *user), void *user); #if defined(__cplusplus) } diff -Nru isl-0.12.2/interface/extract_interface.cc isl-0.15/interface/extract_interface.cc --- isl-0.12.2/interface/extract_interface.cc 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/interface/extract_interface.cc 2015-06-02 09:28:09.000000000 +0000 @@ -35,6 +35,11 @@ #include #include +#ifdef HAVE_ADT_OWNINGPTR_H +#include +#else +#include +#endif #include #include #include @@ -70,13 +75,18 @@ using namespace clang; using namespace clang::driver; +#ifdef HAVE_ADT_OWNINGPTR_H +#define unique_ptr llvm::OwningPtr +#endif + static llvm::cl::opt InputFilename(llvm::cl::Positional, llvm::cl::Required, llvm::cl::desc("")); static llvm::cl::list Includes("I", llvm::cl::desc("Header search path"), llvm::cl::value_desc("path"), llvm::cl::Prefix); -static const char *ResourceDir = CLANG_PREFIX"/lib/clang/"CLANG_VERSION_STRING; +static const char *ResourceDir = + CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING; /* Does decl have an attribute of the following form? * @@ -151,14 +161,27 @@ return new Driver(binary, llvm::sys::getDefaultTargetTriple(), "", false, Diags); } -#else +#elif defined(DRIVER_CTOR_TAKES_DEFAULTIMAGENAME) static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags) { return new Driver(binary, llvm::sys::getDefaultTargetTriple(), "", Diags); } +#else +static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags) +{ + return new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags); +} #endif +/* Clang changed its API from 3.5 to 3.6, we fix this with a simple overloaded + * function here. + */ +struct ClangAPI { + static Job *command(Job *J) { return J; } + static Job *command(Job &J) { return &J; } +}; + /* Create a CompilerInvocation object that stores the command line * arguments constructed by the driver. * The arguments are mainly useful for setting up the system include @@ -168,15 +191,15 @@ DiagnosticsEngine &Diags) { const char *binary = CLANG_PREFIX"/bin/clang"; - const llvm::OwningPtr driver(construct_driver(binary, Diags)); + const unique_ptr driver(construct_driver(binary, Diags)); std::vector Argv; Argv.push_back(binary); Argv.push_back(filename); - const llvm::OwningPtr compilation( + const unique_ptr compilation( driver->BuildCompilation(llvm::ArrayRef(Argv))); JobList &Jobs = compilation->getJobs(); - Command *cmd = cast(*Jobs.begin()); + Command *cmd = cast(ClangAPI::command(*Jobs.begin())); if (strcmp(cmd->getCreator().getName(), "clang")) return NULL; @@ -216,7 +239,17 @@ #endif -#ifdef CREATETARGETINFO_TAKES_POINTER +#ifdef CREATETARGETINFO_TAKES_SHARED_PTR + +static TargetInfo *create_target_info(CompilerInstance *Clang, + DiagnosticsEngine &Diags) +{ + shared_ptr TO = Clang->getInvocation().TargetOpts; + TO->Triple = llvm::sys::getDefaultTargetTriple(); + return TargetInfo::CreateTargetInfo(Diags, TO); +} + +#elif defined(CREATETARGETINFO_TAKES_POINTER) static TargetInfo *create_target_info(CompilerInstance *Clang, DiagnosticsEngine &Diags) @@ -254,6 +287,22 @@ #endif +#ifdef CREATEPREPROCESSOR_TAKES_TUKIND + +static void create_preprocessor(CompilerInstance *Clang) +{ + Clang->createPreprocessor(TU_Complete); +} + +#else + +static void create_preprocessor(CompilerInstance *Clang) +{ + Clang->createPreprocessor(); +} + +#endif + #ifdef ADDPATH_TAKES_4_ARGUMENTS void add_path(HeaderSearchOptions &HSO, string Path) @@ -270,6 +319,23 @@ #endif +#ifdef HAVE_SETMAINFILEID + +static void create_main_file_id(SourceManager &SM, const FileEntry *file) +{ + SM.setMainFileID(SM.createFileID(file, SourceLocation(), + SrcMgr::C_User)); +} + +#else + +static void create_main_file_id(SourceManager &SM, const FileEntry *file) +{ + SM.createMainFileID(file); +} + +#endif + int main(int argc, char *argv[]) { llvm::cl::ParseCommandLineOptions(argc, argv); @@ -303,14 +369,14 @@ PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))"); PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))"); - Clang->createPreprocessor(); + create_preprocessor(Clang); Preprocessor &PP = Clang->getPreprocessor(); PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), LO); const FileEntry *file = Clang->getFileManager().getFile(InputFilename); assert(file); - Clang->getSourceManager().createMainFileID(file); + create_main_file_id(Clang->getSourceManager(), file); Clang->createASTContext(); MyASTConsumer consumer; diff -Nru isl-0.12.2/interface/isl.py isl-0.15/interface/isl.py --- isl-0.12.2/interface/isl.py 2014-01-12 11:45:44.000000000 +0000 +++ isl-0.15/interface/isl.py 2015-06-11 10:47:44.000000000 +0000 @@ -57,6 +57,14 @@ return res def __repr__(self): return 'isl.union_map("%s")' % str(self) + def affine_hull(arg0): + try: + if not arg0.__class__ is union_map: + arg0 = union_map(arg0) + except: + raise + res = isl.isl_union_map_affine_hull(isl.isl_union_map_copy(arg0.ptr)) + return union_map(ctx=arg0.ctx, ptr=res) def polyhedral_hull(arg0): try: if not arg0.__class__ is union_map: @@ -128,14 +136,6 @@ raise res = isl.isl_union_map_intersect(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr)) return union_map(ctx=arg0.ctx, ptr=res) - def affine_hull(arg0): - try: - if not arg0.__class__ is union_map: - arg0 = union_map(arg0) - except: - raise - res = isl.isl_union_map_affine_hull(isl.isl_union_map_copy(arg0.ptr)) - return union_map(ctx=arg0.ctx, ptr=res) def intersect_params(arg0, arg1): try: if not arg0.__class__ is union_map: @@ -380,6 +380,11 @@ arg0 = union_map(arg0) except: raise + try: + if not arg1.__class__ is stat (isl_map *, void *): + arg1 = stat (isl_map *, void *)(arg1) + except: + raise exc_info = [None] fn = CFUNCTYPE(c_int, c_void_p, c_void_p) def cb_func(cb_arg0, cb_arg1): @@ -403,6 +408,7 @@ isl.isl_union_map_from_map.argtypes = [c_void_p] isl.isl_union_map_read_from_str.restype = c_void_p isl.isl_union_map_read_from_str.argtypes = [Context, c_char_p] +isl.isl_union_map_affine_hull.restype = c_void_p isl.isl_union_map_polyhedral_hull.restype = c_void_p isl.isl_union_map_coalesce.restype = c_void_p isl.isl_union_map_lexmin.restype = c_void_p @@ -410,7 +416,6 @@ isl.isl_union_map_union.restype = c_void_p isl.isl_union_map_subtract.restype = c_void_p isl.isl_union_map_intersect.restype = c_void_p -isl.isl_union_map_affine_hull.restype = c_void_p isl.isl_union_map_intersect_params.restype = c_void_p isl.isl_union_map_gist.restype = c_void_p isl.isl_union_map_gist_params.restype = c_void_p @@ -778,6 +783,11 @@ arg0 = map(arg0) except: raise + try: + if not arg1.__class__ is stat (isl_basic_map *, void *): + arg1 = stat (isl_basic_map *, void *)(arg1) + except: + return union_map(arg0).foreach_basic_map(arg1) exc_info = [None] fn = CFUNCTYPE(c_int, c_void_p, c_void_p) def cb_func(cb_arg0, cb_arg1): @@ -1082,10 +1092,6 @@ self.ctx = keywords["ctx"] self.ptr = keywords["ptr"] return - if len(args) == 1 and type(args[0]) == str: - self.ctx = Context.getDefaultInstance() - self.ptr = isl.isl_union_set_read_from_str(self.ctx, args[0]) - return if len(args) == 1 and args[0].__class__ is basic_set: self.ctx = Context.getDefaultInstance() self.ptr = isl.isl_union_set_from_basic_set(isl.isl_basic_set_copy(args[0].ptr)) @@ -1094,6 +1100,10 @@ self.ctx = Context.getDefaultInstance() self.ptr = isl.isl_union_set_from_set(isl.isl_set_copy(args[0].ptr)) return + if len(args) == 1 and type(args[0]) == str: + self.ctx = Context.getDefaultInstance() + self.ptr = isl.isl_union_set_read_from_str(self.ctx, args[0]) + return raise Error def __del__(self): if hasattr(self, 'ptr'): @@ -1292,6 +1302,11 @@ arg0 = union_set(arg0) except: raise + try: + if not arg1.__class__ is stat (isl_set *, void *): + arg1 = stat (isl_set *, void *)(arg1) + except: + raise exc_info = [None] fn = CFUNCTYPE(c_int, c_void_p, c_void_p) def cb_func(cb_arg0, cb_arg1): @@ -1309,12 +1324,12 @@ raise exc_info[0][0], exc_info[0][1], exc_info[0][2] return res -isl.isl_union_set_read_from_str.restype = c_void_p -isl.isl_union_set_read_from_str.argtypes = [Context, c_char_p] isl.isl_union_set_from_basic_set.restype = c_void_p isl.isl_union_set_from_basic_set.argtypes = [c_void_p] isl.isl_union_set_from_set.restype = c_void_p isl.isl_union_set_from_set.argtypes = [c_void_p] +isl.isl_union_set_read_from_str.restype = c_void_p +isl.isl_union_set_read_from_str.argtypes = [Context, c_char_p] isl.isl_union_set_identity.restype = c_void_p isl.isl_union_set_detect_equalities.restype = c_void_p isl.isl_union_set_affine_hull.restype = c_void_p @@ -1565,6 +1580,11 @@ arg0 = set(arg0) except: raise + try: + if not arg1.__class__ is stat (isl_basic_set *, void *): + arg1 = stat (isl_basic_set *, void *)(arg1) + except: + return union_set(arg0).foreach_basic_set(arg1) exc_info = [None] fn = CFUNCTYPE(c_int, c_void_p, c_void_p) def cb_func(cb_arg0, cb_arg1): @@ -1715,6 +1735,16 @@ res = isl.isl_basic_set_detect_equalities(isl.isl_basic_set_copy(arg0.ptr)) return basic_set(ctx=arg0.ctx, ptr=res) def is_equal(arg0, arg1): + try: + if not arg0.__class__ is basic_set: + arg0 = basic_set(arg0) + except: + raise + try: + if not arg1.__class__ is basic_set: + arg1 = basic_set(arg1) + except: + return set(arg0).is_equal(arg1) res = isl.isl_basic_set_is_equal(arg0.ptr, arg1.ptr) return res def lexmin(arg0): @@ -1813,47 +1843,3 @@ isl.isl_basic_set_free.argtypes = [c_void_p] isl.isl_basic_set_to_str.argtypes = [c_void_p] isl.isl_basic_set_to_str.restype = POINTER(c_char) - -class pw_qpolynomial: - def __init__(self, *args, **keywords): - if "ptr" in keywords: - self.ctx = keywords["ctx"] - self.ptr = keywords["ptr"] - return - raise Error - def __del__(self): - if hasattr(self, 'ptr'): - isl.isl_pw_qpolynomial_free(self.ptr) - def __str__(self): - ptr = isl.isl_pw_qpolynomial_to_str(self.ptr) - res = str(cast(ptr, c_char_p).value) - libc.free(ptr) - return res - def __repr__(self): - return 'isl.pw_qpolynomial("%s")' % str(self) - -isl.isl_pw_qpolynomial_free.argtypes = [c_void_p] -isl.isl_pw_qpolynomial_to_str.argtypes = [c_void_p] -isl.isl_pw_qpolynomial_to_str.restype = POINTER(c_char) - -class union_pw_qpolynomial: - def __init__(self, *args, **keywords): - if "ptr" in keywords: - self.ctx = keywords["ctx"] - self.ptr = keywords["ptr"] - return - raise Error - def __del__(self): - if hasattr(self, 'ptr'): - isl.isl_union_pw_qpolynomial_free(self.ptr) - def __str__(self): - ptr = isl.isl_union_pw_qpolynomial_to_str(self.ptr) - res = str(cast(ptr, c_char_p).value) - libc.free(ptr) - return res - def __repr__(self): - return 'isl.union_pw_qpolynomial("%s")' % str(self) - -isl.isl_union_pw_qpolynomial_free.argtypes = [c_void_p] -isl.isl_union_pw_qpolynomial_to_str.argtypes = [c_void_p] -isl.isl_union_pw_qpolynomial_to_str.restype = POINTER(c_char) diff -Nru isl-0.12.2/interface/Makefile.am isl-0.15/interface/Makefile.am --- isl-0.12.2/interface/Makefile.am 2013-01-08 11:20:44.000000000 +0000 +++ isl-0.15/interface/Makefile.am 2015-04-19 12:02:52.000000000 +0000 @@ -5,9 +5,10 @@ AM_CXXFLAGS = $(CLANG_CXXFLAGS) AM_LDFLAGS = $(CLANG_LDFLAGS) -INCLUDES = -I$(top_builddir) -I$(top_srcdir) \ +includes = -I$(top_builddir) -I$(top_srcdir) \ -I$(top_builddir)/include -I$(top_srcdir)/include +extract_interface_CPPFLAGS = $(includes) extract_interface_SOURCES = \ python.h \ python.cc \ @@ -20,11 +21,11 @@ $(CLANG_LIBS) $(CLANG_LDFLAGS) test: extract_interface - ./extract_interface$(EXEEXT) $(INCLUDES) $(srcdir)/all.h + ./extract_interface$(EXEEXT) $(includes) $(srcdir)/all.h isl.py: extract_interface isl.py.top (cat $(srcdir)/isl.py.top; \ - ./extract_interface$(EXEEXT) $(INCLUDES) $(srcdir)/all.h) \ + ./extract_interface$(EXEEXT) $(includes) $(srcdir)/all.h) \ > isl.py dist-hook: isl.py diff -Nru isl-0.12.2/interface/Makefile.in isl-0.15/interface/Makefile.in --- isl-0.12.2/interface/Makefile.in 2014-01-12 11:45:17.000000000 +0000 +++ isl-0.15/interface/Makefile.in 2015-06-11 10:47:03.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,23 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ esac; \ - test $$am__dry = yes; \ - } + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -53,7 +80,8 @@ host_triplet = @host@ noinst_PROGRAMS = extract_interface$(EXEEXT) subdir = interface -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \ $(top_srcdir)/m4/ax_cc_maxopt.m4 \ @@ -62,6 +90,8 @@ $(top_srcdir)/m4/ax_create_pkgconfig_info.m4 \ $(top_srcdir)/m4/ax_create_stdint_h.m4 \ $(top_srcdir)/m4/ax_detect_git_head.m4 \ + $(top_srcdir)/m4/ax_detect_gmp.m4 \ + $(top_srcdir)/m4/ax_detect_imath.m4 \ $(top_srcdir)/m4/ax_gcc_archflag.m4 \ $(top_srcdir)/m4/ax_gcc_warn_unused_result.m4 \ $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ @@ -73,13 +103,12 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/isl_config.h \ - $(top_builddir)/include/isl/config.h +CONFIG_HEADER = $(top_builddir)/isl_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am_extract_interface_OBJECTS = python.$(OBJEXT) \ - extract_interface.$(OBJEXT) +am_extract_interface_OBJECTS = extract_interface-python.$(OBJEXT) \ + extract_interface-extract_interface.$(OBJEXT) extract_interface_OBJECTS = $(am_extract_interface_OBJECTS) am__DEPENDENCIES_1 = extract_interface_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @@ -87,6 +116,19 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -99,17 +141,16 @@ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -118,17 +159,16 @@ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(extract_interface_SOURCES) DIST_SOURCES = $(extract_interface_SOURCES) am__can_run_installinfo = \ @@ -136,6 +176,23 @@ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -174,9 +231,6 @@ GIT_HEAD = @GIT_HEAD@ GIT_HEAD_ID = @GIT_HEAD_ID@ GIT_HEAD_VERSION = @GIT_HEAD_VERSION@ -GMP_CPPFLAGS = @GMP_CPPFLAGS@ -GMP_LDFLAGS = @GMP_LDFLAGS@ -GMP_LIBS = @GMP_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -195,6 +249,9 @@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MP_CPPFLAGS = @MP_CPPFLAGS@ +MP_LDFLAGS = @MP_LDFLAGS@ +MP_LIBS = @MP_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ @@ -211,9 +268,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ -PIPLIB_CPPFLAGS = @PIPLIB_CPPFLAGS@ -PIPLIB_LDFLAGS = @PIPLIB_LDFLAGS@ -PIPLIB_LIBS = @PIPLIB_LIBS@ POD2HTML = @POD2HTML@ PRTDIAG = @PRTDIAG@ RANLIB = @RANLIB@ @@ -283,9 +337,10 @@ AUTOMAKE_OPTIONS = nostdinc AM_CXXFLAGS = $(CLANG_CXXFLAGS) AM_LDFLAGS = $(CLANG_LDFLAGS) -INCLUDES = -I$(top_builddir) -I$(top_srcdir) \ +includes = -I$(top_builddir) -I$(top_srcdir) \ -I$(top_builddir)/include -I$(top_srcdir)/include +extract_interface_CPPFLAGS = $(includes) extract_interface_SOURCES = \ python.h \ python.cc \ @@ -341,6 +396,7 @@ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + extract_interface$(EXEEXT): $(extract_interface_OBJECTS) $(extract_interface_DEPENDENCIES) $(EXTRA_extract_interface_DEPENDENCIES) @rm -f extract_interface$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(extract_interface_OBJECTS) $(extract_interface_LDADD) $(LIBS) @@ -351,8 +407,8 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/python.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-extract_interface.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-python.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -375,32 +431,49 @@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< +extract_interface-python.o: python.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-python.o -MD -MP -MF $(DEPDIR)/extract_interface-python.Tpo -c -o extract_interface-python.o `test -f 'python.cc' || echo '$(srcdir)/'`python.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-python.Tpo $(DEPDIR)/extract_interface-python.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='python.cc' object='extract_interface-python.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-python.o `test -f 'python.cc' || echo '$(srcdir)/'`python.cc + +extract_interface-python.obj: python.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-python.obj -MD -MP -MF $(DEPDIR)/extract_interface-python.Tpo -c -o extract_interface-python.obj `if test -f 'python.cc'; then $(CYGPATH_W) 'python.cc'; else $(CYGPATH_W) '$(srcdir)/python.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-python.Tpo $(DEPDIR)/extract_interface-python.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='python.cc' object='extract_interface-python.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-python.obj `if test -f 'python.cc'; then $(CYGPATH_W) 'python.cc'; else $(CYGPATH_W) '$(srcdir)/python.cc'; fi` + +extract_interface-extract_interface.o: extract_interface.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-extract_interface.o -MD -MP -MF $(DEPDIR)/extract_interface-extract_interface.Tpo -c -o extract_interface-extract_interface.o `test -f 'extract_interface.cc' || echo '$(srcdir)/'`extract_interface.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-extract_interface.Tpo $(DEPDIR)/extract_interface-extract_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='extract_interface.cc' object='extract_interface-extract_interface.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-extract_interface.o `test -f 'extract_interface.cc' || echo '$(srcdir)/'`extract_interface.cc + +extract_interface-extract_interface.obj: extract_interface.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-extract_interface.obj -MD -MP -MF $(DEPDIR)/extract_interface-extract_interface.Tpo -c -o extract_interface-extract_interface.obj `if test -f 'extract_interface.cc'; then $(CYGPATH_W) 'extract_interface.cc'; else $(CYGPATH_W) '$(srcdir)/extract_interface.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-extract_interface.Tpo $(DEPDIR)/extract_interface-extract_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='extract_interface.cc' object='extract_interface-extract_interface.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-extract_interface.obj `if test -f 'extract_interface.cc'; then $(CYGPATH_W) 'extract_interface.cc'; else $(CYGPATH_W) '$(srcdir)/extract_interface.cc'; fi` + mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -412,15 +485,11 @@ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -429,6 +498,21 @@ here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -573,26 +657,27 @@ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstPROGRAMS ctags dist-hook distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am dist-hook distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am test: extract_interface - ./extract_interface$(EXEEXT) $(INCLUDES) $(srcdir)/all.h + ./extract_interface$(EXEEXT) $(includes) $(srcdir)/all.h isl.py: extract_interface isl.py.top (cat $(srcdir)/isl.py.top; \ - ./extract_interface$(EXEEXT) $(INCLUDES) $(srcdir)/all.h) \ + ./extract_interface$(EXEEXT) $(includes) $(srcdir)/all.h) \ > isl.py dist-hook: isl.py diff -Nru isl-0.12.2/interface/python.cc isl-0.15/interface/python.cc --- isl-0.12.2/interface/python.cc 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/interface/python.cc 2015-06-02 09:28:09.000000000 +0000 @@ -31,6 +31,8 @@ * Sven Verdoolaege. */ +#include "isl_config.h" + #include #include #include @@ -218,8 +220,8 @@ for (int i = 0; i < n_arg - 1; ++i) { string arg_type; arg_type = type2python(extract_type(fn->getArgType(i))); - printf(" cb_arg%d = %s(ctx=arg0.ctx, ptr=cb_arg%d)\n", - i, arg_type.c_str(), i); + printf(" cb_arg%d = %s(ctx=arg0.ctx, " + "ptr=cb_arg%d)\n", i, arg_type.c_str(), i); } printf(" try:\n"); printf(" arg%d(", arg); @@ -326,9 +328,9 @@ printf(", None"); printf(")\n"); - if (is_isl_type(method->getResultType())) { + if (is_isl_type(method->getReturnType())) { string type; - type = type2python(extract_type(method->getResultType())); + type = type2python(extract_type(method->getReturnType())); printf(" return %s(ctx=arg0.ctx, ptr=res)\n", type.c_str()); } else { @@ -444,7 +446,8 @@ printf(" libc.free(ptr)\n"); printf(" return res\n"); printf(" def __repr__(self):\n"); - printf(" return 'isl.%s(\"%%s\")' %% str(self)\n", p_name.c_str()); + printf(" return 'isl.%s(\"%%s\")' %% str(self)\n", + p_name.c_str()); for (in = methods.begin(); in != methods.end(); ++in) print_method(*in, subclass, super); @@ -472,7 +475,7 @@ } for (in = methods.begin(); in != methods.end(); ++in) { string fullname = (*in)->getName(); - if (is_isl_type((*in)->getResultType())) + if (is_isl_type((*in)->getReturnType())) printf("isl.%s.restype = c_void_p\n", fullname.c_str()); } printf("isl.%s_free.argtypes = [c_void_p]\n", name.c_str()); diff -Nru isl-0.12.2/isl_aff.c isl-0.15/isl_aff.c --- isl-0.12.2/isl_aff.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_aff.c 2015-06-10 18:25:32.000000000 +0000 @@ -1,7 +1,8 @@ /* * Copyright 2011 INRIA Saclay * Copyright 2011 Sven Verdoolaege - * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * @@ -9,6 +10,8 @@ * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include @@ -18,11 +21,13 @@ #include #include #include +#include #include #include -#include +#include #include #include +#include #include #undef BASE @@ -35,6 +40,16 @@ #include +#undef BASE +#define BASE union_pw_aff + +#include + +#undef BASE +#define BASE union_pw_multi_aff + +#include + __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, __isl_take isl_vec *v) { @@ -106,6 +121,61 @@ return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls)); } +/* Return an affine expression defined on the specified domain + * that represents NaN. + */ +__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls) +{ + isl_aff *aff; + + aff = isl_aff_alloc(ls); + if (!aff) + return NULL; + + isl_seq_clr(aff->v->el, aff->v->size); + + return aff; +} + +/* Return a piecewise affine expression defined on the specified domain + * that represents NaN. + */ +__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls) +{ + return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls)); +} + +/* Return an affine expression that is equal to "val" on + * domain local space "ls". + */ +__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls, + __isl_take isl_val *val) +{ + isl_aff *aff; + + if (!ls || !val) + goto error; + if (!isl_val_is_rat(val)) + isl_die(isl_val_get_ctx(val), isl_error_invalid, + "expecting rational value", goto error); + + aff = isl_aff_alloc(isl_local_space_copy(ls)); + if (!aff) + goto error; + + isl_seq_clr(aff->v->el + 2, aff->v->size - 2); + isl_int_set(aff->v->el[1], val->n); + isl_int_set(aff->v->el[0], val->d); + + isl_local_space_free(ls); + isl_val_free(val); + return aff; +error: + isl_local_space_free(ls); + isl_val_free(val); + return NULL; +} + /* Return an affine expression that is equal to the specified dimension * in "ls". */ @@ -184,7 +254,7 @@ return isl_aff_dup(aff); } -void *isl_aff_free(__isl_take isl_aff *aff) +__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff) { if (!aff) return NULL; @@ -219,6 +289,22 @@ return isl_local_space_dim(aff->ls, type); } +/* Return the position of the dimension of the given type and name + * in "aff". + * Return -1 if no such dimension can be found. + */ +int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type, + const char *name) +{ + if (!aff) + return -1; + if (type == isl_dim_out) + return -1; + if (type == isl_dim_in) + type = isl_dim_set; + return isl_local_space_find_dim_by_name(aff->ls, type, name); +} + __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff) { return aff ? isl_local_space_get_space(aff->ls) : NULL; @@ -379,20 +465,64 @@ return NULL; } -int isl_aff_plain_is_zero(__isl_keep isl_aff *aff) +/* Is "aff" obviously equal to zero? + * + * If the denominator is zero, then "aff" is not equal to zero. + */ +isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff) { if (!aff) - return -1; + return isl_bool_error; + if (isl_int_is_zero(aff->v->el[0])) + return isl_bool_false; return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0; } -int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2) +/* Does "aff" represent NaN? + */ +isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff) { - int equal; + if (!aff) + return isl_bool_error; + + return isl_seq_first_non_zero(aff->v->el, 2) < 0; +} + +/* Does "pa" involve any NaNs? + */ +isl_bool isl_pw_aff_involves_nan(__isl_keep isl_pw_aff *pa) +{ + int i; + + if (!pa) + return isl_bool_error; + if (pa->n == 0) + return isl_bool_false; + + for (i = 0; i < pa->n; ++i) { + isl_bool is_nan = isl_aff_is_nan(pa->p[i].aff); + if (is_nan < 0 || is_nan) + return is_nan; + } + + return isl_bool_false; +} + +/* Are "aff1" and "aff2" obviously equal? + * + * NaN is not equal to anything, not even to another NaN. + */ +isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, + __isl_keep isl_aff *aff2) +{ + isl_bool equal; if (!aff1 || !aff2) - return -1; + return isl_bool_error; + + if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2)) + return isl_bool_false; equal = isl_local_space_is_equal(aff1->ls, aff2->ls); if (equal < 0 || !equal) @@ -401,10 +531,17 @@ return isl_vec_is_equal(aff1->v, aff2->v); } +/* Return the common denominator of "aff" in "v". + * + * We cannot return anything meaningful in case of a NaN. + */ int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v) { if (!aff) return -1; + if (isl_aff_is_nan(aff)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot get denominator of NaN", return -1); isl_int_set(*v, aff->v->el[0]); return 0; } @@ -419,13 +556,22 @@ return NULL; ctx = isl_aff_get_ctx(aff); + if (isl_aff_is_nan(aff)) + return isl_val_nan(ctx); return isl_val_int_from_isl_int(ctx, aff->v->el[0]); } +/* Return the constant term of "aff" in "v". + * + * We cannot return anything meaningful in case of a NaN. + */ int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v) { if (!aff) return -1; + if (isl_aff_is_nan(aff)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot get constant term of NaN", return -1); isl_int_set(*v, aff->v->el[1]); return 0; } @@ -441,10 +587,17 @@ return NULL; ctx = isl_aff_get_ctx(aff); + if (isl_aff_is_nan(aff)) + return isl_val_nan(ctx); v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]); return isl_val_normalize(v); } +/* Return the coefficient of the variable of type "type" at position "pos" + * of "aff" in "v". + * + * We cannot return anything meaningful in case of a NaN. + */ int isl_aff_get_coefficient(__isl_keep isl_aff *aff, enum isl_dim_type type, int pos, isl_int *v) { @@ -462,6 +615,9 @@ isl_die(aff->v->ctx, isl_error_invalid, "position out of bounds", return -1); + if (isl_aff_is_nan(aff)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot get coefficient of NaN", return -1); pos += isl_local_space_offset(aff->ls, type); isl_int_set(*v, aff->v->el[1 + pos]); @@ -492,13 +648,50 @@ isl_die(ctx, isl_error_invalid, "position out of bounds", return NULL); + if (isl_aff_is_nan(aff)) + return isl_val_nan(ctx); pos += isl_local_space_offset(aff->ls, type); v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]); return isl_val_normalize(v); } +/* Return the sign of the coefficient of the variable of type "type" + * at position "pos" of "aff". + */ +int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type, + int pos) +{ + isl_ctx *ctx; + + if (!aff) + return 0; + + ctx = isl_aff_get_ctx(aff); + if (type == isl_dim_out) + isl_die(ctx, isl_error_invalid, + "output/set dimension does not have a coefficient", + return 0); + if (type == isl_dim_in) + type = isl_dim_set; + + if (pos >= isl_local_space_dim(aff->ls, type)) + isl_die(ctx, isl_error_invalid, + "position out of bounds", return 0); + + pos += isl_local_space_offset(aff->ls, type); + return isl_int_sgn(aff->v->el[1 + pos]); +} + +/* Replace the denominator of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v) { + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -512,8 +705,16 @@ return aff; } +/* Replace the numerator of the constant term of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v) { + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -528,6 +729,8 @@ } /* Replace the constant term of "aff" by "v". + * + * A NaN is unaffected by this operation. */ __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v) @@ -535,6 +738,11 @@ if (!aff || !v) goto error; + if (isl_aff_is_nan(aff)) { + isl_val_free(v); + return aff; + } + if (!isl_val_is_rat(v)) isl_die(isl_aff_get_ctx(aff), isl_error_invalid, "expecting rational value", goto error); @@ -574,11 +782,19 @@ return NULL; } +/* Add "v" to the constant term of "aff". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v) { if (isl_int_is_zero(v)) return aff; + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -593,6 +809,8 @@ } /* Add "v" to the constant term of "aff". + * + * A NaN is unaffected by this operation. */ __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v) @@ -600,7 +818,7 @@ if (!aff || !v) goto error; - if (isl_val_is_zero(v)) { + if (isl_aff_is_nan(aff) || isl_val_is_zero(v)) { isl_val_free(v); return aff; } @@ -655,12 +873,18 @@ } /* Add "v" to the numerator of the constant term of "aff". + * + * A NaN is unaffected by this operation. */ __isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v) { if (isl_int_is_zero(v)) return aff; + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -675,6 +899,8 @@ } /* Add "v" to the numerator of the constant term of "aff". + * + * A NaN is unaffected by this operation. */ __isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v) { @@ -691,8 +917,16 @@ return aff; } +/* Replace the numerator of the constant term of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v) { + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -706,6 +940,11 @@ return aff; } +/* Replace the numerator of the coefficient of the variable of type "type" + * at position "pos" of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, isl_int v) { @@ -723,6 +962,8 @@ isl_die(aff->v->ctx, isl_error_invalid, "position out of bounds", return isl_aff_free(aff)); + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -737,6 +978,11 @@ return aff; } +/* Replace the numerator of the coefficient of the variable of type "type" + * at position "pos" of "aff" by "v". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, int v) { @@ -750,10 +996,16 @@ if (type == isl_dim_in) type = isl_dim_set; - if (pos >= isl_local_space_dim(aff->ls, type)) + if (pos < 0 || pos >= isl_local_space_dim(aff->ls, type)) isl_die(aff->v->ctx, isl_error_invalid, "position out of bounds", return isl_aff_free(aff)); + if (isl_aff_is_nan(aff)) + return aff; + pos += isl_local_space_offset(aff->ls, type); + if (isl_int_cmp_si(aff->v->el[1 + pos], v) == 0) + return aff; + aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -762,7 +1014,6 @@ if (!aff->v) return isl_aff_free(aff); - pos += isl_local_space_offset(aff->ls, type); isl_int_set_si(aff->v->el[1 + pos], v); return aff; @@ -770,6 +1021,8 @@ /* Replace the coefficient of the variable of type "type" at position "pos" * of "aff" by "v". + * + * A NaN is unaffected by this operation. */ __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, __isl_take isl_val *v) @@ -788,6 +1041,10 @@ isl_die(aff->v->ctx, isl_error_invalid, "position out of bounds", goto error); + if (isl_aff_is_nan(aff)) { + isl_val_free(v); + return aff; + } if (!isl_val_is_rat(v)) isl_die(isl_aff_get_ctx(aff), isl_error_invalid, "expecting rational value", goto error); @@ -828,6 +1085,11 @@ return NULL; } +/* Add "v" to the coefficient of the variable of type "type" + * at position "pos" of "aff". + * + * A NaN is unaffected by this operation. + */ __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, isl_int v) { @@ -845,6 +1107,8 @@ isl_die(aff->v->ctx, isl_error_invalid, "position out of bounds", return isl_aff_free(aff)); + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -861,6 +1125,8 @@ /* Add "v" to the coefficient of the variable of type "type" * at position "pos" of "aff". + * + * A NaN is unaffected by this operation. */ __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, __isl_take isl_val *v) @@ -884,6 +1150,10 @@ isl_die(aff->v->ctx, isl_error_invalid, "position out of bounds", goto error); + if (isl_aff_is_nan(aff)) { + isl_val_free(v); + return aff; + } if (!isl_val_is_rat(v)) isl_die(isl_aff_get_ctx(aff), isl_error_invalid, "expecting rational value", goto error); @@ -943,8 +1213,16 @@ return isl_local_space_get_div(aff->ls, pos); } +/* Return the negation of "aff". + * + * As a special case, -NaN = NaN. + */ __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff) { + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; aff = isl_aff_cow(aff); if (!aff) return NULL; @@ -1182,12 +1460,10 @@ static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff) { int i, j, n; - unsigned off; if (!aff) return NULL; - off = isl_local_space_offset(aff->ls, isl_dim_div); n = isl_aff_dim(aff, isl_dim_div); for (i = 1; i < n; ++i) { for (j = i - 1; j >= 0; --j) { @@ -1232,6 +1508,8 @@ * Otherwise, if f = g/m, write g = q m + r, * create a new div d = [r/m] and return the expression q + d. * The coefficients in r are taken to lie between -m/2 and m/2. + * + * As a special case, floor(NaN) = NaN. */ __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff) { @@ -1243,6 +1521,8 @@ if (!aff) return NULL; + if (isl_aff_is_nan(aff)) + return aff; if (isl_int_is_one(aff->v->el[0])) return aff; @@ -1389,12 +1669,16 @@ * then return * * floor((e + m - 1)/m) + * + * As a special case, ceil(NaN) = NaN. */ __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff) { if (!aff) return NULL; + if (isl_aff_is_nan(aff)) + return aff; if (isl_int_is_one(aff->v->el[0])) return aff; @@ -1496,6 +1780,10 @@ return NULL; } +/* Return the sum of "aff1" and "aff2". + * + * If either of the two is NaN, then the result is NaN. + */ __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2) { @@ -1513,6 +1801,15 @@ isl_die(ctx, isl_error_invalid, "spaces don't match", goto error); + if (isl_aff_is_nan(aff1)) { + isl_aff_free(aff2); + return aff1; + } + if (isl_aff_is_nan(aff2)) { + isl_aff_free(aff1); + return aff2; + } + n_div1 = isl_aff_dim(aff1, isl_dim_div); n_div2 = isl_aff_dim(aff2, isl_dim_div); if (n_div1 == 0 && n_div2 == 0) @@ -1544,10 +1841,19 @@ return isl_aff_add(aff1, isl_aff_neg(aff2)); } +/* Return the result of scaling "aff" by a factor of "f". + * + * As a special case, f * NaN = NaN. + */ __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f) { isl_int gcd; + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; + if (isl_int_is_one(f)) return aff; @@ -1601,10 +1907,19 @@ return NULL; } +/* Return the result of scaling "aff" down by a factor of "f". + * + * As a special case, NaN/f = NaN. + */ __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f) { isl_int gcd; + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) + return aff; + if (isl_int_is_one(f)) return aff; @@ -1701,7 +2016,7 @@ { aff = isl_aff_cow(aff); if (!aff) - return isl_id_free(id); + goto error; if (type == isl_dim_out) isl_die(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension", @@ -1719,6 +2034,29 @@ return NULL; } +/* Replace the identifier of the input tuple of "aff" by "id". + * type is currently required to be equal to isl_dim_in + */ +__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff, + enum isl_dim_type type, __isl_take isl_id *id) +{ + aff = isl_aff_cow(aff); + if (!aff) + goto error; + if (type != isl_dim_out) + isl_die(aff->v->ctx, isl_error_invalid, + "cannot only set id of input tuple", goto error); + aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id); + if (!aff->ls) + return isl_aff_free(aff); + + return aff; +error: + isl_id_free(id); + isl_aff_free(aff); + return NULL; +} + /* Exploit the equalities in "eq" to simplify the affine expression * and the expressions of the integer divisions in the local space. * The integer divisions in this local space are assumed to appear @@ -1771,8 +2109,8 @@ /* Exploit the equalities in "eq" to simplify the affine expression * and the expressions of the integer divisions in the local space. */ -static __isl_give isl_aff *isl_aff_substitute_equalities( - __isl_take isl_aff *aff, __isl_take isl_basic_set *eq) +__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff, + __isl_take isl_basic_set *eq) { int n_div; @@ -1831,8 +2169,46 @@ } /* Return a basic set containing those elements in the space + * of aff where it is positive. "rational" should not be set. + * + * If "aff" is NaN, then it is not positive. + */ +static __isl_give isl_basic_set *aff_pos_basic_set(__isl_take isl_aff *aff, + int rational) +{ + isl_constraint *ineq; + isl_basic_set *bset; + isl_val *c; + + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) { + isl_space *space = isl_aff_get_domain_space(aff); + isl_aff_free(aff); + return isl_basic_set_empty(space); + } + if (rational) + isl_die(isl_aff_get_ctx(aff), isl_error_unsupported, + "rational sets not supported", goto error); + + ineq = isl_inequality_from_aff(aff); + c = isl_constraint_get_constant_val(ineq); + c = isl_val_sub_ui(c, 1); + ineq = isl_constraint_set_constant_val(ineq, c); + + bset = isl_basic_set_from_constraint(ineq); + bset = isl_basic_set_simplify(bset); + return bset; +error: + isl_aff_free(aff); + return NULL; +} + +/* Return a basic set containing those elements in the space * of aff where it is non-negative. * If "rational" is set, then return a rational basic set. + * + * If "aff" is NaN, then it is not non-negative (it's not negative either). */ static __isl_give isl_basic_set *aff_nonneg_basic_set( __isl_take isl_aff *aff, int rational) @@ -1840,6 +2216,14 @@ isl_constraint *ineq; isl_basic_set *bset; + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) { + isl_space *space = isl_aff_get_domain_space(aff); + isl_aff_free(aff); + return isl_basic_set_empty(space); + } + ineq = isl_inequality_from_aff(aff); bset = isl_basic_set_from_constraint(ineq); @@ -1870,6 +2254,8 @@ /* Return a basic set containing those elements in the space * of aff where it is zero. * If "rational" is set, then return a rational basic set. + * + * If "aff" is NaN, then it is not zero. */ static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff, int rational) @@ -1877,6 +2263,14 @@ isl_constraint *ineq; isl_basic_set *bset; + if (!aff) + return NULL; + if (isl_aff_is_nan(aff)) { + isl_space *space = isl_aff_get_domain_space(aff); + isl_aff_free(aff); + return isl_basic_set_empty(space); + } + ineq = isl_equality_from_aff(aff); bset = isl_basic_set_from_constraint(ineq); @@ -1935,23 +2329,23 @@ * appear with non-zero coefficients in any of the integer divisions * involved in the affine expression. */ -int isl_aff_involves_dims(__isl_keep isl_aff *aff, +isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, enum isl_dim_type type, unsigned first, unsigned n) { int i; isl_ctx *ctx; int *active = NULL; - int involves = 0; + isl_bool involves = isl_bool_false; if (!aff) - return -1; + return isl_bool_error; if (n == 0) - return 0; + return isl_bool_false; ctx = isl_aff_get_ctx(aff); if (first + n > isl_aff_dim(aff, type)) isl_die(ctx, isl_error_invalid, - "range out of bounds", return -1); + "range out of bounds", return isl_bool_error); active = isl_local_space_get_active(aff->ls, aff->v->el + 2); if (!active) @@ -1960,7 +2354,7 @@ first += isl_local_space_offset(aff->ls, type) - 1; for (i = 0; i < n; ++i) if (active[first + i]) { - involves = 1; + involves = isl_bool_true; break; } @@ -1969,7 +2363,7 @@ return involves; error: free(active); - return -1; + return isl_bool_error; } __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff, @@ -2090,15 +2484,74 @@ return isl_pw_aff_insert_dims(pwaff, type, pos, n); } -__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff) +/* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff" + * to dimensions of "dst_type" at "dst_pos". + * + * We only support moving input dimensions to parameters and vice versa. + */ +__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) { - isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff)); - return isl_pw_aff_alloc(dom, aff); -} + unsigned g_dst_pos; + unsigned g_src_pos; -#undef PW -#define PW isl_pw_aff -#undef EL + if (!aff) + return NULL; + if (n == 0 && + !isl_local_space_is_named_or_nested(aff->ls, src_type) && + !isl_local_space_is_named_or_nested(aff->ls, dst_type)) + return aff; + + if (dst_type == isl_dim_out || src_type == isl_dim_out) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot move output/set dimension", + return isl_aff_free(aff)); + if (dst_type == isl_dim_div || src_type == isl_dim_div) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot move divs", return isl_aff_free(aff)); + if (dst_type == isl_dim_in) + dst_type = isl_dim_set; + if (src_type == isl_dim_in) + src_type = isl_dim_set; + + if (src_pos + n > isl_local_space_dim(aff->ls, src_type)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "range out of bounds", return isl_aff_free(aff)); + if (dst_type == src_type) + isl_die(isl_aff_get_ctx(aff), isl_error_unsupported, + "moving dims within the same type not supported", + return isl_aff_free(aff)); + + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + + g_src_pos = 1 + isl_local_space_offset(aff->ls, src_type) + src_pos; + g_dst_pos = 1 + isl_local_space_offset(aff->ls, dst_type) + dst_pos; + if (dst_type > src_type) + g_dst_pos -= n; + + aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n); + aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos, + src_type, src_pos, n); + if (!aff->v || !aff->ls) + return isl_aff_free(aff); + + aff = sort_divs(aff); + + return aff; +} + +__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff) +{ + isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff)); + return isl_pw_aff_alloc(dom, aff); +} + +#undef PW +#define PW isl_pw_aff +#undef EL #define EL isl_aff #undef EL_IS_ZERO #define EL_IS_ZERO is_empty @@ -2113,12 +2566,22 @@ #define NO_EVAL #define NO_OPT -#define NO_MOVE_DIMS #define NO_LIFT #define NO_MORPH #include +#undef UNION +#define UNION isl_union_pw_aff +#undef PART +#define PART isl_pw_aff +#undef PARTS +#define PARTS pw_aff + +#define NO_EVAL + +#include + static __isl_give isl_set *align_params_pw_pw_set_and( __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2, __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1, @@ -2142,6 +2605,31 @@ return NULL; } +/* Align the parameters of the to isl_pw_aff arguments and + * then apply a function "fn" on them that returns an isl_map. + */ +static __isl_give isl_map *align_params_pw_pw_map_and( + __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2, + __isl_give isl_map *(*fn)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2)) +{ + if (!pa1 || !pa2) + goto error; + if (isl_space_match(pa1->dim, isl_dim_param, pa2->dim, isl_dim_param)) + return fn(pa1, pa2); + if (!isl_space_has_named_params(pa1->dim) || + !isl_space_has_named_params(pa2->dim)) + isl_die(isl_pw_aff_get_ctx(pa1), isl_error_invalid, + "unaligned unnamed parameters", goto error); + pa1 = isl_pw_aff_align_params(pa1, isl_pw_aff_get_space(pa2)); + pa2 = isl_pw_aff_align_params(pa2, isl_pw_aff_get_space(pa1)); + return fn(pa1, pa2); +error: + isl_pw_aff_free(pa1); + isl_pw_aff_free(pa2); + return NULL; +} + /* Compute a piecewise quasi-affine expression with a domain that * is the union of those of pwaff1 and pwaff2 and such that on each * cell, the quasi-affine expression is the better (according to cmp) @@ -2312,9 +2800,11 @@ return NULL; if (isl_space_is_set(pwaff->dim)) isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid, - "space of input is not a map", - return isl_pw_aff_free(pwaff)); + "space of input is not a map", goto error); return map_from_pw_aff(pwaff); +error: + isl_pw_aff_free(pwaff); + return NULL; } /* Construct a one-dimensional set with as parameter domain @@ -2327,15 +2817,23 @@ return NULL; if (!isl_space_is_set(pwaff->dim)) isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid, - "space of input is not a set", - return isl_pw_aff_free(pwaff)); + "space of input is not a set", goto error); return map_from_pw_aff(pwaff); +error: + isl_pw_aff_free(pwaff); + return NULL; } /* Return a set containing those elements in the domain - * of pwaff where it is non-negative. + * of "pwaff" where it satisfies "fn" (if complement is 0) or + * does not satisfy "fn" (if complement is 1). + * + * The pieces with a NaN never belong to the result since + * NaN does not satisfy any property. */ -__isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff) +static __isl_give isl_set *pw_aff_locus(__isl_take isl_pw_aff *pwaff, + __isl_give isl_basic_set *(*fn)(__isl_take isl_aff *aff, int rational), + int complement) { int i; isl_set *set; @@ -2347,14 +2845,20 @@ for (i = 0; i < pwaff->n; ++i) { isl_basic_set *bset; - isl_set *set_i; + isl_set *set_i, *locus; int rational; + if (isl_aff_is_nan(pwaff->p[i].aff)) + continue; + rational = isl_set_has_rational(pwaff->p[i].set); - bset = aff_nonneg_basic_set(isl_aff_copy(pwaff->p[i].aff), - rational); - set_i = isl_set_from_basic_set(bset); - set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set)); + bset = fn(isl_aff_copy(pwaff->p[i].aff), rational); + locus = isl_set_from_basic_set(bset); + set_i = isl_set_copy(pwaff->p[i].set); + if (complement) + set_i = isl_set_subtract(set_i, locus); + else + set_i = isl_set_intersect(set_i, locus); set = isl_set_union_disjoint(set, set_i); } @@ -2364,40 +2868,19 @@ } /* Return a set containing those elements in the domain - * of pwaff where it is zero (if complement is 0) or not zero - * (if complement is 1). + * of "pa" where it is positive. */ -static __isl_give isl_set *pw_aff_zero_set(__isl_take isl_pw_aff *pwaff, - int complement) +__isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa) { - int i; - isl_set *set; - - if (!pwaff) - return NULL; - - set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff)); - - for (i = 0; i < pwaff->n; ++i) { - isl_basic_set *bset; - isl_set *set_i, *zero; - int rational; - - rational = isl_set_has_rational(pwaff->p[i].set); - bset = aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff), - rational); - zero = isl_set_from_basic_set(bset); - set_i = isl_set_copy(pwaff->p[i].set); - if (complement) - set_i = isl_set_subtract(set_i, zero); - else - set_i = isl_set_intersect(set_i, zero); - set = isl_set_union_disjoint(set, set_i); - } - - isl_pw_aff_free(pwaff); + return pw_aff_locus(pa, &aff_pos_basic_set, 0); +} - return set; +/* Return a set containing those elements in the domain + * of pwaff where it is non-negative. + */ +__isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff) +{ + return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0); } /* Return a set containing those elements in the domain @@ -2405,7 +2888,7 @@ */ __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff) { - return pw_aff_zero_set(pwaff, 0); + return pw_aff_locus(pwaff, &aff_zero_basic_set, 0); } /* Return a set containing those elements in the domain @@ -2413,7 +2896,7 @@ */ __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff) { - return pw_aff_zero_set(pwaff, 1); + return pw_aff_locus(pwaff, &aff_zero_basic_set, 1); } /* Return a set containing those elements in the shared domain @@ -2508,6 +2991,97 @@ return isl_pw_aff_gt_set(pwaff2, pwaff1); } +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function values are ordered in the same way as "order", + * which returns a set in the shared domain of its two arguments. + * The parameters of "pa1" and "pa2" are assumed to have been aligned. + * + * Let "pa1" and "pa2" be defined on domains A and B respectively. + * We first pull back the two functions such that they are defined on + * the domain [A -> B]. Then we apply "order", resulting in a set + * in the space [A -> B]. Finally, we unwrap this set to obtain + * a map in the space A -> B. + */ +static __isl_give isl_map *isl_pw_aff_order_map_aligned( + __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2, + __isl_give isl_set *(*order)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2)) +{ + isl_space *space1, *space2; + isl_multi_aff *ma; + isl_set *set; + + space1 = isl_space_domain(isl_pw_aff_get_space(pa1)); + space2 = isl_space_domain(isl_pw_aff_get_space(pa2)); + space1 = isl_space_map_from_domain_and_range(space1, space2); + ma = isl_multi_aff_domain_map(isl_space_copy(space1)); + pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma); + ma = isl_multi_aff_range_map(space1); + pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma); + set = order(pa1, pa2); + + return isl_set_unwrap(set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function values are equal. + * The parameters of "pa1" and "pa2" are assumed to have been aligned. + */ +static __isl_give isl_map *isl_pw_aff_eq_map_aligned(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_eq_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function values are equal. + */ +__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_eq_map_aligned); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is less than the function value of "pa2". + * The parameters of "pa1" and "pa2" are assumed to have been aligned. + */ +static __isl_give isl_map *isl_pw_aff_lt_map_aligned(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_lt_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is less than the function value of "pa2". + */ +__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_lt_map_aligned); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is greater than the function value + * of "pa2". + * The parameters of "pa1" and "pa2" are assumed to have been aligned. + */ +static __isl_give isl_map *isl_pw_aff_gt_map_aligned(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_gt_set); +} + +/* Return a map containing pairs of elements in the domains of "pa1" and "pa2" + * where the function value of "pa1" is greater than the function value + * of "pa2". + */ +__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2) +{ + return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_gt_map_aligned); +} + /* Return a set containing those elements in the shared domain * of the elements of list1 and list2 where each element in list1 * has the relation specified by "fn" with each element in list2. @@ -2639,49 +3213,6 @@ return pwaff; } -/* Divide "pa" by "f". - */ -__isl_give isl_pw_aff *isl_pw_aff_scale_down_val(__isl_take isl_pw_aff *pa, - __isl_take isl_val *f) -{ - int i; - - if (!pa || !f) - goto error; - - if (isl_val_is_one(f)) { - isl_val_free(f); - return pa; - } - - if (!isl_val_is_rat(f)) - isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, - "expecting rational factor", goto error); - if (!isl_val_is_pos(f)) - isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, - "factor needs to be positive", goto error); - - pa = isl_pw_aff_cow(pa); - if (!pa) - return NULL; - if (pa->n == 0) - return pa; - - for (i = 0; i < pa->n; ++i) { - pa->p[i].aff = isl_aff_scale_down_val(pa->p[i].aff, - isl_val_copy(f)); - if (!pa->p[i].aff) - goto error; - } - - isl_val_free(f); - return pa; -error: - isl_pw_aff_free(pa); - isl_val_free(f); - return NULL; -} - __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff) { int i; @@ -2738,47 +3269,85 @@ * where "cond" is non-zero and to pwaff_false for elements where "cond" * is zero. * That is, return cond ? pwaff_true : pwaff_false; + * + * If "cond" involves and NaN, then we conservatively return a NaN + * on its entire domain. In principle, we could consider the pieces + * where it is NaN separately from those where it is not. */ __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond, __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false) { isl_set *cond_true, *cond_false; + if (!cond) + goto error; + if (isl_pw_aff_involves_nan(cond)) { + isl_space *space = isl_pw_aff_get_domain_space(cond); + isl_local_space *ls = isl_local_space_from_space(space); + isl_pw_aff_free(cond); + isl_pw_aff_free(pwaff_true); + isl_pw_aff_free(pwaff_false); + return isl_pw_aff_nan_on_domain(ls); + } + cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond)); cond_false = isl_pw_aff_zero_set(cond); return isl_pw_aff_select(cond_true, pwaff_true, cond_false, pwaff_false); +error: + isl_pw_aff_free(cond); + isl_pw_aff_free(pwaff_true); + isl_pw_aff_free(pwaff_false); + return NULL; } -int isl_aff_is_cst(__isl_keep isl_aff *aff) +isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff) { if (!aff) - return -1; + return isl_bool_error; return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1; } /* Check whether pwaff is a piecewise constant. */ -int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff) +isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff) { int i; if (!pwaff) - return -1; + return isl_bool_error; for (i = 0; i < pwaff->n; ++i) { - int is_cst = isl_aff_is_cst(pwaff->p[i].aff); + isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff); if (is_cst < 0 || !is_cst) return is_cst; } - return 1; + return isl_bool_true; } +/* Return the product of "aff1" and "aff2". + * + * If either of the two is NaN, then the result is NaN. + * + * Otherwise, at least one of "aff1" or "aff2" needs to be a constant. + */ __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2) { + if (!aff1 || !aff2) + goto error; + + if (isl_aff_is_nan(aff1)) { + isl_aff_free(aff2); + return aff1; + } + if (isl_aff_is_nan(aff2)) { + isl_aff_free(aff1); + return aff2; + } + if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1)) return isl_aff_mul(aff2, aff1); @@ -2802,7 +3371,9 @@ return NULL; } -/* Divide "aff1" by "aff2", assuming "aff2" is a piecewise constant. +/* Divide "aff1" by "aff2", assuming "aff2" is a constant. + * + * If either of the two is NaN, then the result is NaN. */ __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2) @@ -2810,6 +3381,18 @@ int is_cst; int neg; + if (!aff1 || !aff2) + goto error; + + if (isl_aff_is_nan(aff1)) { + isl_aff_free(aff2); + return aff1; + } + if (isl_aff_is_nan(aff2)) { + isl_aff_free(aff1); + return aff2; + } + is_cst = isl_aff_is_cst(aff2); if (is_cst < 0) goto error; @@ -3022,8 +3605,7 @@ ctx = isl_pw_aff_list_get_ctx(list); if (list->n < 1) isl_die(ctx, isl_error_invalid, - "list should contain at least one element", - return isl_pw_aff_list_free(list)); + "list should contain at least one element", goto error); res = isl_pw_aff_copy(list->p[0]); for (i = 1; i < list->n; ++i) @@ -3031,6 +3613,9 @@ isl_pw_aff_list_free(list); return res; +error: + isl_pw_aff_list_free(list); + return NULL; } /* Return an isl_pw_aff that maps each element in the intersection of the @@ -3096,6 +3681,25 @@ return list; } +/* Do the parameters of "aff" match those of "space"? + */ +int isl_aff_matching_params(__isl_keep isl_aff *aff, + __isl_keep isl_space *space) +{ + isl_space *aff_space; + int match; + + if (!aff || !space) + return -1; + + aff_space = isl_aff_get_domain_space(aff); + + match = isl_space_match(space, isl_dim_param, aff_space, isl_dim_param); + + isl_space_free(aff_space); + return match; +} + /* Check that the domain space of "aff" matches "space". * * Return 0 on success and -1 on error. @@ -3117,7 +3721,7 @@ if (!match) isl_die(isl_aff_get_ctx(aff), isl_error_invalid, "parameters don't match", goto error); - match = isl_space_tuple_match(space, isl_dim_in, + match = isl_space_tuple_is_equal(space, isl_dim_in, aff_space, isl_dim_set); if (match < 0) goto error; @@ -3133,92 +3737,247 @@ #undef BASE #define BASE aff +#undef DOMBASE +#define DOMBASE set +#define NO_DOMAIN #include +#include +#include +#include -/* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe - * domain. +#undef NO_DOMAIN + +/* Remove any internal structure of the domain of "ma". + * If there is any such internal structure in the input, + * then the name of the corresponding space is also removed. */ -__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff( +__isl_give isl_multi_aff *isl_multi_aff_flatten_domain( __isl_take isl_multi_aff *ma) { - isl_set *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma)); - return isl_pw_multi_aff_alloc(dom, ma); -} + isl_space *space; -/* Create a piecewise multi-affine expression in the given space that maps each - * input dimension to the corresponding output dimension. - */ -__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( - __isl_take isl_space *space) -{ - return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space)); -} + if (!ma) + return NULL; -__isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1, - __isl_take isl_multi_aff *maff2) -{ - return isl_multi_aff_bin_op(maff1, maff2, &isl_aff_add); -} + if (!ma->space->nested[0]) + return ma; -/* Subtract "ma2" from "ma1" and return the result. - */ -__isl_give isl_multi_aff *isl_multi_aff_sub(__isl_take isl_multi_aff *ma1, - __isl_take isl_multi_aff *ma2) -{ - return isl_multi_aff_bin_op(ma1, ma2, &isl_aff_sub); + space = isl_multi_aff_get_space(ma); + space = isl_space_flatten_domain(space); + ma = isl_multi_aff_reset_space(ma, space); + + return ma; } -/* Given two multi-affine expressions A -> B and C -> D, - * construct a multi-affine expression [A -> C] -> [B -> D]. +/* Given a map space, return an isl_multi_aff that maps a wrapped copy + * of the space to its domain. */ -__isl_give isl_multi_aff *isl_multi_aff_product( - __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) +__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space) { - int i; - isl_aff *aff; - isl_space *space; - isl_multi_aff *res; - int in1, in2, out1, out2; + int i, n_in; + isl_local_space *ls; + isl_multi_aff *ma; - in1 = isl_multi_aff_dim(ma1, isl_dim_in); - in2 = isl_multi_aff_dim(ma2, isl_dim_in); - out1 = isl_multi_aff_dim(ma1, isl_dim_out); - out2 = isl_multi_aff_dim(ma2, isl_dim_out); - space = isl_space_product(isl_multi_aff_get_space(ma1), - isl_multi_aff_get_space(ma2)); - res = isl_multi_aff_alloc(isl_space_copy(space)); - space = isl_space_domain(space); + if (!space) + return NULL; + if (!isl_space_is_map(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a map space", goto error); - for (i = 0; i < out1; ++i) { - aff = isl_multi_aff_get_aff(ma1, i); - aff = isl_aff_insert_dims(aff, isl_dim_in, in1, in2); - aff = isl_aff_reset_domain_space(aff, isl_space_copy(space)); - res = isl_multi_aff_set_aff(res, i, aff); - } + n_in = isl_space_dim(space, isl_dim_in); + space = isl_space_domain_map(space); - for (i = 0; i < out2; ++i) { - aff = isl_multi_aff_get_aff(ma2, i); - aff = isl_aff_insert_dims(aff, isl_dim_in, 0, in1); - aff = isl_aff_reset_domain_space(aff, isl_space_copy(space)); - res = isl_multi_aff_set_aff(res, out1 + i, aff); + ma = isl_multi_aff_alloc(isl_space_copy(space)); + if (n_in == 0) { + isl_space_free(space); + return ma; } + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + for (i = 0; i < n_in; ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_local_space_free(ls); + return ma; +error: isl_space_free(space); - isl_multi_aff_free(ma1); - isl_multi_aff_free(ma2); - return res; + return NULL; } -/* Exploit the equalities in "eq" to simplify the affine expressions. +/* Given a map space, return an isl_multi_aff that maps a wrapped copy + * of the space to its range. */ -static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities( - __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq) +__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space) { - int i; + int i, n_in, n_out; + isl_local_space *ls; + isl_multi_aff *ma; - maff = isl_multi_aff_cow(maff); - if (!maff || !eq) + if (!space) + return NULL; + if (!isl_space_is_map(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "not a map space", goto error); + + n_in = isl_space_dim(space, isl_dim_in); + n_out = isl_space_dim(space, isl_dim_out); + space = isl_space_range_map(space); + + ma = isl_multi_aff_alloc(isl_space_copy(space)); + if (n_out == 0) { + isl_space_free(space); + return ma; + } + + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + for (i = 0; i < n_out; ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, n_in + i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_local_space_free(ls); + return ma; +error: + isl_space_free(space); + return NULL; +} + +/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy + * of the space to its range. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space)); +} + +/* Given the space of a set and a range of set dimensions, + * construct an isl_multi_aff that projects out those dimensions. + */ +__isl_give isl_multi_aff *isl_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n) +{ + int i, dim; + isl_local_space *ls; + isl_multi_aff *ma; + + if (!space) + return NULL; + if (!isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_unsupported, + "expecting set space", goto error); + if (type != isl_dim_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "only set dimensions can be projected out", goto error); + + dim = isl_space_dim(space, isl_dim_set); + if (first + n > dim) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "range out of bounds", goto error); + + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, dim - n); + + if (dim == n) + return isl_multi_aff_alloc(space); + + ma = isl_multi_aff_alloc(isl_space_copy(space)); + space = isl_space_domain(space); + ls = isl_local_space_from_space(space); + + for (i = 0; i < first; ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, i); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + for (i = 0; i < dim - (first + n); ++i) { + isl_aff *aff; + + aff = isl_aff_var_on_domain(isl_local_space_copy(ls), + isl_dim_set, first + n + i); + ma = isl_multi_aff_set_aff(ma, first + i, aff); + } + + isl_local_space_free(ls); + return ma; +error: + isl_space_free(space); + return NULL; +} + +/* Given the space of a set and a range of set dimensions, + * construct an isl_pw_multi_aff that projects out those dimensions. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map( + __isl_take isl_space *space, enum isl_dim_type type, + unsigned first, unsigned n) +{ + isl_multi_aff *ma; + + ma = isl_multi_aff_project_out_map(space, type, first, n); + return isl_pw_multi_aff_from_multi_aff(ma); +} + +/* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe + * domain. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + isl_set *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma)); + return isl_pw_multi_aff_alloc(dom, ma); +} + +/* Create a piecewise multi-affine expression in the given space that maps each + * input dimension to the corresponding output dimension. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( + __isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space)); +} + +/* Add "ma2" to "ma1" and return the result. + * + * The parameters of "ma1" and "ma2" are assumed to have been aligned. + */ +static __isl_give isl_multi_aff *isl_multi_aff_add_aligned( + __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2) +{ + return isl_multi_aff_bin_op(maff1, maff2, &isl_aff_add); +} + +/* Add "ma2" to "ma1" and return the result. + */ +__isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2) +{ + return isl_multi_aff_align_params_multi_multi_and(ma1, ma2, + &isl_multi_aff_add_aligned); +} + +/* Exploit the equalities in "eq" to simplify the affine expressions. + */ +static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities( + __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq) +{ + int i; + + maff = isl_multi_aff_cow(maff); + if (!maff || !eq) goto error; for (i = 0; i < maff->n; ++i) { @@ -3270,29 +4029,6 @@ return 0; } -int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1, - __isl_keep isl_multi_aff *maff2) -{ - int i; - int equal; - - if (!maff1 || !maff2) - return -1; - if (maff1->n != maff2->n) - return 0; - equal = isl_space_is_equal(maff1->space, maff2->space); - if (equal < 0 || !equal) - return equal; - - for (i = 0; i < maff1->n; ++i) { - equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]); - if (equal < 0 || !equal) - return equal; - } - - return 1; -} - /* Return the set of domain elements where "ma1" is lexicographically * smaller than or equal to "ma2". */ @@ -3338,24 +4074,24 @@ #undef DEFAULT_IS_ZERO #define DEFAULT_IS_ZERO 0 -#define NO_NEG +#define NO_SUB #define NO_EVAL #define NO_OPT #define NO_INVOLVES_DIMS -#define NO_MOVE_DIMS #define NO_INSERT_DIMS #define NO_LIFT #define NO_MORPH #include +#undef NO_SUB + #undef UNION #define UNION isl_union_pw_multi_aff #undef PART #define PART isl_pw_multi_aff #undef PARTS #define PARTS pw_multi_aff -#define ALIGN_DOMAIN #define NO_EVAL @@ -3549,6 +4285,27 @@ return isl_pw_multi_aff_union_add_(pma1, pma2); } +/* Compute the sum of "upa1" and "upa2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( + __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2) +{ + return isl_union_pw_aff_union_add_(upa1, upa2); +} + +/* Compute the sum of "upma1" and "upma2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_union_add( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return isl_union_pw_multi_aff_union_add_(upma1, upma2); +} + /* Given two piecewise multi-affine expressions A -> B and C -> D, * construct a piecewise multi-affine expression [A -> C] -> [B -> D]. */ @@ -3636,19 +4393,20 @@ if (!isl_space_is_set(pma->dim)) isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, "isl_pw_multi_aff cannot be converted into an isl_set", - return isl_pw_multi_aff_free(pma)); + goto error); return isl_map_from_pw_multi_aff(pma); +error: + isl_pw_multi_aff_free(pma); + return NULL; } /* Given a basic map with a single output dimension that is defined * in terms of the parameters and input dimensions using an equality, * extract an isl_aff that expresses the output dimension in terms * of the parameters and input dimensions. - * - * Since some applications expect the result of isl_pw_multi_aff_from_map - * to only contain integer affine expressions, we compute the floor - * of the expression before returning. + * Note that this expression may involve integer divisions defined + * in terms of parameters and input dimensions. * * This function shares some similarities with * isl_basic_map_has_defining_equality and isl_constraint_get_bound. @@ -3656,9 +4414,9 @@ static __isl_give isl_aff *extract_isl_aff_from_basic_map( __isl_take isl_basic_map *bmap) { - int i; + int eq; unsigned offset; - unsigned total; + unsigned n_div; isl_local_space *ls; isl_aff *aff; @@ -3668,33 +4426,29 @@ isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, "basic map should have a single output dimension", goto error); - offset = isl_basic_map_offset(bmap, isl_dim_out); - total = isl_basic_map_total_dim(bmap); - for (i = 0; i < bmap->n_eq; ++i) { - if (isl_int_is_zero(bmap->eq[i][offset])) - continue; - if (isl_seq_first_non_zero(bmap->eq[i] + offset + 1, - 1 + total - (offset + 1)) != -1) - continue; - break; - } - if (i >= bmap->n_eq) + eq = isl_basic_map_output_defining_equality(bmap, 0); + if (eq >= bmap->n_eq) isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, "unable to find suitable equality", goto error); ls = isl_basic_map_get_local_space(bmap); aff = isl_aff_alloc(isl_local_space_domain(ls)); if (!aff) goto error; - if (isl_int_is_neg(bmap->eq[i][offset])) - isl_seq_cpy(aff->v->el + 1, bmap->eq[i], offset); - else - isl_seq_neg(aff->v->el + 1, bmap->eq[i], offset); - isl_seq_clr(aff->v->el + 1 + offset, aff->v->size - (1 + offset)); - isl_int_abs(aff->v->el[0], bmap->eq[i][offset]); + offset = isl_basic_map_offset(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (isl_int_is_neg(bmap->eq[eq][offset])) { + isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], offset); + isl_seq_cpy(aff->v->el + 1 + offset, bmap->eq[eq] + offset + 1, + n_div); + } else { + isl_seq_neg(aff->v->el + 1, bmap->eq[eq], offset); + isl_seq_neg(aff->v->el + 1 + offset, bmap->eq[eq] + offset + 1, + n_div); + } + isl_int_abs(aff->v->el[0], bmap->eq[eq][offset]); isl_basic_map_free(bmap); aff = isl_aff_remove_unused_divs(aff); - aff = isl_aff_floor(aff); return aff; error: isl_basic_map_free(bmap); @@ -3736,10 +4490,25 @@ return ma; } +/* Given a basic set where each set dimension is defined + * in terms of the parameters using an equality, + * extract an isl_multi_aff that expresses the set dimensions in terms + * of the parameters. + */ +__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities( + __isl_take isl_basic_set *bset) +{ + return extract_isl_multi_aff_from_basic_map(bset); +} + /* Create an isl_pw_multi_aff that is equivalent to * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain). * The given basic map is such that each output dimension is defined * in terms of the parameters and input dimensions using an equality. + * + * Since some applications expect the result of isl_pw_multi_aff_from_map + * to only contain integer affine expressions, we compute the floor + * of the expression before returning. */ static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map( __isl_take isl_set *domain, __isl_take isl_basic_map *bmap) @@ -3747,6 +4516,7 @@ isl_multi_aff *ma; ma = extract_isl_multi_aff_from_basic_map(bmap); + ma = isl_multi_aff_floor(ma); return isl_pw_multi_aff_alloc(domain, ma); } @@ -4138,7 +4908,7 @@ map = set; else map = isl_set_unwrap(set); - pma = isl_pw_multi_aff_from_map(set); + pma = isl_pw_multi_aff_from_map(map); if (!is_set) { space = isl_pw_multi_aff_get_domain_space(pma); @@ -4250,7 +5020,7 @@ /* Convert "map" into an isl_pw_multi_aff (if possible) and * add it to *user. */ -static int pw_multi_aff_from_map(__isl_take isl_map *map, void *user) +static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user) { isl_union_pw_multi_aff **upma = user; isl_pw_multi_aff *pma; @@ -4258,7 +5028,21 @@ pma = isl_pw_multi_aff_from_map(map); *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); - return *upma ? 0 : -1; + return *upma ? isl_stat_ok : isl_stat_error; +} + +/* Create an isl_union_pw_multi_aff with the given isl_aff on a universe + * domain. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff( + __isl_take isl_aff *aff) +{ + isl_multi_aff *ma; + isl_pw_multi_aff *pma; + + ma = isl_multi_aff_from_aff(aff); + pma = isl_pw_multi_aff_from_multi_aff(ma); + return isl_union_pw_multi_aff_from_pw_multi_aff(pma); } /* Try and create an isl_union_pw_multi_aff that is equivalent @@ -4617,10 +5401,28 @@ return NULL; } +/* Compute the pullback of "aff1" by the function represented by "aff2". + * In other words, plug in "aff2" in "aff1". The result is an affine expression + * defined over the domain space of "aff1". + * + * The domain of "aff1" should match the range of "aff2", which means + * that it should be single-dimensional. + */ +__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_multi_aff *ma; + + ma = isl_multi_aff_from_aff(aff2); + return isl_aff_pullback_multi_aff(aff1, ma); +} + /* Compute the pullback of "ma1" by the function represented by "ma2". * In other words, plug in "ma2" in "ma1". + * + * The parameters of "ma1" and "ma2" are assumed to have been aligned. */ -__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( +static __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff_aligned( __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) { int i; @@ -4651,6 +5453,16 @@ return NULL; } +/* Compute the pullback of "ma1" by the function represented by "ma2". + * In other words, plug in "ma2" in "ma1". + */ +__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) +{ + return isl_multi_aff_align_params_multi_multi_and(ma1, ma2, + &isl_multi_aff_pullback_multi_aff_aligned); +} + /* Extend the local space of "dst" to include the divs * in the local space of "src". */ @@ -4844,7 +5656,8 @@ /* Add an isl_pw_multi_aff with the given "set" as domain and * an unnamed zero-dimensional range to *user. */ -static int add_pw_multi_aff_from_domain(__isl_take isl_set *set, void *user) +static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_set *set, + void *user) { isl_union_pw_multi_aff **upma = user; isl_pw_multi_aff *pma; @@ -4852,7 +5665,7 @@ pma = isl_pw_multi_aff_from_domain(set); *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); - return 0; + return isl_stat_ok; } /* Return an isl_union_pw_multi_aff with the given "uset" as domain and @@ -4884,7 +5697,8 @@ /* Convert "pma" to an isl_map and add it to *umap. */ -static int map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, void *user) +static isl_stat map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, + void *user) { isl_union_map **umap = user; isl_map *map; @@ -4892,7 +5706,7 @@ map = isl_map_from_pw_multi_aff(pma); *umap = isl_union_map_add_map(*umap, map); - return 0; + return isl_stat_ok; } /* Construct a union map mapping the domain of the union @@ -4929,23 +5743,23 @@ isl_union_pw_multi_aff *upma2; isl_union_pw_multi_aff *res; isl_pw_multi_aff *pma; - int (*fn)(void **entry, void *user); + isl_stat (*fn)(void **entry, void *user); }; /* Given an isl_pw_multi_aff from upma1, store it in data->pma * and call data->fn for each isl_pw_multi_aff in data->upma2. */ -static int bin_entry(void **entry, void *user) +static isl_stat bin_entry(void **entry, void *user) { struct isl_union_pw_multi_aff_bin_data *data = user; isl_pw_multi_aff *pma = *entry; data->pma = pma; - if (isl_hash_table_foreach(data->upma2->dim->ctx, &data->upma2->table, + if (isl_hash_table_foreach(data->upma2->space->ctx, &data->upma2->table, data->fn, data) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2". @@ -4956,7 +5770,7 @@ static __isl_give isl_union_pw_multi_aff *bin_op( __isl_take isl_union_pw_multi_aff *upma1, __isl_take isl_union_pw_multi_aff *upma2, - int (*fn)(void **entry, void *user)) + isl_stat (*fn)(void **entry, void *user)) { isl_space *space; struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn }; @@ -4970,9 +5784,9 @@ goto error; data.upma2 = upma2; - data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma1->dim), + data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma1->space), upma1->table.n); - if (isl_hash_table_foreach(upma1->dim->ctx, &upma1->table, + if (isl_hash_table_foreach(upma1->space->ctx, &upma1->table, &bin_entry, &data) < 0) goto error; @@ -5038,14 +5852,14 @@ /* If data->pma and *entry have the same domain space, then compute * their flat range product and the result to data->res. */ -static int flat_range_product_entry(void **entry, void *user) +static isl_stat flat_range_product_entry(void **entry, void *user) { struct isl_union_pw_multi_aff_bin_data *data = user; isl_pw_multi_aff *pma2 = *entry; - if (!isl_space_tuple_match(data->pma->dim, isl_dim_in, + if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in, pma2->dim, isl_dim_in)) - return 0; + return isl_stat_ok; pma2 = isl_pw_multi_aff_flat_range_product( isl_pw_multi_aff_copy(data->pma), @@ -5053,7 +5867,7 @@ data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); - return 0; + return isl_stat_ok; } /* Given two isl_union_pw_multi_affs A -> B and C -> D, @@ -5082,7 +5896,8 @@ if (!pma || !pa) goto error; - if (!isl_space_tuple_match(pma->dim, isl_dim_in, pa->dim, isl_dim_in)) + if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in, + pa->dim, isl_dim_in)) isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, "domains don't match", goto error); if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out)) @@ -5150,6 +5965,25 @@ return NULL; } +/* Do the parameters of "pa" match those of "space"? + */ +int isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa, + __isl_keep isl_space *space) +{ + isl_space *pa_space; + int match; + + if (!pa || !space) + return -1; + + pa_space = isl_pw_aff_get_space(pa); + + match = isl_space_match(space, isl_dim_param, pa_space, isl_dim_param); + + isl_space_free(pa_space); + return match; +} + /* Check that the domain space of "pa" matches "space". * * Return 0 on success and -1 on error. @@ -5171,7 +6005,8 @@ if (!match) isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, "parameters don't match", goto error); - match = isl_space_tuple_match(space, isl_dim_in, pa_space, isl_dim_in); + match = isl_space_tuple_is_equal(space, isl_dim_in, + pa_space, isl_dim_in); if (match < 0) goto error; if (!match) @@ -5186,8 +6021,13 @@ #undef BASE #define BASE pw_aff +#undef DOMBASE +#define DOMBASE set #include +#include +#include +#include /* Scale the elements of "pma" by the corresponding elements of "mv". */ @@ -5199,7 +6039,7 @@ pma = isl_pw_multi_aff_cow(pma); if (!pma || !mv) goto error; - if (!isl_space_tuple_match(pma->dim, isl_dim_out, + if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out, mv->space, isl_dim_set)) isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, "spaces don't match", goto error); @@ -5242,25 +6082,26 @@ * then apply isl_pw_multi_aff_scale_multi_val and add the result * to data->res. */ -static int union_pw_multi_aff_scale_multi_val_entry(void **entry, void *user) +static isl_stat union_pw_multi_aff_scale_multi_val_entry(void **entry, + void *user) { struct isl_union_pw_multi_aff_scale_multi_val_data *data = user; isl_pw_multi_aff *pma = *entry; if (!pma) - return -1; - if (!isl_space_tuple_match(pma->dim, isl_dim_out, + return isl_stat_error; + if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out, data->mv->space, isl_dim_set)) - return 0; + return isl_stat_ok; pma = isl_pw_multi_aff_copy(pma); pma = isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(data->mv)); data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); if (!data->res) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Scale the elements of "upma" by the corresponding elements of "mv", @@ -5279,9 +6120,9 @@ goto error; data.mv = mv; - data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma->dim), + data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma->space), upma->table.n); - if (isl_hash_table_foreach(upma->dim->ctx, &upma->table, + if (isl_hash_table_foreach(upma->space->ctx, &upma->table, &union_pw_multi_aff_scale_multi_val_entry, &data) < 0) goto error; @@ -5293,3 +6134,2570 @@ isl_union_pw_multi_aff_free(upma); return NULL; } + +/* Construct and return a piecewise multi affine expression + * in the given space with value zero in each of the output dimensions and + * a universe domain. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space) +{ + return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space)); +} + +/* Construct and return a piecewise multi affine expression + * that is equal to the given piecewise affine expression. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( + __isl_take isl_pw_aff *pa) +{ + int i; + isl_space *space; + isl_pw_multi_aff *pma; + + if (!pa) + return NULL; + + space = isl_pw_aff_get_space(pa); + pma = isl_pw_multi_aff_alloc_size(space, pa->n); + + for (i = 0; i < pa->n; ++i) { + isl_set *set; + isl_multi_aff *ma; + + set = isl_set_copy(pa->p[i].set); + ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff)); + pma = isl_pw_multi_aff_add_piece(pma, set, ma); + } + + isl_pw_aff_free(pa); + return pma; +} + +/* Construct a set or map mapping the shared (parameter) domain + * of the piecewise affine expressions to the range of "mpa" + * with each dimension in the range equated to the + * corresponding piecewise affine expression. + */ +static __isl_give isl_map *map_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_space *space; + isl_map *map; + + if (!mpa) + return NULL; + + if (isl_space_dim(mpa->space, isl_dim_out) != mpa->n) + isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal, + "invalid space", goto error); + + space = isl_multi_pw_aff_get_domain_space(mpa); + map = isl_map_universe(isl_space_from_domain(space)); + + for (i = 0; i < mpa->n; ++i) { + isl_pw_aff *pa; + isl_map *map_i; + + pa = isl_pw_aff_copy(mpa->p[i]); + map_i = map_from_pw_aff(pa); + + map = isl_map_flat_range_product(map, map_i); + } + + map = isl_map_reset_space(map, isl_multi_pw_aff_get_space(mpa)); + + isl_multi_pw_aff_free(mpa); + return map; +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct a map mapping the shared domain + * of the piecewise affine expressions to the range of "mpa" + * with each dimension in the range equated to the + * corresponding piecewise affine expression. + */ +__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa) +{ + if (!mpa) + return NULL; + if (isl_space_is_set(mpa->space)) + isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal, + "space of input is not a map", goto error); + + return map_from_multi_pw_aff(mpa); +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct a set mapping the shared parameter domain + * of the piecewise affine expressions to the space of "mpa" + * with each dimension in the range equated to the + * corresponding piecewise affine expression. + */ +__isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa) +{ + if (!mpa) + return NULL; + if (!isl_space_is_set(mpa->space)) + isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal, + "space of input is not a set", goto error); + + return map_from_multi_pw_aff(mpa); +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct and return a piecewise multi affine expression + * that is equal to the given multi piecewise affine expression + * on the shared domain of the piecewise affine expressions. + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + isl_space *space; + isl_pw_aff *pa; + isl_pw_multi_aff *pma; + + if (!mpa) + return NULL; + + space = isl_multi_pw_aff_get_space(mpa); + + if (mpa->n == 0) { + isl_multi_pw_aff_free(mpa); + return isl_pw_multi_aff_zero(space); + } + + pa = isl_multi_pw_aff_get_pw_aff(mpa, 0); + pma = isl_pw_multi_aff_from_pw_aff(pa); + + for (i = 1; i < mpa->n; ++i) { + isl_pw_multi_aff *pma_i; + + pa = isl_multi_pw_aff_get_pw_aff(mpa, i); + pma_i = isl_pw_multi_aff_from_pw_aff(pa); + pma = isl_pw_multi_aff_range_product(pma, pma_i); + } + + pma = isl_pw_multi_aff_reset_space(pma, space); + + isl_multi_pw_aff_free(mpa); + return pma; +} + +/* Construct and return a multi piecewise affine expression + * that is equal to the given multi affine expression. + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + int i, n; + isl_multi_pw_aff *mpa; + + if (!ma) + return NULL; + + n = isl_multi_aff_dim(ma, isl_dim_out); + mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma)); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i)); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + } + + isl_multi_aff_free(ma); + return mpa; +} + +/* Construct and return a multi piecewise affine expression + * that is equal to the given piecewise multi affine expression. + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma) +{ + int i, n; + isl_space *space; + isl_multi_pw_aff *mpa; + + if (!pma) + return NULL; + + n = isl_pw_multi_aff_dim(pma, isl_dim_out); + space = isl_pw_multi_aff_get_space(pma); + mpa = isl_multi_pw_aff_alloc(space); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_multi_aff_get_pw_aff(pma, i); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + } + + isl_pw_multi_aff_free(pma); + return mpa; +} + +/* Do "pa1" and "pa2" represent the same function? + * + * We first check if they are obviously equal. + * If not, we convert them to maps and check if those are equal. + */ +int isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, __isl_keep isl_pw_aff *pa2) +{ + int equal; + isl_map *map1, *map2; + + if (!pa1 || !pa2) + return -1; + + equal = isl_pw_aff_plain_is_equal(pa1, pa2); + if (equal < 0 || equal) + return equal; + + map1 = map_from_pw_aff(isl_pw_aff_copy(pa1)); + map2 = map_from_pw_aff(isl_pw_aff_copy(pa2)); + equal = isl_map_is_equal(map1, map2); + isl_map_free(map1); + isl_map_free(map2); + + return equal; +} + +/* Do "mpa1" and "mpa2" represent the same function? + * + * Note that we cannot convert the entire isl_multi_pw_aff + * to a map because the domains of the piecewise affine expressions + * may not be the same. + */ +isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2) +{ + int i; + isl_bool equal; + + if (!mpa1 || !mpa2) + return isl_bool_error; + + if (!isl_space_match(mpa1->space, isl_dim_param, + mpa2->space, isl_dim_param)) { + if (!isl_space_has_named_params(mpa1->space)) + return isl_bool_false; + if (!isl_space_has_named_params(mpa2->space)) + return isl_bool_false; + mpa1 = isl_multi_pw_aff_copy(mpa1); + mpa2 = isl_multi_pw_aff_copy(mpa2); + mpa1 = isl_multi_pw_aff_align_params(mpa1, + isl_multi_pw_aff_get_space(mpa2)); + mpa2 = isl_multi_pw_aff_align_params(mpa2, + isl_multi_pw_aff_get_space(mpa1)); + equal = isl_multi_pw_aff_is_equal(mpa1, mpa2); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return equal; + } + + equal = isl_space_is_equal(mpa1->space, mpa2->space); + if (equal < 0 || !equal) + return equal; + + for (i = 0; i < mpa1->n; ++i) { + equal = isl_pw_aff_is_equal(mpa1->p[i], mpa2->p[i]); + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} + +/* Coalesce the elements of "mpa". + * + * Note that such coalescing does not change the meaning of "mpa" + * so there is no need to cow. We do need to be careful not to + * destroy any other copies of "mpa" in case of failure. + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce( + __isl_take isl_multi_pw_aff *mpa) +{ + int i; + + if (!mpa) + return NULL; + + for (i = 0; i < mpa->n; ++i) { + isl_pw_aff *pa = isl_pw_aff_copy(mpa->p[i]); + pa = isl_pw_aff_coalesce(pa); + if (!pa) + return isl_multi_pw_aff_free(mpa); + isl_pw_aff_free(mpa->p[i]); + mpa->p[i] = pa; + } + + return mpa; +} + +/* Compute the pullback of "mpa" by the function represented by "ma". + * In other words, plug in "ma" in "mpa". + * + * The parameters of "mpa" and "ma" are assumed to have been aligned. + */ +static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff_aligned( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma) +{ + int i; + isl_space *space = NULL; + + mpa = isl_multi_pw_aff_cow(mpa); + if (!mpa || !ma) + goto error; + + space = isl_space_join(isl_multi_aff_get_space(ma), + isl_multi_pw_aff_get_space(mpa)); + if (!space) + goto error; + + for (i = 0; i < mpa->n; ++i) { + mpa->p[i] = isl_pw_aff_pullback_multi_aff(mpa->p[i], + isl_multi_aff_copy(ma)); + if (!mpa->p[i]) + goto error; + } + + isl_multi_aff_free(ma); + isl_space_free(mpa->space); + mpa->space = space; + return mpa; +error: + isl_space_free(space); + isl_multi_pw_aff_free(mpa); + isl_multi_aff_free(ma); + return NULL; +} + +/* Compute the pullback of "mpa" by the function represented by "ma". + * In other words, plug in "ma" in "mpa". + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma) +{ + if (!mpa || !ma) + goto error; + if (isl_space_match(mpa->space, isl_dim_param, + ma->space, isl_dim_param)) + return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma); + mpa = isl_multi_pw_aff_align_params(mpa, isl_multi_aff_get_space(ma)); + ma = isl_multi_aff_align_params(ma, isl_multi_pw_aff_get_space(mpa)); + return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma); +error: + isl_multi_pw_aff_free(mpa); + isl_multi_aff_free(ma); + return NULL; +} + +/* Compute the pullback of "mpa" by the function represented by "pma". + * In other words, plug in "pma" in "mpa". + * + * The parameters of "mpa" and "mpa" are assumed to have been aligned. + */ +static __isl_give isl_multi_pw_aff * +isl_multi_pw_aff_pullback_pw_multi_aff_aligned( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma) +{ + int i; + isl_space *space = NULL; + + mpa = isl_multi_pw_aff_cow(mpa); + if (!mpa || !pma) + goto error; + + space = isl_space_join(isl_pw_multi_aff_get_space(pma), + isl_multi_pw_aff_get_space(mpa)); + + for (i = 0; i < mpa->n; ++i) { + mpa->p[i] = isl_pw_aff_pullback_pw_multi_aff_aligned(mpa->p[i], + isl_pw_multi_aff_copy(pma)); + if (!mpa->p[i]) + goto error; + } + + isl_pw_multi_aff_free(pma); + isl_space_free(mpa->space); + mpa->space = space; + return mpa; +error: + isl_space_free(space); + isl_multi_pw_aff_free(mpa); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Compute the pullback of "mpa" by the function represented by "pma". + * In other words, plug in "pma" in "mpa". + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma) +{ + if (!mpa || !pma) + goto error; + if (isl_space_match(mpa->space, isl_dim_param, pma->dim, isl_dim_param)) + return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma); + mpa = isl_multi_pw_aff_align_params(mpa, + isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, + isl_multi_pw_aff_get_space(mpa)); + return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma); +error: + isl_multi_pw_aff_free(mpa); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "aff". The domain of the result is the same + * as that of "mpa". + * "mpa" and "aff" are assumed to have been aligned. + * + * We first extract the parametric constant from "aff", defined + * over the correct domain. + * Then we add the appropriate combinations of the members of "mpa". + * Finally, we add the integer divisions through recursive calls. + */ +static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff) +{ + int i, n_in, n_div; + isl_space *space; + isl_val *v; + isl_pw_aff *pa; + isl_aff *tmp; + + n_in = isl_aff_dim(aff, isl_dim_in); + n_div = isl_aff_dim(aff, isl_dim_div); + + space = isl_space_domain(isl_multi_pw_aff_get_space(mpa)); + tmp = isl_aff_copy(aff); + tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div); + tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in); + tmp = isl_aff_add_dims(tmp, isl_dim_in, + isl_space_dim(space, isl_dim_set)); + tmp = isl_aff_reset_domain_space(tmp, space); + pa = isl_pw_aff_from_aff(tmp); + + for (i = 0; i < n_in; ++i) { + isl_pw_aff *pa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1)) + continue; + v = isl_aff_get_coefficient_val(aff, isl_dim_in, i); + pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i); + pa_i = isl_pw_aff_scale_val(pa_i, v); + pa = isl_pw_aff_add(pa, pa_i); + } + + for (i = 0; i < n_div; ++i) { + isl_aff *div; + isl_pw_aff *pa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1)) + continue; + div = isl_aff_get_div(aff, i); + pa_i = isl_multi_pw_aff_apply_aff_aligned( + isl_multi_pw_aff_copy(mpa), div); + pa_i = isl_pw_aff_floor(pa_i); + v = isl_aff_get_coefficient_val(aff, isl_dim_div, i); + pa_i = isl_pw_aff_scale_val(pa_i, v); + pa = isl_pw_aff_add(pa, pa_i); + } + + isl_multi_pw_aff_free(mpa); + isl_aff_free(aff); + + return pa; +} + +/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "aff". The domain of the result is the same + * as that of "mpa". + */ +__isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff) +{ + if (!aff || !mpa) + goto error; + if (isl_space_match(aff->ls->dim, isl_dim_param, + mpa->space, isl_dim_param)) + return isl_multi_pw_aff_apply_aff_aligned(mpa, aff); + + aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa)); + mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff)); + + return isl_multi_pw_aff_apply_aff_aligned(mpa, aff); +error: + isl_aff_free(aff); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "pa". The domain of the result is the same + * as that of "mpa". + * "mpa" and "pa" are assumed to have been aligned. + * + * We consider each piece in turn. Note that the domains of the + * pieces are assumed to be disjoint and they remain disjoint + * after taking the preimage (over the same function). + */ +static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa) +{ + isl_space *space; + isl_pw_aff *res; + int i; + + if (!mpa || !pa) + goto error; + + space = isl_space_join(isl_multi_pw_aff_get_space(mpa), + isl_pw_aff_get_space(pa)); + res = isl_pw_aff_empty(space); + + for (i = 0; i < pa->n; ++i) { + isl_pw_aff *pa_i; + isl_set *domain; + + pa_i = isl_multi_pw_aff_apply_aff_aligned( + isl_multi_pw_aff_copy(mpa), + isl_aff_copy(pa->p[i].aff)); + domain = isl_set_copy(pa->p[i].set); + domain = isl_set_preimage_multi_pw_aff(domain, + isl_multi_pw_aff_copy(mpa)); + pa_i = isl_pw_aff_intersect_domain(pa_i, domain); + res = isl_pw_aff_add_disjoint(res, pa_i); + } + + isl_pw_aff_free(pa); + isl_multi_pw_aff_free(mpa); + return res; +error: + isl_pw_aff_free(pa); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible + * with the domain of "pa". The domain of the result is the same + * as that of "mpa". + */ +__isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff( + __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa) +{ + if (!pa || !mpa) + goto error; + if (isl_space_match(pa->dim, isl_dim_param, mpa->space, isl_dim_param)) + return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); + + pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa)); + mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa)); + + return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); +error: + isl_pw_aff_free(pa); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Compute the pullback of "pa" by the function represented by "mpa". + * In other words, plug in "mpa" in "pa". + * "pa" and "mpa" are assumed to have been aligned. + * + * The pullback is computed by applying "pa" to "mpa". + */ +static __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff_aligned( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); +} + +/* Compute the pullback of "pa" by the function represented by "mpa". + * In other words, plug in "mpa" in "pa". + * + * The pullback is computed by applying "pa" to "mpa". + */ +__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( + __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_multi_pw_aff_apply_pw_aff(mpa, pa); +} + +/* Compute the pullback of "mpa1" by the function represented by "mpa2". + * In other words, plug in "mpa2" in "mpa1". + * + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * We pullback each member of "mpa1" in turn. + */ +static __isl_give isl_multi_pw_aff * +isl_multi_pw_aff_pullback_multi_pw_aff_aligned( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) +{ + int i; + isl_space *space = NULL; + + mpa1 = isl_multi_pw_aff_cow(mpa1); + if (!mpa1 || !mpa2) + goto error; + + space = isl_space_join(isl_multi_pw_aff_get_space(mpa2), + isl_multi_pw_aff_get_space(mpa1)); + + for (i = 0; i < mpa1->n; ++i) { + mpa1->p[i] = isl_pw_aff_pullback_multi_pw_aff_aligned( + mpa1->p[i], isl_multi_pw_aff_copy(mpa2)); + if (!mpa1->p[i]) + goto error; + } + + mpa1 = isl_multi_pw_aff_reset_space(mpa1, space); + + isl_multi_pw_aff_free(mpa2); + return mpa1; +error: + isl_space_free(space); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return NULL; +} + +/* Compute the pullback of "mpa1" by the function represented by "mpa2". + * In other words, plug in "mpa2" in "mpa1". + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) +{ + return isl_multi_pw_aff_align_params_multi_multi_and(mpa1, mpa2, + &isl_multi_pw_aff_pullback_multi_pw_aff_aligned); +} + +/* Align the parameters of "mpa1" and "mpa2", check that the ranges + * of "mpa1" and "mpa2" live in the same space, construct map space + * between the domain spaces of "mpa1" and "mpa2" and call "order" + * with this map space as extract argument. + */ +static __isl_give isl_map *isl_multi_pw_aff_order_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2, + __isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1, + __isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space)) +{ + int match; + isl_space *space1, *space2; + isl_map *res; + + mpa1 = isl_multi_pw_aff_align_params(mpa1, + isl_multi_pw_aff_get_space(mpa2)); + mpa2 = isl_multi_pw_aff_align_params(mpa2, + isl_multi_pw_aff_get_space(mpa1)); + if (!mpa1 || !mpa2) + goto error; + match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out, + mpa2->space, isl_dim_out); + if (match < 0) + goto error; + if (!match) + isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid, + "range spaces don't match", goto error); + space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1)); + space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2)); + space1 = isl_space_map_from_domain_and_range(space1, space2); + + res = order(mpa1, mpa2, space1); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return res; +error: + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + return NULL; +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function values are equal. "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" and "mpa2" are equal when each of the pairs of elements + * in the sequences are equal. + */ +static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space( + __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, + __isl_take isl_space *space) +{ + int i, n; + isl_map *res; + + res = isl_map_universe(space); + + n = isl_multi_pw_aff_dim(mpa1, isl_dim_out); + for (i = 0; i < n; ++i) { + isl_pw_aff *pa1, *pa2; + isl_map *map; + + pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); + pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); + map = isl_pw_aff_eq_map(pa1, pa2); + res = isl_map_intersect(res, map); + } + + return res; +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function values are equal. + */ +__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2) +{ + return isl_multi_pw_aff_order_map(mpa1, mpa2, + &isl_multi_pw_aff_eq_map_on_space); +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function values of "mpa1" is lexicographically satisfies "base" + * compared to that of "mpa2". "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" lexicographically satisfies "base" compared to "mpa2" + * if its i-th element satisfies "base" when compared to + * the i-th element of "mpa2" while all previous elements are + * pairwise equal. + */ +static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2, + __isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1, + __isl_take isl_pw_aff *pa2), + __isl_take isl_space *space) +{ + int i, n; + isl_map *res, *rest; + + res = isl_map_empty(isl_space_copy(space)); + rest = isl_map_universe(space); + + n = isl_multi_pw_aff_dim(mpa1, isl_dim_out); + for (i = 0; i < n; ++i) { + isl_pw_aff *pa1, *pa2; + isl_map *map; + + pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); + pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); + map = base(pa1, pa2); + map = isl_map_intersect(map, isl_map_copy(rest)); + res = isl_map_union(res, map); + + if (i == n - 1) + continue; + + pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); + pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); + map = isl_pw_aff_eq_map(pa1, pa2); + rest = isl_map_intersect(rest, map); + } + + isl_map_free(rest); + return res; +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function value of "mpa1" is lexicographically less than that + * of "mpa2". "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" is less than "mpa2" if its i-th element is smaller + * than the i-th element of "mpa2" while all previous elements are + * pairwise equal. + */ +__isl_give isl_map *isl_multi_pw_aff_lex_lt_map_on_space( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2, + __isl_take isl_space *space) +{ + return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2, + &isl_pw_aff_lt_map, space); +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function value of "mpa1" is lexicographically less than that + * of "mpa2". + */ +__isl_give isl_map *isl_multi_pw_aff_lex_lt_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) +{ + return isl_multi_pw_aff_order_map(mpa1, mpa2, + &isl_multi_pw_aff_lex_lt_map_on_space); +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function value of "mpa1" is lexicographically greater than that + * of "mpa2". "space" is the space of the result. + * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. + * + * "mpa1" is greater than "mpa2" if its i-th element is greater + * than the i-th element of "mpa2" while all previous elements are + * pairwise equal. + */ +__isl_give isl_map *isl_multi_pw_aff_lex_gt_map_on_space( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2, + __isl_take isl_space *space) +{ + return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2, + &isl_pw_aff_gt_map, space); +} + +/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" + * where the function value of "mpa1" is lexicographically greater than that + * of "mpa2". + */ +__isl_give isl_map *isl_multi_pw_aff_lex_gt_map( + __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) +{ + return isl_multi_pw_aff_order_map(mpa1, mpa2, + &isl_multi_pw_aff_lex_gt_map_on_space); +} + +/* Compare two isl_affs. + * + * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater" + * than "aff2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do consider expressions that only involve + * earlier dimensions as "smaller". + */ +int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2) +{ + int cmp; + int last1, last2; + + if (aff1 == aff2) + return 0; + + if (!aff1) + return -1; + if (!aff2) + return 1; + + cmp = isl_local_space_cmp(aff1->ls, aff2->ls); + if (cmp != 0) + return cmp; + + last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1); + last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1); + if (last1 != last2) + return last1 - last2; + + return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size); +} + +/* Compare two isl_pw_affs. + * + * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater" + * than "pa2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do consider expressions that only involve + * earlier dimensions as "smaller". + */ +int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, + __isl_keep isl_pw_aff *pa2) +{ + int i; + int cmp; + + if (pa1 == pa2) + return 0; + + if (!pa1) + return -1; + if (!pa2) + return 1; + + cmp = isl_space_cmp(pa1->dim, pa2->dim); + if (cmp != 0) + return cmp; + + if (pa1->n != pa2->n) + return pa1->n - pa2->n; + + for (i = 0; i < pa1->n; ++i) { + cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set); + if (cmp != 0) + return cmp; + cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff); + if (cmp != 0) + return cmp; + } + + return 0; +} + +/* Return a piecewise affine expression that is equal to "v" on "domain". + */ +__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain, + __isl_take isl_val *v) +{ + isl_space *space; + isl_local_space *ls; + isl_aff *aff; + + space = isl_set_get_space(domain); + ls = isl_local_space_from_space(space); + aff = isl_aff_val_on_domain(ls, v); + + return isl_pw_aff_alloc(domain, aff); +} + +/* Return a multi affine expression that is equal to "mv" on domain + * space "space". + */ +__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space( + __isl_take isl_space *space, __isl_take isl_multi_val *mv) +{ + int i, n; + isl_space *space2; + isl_local_space *ls; + isl_multi_aff *ma; + + if (!space || !mv) + goto error; + + n = isl_multi_val_dim(mv, isl_dim_set); + space2 = isl_multi_val_get_space(mv); + space2 = isl_space_align_params(space2, isl_space_copy(space)); + space = isl_space_align_params(space, isl_space_copy(space2)); + space = isl_space_map_from_domain_and_range(space, space2); + ma = isl_multi_aff_alloc(isl_space_copy(space)); + ls = isl_local_space_from_space(isl_space_domain(space)); + for (i = 0; i < n; ++i) { + isl_val *v; + isl_aff *aff; + + v = isl_multi_val_get_val(mv, i); + aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + isl_local_space_free(ls); + + isl_multi_val_free(mv); + return ma; +error: + isl_space_free(space); + isl_multi_val_free(mv); + return NULL; +} + +/* Return a piecewise multi-affine expression + * that is equal to "mv" on "domain". + */ +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain( + __isl_take isl_set *domain, __isl_take isl_multi_val *mv) +{ + isl_space *space; + isl_multi_aff *ma; + + space = isl_set_get_space(domain); + ma = isl_multi_aff_multi_val_on_space(space, mv); + + return isl_pw_multi_aff_alloc(domain, ma); +} + +/* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain. + * mv is the value that should be attained on each domain set + * res collects the results + */ +struct isl_union_pw_multi_aff_multi_val_on_domain_data { + isl_multi_val *mv; + isl_union_pw_multi_aff *res; +}; + +/* Create an isl_pw_multi_aff equal to data->mv on "domain" + * and add it to data->res. + */ +static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_set *domain, + void *user) +{ + struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user; + isl_pw_multi_aff *pma; + isl_multi_val *mv; + + mv = isl_multi_val_copy(data->mv); + pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv); + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Return a union piecewise multi-affine expression + * that is equal to "mv" on "domain". + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv) +{ + struct isl_union_pw_multi_aff_multi_val_on_domain_data data; + isl_space *space; + + space = isl_union_set_get_space(domain); + data.res = isl_union_pw_multi_aff_empty(space); + data.mv = mv; + if (isl_union_set_foreach_set(domain, + &pw_multi_aff_multi_val_on_domain, &data) < 0) + data.res = isl_union_pw_multi_aff_free(data.res); + isl_union_set_free(domain); + isl_multi_val_free(mv); + return data.res; +} + +/* Compute the pullback of data->pma by the function represented by "pma2", + * provided the spaces match, and add the results to data->res. + */ +static isl_stat pullback_entry(void **entry, void *user) +{ + struct isl_union_pw_multi_aff_bin_data *data = user; + isl_pw_multi_aff *pma2 = *entry; + + if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in, + pma2->dim, isl_dim_out)) + return isl_stat_ok; + + pma2 = isl_pw_multi_aff_pullback_pw_multi_aff( + isl_pw_multi_aff_copy(data->pma), + isl_pw_multi_aff_copy(pma2)); + + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Compute the pullback of "upma1" by the function represented by "upma2". + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2) +{ + return bin_op(upma1, upma2, &pullback_entry); +} + +/* Check that the domain space of "upa" matches "space". + * + * Return 0 on success and -1 on error. + * + * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and + * can in principle never fail since the space "space" is that + * of the isl_multi_union_pw_aff and is a set space such that + * there is no domain space to match. + * + * We check the parameters and double-check that "space" is + * indeed that of a set. + */ +static int isl_union_pw_aff_check_match_domain_space( + __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space) +{ + isl_space *upa_space; + int match; + + if (!upa || !space) + return -1; + + match = isl_space_is_set(space); + if (match < 0) + return -1; + if (!match) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting set space", return -1); + + upa_space = isl_union_pw_aff_get_space(upa); + match = isl_space_match(space, isl_dim_param, upa_space, isl_dim_param); + if (match < 0) + goto error; + if (!match) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "parameters don't match", goto error); + + isl_space_free(upa_space); + return 0; +error: + isl_space_free(upa_space); + return -1; +} + +/* Do the parameters of "upa" match those of "space"? + */ +static int isl_union_pw_aff_matching_params(__isl_keep isl_union_pw_aff *upa, + __isl_keep isl_space *space) +{ + isl_space *upa_space; + int match; + + if (!upa || !space) + return -1; + + upa_space = isl_union_pw_aff_get_space(upa); + + match = isl_space_match(space, isl_dim_param, upa_space, isl_dim_param); + + isl_space_free(upa_space); + return match; +} + +/* Internal data structure for isl_union_pw_aff_reset_domain_space. + * space represents the new parameters. + * res collects the results. + */ +struct isl_union_pw_aff_reset_params_data { + isl_space *space; + isl_union_pw_aff *res; +}; + +/* Replace the parameters of "pa" by data->space and + * add the result to data->res. + */ +static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user) +{ + struct isl_union_pw_aff_reset_params_data *data = user; + isl_space *space; + + space = isl_pw_aff_get_space(pa); + space = isl_space_replace(space, isl_dim_param, data->space); + pa = isl_pw_aff_reset_space(pa, space); + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the domain space of "upa" by "space". + * Since a union expression does not have a (single) domain space, + * "space" is necessarily a parameter space. + * + * Since the order and the names of the parameters determine + * the hash value, we need to create a new hash table. + */ +static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space( + __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space) +{ + struct isl_union_pw_aff_reset_params_data data = { space }; + int match; + + match = isl_union_pw_aff_matching_params(upa, space); + if (match < 0) + upa = isl_union_pw_aff_free(upa); + else if (match) { + isl_space_free(space); + return upa; + } + + data.res = isl_union_pw_aff_empty(isl_space_copy(space)); + if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + + isl_union_pw_aff_free(upa); + isl_space_free(space); + return data.res; +} + +/* Replace the entry of isl_union_pw_aff to which "entry" points + * by its floor. + */ +static isl_stat floor_entry(void **entry, void *user) +{ + isl_pw_aff **pa = (isl_pw_aff **) entry; + + *pa = isl_pw_aff_floor(*pa); + if (!*pa) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Given f, return floor(f). + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_floor( + __isl_take isl_union_pw_aff *upa) +{ + isl_ctx *ctx; + + upa = isl_union_pw_aff_cow(upa); + if (!upa) + return NULL; + + ctx = isl_union_pw_aff_get_ctx(upa); + if (isl_hash_table_foreach(ctx, &upa->table, &floor_entry, NULL) < 0) + upa = isl_union_pw_aff_free(upa); + + return upa; +} + +/* Compute + * + * upa mod m = upa - m * floor(upa/m) + * + * with m an integer value. + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( + __isl_take isl_union_pw_aff *upa, __isl_take isl_val *m) +{ + isl_union_pw_aff *res; + + if (!upa || !m) + goto error; + + if (!isl_val_is_int(m)) + isl_die(isl_val_get_ctx(m), isl_error_invalid, + "expecting integer modulo", goto error); + if (!isl_val_is_pos(m)) + isl_die(isl_val_get_ctx(m), isl_error_invalid, + "expecting positive modulo", goto error); + + res = isl_union_pw_aff_copy(upa); + upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m)); + upa = isl_union_pw_aff_floor(upa); + upa = isl_union_pw_aff_scale_val(upa, m); + res = isl_union_pw_aff_sub(res, upa); + + return res; +error: + isl_val_free(m); + isl_union_pw_aff_free(upa); + return NULL; +} + +/* Internal data structure for isl_union_pw_aff_aff_on_domain. + * "aff" is the symbolic value that the resulting isl_union_pw_aff + * needs to attain. + * "res" collects the results. + */ +struct isl_union_pw_aff_aff_on_domain_data { + isl_aff *aff; + isl_union_pw_aff *res; +}; + +/* Construct a piecewise affine expression that is equal to data->aff + * on "domain" and add the result to data->res. + */ +static isl_stat pw_aff_aff_on_domain(__isl_take isl_set *domain, void *user) +{ + struct isl_union_pw_aff_aff_on_domain_data *data = user; + isl_pw_aff *pa; + isl_aff *aff; + int dim; + + aff = isl_aff_copy(data->aff); + dim = isl_set_dim(domain, isl_dim_set); + aff = isl_aff_add_dims(aff, isl_dim_in, dim); + aff = isl_aff_reset_domain_space(aff, isl_set_get_space(domain)); + pa = isl_pw_aff_alloc(domain, aff); + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff. + * pos is the output position that needs to be extracted. + * res collects the results. + */ +struct isl_union_pw_multi_aff_get_union_pw_aff_data { + int pos; + isl_union_pw_aff *res; +}; + +/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma" + * (assuming it has such a dimension) and add it to data->res. + */ +static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user; + int n_out; + isl_pw_aff *pa; + + if (!pma) + return isl_stat_error; + + n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (data->pos >= n_out) { + isl_pw_multi_aff_free(pma); + return isl_stat_ok; + } + + pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos); + isl_pw_multi_aff_free(pma); + + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Extract an isl_union_pw_aff corresponding to + * output dimension "pos" of "upma". + */ +__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff( + __isl_keep isl_union_pw_multi_aff *upma, int pos) +{ + struct isl_union_pw_multi_aff_get_union_pw_aff_data data; + isl_space *space; + + if (!upma) + return NULL; + + if (pos < 0) + isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid, + "cannot extract at negative position", return NULL); + + space = isl_union_pw_multi_aff_get_space(upma); + data.res = isl_union_pw_aff_empty(space); + data.pos = pos; + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &get_union_pw_aff, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + + return data.res; +} + +/* Return a union piecewise affine expression + * that is equal to "aff" on "domain". + * + * Construct an isl_pw_aff on each of the sets in "domain" and + * collect the results. + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_aff *aff) +{ + struct isl_union_pw_aff_aff_on_domain_data data; + isl_space *space; + + if (!domain || !aff) + goto error; + if (!isl_local_space_is_params(aff->ls)) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "expecting parametric expression", goto error); + + space = isl_union_set_get_space(domain); + data.res = isl_union_pw_aff_empty(space); + data.aff = aff; + if (isl_union_set_foreach_set(domain, &pw_aff_aff_on_domain, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + isl_union_set_free(domain); + isl_aff_free(aff); + return data.res; +error: + isl_union_set_free(domain); + isl_aff_free(aff); + return NULL; +} + +/* Internal data structure for isl_union_pw_aff_val_on_domain. + * "v" is the value that the resulting isl_union_pw_aff needs to attain. + * "res" collects the results. + */ +struct isl_union_pw_aff_val_on_domain_data { + isl_val *v; + isl_union_pw_aff *res; +}; + +/* Construct a piecewise affine expression that is equal to data->v + * on "domain" and add the result to data->res. + */ +static isl_stat pw_aff_val_on_domain(__isl_take isl_set *domain, void *user) +{ + struct isl_union_pw_aff_val_on_domain_data *data = user; + isl_pw_aff *pa; + isl_val *v; + + v = isl_val_copy(data->v); + pa = isl_pw_aff_val_on_domain(domain, v); + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Return a union piecewise affine expression + * that is equal to "v" on "domain". + * + * Construct an isl_pw_aff on each of the sets in "domain" and + * collect the results. + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_val *v) +{ + struct isl_union_pw_aff_val_on_domain_data data; + isl_space *space; + + space = isl_union_set_get_space(domain); + data.res = isl_union_pw_aff_empty(space); + data.v = v; + if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + isl_union_set_free(domain); + isl_val_free(v); + return data.res; +} + +/* Construct a piecewise multi affine expression + * that is equal to "pa" and add it to upma. + */ +static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa, + void *user) +{ + isl_union_pw_multi_aff **upma = user; + isl_pw_multi_aff *pma; + + pma = isl_pw_multi_aff_from_pw_aff(pa); + *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); + + return *upma ? isl_stat_ok : isl_stat_error; +} + +/* Construct and return a union piecewise multi affine expression + * that is equal to the given union piecewise affine expression. + */ +__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa) +{ + isl_space *space; + isl_union_pw_multi_aff *upma; + + if (!upa) + return NULL; + + space = isl_union_pw_aff_get_space(upa); + upma = isl_union_pw_multi_aff_empty(space); + + if (isl_union_pw_aff_foreach_pw_aff(upa, + &pw_multi_aff_from_pw_aff_entry, &upma) < 0) + upma = isl_union_pw_multi_aff_free(upma); + + isl_union_pw_aff_free(upa); + return upma; +} + +/* Compute the set of elements in the domain of "pa" where it is zero and + * add this set to "uset". + */ +static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user) +{ + isl_union_set **uset = (isl_union_set **)user; + + *uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa)); + + return *uset ? isl_stat_ok : isl_stat_error; +} + +/* Return a union set containing those elements in the domain + * of "upa" where it is zero. + */ +__isl_give isl_union_set *isl_union_pw_aff_zero_union_set( + __isl_take isl_union_pw_aff *upa) +{ + isl_union_set *zero; + + zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa)); + if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0) + zero = isl_union_set_free(zero); + + isl_union_pw_aff_free(upa); + return zero; +} + +/* Convert "pa" to an isl_map and add it to *umap. + */ +static isl_stat map_from_pw_aff_entry(__isl_take isl_pw_aff *pa, void *user) +{ + isl_union_map **umap = user; + isl_map *map; + + map = isl_map_from_pw_aff(pa); + *umap = isl_union_map_add_map(*umap, map); + + return *umap ? isl_stat_ok : isl_stat_error; +} + +/* Construct a union map mapping the domain of the union + * piecewise affine expression to its range, with the single output dimension + * equated to the corresponding affine expressions on their cells. + */ +__isl_give isl_union_map *isl_union_map_from_union_pw_aff( + __isl_take isl_union_pw_aff *upa) +{ + isl_space *space; + isl_union_map *umap; + + if (!upa) + return NULL; + + space = isl_union_pw_aff_get_space(upa); + umap = isl_union_map_empty(space); + + if (isl_union_pw_aff_foreach_pw_aff(upa, &map_from_pw_aff_entry, + &umap) < 0) + umap = isl_union_map_free(umap); + + isl_union_pw_aff_free(upa); + return umap; +} + +/* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff. + * upma is the function that is plugged in. + * pa is the current part of the function in which upma is plugged in. + * res collects the results. + */ +struct isl_union_pw_aff_pullback_upma_data { + isl_union_pw_multi_aff *upma; + isl_pw_aff *pa; + isl_union_pw_aff *res; +}; + +/* Check if "pma" can be plugged into data->pa. + * If so, perform the pullback and add the result to data->res. + */ +static isl_stat pa_pb_pma(void **entry, void *user) +{ + struct isl_union_pw_aff_pullback_upma_data *data = user; + isl_pw_multi_aff *pma = *entry; + isl_pw_aff *pa; + + if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in, + pma->dim, isl_dim_out)) + return isl_stat_ok; + + pma = isl_pw_multi_aff_copy(pma); + pa = isl_pw_aff_copy(data->pa); + pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma); + + data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Check if any of the elements of data->upma can be plugged into pa, + * add if so add the result to data->res. + */ +static isl_stat upa_pb_upma(void **entry, void *user) +{ + struct isl_union_pw_aff_pullback_upma_data *data = user; + isl_ctx *ctx; + isl_pw_aff *pa = *entry; + + data->pa = pa; + ctx = isl_union_pw_multi_aff_get_ctx(data->upma); + if (isl_hash_table_foreach(ctx, &data->upma->table, + &pa_pb_pma, data) < 0) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Compute the pullback of "upa" by the function represented by "upma". + * In other words, plug in "upma" in "upa". The result contains + * expressions defined over the domain space of "upma". + * + * Run over all pairs of elements in "upa" and "upma", perform + * the pullback when appropriate and collect the results. + * If the hash value were based on the domain space rather than + * the function space, then we could run through all elements + * of "upma" and directly pick out the corresponding element of "upa". + */ +__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_union_pw_aff *upa, + __isl_take isl_union_pw_multi_aff *upma) +{ + struct isl_union_pw_aff_pullback_upma_data data = { NULL, NULL }; + isl_ctx *ctx; + isl_space *space; + + space = isl_union_pw_multi_aff_get_space(upma); + upa = isl_union_pw_aff_align_params(upa, space); + space = isl_union_pw_aff_get_space(upa); + upma = isl_union_pw_multi_aff_align_params(upma, space); + + if (!upa || !upma) + goto error; + + ctx = isl_union_pw_aff_get_ctx(upa); + data.upma = upma; + space = isl_union_pw_aff_get_space(upa); + data.res = isl_union_pw_aff_alloc(space, upa->table.n); + if (isl_hash_table_foreach(ctx, &upa->table, &upa_pb_upma, &data) < 0) + data.res = isl_union_pw_aff_free(data.res); + + isl_union_pw_aff_free(upa); + isl_union_pw_multi_aff_free(upma); + return data.res; +error: + isl_union_pw_aff_free(upa); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +#undef BASE +#define BASE union_pw_aff +#undef DOMBASE +#define DOMBASE union_set + +#define NO_MOVE_DIMS +#define NO_DIMS +#define NO_DOMAIN +#define NO_PRODUCT +#define NO_SPLICE +#define NO_ZERO +#define NO_IDENTITY +#define NO_GIST + +#include +#include +#include +#include +#include +#include + +/* Construct a multiple union piecewise affine expression + * in the given space with value zero in each of the output dimensions. + * + * Since there is no canonical zero value for + * a union piecewise affine expression, we can only construct + * zero-dimensional "zero" value. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero( + __isl_take isl_space *space) +{ + if (!space) + return NULL; + + if (!isl_space_is_set(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting set space", goto error); + if (isl_space_dim(space , isl_dim_out) != 0) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting 0D space", goto error); + + return isl_multi_union_pw_aff_alloc(space); +error: + isl_space_free(space); + return NULL; +} + +/* Compute the sum of "mupa1" and "mupa2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + * + * We simply iterate over the elements in both arguments and + * call isl_union_pw_aff_union_add on each of them. + */ +static __isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_union_add_aligned( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2) +{ + return isl_multi_union_pw_aff_bin_op(mupa1, mupa2, + &isl_union_pw_aff_union_add); +} + +/* Compute the sum of "mupa1" and "mupa2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add( + __isl_take isl_multi_union_pw_aff *mupa1, + __isl_take isl_multi_union_pw_aff *mupa2) +{ + return isl_multi_union_pw_aff_align_params_multi_multi_and(mupa1, mupa2, + &isl_multi_union_pw_aff_union_add_aligned); +} + +/* Construct and return a multi union piecewise affine expression + * that is equal to the given multi affine expression. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff( + __isl_take isl_multi_aff *ma) +{ + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_from_multi_aff(ma); + return isl_multi_union_pw_aff_from_multi_pw_aff(mpa); +} + +/* Construct and return a multi union piecewise affine expression + * that is equal to the given multi piecewise affine expression. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff( + __isl_take isl_multi_pw_aff *mpa) +{ + int i, n; + isl_space *space; + isl_multi_union_pw_aff *mupa; + + if (!mpa) + return NULL; + + space = isl_multi_pw_aff_get_space(mpa); + space = isl_space_range(space); + mupa = isl_multi_union_pw_aff_alloc(space); + + n = isl_multi_pw_aff_dim(mpa, isl_dim_out); + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + isl_union_pw_aff *upa; + + pa = isl_multi_pw_aff_get_pw_aff(mpa, i); + upa = isl_union_pw_aff_from_pw_aff(pa); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + + isl_multi_pw_aff_free(mpa); + + return mupa; +} + +/* Extract the range space of "pma" and assign it to *space. + * If *space has already been set (through a previous call to this function), + * then check that the range space is the same. + */ +static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user) +{ + isl_space **space = user; + isl_space *pma_space; + isl_bool equal; + + pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma)); + isl_pw_multi_aff_free(pma); + + if (!pma_space) + return isl_stat_error; + if (!*space) { + *space = pma_space; + return isl_stat_ok; + } + + equal = isl_space_is_equal(pma_space, *space); + isl_space_free(pma_space); + + if (equal < 0) + return isl_stat_error; + if (!equal) + isl_die(isl_space_get_ctx(*space), isl_error_invalid, + "range spaces not the same", return isl_stat_error); + return isl_stat_ok; +} + +/* Construct and return a multi union piecewise affine expression + * that is equal to the given union piecewise multi affine expression. + * + * In order to be able to perform the conversion, the input + * needs to be non-empty and may only involve a single range space. + */ +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_from_union_pw_multi_aff( + __isl_take isl_union_pw_multi_aff *upma) +{ + isl_space *space = NULL; + isl_multi_union_pw_aff *mupa; + int i, n; + + if (!upma) + return NULL; + if (isl_union_pw_multi_aff_n_pw_multi_aff(upma) == 0) + isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid, + "cannot extract range space from empty input", + goto error); + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space, + &space) < 0) + goto error; + + if (!space) + goto error; + + n = isl_space_dim(space, isl_dim_set); + mupa = isl_multi_union_pw_aff_alloc(space); + + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + + upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + + isl_union_pw_multi_aff_free(upma); + return mupa; +error: + isl_space_free(space); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +/* Try and create an isl_multi_union_pw_aff that is equivalent + * to the given isl_union_map. + * The isl_union_map is required to be single-valued in each space. + * Moreover, it cannot be empty and all range spaces need to be the same. + * Otherwise, an error is produced. + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( + __isl_take isl_union_map *umap) +{ + isl_union_pw_multi_aff *upma; + + upma = isl_union_pw_multi_aff_from_union_map(umap); + return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma); +} + +/* Return a multiple union piecewise affine expression + * that is equal to "mv" on "domain", assuming "domain" and "mv" + * have been aligned. + */ +static __isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_multi_val_on_domain_aligned( + __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv) +{ + int i, n; + isl_space *space; + isl_multi_union_pw_aff *mupa; + + if (!domain || !mv) + goto error; + + n = isl_multi_val_dim(mv, isl_dim_set); + space = isl_multi_val_get_space(mv); + mupa = isl_multi_union_pw_aff_alloc(space); + for (i = 0; i < n; ++i) { + isl_val *v; + isl_union_pw_aff *upa; + + v = isl_multi_val_get_val(mv, i); + upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain), + v); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + + isl_union_set_free(domain); + isl_multi_val_free(mv); + return mupa; +error: + isl_union_set_free(domain); + isl_multi_val_free(mv); + return NULL; +} + +/* Return a multiple union piecewise affine expression + * that is equal to "mv" on "domain". + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv) +{ + if (!domain || !mv) + goto error; + if (isl_space_match(domain->dim, isl_dim_param, + mv->space, isl_dim_param)) + return isl_multi_union_pw_aff_multi_val_on_domain_aligned( + domain, mv); + domain = isl_union_set_align_params(domain, + isl_multi_val_get_space(mv)); + mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain)); + return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv); +error: + isl_union_set_free(domain); + isl_multi_val_free(mv); + return NULL; +} + +/* Return a multiple union piecewise affine expression + * that is equal to "ma" on "domain", assuming "domain" and "ma" + * have been aligned. + */ +static __isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_multi_aff_on_domain_aligned( + __isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma) +{ + int i, n; + isl_space *space; + isl_multi_union_pw_aff *mupa; + + if (!domain || !ma) + goto error; + + n = isl_multi_aff_dim(ma, isl_dim_set); + space = isl_multi_aff_get_space(ma); + mupa = isl_multi_union_pw_aff_alloc(space); + for (i = 0; i < n; ++i) { + isl_aff *aff; + isl_union_pw_aff *upa; + + aff = isl_multi_aff_get_aff(ma, i); + upa = isl_union_pw_aff_aff_on_domain(isl_union_set_copy(domain), + aff); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + + isl_union_set_free(domain); + isl_multi_aff_free(ma); + return mupa; +error: + isl_union_set_free(domain); + isl_multi_aff_free(ma); + return NULL; +} + +/* Return a multiple union piecewise affine expression + * that is equal to "ma" on "domain". + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain( + __isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma) +{ + if (!domain || !ma) + goto error; + if (isl_space_match(domain->dim, isl_dim_param, + ma->space, isl_dim_param)) + return isl_multi_union_pw_aff_multi_aff_on_domain_aligned( + domain, ma); + domain = isl_union_set_align_params(domain, + isl_multi_aff_get_space(ma)); + ma = isl_multi_aff_align_params(ma, isl_union_set_get_space(domain)); + return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(domain, ma); +error: + isl_union_set_free(domain); + isl_multi_aff_free(ma); + return NULL; +} + +/* Return a union set containing those elements in the domains + * of the elements of "mupa" where they are all zero. + */ +__isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i, n; + isl_union_pw_aff *upa; + isl_union_set *zero; + + if (!mupa) + return NULL; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n == 0) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "cannot determine zero set " + "of zero-dimensional function", goto error); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + zero = isl_union_pw_aff_zero_union_set(upa); + + for (i = 1; i < n; ++i) { + isl_union_set *zero_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + zero_i = isl_union_pw_aff_zero_union_set(upa); + + zero = isl_union_set_intersect(zero, zero_i); + } + + isl_multi_union_pw_aff_free(mupa); + return zero; +error: + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Construct a union map mapping the shared domain + * of the union piecewise affine expressions to the range of "mupa" + * with each dimension in the range equated to the + * corresponding union piecewise affine expression. + * + * The input cannot be zero-dimensional as there is + * no way to extract a domain from a zero-dimensional isl_multi_union_pw_aff. + */ +__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i, n; + isl_space *space; + isl_union_map *umap; + isl_union_pw_aff *upa; + + if (!mupa) + return NULL; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n == 0) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "cannot determine domain of zero-dimensional " + "isl_multi_union_pw_aff", goto error); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + umap = isl_union_map_from_union_pw_aff(upa); + + for (i = 1; i < n; ++i) { + isl_union_map *umap_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + umap_i = isl_union_map_from_union_pw_aff(upa); + umap = isl_union_map_flat_range_product(umap, umap_i); + } + + space = isl_multi_union_pw_aff_get_space(mupa); + umap = isl_union_map_reset_range_space(umap, space); + + isl_multi_union_pw_aff_free(mupa); + return umap; +error: + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Internal data structure for isl_union_pw_multi_aff_reset_range_space. + * "range" is the space from which to set the range space. + * "res" collects the results. + */ +struct isl_union_pw_multi_aff_reset_range_space_data { + isl_space *range; + isl_union_pw_multi_aff *res; +}; + +/* Replace the range space of "pma" by the range space of data->range and + * add the result to data->res. + */ +static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_pw_multi_aff_reset_range_space_data *data = user; + isl_space *space; + + space = isl_pw_multi_aff_get_space(pma); + space = isl_space_domain(space); + space = isl_space_extend_domain_with_range(space, + isl_space_copy(data->range)); + pma = isl_pw_multi_aff_reset_space(pma, space); + data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the range space of all the piecewise affine expressions in "upma" by + * the range space of "space". + * + * This assumes that all these expressions have the same output dimension. + * + * Since the spaces of the expressions change, so do their hash values. + * We therefore need to create a new isl_union_pw_multi_aff. + * Note that the hash value is currently computed based on the entire + * space even though there can only be a single expression with a given + * domain space. + */ +static __isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_reset_range_space( + __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space) +{ + struct isl_union_pw_multi_aff_reset_range_space_data data = { space }; + isl_space *space_upma; + + space_upma = isl_union_pw_multi_aff_get_space(upma); + data.res = isl_union_pw_multi_aff_empty(space_upma); + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &reset_range_space, &data) < 0) + data.res = isl_union_pw_multi_aff_free(data.res); + + isl_space_free(space); + isl_union_pw_multi_aff_free(upma); + return data.res; +} + +/* Construct and return a union piecewise multi affine expression + * that is equal to the given multi union piecewise affine expression. + * + * In order to be able to perform the conversion, the input + * needs to have a least one output dimension. + */ +__isl_give isl_union_pw_multi_aff * +isl_union_pw_multi_aff_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i, n; + isl_space *space; + isl_union_pw_multi_aff *upma; + isl_union_pw_aff *upa; + + if (!mupa) + return NULL; + + space = isl_multi_union_pw_aff_get_space(mupa); + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n == 0) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "cannot determine domain of zero-dimensional " + "isl_multi_union_pw_aff", goto error); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + upma = isl_union_pw_multi_aff_from_union_pw_aff(upa); + + for (i = 1; i < n; ++i) { + isl_union_pw_multi_aff *upma_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa); + upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i); + } + + upma = isl_union_pw_multi_aff_reset_range_space(upma, space); + + isl_multi_union_pw_aff_free(mupa); + return upma; +error: + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Intersect the range of "mupa" with "range". + * That is, keep only those domain elements that have a function value + * in "range". + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range) +{ + isl_union_pw_multi_aff *upma; + isl_union_set *domain; + isl_space *space; + int n; + int match; + + if (!mupa || !range) + goto error; + + space = isl_set_get_space(range); + match = isl_space_tuple_is_equal(mupa->space, isl_dim_set, + space, isl_dim_set); + isl_space_free(space); + if (match < 0) + goto error; + if (!match) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "space don't match", goto error); + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n == 0) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "cannot intersect range of zero-dimensional " + "isl_multi_union_pw_aff", goto error); + + upma = isl_union_pw_multi_aff_from_multi_union_pw_aff( + isl_multi_union_pw_aff_copy(mupa)); + domain = isl_union_set_from_set(range); + domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma); + mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain); + + return mupa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_set_free(range); + return NULL; +} + +/* Return the shared domain of the elements of "mupa". + */ +__isl_give isl_union_set *isl_multi_union_pw_aff_domain( + __isl_take isl_multi_union_pw_aff *mupa) +{ + int i, n; + isl_union_pw_aff *upa; + isl_union_set *dom; + + if (!mupa) + return NULL; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + if (n == 0) + isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid, + "cannot determine domain", goto error); + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); + dom = isl_union_pw_aff_domain(upa); + for (i = 1; i < n; ++i) { + isl_union_set *dom_i; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + dom_i = isl_union_pw_aff_domain(upa); + dom = isl_union_set_intersect(dom, dom_i); + } + + isl_multi_union_pw_aff_free(mupa); + return dom; +error: + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Apply "aff" to "mupa". The space of "mupa" is equal to the domain of "aff". + * In particular, the spaces have been aligned. + * The result is defined over the shared domain of the elements of "mupa" + * + * We first extract the parametric constant part of "aff" and + * define that over the shared domain. + * Then we iterate over all input dimensions of "aff" and add the corresponding + * multiples of the elements of "mupa". + * Finally, we consider the integer divisions, calling the function + * recursively to obtain an isl_union_pw_aff corresponding to the + * integer division argument. + */ +static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff) +{ + int i, n_in, n_div; + isl_union_pw_aff *upa; + isl_union_set *uset; + isl_val *v; + isl_aff *cst; + + n_in = isl_aff_dim(aff, isl_dim_in); + n_div = isl_aff_dim(aff, isl_dim_div); + + uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa)); + cst = isl_aff_copy(aff); + cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div); + cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in); + cst = isl_aff_project_domain_on_params(cst); + upa = isl_union_pw_aff_aff_on_domain(uset, cst); + + for (i = 0; i < n_in; ++i) { + isl_union_pw_aff *upa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1)) + continue; + v = isl_aff_get_coefficient_val(aff, isl_dim_in, i); + upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + upa_i = isl_union_pw_aff_scale_val(upa_i, v); + upa = isl_union_pw_aff_add(upa, upa_i); + } + + for (i = 0; i < n_div; ++i) { + isl_aff *div; + isl_union_pw_aff *upa_i; + + if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1)) + continue; + div = isl_aff_get_div(aff, i); + upa_i = multi_union_pw_aff_apply_aff( + isl_multi_union_pw_aff_copy(mupa), div); + upa_i = isl_union_pw_aff_floor(upa_i); + v = isl_aff_get_coefficient_val(aff, isl_dim_div, i); + upa_i = isl_union_pw_aff_scale_val(upa_i, v); + upa = isl_union_pw_aff_add(upa, upa_i); + } + + isl_multi_union_pw_aff_free(mupa); + isl_aff_free(aff); + + return upa; +} + +/* Apply "aff" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "aff". + * Furthermore, the dimension of this space needs to be greater than zero. + * The result is defined over the shared domain of the elements of "mupa" + * + * We perform these checks and then hand over control to + * multi_union_pw_aff_apply_aff. + */ +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff) +{ + isl_space *space1, *space2; + int equal; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_aff_get_space(aff)); + aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !aff) + goto error; + + space1 = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_aff_get_domain_space(aff); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "spaces don't match", goto error); + if (isl_aff_dim(aff, isl_dim_in) == 0) + isl_die(isl_aff_get_ctx(aff), isl_error_invalid, + "cannot determine domains", goto error); + + return multi_union_pw_aff_apply_aff(mupa, aff); +error: + isl_multi_union_pw_aff_free(mupa); + isl_aff_free(aff); + return NULL; +} + +/* Apply "ma" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "ma". + * Furthermore, the dimension of this space needs to be greater than zero, + * unless the dimension of the target space of "ma" is also zero. + * The result is defined over the shared domain of the elements of "mupa" + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma) +{ + isl_space *space1, *space2; + isl_multi_union_pw_aff *res; + int equal; + int i, n_out; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_multi_aff_get_space(ma)); + ma = isl_multi_aff_align_params(ma, + isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !ma) + goto error; + + space1 = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_multi_aff_get_domain_space(ma); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid, + "spaces don't match", goto error); + n_out = isl_multi_aff_dim(ma, isl_dim_out); + if (isl_multi_aff_dim(ma, isl_dim_in) == 0 && n_out != 0) + isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid, + "cannot determine domains", goto error); + + space1 = isl_space_range(isl_multi_aff_get_space(ma)); + res = isl_multi_union_pw_aff_alloc(space1); + + for (i = 0; i < n_out; ++i) { + isl_aff *aff; + isl_union_pw_aff *upa; + + aff = isl_multi_aff_get_aff(ma, i); + upa = multi_union_pw_aff_apply_aff( + isl_multi_union_pw_aff_copy(mupa), aff); + res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa); + } + + isl_multi_aff_free(ma); + isl_multi_union_pw_aff_free(mupa); + return res; +error: + isl_multi_union_pw_aff_free(mupa); + isl_multi_aff_free(ma); + return NULL; +} + +/* Apply "pa" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "pa". + * Furthermore, the dimension of this space needs to be greater than zero. + * The result is defined over the shared domain of the elements of "mupa" + */ +__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa) +{ + int i; + int equal; + isl_space *space, *space2; + isl_union_pw_aff *upa; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_pw_aff_get_space(pa)); + pa = isl_pw_aff_align_params(pa, + isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !pa) + goto error; + + space = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_pw_aff_get_domain_space(pa); + equal = isl_space_is_equal(space, space2); + isl_space_free(space); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "spaces don't match", goto error); + if (isl_pw_aff_dim(pa, isl_dim_in) == 0) + isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid, + "cannot determine domains", goto error); + + space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa)); + upa = isl_union_pw_aff_empty(space); + + for (i = 0; i < pa->n; ++i) { + isl_aff *aff; + isl_set *domain; + isl_multi_union_pw_aff *mupa_i; + isl_union_pw_aff *upa_i; + + mupa_i = isl_multi_union_pw_aff_copy(mupa); + domain = isl_set_copy(pa->p[i].set); + mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain); + aff = isl_aff_copy(pa->p[i].aff); + upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff); + upa = isl_union_pw_aff_union_add(upa, upa_i); + } + + isl_multi_union_pw_aff_free(mupa); + isl_pw_aff_free(pa); + return upa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_pw_aff_free(pa); + return NULL; +} + +/* Apply "pma" to "mupa". The space of "mupa" needs to be compatible + * with the domain of "pma". + * Furthermore, the dimension of this space needs to be greater than zero, + * unless the dimension of the target space of "pma" is also zero. + * The result is defined over the shared domain of the elements of "mupa" + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_pw_multi_aff *pma) +{ + isl_space *space1, *space2; + isl_multi_union_pw_aff *res; + int equal; + int i, n_out; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, + isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !pma) + goto error; + + space1 = isl_multi_union_pw_aff_get_space(mupa); + space2 = isl_pw_multi_aff_get_domain_space(pma); + equal = isl_space_is_equal(space1, space2); + isl_space_free(space1); + isl_space_free(space2); + if (equal < 0) + goto error; + if (!equal) + isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, + "spaces don't match", goto error); + n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); + if (isl_pw_multi_aff_dim(pma, isl_dim_in) == 0 && n_out != 0) + isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, + "cannot determine domains", goto error); + + space1 = isl_space_range(isl_pw_multi_aff_get_space(pma)); + res = isl_multi_union_pw_aff_alloc(space1); + + for (i = 0; i < n_out; ++i) { + isl_pw_aff *pa; + isl_union_pw_aff *upa; + + pa = isl_pw_multi_aff_get_pw_aff(pma, i); + upa = isl_multi_union_pw_aff_apply_pw_aff( + isl_multi_union_pw_aff_copy(mupa), pa); + res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa); + } + + isl_pw_multi_aff_free(pma); + isl_multi_union_pw_aff_free(mupa); + return res; +error: + isl_multi_union_pw_aff_free(mupa); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Compute the pullback of "mupa" by the function represented by "upma". + * In other words, plug in "upma" in "mupa". The result contains + * expressions defined over the domain space of "upma". + * + * Run over all elements of "mupa" and plug in "upma" in each of them. + */ +__isl_give isl_multi_union_pw_aff * +isl_multi_union_pw_aff_pullback_union_pw_multi_aff( + __isl_take isl_multi_union_pw_aff *mupa, + __isl_take isl_union_pw_multi_aff *upma) +{ + int i, n; + + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_union_pw_multi_aff_get_space(upma)); + upma = isl_union_pw_multi_aff_align_params(upma, + isl_multi_union_pw_aff_get_space(mupa)); + if (!mupa || !upma) + goto error; + + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa, + isl_union_pw_multi_aff_copy(upma)); + mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); + } + + isl_union_pw_multi_aff_free(upma); + return mupa; +error: + isl_multi_union_pw_aff_free(mupa); + isl_union_pw_multi_aff_free(upma); + return NULL; +} + +/* Extract the sequence of elements in "mupa" with domain space "space" + * (ignoring parameters). + * + * For the elements of "mupa" that are not defined on the specified space, + * the corresponding element in the result is empty. + */ +__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff( + __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space) +{ + int i, n; + isl_space *space_mpa = NULL; + isl_multi_pw_aff *mpa; + + if (!mupa || !space) + goto error; + + space_mpa = isl_multi_union_pw_aff_get_space(mupa); + if (!isl_space_match(space_mpa, isl_dim_param, space, isl_dim_param)) { + space = isl_space_drop_dims(space, isl_dim_param, + 0, isl_space_dim(space, isl_dim_param)); + space = isl_space_align_params(space, + isl_space_copy(space_mpa)); + if (!space) + goto error; + } + space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space), + space_mpa); + mpa = isl_multi_pw_aff_alloc(space_mpa); + + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, 1); + n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + isl_pw_aff *pa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); + pa = isl_union_pw_aff_extract_pw_aff(upa, + isl_space_copy(space)); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + isl_union_pw_aff_free(upa); + } + + isl_space_free(space); + return mpa; +error: + isl_space_free(space_mpa); + isl_space_free(space); + return NULL; +} diff -Nru isl-0.12.2/isl_affine_hull.c isl-0.15/isl_affine_hull.c --- isl-0.12.2/isl_affine_hull.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_affine_hull.c 2015-06-02 09:28:09.000000000 +0000 @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -22,6 +22,7 @@ #include "isl_sample.h" #include "isl_tab.h" #include +#include struct isl_basic_map *isl_basic_map_implicit_equalities( struct isl_basic_map *bmap) @@ -473,10 +474,9 @@ } if (j == hull->n_eq) break; - if (tab->samples) - tab = isl_tab_add_sample(tab, isl_vec_copy(sample)); - if (!tab) - goto error; + if (tab->samples && + isl_tab_add_sample(tab, isl_vec_copy(sample)) < 0) + hull = isl_basic_set_free(hull); if (bset) hull = add_adjacent_points(hull, isl_vec_copy(sample), bset); @@ -520,6 +520,7 @@ isl_basic_map_drop_inequality(bmap, i); } + bmap = isl_basic_map_add_known_div_constraints(bmap); return bmap; } @@ -542,8 +543,11 @@ int i; unsigned dim; - if (n == 0) - return isl_basic_map_set_to_empty(bmap); + if (n == 0) { + isl_space *space = isl_basic_map_get_space(bmap); + isl_basic_map_free(bmap); + return isl_basic_map_universe(space); + } bmap = isl_basic_map_cow(bmap); if (!bmap) return NULL; @@ -567,6 +571,7 @@ isl_basic_map_drop_inequality(bmap, i); } + bmap = isl_basic_map_add_known_div_constraints(bmap); return bmap; } @@ -1000,11 +1005,11 @@ if (!cone) goto error; if (cone->n_eq == 0) { - struct isl_basic_set *hull; + isl_space *space; + space = isl_basic_set_get_space(bset); isl_basic_set_free(cone); - hull = isl_basic_set_universe_like(bset); isl_basic_set_free(bset); - return hull; + return isl_basic_set_universe(space); } if (cone->n_eq < isl_basic_set_total_dim(cone)) @@ -1142,6 +1147,19 @@ return (isl_set *)isl_map_detect_equalities((isl_map *)set); } +/* Return the superset of "bmap" described by the equalities + * satisfied by "bmap" that are already known. + */ +__isl_give isl_basic_map *isl_basic_map_plain_affine_hull( + __isl_take isl_basic_map *bmap) +{ + bmap = isl_basic_map_cow(bmap); + if (bmap) + isl_basic_map_free_inequality(bmap, bmap->n_ineq); + bmap = isl_basic_map_finalize(bmap); + return bmap; +} + /* After computing the rational affine hull (by detecting the implicit * equalities), we compute the additional equalities satisfied by * the integer points (if any) and add the original equalities back in. @@ -1149,10 +1167,7 @@ struct isl_basic_map *isl_basic_map_affine_hull(struct isl_basic_map *bmap) { bmap = isl_basic_map_detect_equalities(bmap); - bmap = isl_basic_map_cow(bmap); - if (bmap) - isl_basic_map_free_inequality(bmap, bmap->n_ineq); - bmap = isl_basic_map_finalize(bmap); + bmap = isl_basic_map_plain_affine_hull(bmap); return bmap; } @@ -1331,6 +1346,18 @@ return isl_map_local_affine_hull(set); } +/* Return an empty basic map living in the same space as "map". + */ +static __isl_give isl_basic_map *replace_map_by_empty_basic_map( + __isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + return isl_basic_map_empty(space); +} + /* Compute the affine hull of "map". * * We first compute the affine hull of each basic map separately. @@ -1366,11 +1393,8 @@ if (!map) return NULL; - if (map->n == 0) { - hull = isl_basic_map_empty_like_map(map); - isl_map_free(map); - return hull; - } + if (map->n == 0) + return replace_map_by_empty_basic_map(map); model = isl_basic_map_copy(map->p[0]); set = isl_map_underlying_set(map); diff -Nru isl-0.12.2/isl_aff_private.h isl-0.15/isl_aff_private.h --- isl-0.12.2/isl_aff_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_aff_private.h 2015-06-02 09:28:09.000000000 +0000 @@ -5,9 +5,13 @@ #include #include #include +#include #include /* ls represents the domain space. + * + * If the first two elements of "v" (the denominator and the constant term) + * are zero, then the isl_aff represents NaN. */ struct isl_aff { int ref; @@ -58,6 +62,8 @@ struct isl_pw_multi_aff_piece p[1]; }; +__isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, + __isl_take isl_vec *v); __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls); __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff, @@ -67,6 +73,12 @@ __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff, __isl_take isl_reordering *r); +int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v); +__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v); +__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff, + enum isl_dim_type type, int pos, isl_int v); +__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v); + __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff); __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff, @@ -88,6 +100,13 @@ __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational( __isl_take isl_pw_aff_list *list); +__isl_give isl_pw_aff *isl_pw_aff_scale(__isl_take isl_pw_aff *pwaff, + isl_int f); +__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff, + isl_int f); + +int isl_aff_matching_params(__isl_keep isl_aff *aff, + __isl_keep isl_space *space); int isl_aff_check_match_domain_space(__isl_keep isl_aff *aff, __isl_keep isl_space *space); @@ -101,6 +120,9 @@ __isl_give isl_multi_aff *isl_multi_aff_align_divs( __isl_take isl_multi_aff *maff); +__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities( + __isl_take isl_basic_set *bset); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_domain_space( __isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_space( @@ -119,10 +141,14 @@ int n_div_ma, int n_div_bmap, isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom); +__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff, + __isl_take isl_basic_set *eq); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute( __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos, __isl_keep isl_pw_aff *subs); +int isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa, + __isl_keep isl_space *space); int isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa, __isl_keep isl_space *space); @@ -131,4 +157,19 @@ #include +#undef EL +#define EL isl_union_pw_aff + +#include + +#undef BASE +#define BASE union_pw_aff + +#include + +#undef EL +#define EL isl_union_pw_multi_aff + +#include + #endif diff -Nru isl-0.12.2/isl_arg.c isl-0.15/isl_arg.c --- isl-0.12.2/isl_arg.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_arg.c 2015-06-10 18:25:32.000000000 +0000 @@ -20,6 +20,8 @@ static void set_default_choice(struct isl_arg *arg, void *opt) { + if (arg->offset == (size_t) -1) + return; *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value; } @@ -202,7 +204,89 @@ free(opt); } -static int print_arg_help(struct isl_arg *decl, const char *prefix, int no) +/* Data structure for collecting the prefixes of ancestor nodes. + * + * n is the number of prefixes. + * prefix[i] for i < n is a prefix of an ancestor. + * len[i] for i < n is the length of prefix[i]. + */ +struct isl_prefixes { + int n; + const char *prefix[10]; + size_t len[10]; +}; + +/* Add "prefix" to the list of prefixes and return the updated + * number of prefixes. + */ +static int add_prefix(struct isl_prefixes *prefixes, const char *prefix) +{ + int n = prefixes->n; + + if (!prefix) + return n; + + if (prefixes->n >= 10) { + fprintf(stderr, "too many prefixes\n"); + exit(EXIT_FAILURE); + } + prefixes->len[prefixes->n] = strlen(prefix); + prefixes->prefix[prefixes->n] = prefix; + prefixes->n++; + + return n; +} + +/* Drop all prefixes starting at "first". + */ +static void drop_prefix(struct isl_prefixes *prefixes, int first) +{ + prefixes->n = first; +} + +/* Print the prefixes in "prefixes". + */ +static int print_prefixes(struct isl_prefixes *prefixes) +{ + int i; + int len = 0; + + if (!prefixes) + return 0; + + for (i = 0; i < prefixes->n; ++i) { + printf("%s-", prefixes->prefix[i]); + len += strlen(prefixes->prefix[i]) + 1; + } + + return len; +} + +/* Check if "name" starts with one or more of the prefixes in "prefixes", + * starting at *first. If so, advance the pointer beyond the prefixes + * and return the updated pointer. Additionally, update *first to + * the index after the last prefix found. + */ +static const char *skip_prefixes(const char *name, + struct isl_prefixes *prefixes, int *first) +{ + int i; + + for (i = first ? *first : 0; i < prefixes->n; ++i) { + size_t len = prefixes->len[i]; + const char *prefix = prefixes->prefix[i]; + if (strncmp(name, prefix, len) == 0 && name[len] == '-') { + name += len + 1; + if (first) + *first = i + 1; + } + } + + return name; +} + +static int print_arg_help(struct isl_arg *decl, struct isl_prefixes *prefixes, + int no) { int len = 0; @@ -222,14 +306,11 @@ len += 8; } - if (prefix) { - printf("%s-", prefix); - len += strlen(prefix) + 1; - } if (no) { printf("no-"); len += 3; } + len += print_prefixes(prefixes); printf("%s", decl->long_name); len += strlen(decl->long_name); @@ -307,7 +388,6 @@ printf("\n%30s", ""); else printf("%*s", 30 - pos, ""); - pos = 0; } else { if (pos + len >= 48) printf("\n%30s", ""); @@ -333,13 +413,13 @@ print_default(decl, s, pos); } -static void print_choice_help(struct isl_arg *decl, const char *prefix, - void *opt) +static void print_choice_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) { int i; int pos; - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); printf("="); pos++; @@ -377,7 +457,6 @@ printf("\n%30s", ""); else printf("%*s", 30 - pos, ""); - pos = 0; } else { if (pos + len >= 48) printf("\n%30s", ""); @@ -398,13 +477,13 @@ printf("%s", default_suffix); } -static void print_flags_help(struct isl_arg *decl, const char *prefix, - void *opt) +static void print_flags_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) { int i, j; int pos; - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); printf("="); pos++; @@ -432,12 +511,13 @@ printf("\n"); } -static void print_bool_help(struct isl_arg *decl, const char *prefix, void *opt) +static void print_bool_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) { int pos; unsigned *p = opt ? (unsigned *)(((char *) opt) + decl->offset) : NULL; int no = p ? *p == 1 : 0; - pos = print_arg_help(decl, prefix, no); + pos = print_arg_help(decl, prefixes, no); pos = print_help_msg(decl, pos); if (decl->offset != (size_t) -1) print_default(decl, no ? "yes" : "no", pos); @@ -450,12 +530,13 @@ return pos + 3 + strlen(name); } -static void print_int_help(struct isl_arg *decl, const char *prefix, void *opt) +static void print_int_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) { int pos; char val[20]; int *p = (int *)(((char *) opt) + decl->offset); - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); pos = print_argument_name(decl, decl->argument_name, pos); pos = print_help_msg(decl, pos); snprintf(val, sizeof(val), "%d", *p); @@ -463,11 +544,12 @@ printf("\n"); } -static void print_long_help(struct isl_arg *decl, const char *prefix, void *opt) +static void print_long_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) { int pos; long *p = (long *)(((char *) opt) + decl->offset); - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); if (*p != decl->u.l.default_selected) { printf("["); pos++; @@ -482,22 +564,24 @@ printf("\n"); } -static void print_ulong_help(struct isl_arg *decl, const char *prefix) +static void print_ulong_help(struct isl_arg *decl, + struct isl_prefixes *prefixes) { int pos; - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); printf("=ulong"); pos += 6; print_help_msg(decl, pos); printf("\n"); } -static void print_str_help(struct isl_arg *decl, const char *prefix, void *opt) +static void print_str_help(struct isl_arg *decl, + struct isl_prefixes *prefixes, void *opt) { int pos; const char *a = decl->argument_name ? decl->argument_name : "string"; const char **p = (const char **)(((char *) opt) + decl->offset); - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); pos = print_argument_name(decl, a, pos); pos = print_help_msg(decl, pos); if (*p) @@ -505,17 +589,19 @@ printf("\n"); } -static void print_str_list_help(struct isl_arg *decl, const char *prefix) +static void print_str_list_help(struct isl_arg *decl, + struct isl_prefixes *prefixes) { int pos; const char *a = decl->argument_name ? decl->argument_name : "string"; - pos = print_arg_help(decl, prefix, 0); + pos = print_arg_help(decl, prefixes, 0); pos = print_argument_name(decl, a, pos); pos = print_help_msg(decl, pos); printf("\n"); } -static void print_help(struct isl_arg *arg, const char *prefix, void *opt) +static void print_help(struct isl_arg *arg, + struct isl_prefixes *prefixes, void *opt) { int i; int any = 0; @@ -525,35 +611,35 @@ continue; switch (arg[i].type) { case isl_arg_flags: - print_flags_help(&arg[i], prefix, opt); + print_flags_help(&arg[i], prefixes, opt); any = 1; break; case isl_arg_choice: - print_choice_help(&arg[i], prefix, opt); + print_choice_help(&arg[i], prefixes, opt); any = 1; break; case isl_arg_bool: - print_bool_help(&arg[i], prefix, opt); + print_bool_help(&arg[i], prefixes, opt); any = 1; break; case isl_arg_int: - print_int_help(&arg[i], prefix, opt); + print_int_help(&arg[i], prefixes, opt); any = 1; break; case isl_arg_long: - print_long_help(&arg[i], prefix, opt); + print_long_help(&arg[i], prefixes, opt); any = 1; break; case isl_arg_ulong: - print_ulong_help(&arg[i], prefix); + print_ulong_help(&arg[i], prefixes); any = 1; break; case isl_arg_str: - print_str_help(&arg[i], prefix, opt); + print_str_help(&arg[i], prefixes, opt); any = 1; break; case isl_arg_str_list: - print_str_list_help(&arg[i], prefix); + print_str_list_help(&arg[i], prefixes); any = 1; break; case isl_arg_alias: @@ -569,6 +655,7 @@ for (i = 0; arg[i].type != isl_arg_end; ++i) { void *child; + int first; if (arg[i].type != isl_arg_child) continue; @@ -583,7 +670,9 @@ child = opt; else child = *(void **)(((char *) opt) + arg[i].offset); - print_help(arg[i].u.child.child->args, arg[i].long_name, child); + first = add_prefix(prefixes, arg[i].long_name); + print_help(arg[i].u.child.child->args, prefixes, child); + drop_prefix(prefixes, first); any = 1; } } @@ -625,6 +714,7 @@ void *opt) { int i; + struct isl_prefixes prefixes = { 0 }; printf("Usage: %s [OPTION...]", prog_name(prog)); @@ -634,7 +724,7 @@ printf("\n\n"); - print_help(arg, NULL, opt); + print_help(arg, &prefixes, opt); printf("\n"); if (any_version(arg)) printf(" -V, --version\n"); @@ -672,7 +762,7 @@ } static const char *skip_name(struct isl_arg *decl, const char *arg, - const char *prefix, int need_argument, int *has_argument) + struct isl_prefixes *prefixes, int need_argument, int *has_argument) { const char *equal; const char *name; @@ -700,12 +790,7 @@ *has_argument = !!equal; end = equal ? equal : name + strlen(name); - if (prefix) { - size_t prefix_len = strlen(prefix); - if (strncmp(name, prefix, prefix_len) == 0 && - name[prefix_len] == '-') - name += prefix_len + 1; - } + name = skip_prefixes(name, prefixes, NULL); if (!match_long_name(decl, name, end)) return NULL; @@ -714,13 +799,13 @@ } static int parse_choice_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int i; int has_argument; const char *choice; - choice = skip_name(decl, arg[0], prefix, 0, &has_argument); + choice = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!choice) return 0; @@ -772,14 +857,14 @@ } static int parse_flags_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int has_argument; const char *flags; const char *comma; unsigned val; - flags = skip_name(decl, arg[0], prefix, 0, &has_argument); + flags = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!flags) return 0; @@ -805,12 +890,13 @@ } static int parse_bool_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { const char *name; unsigned *p = (unsigned *)(((char *)opt) + decl->offset); + int next_prefix; - if (skip_name(decl, arg[0], prefix, 0, NULL)) { + if (skip_name(decl, arg[0], prefixes, 0, NULL)) { if ((decl->flags & ISL_ARG_BOOL_ARG) && arg[1]) { char *endptr; int val = strtol(arg[1], &endptr, 0); @@ -837,25 +923,14 @@ if (!name) return 0; - if (prefix) { - size_t prefix_len = strlen(prefix); - if (strncmp(name, prefix, prefix_len) == 0 && - name[prefix_len] == '-') { - name += prefix_len + 1; - prefix = NULL; - } - } + next_prefix = 0; + name = skip_prefixes(name, prefixes, &next_prefix); if (strncmp(name, "no-", 3)) return 0; name += 3; - if (prefix) { - size_t prefix_len = strlen(prefix); - if (strncmp(name, prefix, prefix_len) == 0 && - name[prefix_len] == '-') - name += prefix_len + 1; - } + name = skip_prefixes(name, prefixes, &next_prefix); if (match_long_name(decl, name, name + strlen(name))) { if (decl->offset != (size_t) -1) @@ -870,13 +945,13 @@ } static int parse_str_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int has_argument; const char *s; char **p = (char **)(((char *)opt) + decl->offset); - s = skip_name(decl, arg[0], prefix, 0, &has_argument); + s = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!s) return 0; @@ -911,12 +986,12 @@ } static int parse_str_list_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int has_argument; const char *s; - s = skip_name(decl, arg[0], prefix, 0, &has_argument); + s = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!s) return 0; @@ -934,14 +1009,14 @@ } static int parse_int_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int has_argument; const char *val; char *endptr; int *p = (int *)(((char *)opt) + decl->offset); - val = skip_name(decl, arg[0], prefix, 0, &has_argument); + val = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!val) return 0; @@ -962,14 +1037,14 @@ } static int parse_long_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int has_argument; const char *val; char *endptr; long *p = (long *)(((char *)opt) + decl->offset); - val = skip_name(decl, arg[0], prefix, 0, &has_argument); + val = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!val) return 0; @@ -1002,14 +1077,14 @@ } static int parse_ulong_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int has_argument; const char *val; char *endptr; unsigned long *p = (unsigned long *)(((char *)opt) + decl->offset); - val = skip_name(decl, arg[0], prefix, 0, &has_argument); + val = skip_name(decl, arg[0], prefixes, 0, &has_argument); if (!val) return 0; @@ -1030,24 +1105,28 @@ } static int parse_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt); + struct isl_prefixes *prefixes, void *opt); static int parse_child_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { void *child; + int first, parsed; if (decl->offset == (size_t) -1) child = opt; - else { + else child = *(void **)(((char *)opt) + decl->offset); - prefix = decl->long_name; - } - return parse_option(decl->u.child.child->args, arg, prefix, child); + + first = add_prefix(prefixes, decl->long_name); + parsed = parse_option(decl->u.child.child->args, arg, prefixes, child); + drop_prefix(prefixes, first); + + return parsed; } static int parse_option(struct isl_arg *decl, char **arg, - const char *prefix, void *opt) + struct isl_prefixes *prefixes, void *opt) { int i; @@ -1055,32 +1134,38 @@ int parsed = 0; switch (decl[i].type) { case isl_arg_choice: - parsed = parse_choice_option(&decl[i], arg, prefix, opt); + parsed = parse_choice_option(&decl[i], arg, + prefixes, opt); break; case isl_arg_flags: - parsed = parse_flags_option(&decl[i], arg, prefix, opt); + parsed = parse_flags_option(&decl[i], arg, + prefixes, opt); break; case isl_arg_int: - parsed = parse_int_option(&decl[i], arg, prefix, opt); + parsed = parse_int_option(&decl[i], arg, prefixes, opt); break; case isl_arg_long: - parsed = parse_long_option(&decl[i], arg, prefix, opt); + parsed = parse_long_option(&decl[i], arg, + prefixes, opt); break; case isl_arg_ulong: - parsed = parse_ulong_option(&decl[i], arg, prefix, opt); + parsed = parse_ulong_option(&decl[i], arg, + prefixes, opt); break; case isl_arg_bool: - parsed = parse_bool_option(&decl[i], arg, prefix, opt); + parsed = parse_bool_option(&decl[i], arg, + prefixes, opt); break; case isl_arg_str: - parsed = parse_str_option(&decl[i], arg, prefix, opt); + parsed = parse_str_option(&decl[i], arg, prefixes, opt); break; case isl_arg_str_list: - parsed = parse_str_list_option(&decl[i], arg, prefix, + parsed = parse_str_list_option(&decl[i], arg, prefixes, opt); break; case isl_arg_child: - parsed = parse_child_option(&decl[i], arg, prefix, opt); + parsed = parse_child_option(&decl[i], arg, + prefixes, opt); break; case isl_arg_alias: case isl_arg_arg: @@ -1171,6 +1256,7 @@ int skip = 0; int i; int n; + struct isl_prefixes prefixes = { 0 }; n = n_arg(args->args); @@ -1200,7 +1286,8 @@ continue; } check_help(args, argv[1 + skip], argv[0], opt, flags); - parsed = parse_option(args->args, &argv[1 + skip], NULL, opt); + parsed = parse_option(args->args, &argv[1 + skip], + &prefixes, opt); if (parsed) argc = drop_argument(argc, argv, 1 + skip, parsed); else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) { diff -Nru isl-0.12.2/isl_ast_build.c isl-0.15/isl_ast_build.c --- isl-0.12.2/isl_ast_build.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ast_build.c 2015-06-10 18:25:33.000000000 +0000 @@ -1,15 +1,21 @@ /* - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include #include +#include #include +#include +#include #include #include @@ -63,10 +69,12 @@ isl_multi_aff_free(build->offsets); build->offsets = isl_multi_aff_zero(isl_space_copy(space)); isl_multi_aff_free(build->values); - build->values = isl_multi_aff_identity(space); + build->values = isl_multi_aff_identity(isl_space_copy(space)); + isl_multi_aff_free(build->internal2input); + build->internal2input = isl_multi_aff_identity(space); if (!build->iterators || !build->domain || !build->generated || - !build->pending || !build->values || + !build->pending || !build->values || !build->internal2input || !build->strides || !build->offsets || !build->options) return isl_ast_build_free(build); @@ -98,7 +106,7 @@ * * The input set is usually a parameter domain, but we currently allow it to * be any kind of set. We set the domain of the returned isl_ast_build - * to "set" and initialize all the other field to default values. + * to "set" and initialize all the other fields to default values. */ __isl_give isl_ast_build *isl_ast_build_from_context(__isl_take isl_set *set) { @@ -143,6 +151,19 @@ return NULL; } +/* Create an isl_ast_build with a universe (parametric) context. + */ +__isl_give isl_ast_build *isl_ast_build_alloc(isl_ctx *ctx) +{ + isl_space *space; + isl_set *context; + + space = isl_space_params_alloc(ctx, 0); + context = isl_set_universe(space); + + return isl_ast_build_from_context(context); +} + __isl_give isl_ast_build *isl_ast_build_copy(__isl_keep isl_ast_build *build) { if (!build) @@ -173,6 +194,7 @@ dup->generated = isl_set_copy(build->generated); dup->pending = isl_set_copy(build->pending); dup->values = isl_multi_aff_copy(build->values); + dup->internal2input = isl_multi_aff_copy(build->internal2input); dup->value = isl_pw_aff_copy(build->value); dup->strides = isl_vec_copy(build->strides); dup->offsets = isl_multi_aff_copy(build->offsets); @@ -185,14 +207,32 @@ dup->before_each_for_user = build->before_each_for_user; dup->after_each_for = build->after_each_for; dup->after_each_for_user = build->after_each_for_user; + dup->before_each_mark = build->before_each_mark; + dup->before_each_mark_user = build->before_each_mark_user; + dup->after_each_mark = build->after_each_mark; + dup->after_each_mark_user = build->after_each_mark_user; dup->create_leaf = build->create_leaf; dup->create_leaf_user = build->create_leaf_user; + dup->node = isl_schedule_node_copy(build->node); + if (build->loop_type) { + int i; + + dup->n = build->n; + dup->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, dup->n); + if (dup->n && !dup->loop_type) + return isl_ast_build_free(dup); + for (i = 0; i < dup->n; ++i) + dup->loop_type[i] = build->loop_type[i]; + } if (!dup->iterators || !dup->domain || !dup->generated || !dup->pending || !dup->values || !dup->strides || !dup->offsets || !dup->options || + (build->internal2input && !dup->internal2input) || (build->executed && !dup->executed) || - (build->value && !dup->value)) + (build->value && !dup->value) || + (build->node && !dup->node)) return isl_ast_build_free(dup); return dup; @@ -220,7 +260,15 @@ isl_space_copy(model)); build->options = isl_union_map_align_params(build->options, isl_space_copy(model)); - isl_space_free(model); + if (build->internal2input) { + build->internal2input = + isl_multi_aff_align_params(build->internal2input, + model); + if (!build->internal2input) + return isl_ast_build_free(build); + } else { + isl_space_free(model); + } if (!build->domain || !build->values || !build->offsets || !build->options) @@ -243,7 +291,8 @@ return isl_ast_build_dup(build); } -void *isl_ast_build_free(__isl_take isl_ast_build *build) +__isl_null isl_ast_build *isl_ast_build_free( + __isl_take isl_ast_build *build) { if (!build) return NULL; @@ -256,12 +305,16 @@ isl_set_free(build->generated); isl_set_free(build->pending); isl_multi_aff_free(build->values); + isl_multi_aff_free(build->internal2input); isl_pw_aff_free(build->value); isl_vec_free(build->strides); isl_multi_aff_free(build->offsets); isl_multi_aff_free(build->schedule_map); isl_union_map_free(build->executed); isl_union_map_free(build->options); + isl_schedule_node_free(build->node); + free(build->loop_type); + isl_set_free(build->isolated); free(build); @@ -379,6 +432,42 @@ return build; } +/* Set the "before_each_mark" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_before_each_mark( + __isl_take isl_ast_build *build, + isl_stat (*fn)(__isl_keep isl_id *mark, __isl_keep isl_ast_build *build, + void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->before_each_mark = fn; + build->before_each_mark_user = user; + + return build; +} + +/* Set the "after_each_mark" callback of "build" to "fn". + */ +__isl_give isl_ast_build *isl_ast_build_set_after_each_mark( + __isl_take isl_ast_build *build, + __isl_give isl_ast_node *(*fn)(__isl_take isl_ast_node *node, + __isl_keep isl_ast_build *build, void *user), void *user) +{ + build = isl_ast_build_cow(build); + + if (!build) + return NULL; + + build->after_each_mark = fn; + build->after_each_mark_user = user; + + return build; +} + /* Set the "create_leaf" callback of "build" to "fn". */ __isl_give isl_ast_build *isl_ast_build_set_create_leaf( @@ -419,6 +508,10 @@ build->before_each_for_user = NULL; build->after_each_for = NULL; build->after_each_for_user = NULL; + build->before_each_mark = NULL; + build->before_each_mark_user = NULL; + build->after_each_mark = NULL; + build->after_each_mark_user = NULL; build->create_leaf = NULL; build->create_leaf_user = NULL; @@ -582,6 +675,8 @@ isl_vec_dump(build->strides); fprintf(stderr, "offsets: "); isl_multi_aff_dump(build->offsets); + fprintf(stderr, "internal2input: "); + isl_multi_aff_dump(build->internal2input); } /* Initialize "build" for AST construction in schedule space "space" @@ -616,7 +711,7 @@ * the first (and presumably only) affine expression in the isl_pw_aff * on which this function is used. */ -static int extract_single_piece(__isl_take isl_set *set, +static isl_stat extract_single_piece(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user) { isl_aff **p = user; @@ -624,10 +719,27 @@ *p = aff; isl_set_free(set); - return -1; + return isl_stat_error; +} + +/* Intersect "set" with the stride constraint of "build", if any. + */ +static __isl_give isl_set *intersect_stride_constraint(__isl_take isl_set *set, + __isl_keep isl_ast_build *build) +{ + isl_set *stride; + + if (!build) + return isl_set_free(set); + if (!isl_ast_build_has_stride(build, build->depth)) + return set; + + stride = isl_ast_build_get_stride_constraint(build); + return isl_set_intersect(set, stride); } -/* Check if the given bounds on the current dimension imply that +/* Check if the given bounds on the current dimension (together with + * the stride constraint, if any) imply that * this current dimension attains only a single value (in terms of * parameters and outer dimensions). * If so, we record it in build->value. @@ -654,6 +766,7 @@ set = isl_set_from_basic_set(bounds); set = isl_set_intersect(set, isl_set_copy(build->domain)); + set = intersect_stride_constraint(set, build); it_map = isl_ast_build_map_to_iterator(build, set); sv = isl_map_is_single_valued(it_map); @@ -686,7 +799,7 @@ } /* Update the AST build based on the given loop bounds for - * the current dimension. + * the current dimension and the stride information available in the build. * * We first make sure that the bounds do not refer to any iterators * that have already been eliminated. @@ -699,10 +812,9 @@ * be defined on a subset of the domain. Plugging in the value * would restrict the build domain to this subset, while this * restriction may not be reflected in the generated code. - * build->domain may, however, already refer to the current dimension - * due an earlier call to isl_ast_build_include_stride. If so, we need - * to eliminate the dimension so that we do not introduce it in any other sets. * Finally, we intersect build->domain with the updated bounds. + * We also add the stride constraint unless we have been able + * to find a fixed value expressed as a single affine expression. * * Note that the check for a fixed value in update_values requires * us to intersect the bounds with the current build domain. @@ -733,11 +845,7 @@ set = isl_set_compute_divs(set); build->pending = isl_set_intersect(build->pending, isl_set_copy(set)); - if (isl_ast_build_has_stride(build, build->depth)) { - build->domain = isl_set_eliminate(build->domain, - isl_dim_set, build->depth, 1); - build->domain = isl_set_compute_divs(build->domain); - } + build->domain = isl_set_intersect(build->domain, set); } else { isl_basic_set *generated, *pending; @@ -751,10 +859,13 @@ generated, isl_dim_set, build->depth, 1); build->generated = isl_set_intersect(build->generated, isl_set_from_basic_set(generated)); + build->domain = isl_set_intersect(build->domain, set); + build = isl_ast_build_include_stride(build); + if (!build) + goto error; } isl_basic_set_free(bounds); - build->domain = isl_set_intersect(build->domain, set); if (!build->domain || !build->pending || !build->generated) return isl_ast_build_free(build); @@ -765,38 +876,6 @@ return NULL; } -/* Update build->domain based on the constraints enforced by inner loops. - * - * The constraints in build->pending may end up not getting generated - * if they are implied by "enforced". We therefore reconstruct - * build->domain from build->generated and build->pending, dropping - * those constraint in build->pending that may not get generated. - */ -__isl_give isl_ast_build *isl_ast_build_set_enforced( - __isl_take isl_ast_build *build, __isl_take isl_basic_set *enforced) -{ - isl_set *set; - - build = isl_ast_build_cow(build); - if (!build) - goto error; - - set = isl_set_from_basic_set(enforced); - set = isl_set_gist(isl_set_copy(build->pending), set); - set = isl_set_intersect(isl_set_copy(build->generated), set); - - isl_set_free(build->domain); - build->domain = set; - - if (!build->domain) - return isl_ast_build_free(build); - - return build; -error: - isl_basic_set_free(enforced); - return isl_ast_build_free(build); -} - /* Intersect build->domain with "set", where "set" is specified * in terms of the internal schedule domain. */ @@ -846,6 +925,30 @@ return NULL; } +/* Replace the set of pending constraints by "guard", which is then + * no longer considered as pending. + * That is, add "guard" to the generated constraints and clear all pending + * constraints, making the domain equal to the generated constraints. + */ +__isl_give isl_ast_build *isl_ast_build_replace_pending_by_guard( + __isl_take isl_ast_build *build, __isl_take isl_set *guard) +{ + build = isl_ast_build_restrict_generated(build, guard); + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + isl_set_free(build->domain); + build->domain = isl_set_copy(build->generated); + isl_set_free(build->pending); + build->pending = isl_set_universe(isl_set_get_space(build->domain)); + + if (!build->pending) + return isl_ast_build_free(build); + + return build; +} + /* Intersect build->pending and build->domain with "set", * where "set" is specified in terms of the internal schedule domain. */ @@ -907,6 +1010,95 @@ return NULL; } +/* Does "build" point to a band node? + * That is, are we currently handling a band node inside a schedule tree? + */ +int isl_ast_build_has_schedule_node(__isl_keep isl_ast_build *build) +{ + if (!build) + return -1; + return build->node != NULL; +} + +/* Return a copy of the band node that "build" refers to. + */ +__isl_give isl_schedule_node *isl_ast_build_get_schedule_node( + __isl_keep isl_ast_build *build) +{ + if (!build) + return NULL; + return isl_schedule_node_copy(build->node); +} + +/* Extract the loop AST generation types for the members of build->node + * and store them in build->loop_type. + */ +static __isl_give isl_ast_build *extract_loop_types( + __isl_take isl_ast_build *build) +{ + int i; + isl_ctx *ctx; + isl_schedule_node *node; + + if (!build) + return NULL; + ctx = isl_ast_build_get_ctx(build); + if (!build->node) + isl_die(ctx, isl_error_internal, "missing AST node", + return isl_ast_build_free(build)); + + free(build->loop_type); + build->n = isl_schedule_node_band_n_member(build->node); + build->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, build->n); + if (build->n && !build->loop_type) + return isl_ast_build_free(build); + node = build->node; + for (i = 0; i < build->n; ++i) + build->loop_type[i] = + isl_schedule_node_band_member_get_ast_loop_type(node, i); + + return build; +} + +/* Replace the band node that "build" refers to by "node" and + * extract the corresponding loop AST generation types. + */ +__isl_give isl_ast_build *isl_ast_build_set_schedule_node( + __isl_take isl_ast_build *build, + __isl_take isl_schedule_node *node) +{ + build = isl_ast_build_cow(build); + if (!build || !node) + goto error; + + isl_schedule_node_free(build->node); + build->node = node; + + build = extract_loop_types(build); + + return build; +error: + isl_ast_build_free(build); + isl_schedule_node_free(node); + return NULL; +} + +/* Remove any reference to a band node from "build". + */ +__isl_give isl_ast_build *isl_ast_build_reset_schedule_node( + __isl_take isl_ast_build *build) +{ + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + isl_schedule_node_free(build->node); + build->node = NULL; + + return build; +} + /* Return a copy of the current schedule domain. */ __isl_give isl_set *isl_ast_build_get_domain(__isl_keep isl_ast_build *build) @@ -914,6 +1106,42 @@ return build ? isl_set_copy(build->domain) : NULL; } +/* Return a copy of the set of pending constraints. + */ +__isl_give isl_set *isl_ast_build_get_pending( + __isl_keep isl_ast_build *build) +{ + return build ? isl_set_copy(build->pending) : NULL; +} + +/* Return a copy of the set of generated constraints. + */ +__isl_give isl_set *isl_ast_build_get_generated( + __isl_keep isl_ast_build *build) +{ + return build ? isl_set_copy(build->generated) : NULL; +} + +/* Return a copy of the map from the internal schedule domain + * to the original input schedule domain. + */ +__isl_give isl_multi_aff *isl_ast_build_get_internal2input( + __isl_keep isl_ast_build *build) +{ + return build ? isl_multi_aff_copy(build->internal2input) : NULL; +} + +/* Return the number of variables of the given type + * in the (internal) schedule space. + */ +unsigned isl_ast_build_dim(__isl_keep isl_ast_build *build, + enum isl_dim_type type) +{ + if (!build) + return 0; + return isl_set_dim(build->domain, type); +} + /* Return the (schedule) space of "build". * * If "internal" is set, then this space is the space of the internal @@ -1232,7 +1460,7 @@ * * The expression "-a h(p)/g" can therefore be used as offset. */ -static int detect_stride(__isl_take isl_constraint *c, void *user) +static isl_stat detect_stride(__isl_take isl_constraint *c, void *user) { struct isl_detect_stride_data *data = user; int i, n_div; @@ -1242,7 +1470,7 @@ if (!isl_constraint_is_equality(c) || !isl_constraint_involves_dims(c, isl_dim_set, data->pos, 1)) { isl_constraint_free(c); - return 0; + return isl_stat_ok; } ctx = isl_constraint_get_ctx(c); @@ -1250,7 +1478,7 @@ n_div = isl_constraint_dim(c, isl_dim_div); for (i = 0; i < n_div; ++i) { v = isl_constraint_get_coefficient_val(c, isl_dim_div, i); - v = isl_val_gcd(stride, v); + stride = isl_val_gcd(stride, v); } v = isl_constraint_get_coefficient_val(c, isl_dim_set, data->pos); @@ -1282,7 +1510,7 @@ } isl_constraint_free(c); - return 0; + return isl_stat_ok; } /* Check if the constraints in "set" imply any stride on the current @@ -1327,7 +1555,7 @@ /* Check if "map" involves the input dimension data->depth. */ -static int involves_depth(__isl_take isl_map *map, void *user) +static isl_stat involves_depth(__isl_take isl_map *map, void *user) { struct isl_ast_build_involves_data *data = user; @@ -1335,8 +1563,8 @@ isl_map_free(map); if (data->involves < 0 || data->involves) - return -1; - return 0; + return isl_stat_error; + return isl_stat_ok; } /* Do any options depend on the value of the dimension at the current depth? @@ -1375,7 +1603,7 @@ space = isl_space_set_from_params(space); space = isl_space_add_dims(space, isl_dim_set, 1); space = isl_space_map_from_set(space); - c = isl_equality_alloc(isl_local_space_from_space(space)); + c = isl_constraint_alloc_equality(isl_local_space_from_space(space)); c = isl_constraint_set_coefficient_si(c, isl_dim_in, 0, 1); c = isl_constraint_set_coefficient_si(c, isl_dim_out, 0, -1); bmap1 = isl_basic_map_from_constraint(isl_constraint_copy(c)); @@ -1389,9 +1617,9 @@ } static const char *option_str[] = { - [atomic] = "atomic", - [unroll] = "unroll", - [separate] = "separate" + [isl_ast_loop_atomic] = "atomic", + [isl_ast_loop_unroll] = "unroll", + [isl_ast_loop_separate] = "separate" }; /* Update the "options" to reflect the insertion of a dimension @@ -1420,7 +1648,7 @@ { isl_map *map; isl_union_map *insertion; - enum isl_ast_build_domain_type type; + enum isl_ast_loop_type type; const char *name = "separation_class"; space = isl_space_map_from_set(space); @@ -1436,7 +1664,8 @@ insertion = isl_union_map_empty(isl_union_map_get_space(options)); - for (type = atomic; type <= separate; ++type) { + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { isl_map *map_type = isl_map_copy(map); const char *name = option_str[type]; map_type = isl_map_set_tuple_name(map_type, isl_dim_in, name); @@ -1454,6 +1683,42 @@ return options; } +/* If we are generating an AST from a schedule tree (build->node is set), + * then update the loop AST generation types + * to reflect the insertion of a dimension at (global) position "pos" + * in the schedule domain space. + * We do not need to adjust any isolate option since we would not be inserting + * any dimensions if there were any isolate option. + */ +static __isl_give isl_ast_build *node_insert_dim( + __isl_take isl_ast_build *build, int pos) +{ + int i; + int local_pos; + enum isl_ast_loop_type *loop_type; + isl_ctx *ctx; + + build = isl_ast_build_cow(build); + if (!build) + return NULL; + if (!build->node) + return build; + + ctx = isl_ast_build_get_ctx(build); + local_pos = pos - build->outer_pos; + loop_type = isl_realloc_array(ctx, build->loop_type, + enum isl_ast_loop_type, build->n + 1); + if (!loop_type) + return isl_ast_build_free(build); + build->loop_type = loop_type; + for (i = build->n - 1; i >= local_pos; --i) + loop_type[i + 1] = loop_type[i]; + loop_type[local_pos] = isl_ast_loop_default; + build->n++; + + return build; +} + /* Insert a single dimension in the schedule domain at position "pos". * The new dimension is given an isl_id with the empty string as name. * @@ -1465,6 +1730,12 @@ * However, the original schedule domain space may be named and/or * structured, so we have to take this possibility into account * while performing the transformations. + * + * Since the inserted schedule dimension is used by the caller + * to differentiate between different domain spaces, there is + * no longer a uniform mapping from the internal schedule space + * to the input schedule space. The internal2input mapping is + * therefore removed. */ __isl_give isl_ast_build *isl_ast_build_insert_dim( __isl_take isl_ast_build *build, int pos) @@ -1480,7 +1751,8 @@ ctx = isl_ast_build_get_ctx(build); id = isl_id_alloc(ctx, "", NULL); - space = isl_ast_build_get_space(build, 1); + if (!build->node) + space = isl_ast_build_get_space(build, 1); build->iterators = isl_id_list_insert(build->iterators, pos, id); build->domain = isl_set_insert_dims(build->domain, isl_dim_set, pos, 1); @@ -1498,13 +1770,17 @@ build->offsets = isl_multi_aff_splice(build->offsets, pos, pos, ma); ma = isl_multi_aff_identity(ma_space); build->values = isl_multi_aff_splice(build->values, pos, pos, ma); - build->options = options_insert_dim(build->options, space, pos); + if (!build->node) + build->options = options_insert_dim(build->options, space, pos); + build->internal2input = isl_multi_aff_free(build->internal2input); if (!build->iterators || !build->domain || !build->generated || !build->pending || !build->values || !build->strides || !build->offsets || !build->options) return isl_ast_build_free(build); + build = node_insert_dim(build, pos); + return build; } @@ -1517,7 +1793,11 @@ * This function is called right after the strides have been * detected, but before any constraints on the current dimension * have been included in build->domain. - * We therefore only need to update stride, offset and the options. + * We therefore only need to update stride, offset, the options and + * the mapping from internal schedule space to the original schedule + * space, if we are still keeping track of such a mapping. + * The latter mapping is updated by plugging in + * { [... i ...] -> [... m i ... ] }. */ __isl_give isl_ast_build *isl_ast_build_scale_down( __isl_take isl_ast_build *build, __isl_take isl_val *m, @@ -1533,6 +1813,23 @@ depth = build->depth; + if (build->internal2input) { + isl_space *space; + isl_multi_aff *ma; + isl_aff *aff; + + space = isl_multi_aff_get_space(build->internal2input); + space = isl_space_map_from_set(isl_space_domain(space)); + ma = isl_multi_aff_identity(space); + aff = isl_multi_aff_get_aff(ma, depth); + aff = isl_aff_scale_val(aff, isl_val_copy(m)); + ma = isl_multi_aff_set_aff(ma, depth, aff); + build->internal2input = + isl_multi_aff_pullback_multi_aff(build->internal2input, ma); + if (!build->internal2input) + goto error; + } + v = isl_vec_get_element_val(build->strides, depth); v = isl_val_div(v, isl_val_copy(m)); build->strides = isl_vec_set_element_val(build->strides, depth, v); @@ -1575,7 +1872,7 @@ /* Embed "options" into the given isl_ast_build space. * * This function is called from within a nested call to - * isl_ast_build_ast_from_schedule. + * isl_ast_build_node_from_schedule_map. * "options" refers to the additional schedule, * while space refers to both the space of the outer isl_ast_build and * that of the additional schedule. @@ -1677,7 +1974,18 @@ build->values = isl_multi_aff_align_params(build->values, isl_space_copy(space)); embedding = isl_multi_aff_identity(space); - build->values = isl_multi_aff_product(build->values, embedding); + build->values = isl_multi_aff_product(build->values, + isl_multi_aff_copy(embedding)); + if (build->internal2input) { + build->internal2input = + isl_multi_aff_product(build->internal2input, embedding); + build->internal2input = + isl_multi_aff_flatten_range(build->internal2input); + if (!build->internal2input) + return isl_ast_build_free(build); + } else { + isl_multi_aff_free(embedding); + } space = isl_ast_build_get_space(build, 1); build->options = embed_options(build->options, space); @@ -1768,7 +2076,7 @@ * value that, moreover, can be described by a single affine expression * in terms of the outer dimensions and parameters? * - * If not, then the correponding affine expression in build->values + * If not, then the corresponding affine expression in build->values * is set to be equal to the same input dimension. * Otherwise, it is set to the requested expression in terms of * outer dimensions and parameters. @@ -1855,7 +2163,8 @@ if (!build) goto error; - set = isl_set_preimage_multi_aff(set, + if (!isl_set_is_params(set)) + set = isl_set_preimage_multi_aff(set, isl_multi_aff_copy(build->values)); set = isl_set_gist(set, isl_set_copy(build->domain)); @@ -1865,6 +2174,24 @@ return NULL; } +/* Include information about what we know about the iterators of + * already generated loops to "set". + * + * We currently only plug in the known affine values of outer loop + * iterators. + * In principle we could also introduce equalities or even other + * constraints implied by the intersection of "set" and build->domain. + */ +__isl_give isl_set *isl_ast_build_specialize(__isl_keep isl_ast_build *build, + __isl_take isl_set *set) +{ + if (!build) + return isl_set_free(set); + + return isl_set_preimage_multi_aff(set, + isl_multi_aff_copy(build->values)); +} + /* Simplify the map "map" based on what we know about * the iterators of already generated loops. * @@ -1962,8 +2289,7 @@ * but the position is still that within the current code generation. */ __isl_give isl_set *isl_ast_build_get_option_domain( - __isl_keep isl_ast_build *build, - enum isl_ast_build_domain_type type) + __isl_keep isl_ast_build *build, enum isl_ast_loop_type type) { const char *name; isl_space *space; @@ -1991,6 +2317,145 @@ return domain; } +/* How does the user want the current schedule dimension to be generated? + * These choices have been extracted from the schedule node + * in extract_loop_types and stored in build->loop_type. + * They have been updated to reflect any dimension insertion in + * node_insert_dim. + * Return isl_ast_domain_error on error. + * + * If "isolated" is set, then we get the loop AST generation type + * directly from the band node since node_insert_dim cannot have been + * called on a band with the isolate option. + */ +enum isl_ast_loop_type isl_ast_build_get_loop_type( + __isl_keep isl_ast_build *build, int isolated) +{ + int local_pos; + isl_ctx *ctx; + + if (!build) + return isl_ast_loop_error; + ctx = isl_ast_build_get_ctx(build); + if (!build->node) + isl_die(ctx, isl_error_internal, + "only works for schedule tree based AST generation", + return isl_ast_loop_error); + + local_pos = build->depth - build->outer_pos; + if (!isolated) + return build->loop_type[local_pos]; + return isl_schedule_node_band_member_get_isolate_ast_loop_type( + build->node, local_pos); +} + +/* Extract the isolated set from the isolate option, if any, + * and store in the build. + * If there is no isolate option, then the isolated set is + * set to the empty set. + * + * The isolate option is of the form + * + * isolate[[outer bands] -> current_band] + * + * We flatten this set and then map it back to the internal + * schedule space. + * + * If we have already extracted the isolated set + * or if internal2input is no longer set, then we do not + * need to do anything. In the latter case, we know + * that the current band cannot have any isolate option. + */ +__isl_give isl_ast_build *isl_ast_build_extract_isolated( + __isl_take isl_ast_build *build) +{ + isl_space *space, *space2; + isl_union_set *options; + int n, n2; + isl_set *isolated; + + if (!build) + return NULL; + if (!build->internal2input) + return build; + if (build->isolated) + return build; + + build = isl_ast_build_cow(build); + if (!build) + return NULL; + + options = isl_schedule_node_band_get_ast_build_options(build->node); + + space = isl_multi_aff_get_space(build->internal2input); + space = isl_space_range(space); + space2 = isl_set_get_space(build->domain); + if (isl_space_is_wrapping(space2)) + space2 = isl_space_range(isl_space_unwrap(space2)); + n2 = isl_space_dim(space2, isl_dim_set); + n = isl_space_dim(space, isl_dim_set); + if (n < n2) + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "total input space dimension cannot be smaller " + "than dimension of innermost band", + space = isl_space_free(space)); + space = isl_space_drop_dims(space, isl_dim_set, n - n2, n2); + space = isl_space_map_from_domain_and_range(space, space2); + space = isl_space_wrap(space); + space = isl_space_set_tuple_name(space, isl_dim_set, "isolate"); + isolated = isl_union_set_extract_set(options, space); + isl_union_set_free(options); + + isolated = isl_set_flatten(isolated); + isolated = isl_set_preimage_multi_aff(isolated, + isl_multi_aff_copy(build->internal2input)); + + build->isolated = isolated; + if (!build->isolated) + return isl_ast_build_free(build); + + return build; +} + +/* Does "build" have a non-empty isolated set? + * + * The caller is assumed to have called isl_ast_build_extract_isolated first. + */ +int isl_ast_build_has_isolated(__isl_keep isl_ast_build *build) +{ + int empty; + + if (!build) + return -1; + if (!build->internal2input) + return 0; + if (!build->isolated) + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "isolated set not extracted yet", return -1); + + empty = isl_set_plain_is_empty(build->isolated); + return empty < 0 ? -1 : !empty; +} + +/* Return a copy of the isolated set of "build". + * + * The caller is assume to have called isl_ast_build_has_isolated first, + * with this function returning true. + * In particular, this function should not be called if we are no + * longer keeping track of internal2input (and there therefore could + * not possibly be any isolated set). + */ +__isl_give isl_set *isl_ast_build_get_isolated(__isl_keep isl_ast_build *build) +{ + if (!build) + return NULL; + if (!build->internal2input) + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "build cannot have isolated set", return NULL); + + return isl_set_copy(build->isolated); +} + /* Extract the separation class mapping at the current depth. * * In particular, find and return the subset of build->options that is of diff -Nru isl-0.12.2/isl_ast_build_expr.c isl-0.15/isl_ast_build_expr.c --- isl-0.12.2/isl_ast_build_expr.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ast_build_expr.c 2015-06-02 09:28:09.000000000 +0000 @@ -1,12 +1,16 @@ /* - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ +#include #include #include #include @@ -29,11 +33,120 @@ return aff; } +/* Internal data structure used inside isl_ast_expr_add_term. + * The domain of "build" is used to simplify the expressions. + * "build" needs to be set by the caller of isl_ast_expr_add_term. + * "cst" is the constant term of the expression in which the added term + * appears. It may be modified by isl_ast_expr_add_term. + * + * "v" is the coefficient of the term that is being constructed and + * is set internally by isl_ast_expr_add_term. + */ +struct isl_ast_add_term_data { + isl_ast_build *build; + isl_val *cst; + isl_val *v; +}; + +/* Given the numerator "aff" of the argument of an integer division + * with denominator "d", check if it can be made non-negative over + * data->build->domain by stealing part of the constant term of + * the expression in which the integer division appears. + * + * In particular, the outer expression is of the form + * + * v * floor(aff/d) + cst + * + * We already know that "aff" itself may attain negative values. + * Here we check if aff + d*floor(cst/v) is non-negative, such + * that we could rewrite the expression to + * + * v * floor((aff + d*floor(cst/v))/d) + cst - v*floor(cst/v) + * + * Note that aff + d*floor(cst/v) can only possibly be non-negative + * if data->cst and data->v have the same sign. + * Similarly, if floor(cst/v) is zero, then there is no point in + * checking again. + */ +static int is_non_neg_after_stealing(__isl_keep isl_aff *aff, + __isl_keep isl_val *d, struct isl_ast_add_term_data *data) +{ + isl_aff *shifted; + isl_val *shift; + int is_zero; + int non_neg; + + if (isl_val_sgn(data->cst) != isl_val_sgn(data->v)) + return 0; + + shift = isl_val_div(isl_val_copy(data->cst), isl_val_copy(data->v)); + shift = isl_val_floor(shift); + is_zero = isl_val_is_zero(shift); + if (is_zero < 0 || is_zero) { + isl_val_free(shift); + return is_zero < 0 ? -1 : 0; + } + shift = isl_val_mul(shift, isl_val_copy(d)); + shifted = isl_aff_copy(aff); + shifted = isl_aff_add_constant_val(shifted, shift); + non_neg = isl_ast_build_aff_is_nonneg(data->build, shifted); + isl_aff_free(shifted); + + return non_neg; +} + +/* Given the numerator "aff' of the argument of an integer division + * with denominator "d", steal part of the constant term of + * the expression in which the integer division appears to make it + * non-negative over data->build->domain. + * + * In particular, the outer expression is of the form + * + * v * floor(aff/d) + cst + * + * We know that "aff" itself may attain negative values, + * but that aff + d*floor(cst/v) is non-negative. + * Find the minimal positive value that we need to add to "aff" + * to make it positive and adjust data->cst accordingly. + * That is, compute the minimal value "m" of "aff" over + * data->build->domain and take + * + * s = ceil(m/d) + * + * such that + * + * aff + d * s >= 0 + * + * and rewrite the expression to + * + * v * floor((aff + s*d)/d) + (cst - v*s) + */ +static __isl_give isl_aff *steal_from_cst(__isl_take isl_aff *aff, + __isl_keep isl_val *d, struct isl_ast_add_term_data *data) +{ + isl_set *domain; + isl_val *shift, *t; + + domain = isl_ast_build_get_domain(data->build); + shift = isl_set_min_val(domain, aff); + isl_set_free(domain); + + shift = isl_val_neg(shift); + shift = isl_val_div(shift, isl_val_copy(d)); + shift = isl_val_ceil(shift); + + t = isl_val_copy(shift); + t = isl_val_mul(t, isl_val_copy(data->v)); + data->cst = isl_val_sub(data->cst, t); + + shift = isl_val_mul(shift, isl_val_copy(d)); + return isl_aff_add_constant_val(aff, shift); +} + /* Create an isl_ast_expr evaluating the div at position "pos" in "ls". - * The result is simplified in terms of build->domain. + * The result is simplified in terms of data->build->domain. + * This function may change (the sign of) data->v. * - * *change_sign is set by this function if the sign of - * the expression has changed. * "ls" is known to be non-NULL. * * Let the div be of the form floor(e/d). @@ -52,11 +165,20 @@ * * floor(e/d) = -ceil(-e/d) = -floor((-e + d - 1)/d) * - * and still use pdiv_q. + * and still use pdiv_q, while changing the sign of data->v. + * + * Otherwise, we check if + * + * e + d*floor(cst/v) + * + * is non-negative and if so, replace floor(e/d) by + * + * floor((e + s*d)/d) - s + * + * with s the minimal shift that makes the argument non-negative. */ -static __isl_give isl_ast_expr *var_div(int *change_sign, - __isl_keep isl_local_space *ls, - int pos, __isl_keep isl_ast_build *build) +static __isl_give isl_ast_expr *var_div(struct isl_ast_add_term_data *data, + __isl_keep isl_local_space *ls, int pos) { isl_ctx *ctx = isl_local_space_get_ctx(ls); isl_aff *aff; @@ -71,18 +193,23 @@ type = isl_ast_op_fdiv_q; if (isl_options_get_ast_build_prefer_pdiv(ctx)) { - int non_neg = isl_ast_build_aff_is_nonneg(build, aff); + int non_neg = isl_ast_build_aff_is_nonneg(data->build, aff); if (non_neg >= 0 && !non_neg) { isl_aff *opp = oppose_div_arg(isl_aff_copy(aff), isl_val_copy(d)); - non_neg = isl_ast_build_aff_is_nonneg(build, opp); + non_neg = isl_ast_build_aff_is_nonneg(data->build, opp); if (non_neg >= 0 && non_neg) { - *change_sign = 1; + data->v = isl_val_neg(data->v); isl_aff_free(aff); aff = opp; } else isl_aff_free(opp); } + if (non_neg >= 0 && !non_neg) { + non_neg = is_non_neg_after_stealing(aff, d, data); + if (non_neg >= 0 && non_neg) + aff = steal_from_cst(aff, d, data); + } if (non_neg < 0) aff = isl_aff_free(aff); else if (non_neg) @@ -90,33 +217,30 @@ } isl_val_free(d); - num = isl_ast_expr_from_aff(aff, build); + num = isl_ast_expr_from_aff(aff, data->build); return isl_ast_expr_alloc_binary(type, num, den); } /* Create an isl_ast_expr evaluating the specified dimension of "ls". - * The result is simplified in terms of build->domain. - * - * *change_sign is set by this function if the sign of - * the expression has changed. + * The result is simplified in terms of data->build->domain. + * This function may change (the sign of) data->v. * * The isl_ast_expr is constructed based on the type of the dimension. * - divs are constructed by var_div - * - set variables are constructed from the iterator isl_ids in "build" + * - set variables are constructed from the iterator isl_ids in data->build * - parameters are constructed from the isl_ids in "ls" */ -static __isl_give isl_ast_expr *var(int *change_sign, - __isl_keep isl_local_space *ls, - enum isl_dim_type type, int pos, __isl_keep isl_ast_build *build) +static __isl_give isl_ast_expr *var(struct isl_ast_add_term_data *data, + __isl_keep isl_local_space *ls, enum isl_dim_type type, int pos) { isl_ctx *ctx = isl_local_space_get_ctx(ls); isl_id *id; if (type == isl_dim_div) - return var_div(change_sign, ls, pos, build); + return var_div(data, ls, pos); if (type == isl_dim_set) { - id = isl_ast_build_get_iterator_id(build, pos); + id = isl_ast_build_get_iterator_id(data->build, pos); return isl_ast_expr_from_id(id); } @@ -209,14 +333,12 @@ __isl_keep isl_aff *aff, __isl_keep isl_val *d, __isl_keep isl_ast_build *build) { - isl_ctx *ctx; isl_ast_expr *expr; isl_ast_expr *c; if (!aff) return NULL; - ctx = isl_aff_get_ctx(aff); expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build); c = isl_ast_expr_from_val(isl_val_copy(d)); @@ -270,6 +392,9 @@ /* Add an expression for "*v" times the specified dimension of "ls" * to expr. + * If the dimension is an integer division, then this function + * may modify data->cst in order to make the numerator non-negative. + * The result is simplified in terms of data->build->domain. * * Let e be the expression for the specified dimension, * multiplied by the absolute value of "*v". @@ -291,18 +416,16 @@ static __isl_give isl_ast_expr *isl_ast_expr_add_term( __isl_take isl_ast_expr *expr, __isl_keep isl_local_space *ls, enum isl_dim_type type, int pos, - __isl_take isl_val *v, __isl_keep isl_ast_build *build) + __isl_take isl_val *v, struct isl_ast_add_term_data *data) { isl_ast_expr *term; - int change_sign; if (!expr) return NULL; - change_sign = 0; - term = var(&change_sign, ls, type, pos, build); - if (change_sign) - v = isl_val_neg(v); + data->v = v; + term = var(data, ls, type, pos); + v = data->v; if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) { v = isl_val_neg(v); @@ -319,7 +442,6 @@ static __isl_give isl_ast_expr *isl_ast_expr_add_int( __isl_take isl_ast_expr *expr, __isl_take isl_val *v) { - isl_ctx *ctx; isl_ast_expr *expr_int; if (!expr || !v) @@ -330,7 +452,6 @@ return expr; } - ctx = isl_ast_expr_get_ctx(expr); if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) { v = isl_val_neg(v); expr_int = isl_ast_expr_from_val(v); @@ -345,19 +466,415 @@ return NULL; } -/* Check if "aff" involves any (implicit) modulo computations based - * on div "j". +/* Internal data structure used inside extract_modulos. + * + * If any modulo expressions are detected in "aff", then the + * expression is removed from "aff" and added to either "pos" or "neg" + * depending on the sign of the coefficient of the modulo expression + * inside "aff". + * + * "add" is an expression that needs to be added to "aff" at the end of + * the computation. It is NULL as long as no modulos have been extracted. + * + * "i" is the position in "aff" of the div under investigation + * "v" is the coefficient in "aff" of the div + * "div" is the argument of the div, with the denominator removed + * "d" is the original denominator of the argument of the div + * + * "nonneg" is an affine expression that is non-negative over "build" + * and that can be used to extract a modulo expression from "div". + * In particular, if "sign" is 1, then the coefficients of "nonneg" + * are equal to those of "div" modulo "d". If "sign" is -1, then + * the coefficients of "nonneg" are opposite to those of "div" modulo "d". + * If "sign" is 0, then no such affine expression has been found (yet). + */ +struct isl_extract_mod_data { + isl_ast_build *build; + isl_aff *aff; + + isl_ast_expr *pos; + isl_ast_expr *neg; + + isl_aff *add; + + int i; + isl_val *v; + isl_val *d; + isl_aff *div; + + isl_aff *nonneg; + int sign; +}; + +/* Given that data->v * div_i in data->aff is equal to + * + * f * (term - (arg mod d)) + * + * with data->d * f = data->v, add + * + * f * term + * + * to data->add and + * + * abs(f) * (arg mod d) + * + * to data->neg or data->pos depending on the sign of -f. + */ +static int extract_term_and_mod(struct isl_extract_mod_data *data, + __isl_take isl_aff *term, __isl_take isl_aff *arg) +{ + isl_ast_expr *expr; + int s; + + data->v = isl_val_div(data->v, isl_val_copy(data->d)); + s = isl_val_sgn(data->v); + data->v = isl_val_abs(data->v); + expr = isl_ast_expr_mod(data->v, arg, data->d, data->build); + isl_aff_free(arg); + if (s > 0) + data->neg = ast_expr_add(data->neg, expr); + else + data->pos = ast_expr_add(data->pos, expr); + data->aff = isl_aff_set_coefficient_si(data->aff, + isl_dim_div, data->i, 0); + if (s < 0) + data->v = isl_val_neg(data->v); + term = isl_aff_scale_val(data->div, isl_val_copy(data->v)); + + if (!data->add) + data->add = term; + else + data->add = isl_aff_add(data->add, term); + if (!data->add) + return -1; + + return 0; +} + +/* Given that data->v * div_i in data->aff is of the form + * + * f * d * floor(div/d) + * + * with div nonnegative on data->build, rewrite it as + * + * f * (div - (div mod d)) = f * div - f * (div mod d) + * + * and add + * + * f * div + * + * to data->add and + * + * abs(f) * (div mod d) + * + * to data->neg or data->pos depending on the sign of -f. + */ +static int extract_mod(struct isl_extract_mod_data *data) +{ + return extract_term_and_mod(data, isl_aff_copy(data->div), + isl_aff_copy(data->div)); +} + +/* Given that data->v * div_i in data->aff is of the form + * + * f * d * floor(div/d) (1) + * + * check if div is non-negative on data->build and, if so, + * extract the corresponding modulo from data->aff. + * If not, then check if + * + * -div + d - 1 + * + * is non-negative on data->build. If so, replace (1) by + * + * -f * d * floor((-div + d - 1)/d) + * + * and extract the corresponding modulo from data->aff. + * + * This function may modify data->div. + */ +static int extract_nonneg_mod(struct isl_extract_mod_data *data) +{ + int mod; + + mod = isl_ast_build_aff_is_nonneg(data->build, data->div); + if (mod < 0) + goto error; + if (mod) + return extract_mod(data); + + data->div = oppose_div_arg(data->div, isl_val_copy(data->d)); + mod = isl_ast_build_aff_is_nonneg(data->build, data->div); + if (mod < 0) + goto error; + if (mod) { + data->v = isl_val_neg(data->v); + return extract_mod(data); + } + + return 0; +error: + data->aff = isl_aff_free(data->aff); + return -1; +} + +/* Is the affine expression of constraint "c" "simpler" than data->nonneg + * for use in extracting a modulo expression? + * + * We currently only consider the constant term of the affine expression. + * In particular, we prefer the affine expression with the smallest constant + * term. + * This means that if there are two constraints, say x >= 0 and -x + 10 >= 0, + * then we would pick x >= 0 + * + * More detailed heuristics could be used if it turns out that there is a need. + */ +static int mod_constraint_is_simpler(struct isl_extract_mod_data *data, + __isl_keep isl_constraint *c) +{ + isl_val *v1, *v2; + int simpler; + + if (!data->nonneg) + return 1; + + v1 = isl_val_abs(isl_constraint_get_constant_val(c)); + v2 = isl_val_abs(isl_aff_get_constant_val(data->nonneg)); + simpler = isl_val_lt(v1, v2); + isl_val_free(v1); + isl_val_free(v2); + + return simpler; +} + +/* Check if the coefficients of "c" are either equal or opposite to those + * of data->div modulo data->d. If so, and if "c" is "simpler" than + * data->nonneg, then replace data->nonneg by the affine expression of "c" + * and set data->sign accordingly. + * + * Both "c" and data->div are assumed not to involve any integer divisions. + * + * Before we start the actual comparison, we first quickly check if + * "c" and data->div have the same non-zero coefficients. + * If not, then we assume that "c" is not of the desired form. + * Note that while the coefficients of data->div can be reasonably expected + * not to involve any coefficients that are multiples of d, "c" may + * very well involve such coefficients. This means that we may actually + * miss some cases. + */ +static isl_stat check_parallel_or_opposite(__isl_take isl_constraint *c, + void *user) +{ + struct isl_extract_mod_data *data = user; + enum isl_dim_type c_type[2] = { isl_dim_param, isl_dim_set }; + enum isl_dim_type a_type[2] = { isl_dim_param, isl_dim_in }; + int i, t; + int n[2]; + int parallel = 1, opposite = 1; + + for (t = 0; t < 2; ++t) { + n[t] = isl_constraint_dim(c, c_type[t]); + for (i = 0; i < n[t]; ++i) { + int a, b; + + a = isl_constraint_involves_dims(c, c_type[t], i, 1); + b = isl_aff_involves_dims(data->div, a_type[t], i, 1); + if (a != b) + parallel = opposite = 0; + } + } + + for (t = 0; t < 2; ++t) { + for (i = 0; i < n[t]; ++i) { + isl_val *v1, *v2; + + if (!parallel && !opposite) + break; + v1 = isl_constraint_get_coefficient_val(c, + c_type[t], i); + v2 = isl_aff_get_coefficient_val(data->div, + a_type[t], i); + if (parallel) { + v1 = isl_val_sub(v1, isl_val_copy(v2)); + parallel = isl_val_is_divisible_by(v1, data->d); + v1 = isl_val_add(v1, isl_val_copy(v2)); + } + if (opposite) { + v1 = isl_val_add(v1, isl_val_copy(v2)); + opposite = isl_val_is_divisible_by(v1, data->d); + } + isl_val_free(v1); + isl_val_free(v2); + } + } + + if ((parallel || opposite) && mod_constraint_is_simpler(data, c)) { + isl_aff_free(data->nonneg); + data->nonneg = isl_constraint_get_aff(c); + data->sign = parallel ? 1 : -1; + } + + isl_constraint_free(c); + + if (data->sign != 0 && data->nonneg == NULL) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Given that data->v * div_i in data->aff is of the form + * + * f * d * floor(div/d) (1) + * + * see if we can find an expression div' that is non-negative over data->build + * and that is related to div through + * + * div' = div + d * e + * + * or + * + * div' = -div + d - 1 + d * e + * + * with e some affine expression. + * If so, we write (1) as + * + * f * div + f * (div' mod d) + * + * or + * + * -f * (-div + d - 1) - f * (div' mod d) + * + * exploiting (in the second case) the fact that + * + * f * d * floor(div/d) = -f * d * floor((-div + d - 1)/d) + * + * + * We first try to find an appropriate expression for div' + * from the constraints of data->build->domain (which is therefore + * guaranteed to be non-negative on data->build), where we remove + * any integer divisions from the constraints and skip this step + * if "div" itself involves any integer divisions. + * If we cannot find an appropriate expression this way, then + * we pass control to extract_nonneg_mod where check + * if div or "-div + d -1" themselves happen to be + * non-negative on data->build. + * + * While looking for an appropriate constraint in data->build->domain, + * we ignore the constant term, so after finding such a constraint, + * we still need to fix up the constant term. + * In particular, if a is the constant term of "div" + * (or d - 1 - the constant term of "div" if data->sign < 0) + * and b is the constant term of the constraint, then we need to find + * a non-negative constant c such that + * + * b + c \equiv a mod d + * + * We therefore take + * + * c = (a - b) mod d + * + * and add it to b to obtain the constant term of div'. + * If this constant term is "too negative", then we add an appropriate + * multiple of d to make it positive. + * + * + * Note that the above is a only a very simple heuristic for finding an + * appropriate expression. We could try a bit harder by also considering + * sums of constraints that involve disjoint sets of variables or + * we could consider arbitrary linear combinations of constraints, + * although that could potentially be much more expensive as it involves + * the solution of an LP problem. + * + * In particular, if v_i is a column vector representing constraint i, + * w represents div and e_i is the i-th unit vector, then we are looking + * for a solution of the constraints + * + * \sum_i lambda_i v_i = w + \sum_i alpha_i d e_i + * + * with \lambda_i >= 0 and alpha_i of unrestricted sign. + * If we are not just interested in a non-negative expression, but + * also in one with a minimal range, then we don't just want + * c = \sum_i lambda_i v_i to be non-negative over the domain, + * but also beta - c = \sum_i mu_i v_i, where beta is a scalar + * that we want to minimize and we now also have to take into account + * the constant terms of the constraints. + * Alternatively, we could first compute the dual of the domain + * and plug in the constraints on the coefficients. + */ +static int try_extract_mod(struct isl_extract_mod_data *data) +{ + isl_basic_set *hull; + isl_val *v1, *v2; + int r, n; + + if (!data->build) + goto error; + + n = isl_aff_dim(data->div, isl_dim_div); + + if (isl_aff_involves_dims(data->div, isl_dim_div, 0, n)) + return extract_nonneg_mod(data); + + hull = isl_set_simple_hull(isl_set_copy(data->build->domain)); + hull = isl_basic_set_remove_divs(hull); + data->sign = 0; + data->nonneg = NULL; + r = isl_basic_set_foreach_constraint(hull, &check_parallel_or_opposite, + data); + isl_basic_set_free(hull); + + if (!data->sign || r < 0) { + isl_aff_free(data->nonneg); + if (r < 0) + goto error; + return extract_nonneg_mod(data); + } + + v1 = isl_aff_get_constant_val(data->div); + v2 = isl_aff_get_constant_val(data->nonneg); + if (data->sign < 0) { + v1 = isl_val_neg(v1); + v1 = isl_val_add(v1, isl_val_copy(data->d)); + v1 = isl_val_sub_ui(v1, 1); + } + v1 = isl_val_sub(v1, isl_val_copy(v2)); + v1 = isl_val_mod(v1, isl_val_copy(data->d)); + v1 = isl_val_add(v1, v2); + v2 = isl_val_div(isl_val_copy(v1), isl_val_copy(data->d)); + v2 = isl_val_ceil(v2); + if (isl_val_is_neg(v2)) { + v2 = isl_val_mul(v2, isl_val_copy(data->d)); + v1 = isl_val_sub(v1, isl_val_copy(v2)); + } + data->nonneg = isl_aff_set_constant_val(data->nonneg, v1); + isl_val_free(v2); + + if (data->sign < 0) { + data->div = oppose_div_arg(data->div, isl_val_copy(data->d)); + data->v = isl_val_neg(data->v); + } + + return extract_term_and_mod(data, + isl_aff_copy(data->div), data->nonneg); +error: + data->aff = isl_aff_free(data->aff); + return -1; +} + +/* Check if "data->aff" involves any (implicit) modulo computations based + * on div "data->i". * If so, remove them from aff and add expressions corresponding - * to those modulo computations to *pos and/or *neg. - * "v" is the coefficient of div "j". + * to those modulo computations to data->pos and/or data->neg. + * + * "aff" is assumed to be an integer affine expression. * - * In particular, check if (v * div_j) / d is of the form + * In particular, check if (v * div_j) is of the form * - * (f * m * floor(a / m)) / d + * f * m * floor(a / m) * * and, if so, rewrite it as * - * (f * (a - (a mod m))) / d = (f * a) / d - (f * (a mod m)) / d + * f * (a - (a mod m)) = f * a - f * (a mod m) * * and extract out -f * (a mod m). * In particular, if f > 0, we add (f * (a mod m)) to *neg. @@ -374,66 +891,19 @@ * floor(a/m) = -ceil(-a/m) = -floor((-a + m - 1)/m) * * and still extract a modulo. - * - * The caller is responsible for dividing *neg and/or *pos by d. */ -static __isl_give isl_aff *extract_modulo(__isl_take isl_aff *aff, - __isl_keep isl_ast_expr **pos, __isl_keep isl_ast_expr **neg, - __isl_keep isl_ast_build *build, int j, __isl_take isl_val *v) +static int extract_modulo(struct isl_extract_mod_data *data) { - isl_ast_expr *expr; - isl_aff *div; - int s; - int mod; - isl_val *d; - - div = isl_aff_get_div(aff, j); - d = isl_aff_get_denominator_val(div); - mod = isl_val_is_divisible_by(v, d); - if (mod) { - div = isl_aff_scale_val(div, isl_val_copy(d)); - mod = isl_ast_build_aff_is_nonneg(build, div); - if (mod >= 0 && !mod) { - isl_aff *opp = oppose_div_arg(isl_aff_copy(div), - isl_val_copy(d)); - mod = isl_ast_build_aff_is_nonneg(build, opp); - if (mod >= 0 && mod) { - isl_aff_free(div); - div = opp; - v = isl_val_neg(v); - } else - isl_aff_free(opp); - } - } - if (mod < 0) { - isl_aff_free(div); - isl_val_free(d); - isl_val_free(v); - return isl_aff_free(aff); - } else if (!mod) { - isl_aff_free(div); - isl_val_free(d); - isl_val_free(v); - return aff; + data->div = isl_aff_get_div(data->aff, data->i); + data->d = isl_aff_get_denominator_val(data->div); + if (isl_val_is_divisible_by(data->v, data->d)) { + data->div = isl_aff_scale_val(data->div, isl_val_copy(data->d)); + if (try_extract_mod(data) < 0) + data->aff = isl_aff_free(data->aff); } - v = isl_val_div(v, isl_val_copy(d)); - s = isl_val_sgn(v); - v = isl_val_abs(v); - expr = isl_ast_expr_mod(v, div, d, build); - isl_val_free(d); - if (s > 0) - *neg = ast_expr_add(*neg, expr); - else - *pos = ast_expr_add(*pos, expr); - aff = isl_aff_set_coefficient_si(aff, isl_dim_div, j, 0); - if (s < 0) - v = isl_val_neg(v); - div = isl_aff_scale_val(div, v); - d = isl_aff_get_denominator_val(aff); - div = isl_aff_scale_down_val(div, d); - aff = isl_aff_add(aff, div); - - return aff; + isl_aff_free(data->div); + isl_val_free(data->d); + return 0; } /* Check if "aff" involves any (implicit) modulo computations. @@ -463,8 +933,9 @@ __isl_keep isl_ast_expr **pos, __isl_keep isl_ast_expr **neg, __isl_keep isl_ast_build *build) { + struct isl_extract_mod_data data = { build, aff, *pos, *neg }; isl_ctx *ctx; - int j, n; + int n; if (!aff) return NULL; @@ -473,94 +944,177 @@ if (!isl_options_get_ast_build_prefer_pdiv(ctx)) return aff; - n = isl_aff_dim(aff, isl_dim_div); - for (j = 0; j < n; ++j) { - isl_val *v; - - v = isl_aff_get_coefficient_val(aff, isl_dim_div, j); - if (!v) + n = isl_aff_dim(data.aff, isl_dim_div); + for (data.i = 0; data.i < n; ++data.i) { + data.v = isl_aff_get_coefficient_val(data.aff, + isl_dim_div, data.i); + if (!data.v) return isl_aff_free(aff); - if (isl_val_is_zero(v) || - isl_val_is_one(v) || isl_val_is_negone(v)) { - isl_val_free(v); + if (isl_val_is_zero(data.v) || + isl_val_is_one(data.v) || isl_val_is_negone(data.v)) { + isl_val_free(data.v); continue; } - aff = extract_modulo(aff, pos, neg, build, j, v); - if (!aff) + if (extract_modulo(&data) < 0) + data.aff = isl_aff_free(data.aff); + isl_val_free(data.v); + if (!data.aff) break; } - return aff; + if (data.add) + data.aff = isl_aff_add(data.aff, data.add); + + *pos = data.pos; + *neg = data.neg; + return data.aff; } -/* Construct an isl_ast_expr that evaluates the affine expression "aff", - * The result is simplified in terms of build->domain. +/* Check if aff involves any non-integer coefficients. + * If so, split aff into * - * We first extract hidden modulo computations from the affine expression - * and then add terms for each variable with a non-zero coefficient. - * Finally, if the affine expression has a non-trivial denominator, - * we divide the resulting isl_ast_expr by this denominator. + * aff = aff1 + (aff2 / d) + * + * with both aff1 and aff2 having only integer coefficients. + * Return aff1 and add (aff2 / d) to *expr. */ -__isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff, - __isl_keep isl_ast_build *build) +static __isl_give isl_aff *extract_rational(__isl_take isl_aff *aff, + __isl_keep isl_ast_expr **expr, __isl_keep isl_ast_build *build) { - int i, j; - int n; + int i, j, n; + isl_aff *rat = NULL; + isl_local_space *ls = NULL; + isl_ast_expr *rat_expr; isl_val *v, *d; - isl_ctx *ctx = isl_aff_get_ctx(aff); - isl_ast_expr *expr, *expr_neg; enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div }; enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div }; - isl_local_space *ls; if (!aff) return NULL; - - expr = isl_ast_expr_alloc_int_si(ctx, 0); - expr_neg = isl_ast_expr_alloc_int_si(ctx, 0); - d = isl_aff_get_denominator_val(aff); - aff = isl_aff_scale_val(aff, isl_val_copy(d)); + if (!d) + goto error; + if (isl_val_is_one(d)) { + isl_val_free(d); + return aff; + } - aff = extract_modulos(aff, &expr, &expr_neg, build); - expr = ast_expr_sub(expr, expr_neg); + aff = isl_aff_scale_val(aff, isl_val_copy(d)); ls = isl_aff_get_domain_local_space(aff); + rat = isl_aff_zero_on_domain(isl_local_space_copy(ls)); for (i = 0; i < 3; ++i) { n = isl_aff_dim(aff, t[i]); for (j = 0; j < n; ++j) { + isl_aff *rat_j; + v = isl_aff_get_coefficient_val(aff, t[i], j); if (!v) - expr = isl_ast_expr_free(expr); - if (isl_val_is_zero(v)) { + goto error; + if (isl_val_is_divisible_by(v, d)) { isl_val_free(v); continue; } - expr = isl_ast_expr_add_term(expr, - ls, l[i], j, v, build); + rat_j = isl_aff_var_on_domain(isl_local_space_copy(ls), + l[i], j); + rat_j = isl_aff_scale_val(rat_j, v); + rat = isl_aff_add(rat, rat_j); } } v = isl_aff_get_constant_val(aff); - expr = isl_ast_expr_add_int(expr, v); + if (isl_val_is_divisible_by(v, d)) { + isl_val_free(v); + } else { + isl_aff *rat_0; - if (!isl_val_is_one(d)) - expr = isl_ast_expr_div(expr, isl_ast_expr_from_val(d)); - else - isl_val_free(d); + rat_0 = isl_aff_val_on_domain(isl_local_space_copy(ls), v); + rat = isl_aff_add(rat, rat_0); + } isl_local_space_free(ls); - isl_aff_free(aff); - return expr; -} -/* Add terms to "expr" for each variable in "aff" with a coefficient - * with sign equal to "sign". + aff = isl_aff_sub(aff, isl_aff_copy(rat)); + aff = isl_aff_scale_down_val(aff, isl_val_copy(d)); + + rat_expr = isl_ast_expr_from_aff(rat, build); + rat_expr = isl_ast_expr_div(rat_expr, isl_ast_expr_from_val(d)); + *expr = ast_expr_add(*expr, rat_expr); + + return aff; +error: + isl_aff_free(rat); + isl_local_space_free(ls); + isl_aff_free(aff); + isl_val_free(d); + return NULL; +} + +/* Construct an isl_ast_expr that evaluates the affine expression "aff", * The result is simplified in terms of build->domain. + * + * We first extract hidden modulo computations from the affine expression + * and then add terms for each variable with a non-zero coefficient. + * Finally, if the affine expression has a non-trivial denominator, + * we divide the resulting isl_ast_expr by this denominator. + */ +__isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff, + __isl_keep isl_ast_build *build) +{ + int i, j; + int n; + isl_val *v; + isl_ctx *ctx = isl_aff_get_ctx(aff); + isl_ast_expr *expr, *expr_neg; + enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div }; + enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div }; + isl_local_space *ls; + struct isl_ast_add_term_data data; + + if (!aff) + return NULL; + + expr = isl_ast_expr_alloc_int_si(ctx, 0); + expr_neg = isl_ast_expr_alloc_int_si(ctx, 0); + + aff = extract_rational(aff, &expr, build); + + aff = extract_modulos(aff, &expr, &expr_neg, build); + expr = ast_expr_sub(expr, expr_neg); + + ls = isl_aff_get_domain_local_space(aff); + + data.build = build; + data.cst = isl_aff_get_constant_val(aff); + for (i = 0; i < 3; ++i) { + n = isl_aff_dim(aff, t[i]); + for (j = 0; j < n; ++j) { + v = isl_aff_get_coefficient_val(aff, t[i], j); + if (!v) + expr = isl_ast_expr_free(expr); + if (isl_val_is_zero(v)) { + isl_val_free(v); + continue; + } + expr = isl_ast_expr_add_term(expr, + ls, l[i], j, v, &data); + } + } + + expr = isl_ast_expr_add_int(expr, data.cst); + + isl_local_space_free(ls); + isl_aff_free(aff); + return expr; +} + +/* Add terms to "expr" for each variable in "aff" with a coefficient + * with sign equal to "sign". + * The result is simplified in terms of data->build->domain. */ static __isl_give isl_ast_expr *add_signed_terms(__isl_take isl_ast_expr *expr, - __isl_keep isl_aff *aff, int sign, __isl_keep isl_ast_build *build) + __isl_keep isl_aff *aff, int sign, struct isl_ast_add_term_data *data) { int i, j; isl_val *v; @@ -580,7 +1134,7 @@ } v = isl_val_abs(v); expr = isl_ast_expr_add_term(expr, - ls, l[i], j, v, build); + ls, l[i], j, v, data); } } @@ -608,10 +1162,143 @@ return isl_val_is_pos(v); } +/* Check if the equality + * + * aff = 0 + * + * represents a stride constraint on the integer division "pos". + * + * In particular, if the integer division "pos" is equal to + * + * floor(e/d) + * + * then check if aff is equal to + * + * e - d floor(e/d) + * + * or its opposite. + * + * If so, the equality is exactly + * + * e mod d = 0 + * + * Note that in principle we could also accept + * + * e - d floor(e'/d) + * + * where e and e' differ by a constant. + */ +static int is_stride_constraint(__isl_keep isl_aff *aff, int pos) +{ + isl_aff *div; + isl_val *c, *d; + int eq; + + div = isl_aff_get_div(aff, pos); + c = isl_aff_get_coefficient_val(aff, isl_dim_div, pos); + d = isl_aff_get_denominator_val(div); + eq = isl_val_abs_eq(c, d); + if (eq >= 0 && eq) { + aff = isl_aff_copy(aff); + aff = isl_aff_set_coefficient_si(aff, isl_dim_div, pos, 0); + div = isl_aff_scale_val(div, d); + if (isl_val_is_pos(c)) + div = isl_aff_neg(div); + eq = isl_aff_plain_is_equal(div, aff); + isl_aff_free(aff); + } else + isl_val_free(d); + isl_val_free(c); + isl_aff_free(div); + + return eq; +} + +/* Are all coefficients of "aff" (zero or) negative? + */ +static int all_negative_coefficients(__isl_keep isl_aff *aff) +{ + int i, n; + + if (!aff) + return 0; + + n = isl_aff_dim(aff, isl_dim_param); + for (i = 0; i < n; ++i) + if (isl_aff_coefficient_sgn(aff, isl_dim_param, i) > 0) + return 0; + + n = isl_aff_dim(aff, isl_dim_in); + for (i = 0; i < n; ++i) + if (isl_aff_coefficient_sgn(aff, isl_dim_in, i) > 0) + return 0; + + return 1; +} + +/* Give an equality of the form + * + * aff = e - d floor(e/d) = 0 + * + * or + * + * aff = -e + d floor(e/d) = 0 + * + * with the integer division "pos" equal to floor(e/d), + * construct the AST expression + * + * (isl_ast_op_eq, (isl_ast_op_zdiv_r, expr(e), expr(d)), expr(0)) + * + * If e only has negative coefficients, then construct + * + * (isl_ast_op_eq, (isl_ast_op_zdiv_r, expr(-e), expr(d)), expr(0)) + * + * instead. + */ +static __isl_give isl_ast_expr *extract_stride_constraint( + __isl_take isl_aff *aff, int pos, __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_val *c; + isl_ast_expr *expr, *cst; + + if (!aff) + return NULL; + + ctx = isl_aff_get_ctx(aff); + + c = isl_aff_get_coefficient_val(aff, isl_dim_div, pos); + aff = isl_aff_set_coefficient_si(aff, isl_dim_div, pos, 0); + + if (all_negative_coefficients(aff)) + aff = isl_aff_neg(aff); + + cst = isl_ast_expr_from_val(isl_val_abs(c)); + expr = isl_ast_expr_from_aff(aff, build); + + expr = isl_ast_expr_alloc_binary(isl_ast_op_zdiv_r, expr, cst); + cst = isl_ast_expr_alloc_int_si(ctx, 0); + expr = isl_ast_expr_alloc_binary(isl_ast_op_eq, expr, cst); + + return expr; +} + /* Construct an isl_ast_expr that evaluates the condition "constraint", * The result is simplified in terms of build->domain. * - * Let the constraint by either "a >= 0" or "a == 0". + * We first check if the constraint is an equality of the form + * + * e - d floor(e/d) = 0 + * + * i.e., + * + * e mod d = 0 + * + * If so, we convert it to + * + * (isl_ast_op_eq, (isl_ast_op_zdiv_r, expr(e), expr(d)), expr(0)) + * + * Otherwise, let the constraint by either "a >= 0" or "a == 0". * We first extract hidden modulo computations from "a" * and then collect all the terms with a positive coefficient in cons_pos * and the terms with a negative coefficient in cons_neg. @@ -635,39 +1322,54 @@ static __isl_give isl_ast_expr *isl_ast_expr_from_constraint( __isl_take isl_constraint *constraint, __isl_keep isl_ast_build *build) { + int i, n; isl_ctx *ctx; isl_ast_expr *expr_pos; isl_ast_expr *expr_neg; isl_ast_expr *expr; isl_aff *aff; - isl_val *v; int eq; enum isl_ast_op_type type; + struct isl_ast_add_term_data data; if (!constraint) return NULL; aff = isl_constraint_get_aff(constraint); + eq = isl_constraint_is_equality(constraint); + isl_constraint_free(constraint); + + n = isl_aff_dim(aff, isl_dim_div); + if (eq && n > 0) + for (i = 0; i < n; ++i) { + int is_stride; + is_stride = is_stride_constraint(aff, i); + if (is_stride < 0) + goto error; + if (is_stride) + return extract_stride_constraint(aff, i, build); + } - ctx = isl_constraint_get_ctx(constraint); + ctx = isl_aff_get_ctx(aff); expr_pos = isl_ast_expr_alloc_int_si(ctx, 0); expr_neg = isl_ast_expr_alloc_int_si(ctx, 0); aff = extract_modulos(aff, &expr_pos, &expr_neg, build); - expr_pos = add_signed_terms(expr_pos, aff, 1, build); - expr_neg = add_signed_terms(expr_neg, aff, -1, build); + data.build = build; + data.cst = isl_aff_get_constant_val(aff); + expr_pos = add_signed_terms(expr_pos, aff, 1, &data); + data.cst = isl_val_neg(data.cst); + expr_neg = add_signed_terms(expr_neg, aff, -1, &data); + data.cst = isl_val_neg(data.cst); - v = isl_aff_get_constant_val(aff); - if (constant_is_considered_positive(v, expr_pos, expr_neg)) { - expr_pos = isl_ast_expr_add_int(expr_pos, v); + if (constant_is_considered_positive(data.cst, expr_pos, expr_neg)) { + expr_pos = isl_ast_expr_add_int(expr_pos, data.cst); } else { - v = isl_val_neg(v); - expr_neg = isl_ast_expr_add_int(expr_neg, v); + data.cst = isl_val_neg(data.cst); + expr_neg = isl_ast_expr_add_int(expr_neg, data.cst); } - eq = isl_constraint_is_equality(constraint); - if (isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int && isl_ast_expr_get_type(expr_neg) != isl_ast_expr_int) { type = eq ? isl_ast_op_eq : isl_ast_op_le; @@ -677,68 +1379,92 @@ expr = isl_ast_expr_alloc_binary(type, expr_pos, expr_neg); } - isl_constraint_free(constraint); isl_aff_free(aff); return expr; +error: + isl_aff_free(aff); + return NULL; } -struct isl_expr_from_basic_data { - isl_ast_build *build; - int first; - isl_ast_expr *res; -}; - -/* Construct an isl_ast_expr that evaluates the condition "c", - * except if it is a div constraint, and add it to the data->res. - * The result is simplified in terms of data->build->domain. - */ -static int expr_from_basic_set(__isl_take isl_constraint *c, void *user) -{ - struct isl_expr_from_basic_data *data = user; - isl_ast_expr *expr; - - if (isl_constraint_is_div_constraint(c)) { - isl_constraint_free(c); - return 0; - } - - expr = isl_ast_expr_from_constraint(c, data->build); - if (data->first) - data->res = expr; - else - data->res = isl_ast_expr_and(data->res, expr); - - data->first = 0; - - if (!data->res) - return -1; - return 0; +/* Wrapper around isl_constraint_cmp_last_non_zero for use + * as a callback to isl_constraint_list_sort. + * If isl_constraint_cmp_last_non_zero cannot tell the constraints + * apart, then use isl_constraint_plain_cmp instead. + */ +static int cmp_constraint(__isl_keep isl_constraint *a, + __isl_keep isl_constraint *b, void *user) +{ + int cmp; + + cmp = isl_constraint_cmp_last_non_zero(a, b); + if (cmp != 0) + return cmp; + return isl_constraint_plain_cmp(a, b); } /* Construct an isl_ast_expr that evaluates the conditions defining "bset". * The result is simplified in terms of build->domain. * - * We filter out the div constraints during printing, so we do not know - * in advance how many constraints are going to be printed. - * - * If it turns out that there was no constraint, then we contruct + * If "bset" is not bounded by any constraint, then we contruct * the expression "1", i.e., "true". + * + * Otherwise, we sort the constraints, putting constraints that involve + * integer divisions after those that do not, and construct an "and" + * of the ast expressions of the individual constraints. + * + * Each constraint is added to the generated constraints of the build + * after it has been converted to an AST expression so that it can be used + * to simplify the following constraints. This may change the truth value + * of subsequent constraints that do not satisfy the earlier constraints, + * but this does not affect the outcome of the conjunction as it is + * only true if all the conjuncts are true (no matter in what order + * they are evaluated). In particular, the constraints that do not + * involve integer divisions may serve to simplify some constraints + * that do involve integer divisions. */ __isl_give isl_ast_expr *isl_ast_build_expr_from_basic_set( __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset) { - struct isl_expr_from_basic_data data = { build, 1, NULL }; + int i, n; + isl_constraint *c; + isl_constraint_list *list; + isl_ast_expr *res; + isl_set *set; - if (isl_basic_set_foreach_constraint(bset, - &expr_from_basic_set, &data) < 0) { - data.res = isl_ast_expr_free(data.res); - } else if (data.res == NULL) { + list = isl_basic_set_get_constraint_list(bset); + isl_basic_set_free(bset); + list = isl_constraint_list_sort(list, &cmp_constraint, NULL); + if (!list) + return NULL; + n = isl_constraint_list_n_constraint(list); + if (n == 0) { isl_ctx *ctx = isl_basic_set_get_ctx(bset); - data.res = isl_ast_expr_alloc_int_si(ctx, 1); + isl_constraint_list_free(list); + return isl_ast_expr_alloc_int_si(ctx, 1); } - isl_basic_set_free(bset); - return data.res; + build = isl_ast_build_copy(build); + + c = isl_constraint_list_get_constraint(list, 0); + bset = isl_basic_set_from_constraint(isl_constraint_copy(c)); + set = isl_set_from_basic_set(bset); + res = isl_ast_expr_from_constraint(c, build); + build = isl_ast_build_restrict_generated(build, set); + + for (i = 1; i < n; ++i) { + isl_ast_expr *expr; + + c = isl_constraint_list_get_constraint(list, i); + bset = isl_basic_set_from_constraint(isl_constraint_copy(c)); + set = isl_set_from_basic_set(bset); + expr = isl_ast_expr_from_constraint(c, build); + build = isl_ast_build_restrict_generated(build, set); + res = isl_ast_expr_and(res, expr); + } + + isl_constraint_list_free(list); + isl_ast_build_free(build); + return res; } struct isl_expr_from_set_data { @@ -751,7 +1477,7 @@ * and add it to data->res. * The result is simplified in terms of data->build->domain. */ -static int expr_from_set(__isl_take isl_basic_set *bset, void *user) +static isl_stat expr_from_set(__isl_take isl_basic_set *bset, void *user) { struct isl_expr_from_set_data *data = user; isl_ast_expr *expr; @@ -765,25 +1491,59 @@ data->first = 0; if (!data->res) - return -1; - return 0; + return isl_stat_error; + return isl_stat_ok; } /* Construct an isl_ast_expr that evaluates the conditions defining "set". * The result is simplified in terms of build->domain. + * + * If "set" is an (obviously) empty set, then return the expression "0". + * + * "set" lives in the internal schedule space. */ -__isl_give isl_ast_expr *isl_ast_build_expr_from_set( +__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal( __isl_keep isl_ast_build *build, __isl_take isl_set *set) { struct isl_expr_from_set_data data = { build, 1, NULL }; if (isl_set_foreach_basic_set(set, &expr_from_set, &data) < 0) data.res = isl_ast_expr_free(data.res); + else if (data.first) { + isl_ctx *ctx = isl_ast_build_get_ctx(build); + data.res = isl_ast_expr_from_val(isl_val_zero(ctx)); + } isl_set_free(set); return data.res; } +/* Construct an isl_ast_expr that evaluates the conditions defining "set". + * The result is simplified in terms of build->domain. + * + * If "set" is an (obviously) empty set, then return the expression "0". + * + * "set" lives in the external schedule space. + * + * The internal AST expression generation assumes that there are + * no unknown divs, so make sure an explicit representation is available. + * Since the set comes from the outside, it may have constraints that + * are redundant with respect to the build domain. Remove them first. + */ +__isl_give isl_ast_expr *isl_ast_build_expr_from_set( + __isl_keep isl_ast_build *build, __isl_take isl_set *set) +{ + if (isl_ast_build_need_schedule_map(build)) { + isl_multi_aff *ma; + ma = isl_ast_build_get_schedule_map_multi_aff(build); + set = isl_set_preimage_multi_aff(set, ma); + } + + set = isl_set_compute_divs(set); + set = isl_ast_build_compute_gist(build, set); + return isl_ast_build_expr_from_set_internal(build, set); +} + struct isl_from_pw_aff_data { isl_ast_build *build; int n; @@ -801,39 +1561,50 @@ * If this is the last pair, then data->next is set to evaluate aff * and the domain is ignored. * Otherwise, data->next is set to a select operation that selects - * an isl_ast_expr correponding to "aff" on "set" and to an expression + * an isl_ast_expr corresponding to "aff" on "set" and to an expression * that will be filled in by later calls otherwise. + * + * In both cases, the constraints of "set" are added to the generated + * constraints of the build such that they can be exploited to simplify + * the AST expression constructed from "aff". */ -static int ast_expr_from_pw_aff(__isl_take isl_set *set, +static isl_stat ast_expr_from_pw_aff(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user) { struct isl_from_pw_aff_data *data = user; isl_ctx *ctx; + isl_ast_build *build; ctx = isl_set_get_ctx(set); data->n--; if (data->n == 0) { - *data->next = isl_ast_expr_from_aff(aff, data->build); - isl_set_free(set); + build = isl_ast_build_copy(data->build); + build = isl_ast_build_restrict_generated(build, set); + *data->next = isl_ast_expr_from_aff(aff, build); + isl_ast_build_free(build); if (!*data->next) - return -1; + return isl_stat_error; } else { isl_ast_expr *ternary, *arg; + isl_set *gist; ternary = isl_ast_expr_alloc_op(ctx, isl_ast_op_select, 3); - set = isl_set_gist(set, isl_set_copy(data->dom)); - arg = isl_ast_build_expr_from_set(data->build, set); + gist = isl_set_gist(isl_set_copy(set), isl_set_copy(data->dom)); + arg = isl_ast_build_expr_from_set_internal(data->build, gist); ternary = isl_ast_expr_set_op_arg(ternary, 0, arg); - arg = isl_ast_expr_from_aff(aff, data->build); + build = isl_ast_build_copy(data->build); + build = isl_ast_build_restrict_generated(build, set); + arg = isl_ast_expr_from_aff(aff, build); + isl_ast_build_free(build); ternary = isl_ast_expr_set_op_arg(ternary, 1, arg); if (!ternary) - return -1; + return isl_stat_error; *data->next = ternary; data->next = &ternary->u.op.args[2]; } - return 0; + return isl_stat_ok; } /* Construct an isl_ast_expr that evaluates "pa". @@ -847,6 +1618,8 @@ struct isl_from_pw_aff_data data; isl_ast_expr *res = NULL; + pa = isl_ast_build_compute_gist_pw_aff(build, pa); + pa = isl_pw_aff_coalesce(pa); if (!pa) return NULL; @@ -885,102 +1658,258 @@ return expr; } -/* Set the ids of the input dimensions of "pma" to the iterator ids +/* Set the ids of the input dimensions of "mpa" to the iterator ids * of "build". * - * The domain of "pma" is assumed to live in the internal schedule domain. + * The domain of "mpa" is assumed to live in the internal schedule domain. */ -static __isl_give isl_pw_multi_aff *set_iterator_names( - __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +static __isl_give isl_multi_pw_aff *set_iterator_names( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) { int i, n; - n = isl_pw_multi_aff_dim(pma, isl_dim_in); + n = isl_multi_pw_aff_dim(mpa, isl_dim_in); for (i = 0; i < n; ++i) { isl_id *id; id = isl_ast_build_get_iterator_id(build, i); - pma = isl_pw_multi_aff_set_dim_id(pma, isl_dim_in, i, id); + mpa = isl_multi_pw_aff_set_dim_id(mpa, isl_dim_in, i, id); } - return pma; + return mpa; } -/* Construct an isl_ast_expr that calls the domain element specified by "pma". - * The name of the function is obtained from the output tuple name. - * The arguments are given by the piecewise affine expressions. - * - * The domain of "pma" is assumed to live in the internal schedule domain. +/* Construct an isl_ast_expr of type "type" with as first argument "arg0" and + * the remaining arguments derived from "mpa". + * That is, construct a call or access expression that calls/accesses "arg0" + * with arguments/indices specified by "mpa". */ -static __isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff_internal( - __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +static __isl_give isl_ast_expr *isl_ast_build_with_arguments( + __isl_keep isl_ast_build *build, enum isl_ast_op_type type, + __isl_take isl_ast_expr *arg0, __isl_take isl_multi_pw_aff *mpa) { int i, n; isl_ctx *ctx; - isl_id *id; isl_ast_expr *expr; - pma = set_iterator_names(build, pma); - if (!build || !pma) - return isl_pw_multi_aff_free(pma); - ctx = isl_ast_build_get_ctx(build); - n = isl_pw_multi_aff_dim(pma, isl_dim_out); - expr = isl_ast_expr_alloc_op(ctx, isl_ast_op_call, 1 + n); - if (isl_pw_multi_aff_has_tuple_id(pma, isl_dim_out)) - id = isl_pw_multi_aff_get_tuple_id(pma, isl_dim_out); - else - id = isl_id_alloc(ctx, "", NULL); - - expr = isl_ast_expr_set_op_arg(expr, 0, isl_ast_expr_from_id(id)); + n = isl_multi_pw_aff_dim(mpa, isl_dim_out); + expr = isl_ast_expr_alloc_op(ctx, type, 1 + n); + expr = isl_ast_expr_set_op_arg(expr, 0, arg0); for (i = 0; i < n; ++i) { isl_pw_aff *pa; isl_ast_expr *arg; - pa = isl_pw_multi_aff_get_pw_aff(pma, i); + pa = isl_multi_pw_aff_get_pw_aff(mpa, i); arg = isl_ast_build_expr_from_pw_aff_internal(build, pa); expr = isl_ast_expr_set_op_arg(expr, 1 + i, arg); } - isl_pw_multi_aff_free(pma); + isl_multi_pw_aff_free(mpa); return expr; } -/* Construct an isl_ast_expr that calls the domain element specified by "pma". - * The name of the function is obtained from the output tuple name. - * The arguments are given by the piecewise affine expressions. +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_internal( + __isl_keep isl_ast_build *build, enum isl_ast_op_type type, + __isl_take isl_multi_pw_aff *mpa); + +/* Construct an isl_ast_expr that accesses the member specified by "mpa". + * The range of "mpa" is assumed to be wrapped relation. + * The domain of this wrapped relation specifies the structure being + * accessed, while the range of this wrapped relation spacifies the + * member of the structure being accessed. * - * The domain of "pma" is assumed to live in the external schedule domain. + * The domain of "mpa" is assumed to live in the internal schedule domain. */ -__isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff( - __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_member( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + isl_id *id; + isl_multi_pw_aff *domain; + isl_ast_expr *domain_expr, *expr; + enum isl_ast_op_type type = isl_ast_op_access; + + domain = isl_multi_pw_aff_copy(mpa); + domain = isl_multi_pw_aff_range_factor_domain(domain); + domain_expr = isl_ast_build_from_multi_pw_aff_internal(build, + type, domain); + mpa = isl_multi_pw_aff_range_factor_range(mpa); + if (!isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out)) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "missing field name", goto error); + id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out); + expr = isl_ast_expr_from_id(id); + expr = isl_ast_expr_alloc_binary(isl_ast_op_member, domain_expr, expr); + return isl_ast_build_with_arguments(build, type, expr, mpa); +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "mpa". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * If the range of "mpa" is a mapped relation, then we assume it + * represents an access to a member of a structure. + * + * The domain of "mpa" is assumed to live in the internal schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff_internal( + __isl_keep isl_ast_build *build, enum isl_ast_op_type type, + __isl_take isl_multi_pw_aff *mpa) +{ + isl_ctx *ctx; + isl_id *id; + isl_ast_expr *expr; + + if (!mpa) + goto error; + + if (type == isl_ast_op_access && + isl_multi_pw_aff_range_is_wrapping(mpa)) + return isl_ast_build_from_multi_pw_aff_member(build, mpa); + + mpa = set_iterator_names(build, mpa); + if (!build || !mpa) + goto error; + + ctx = isl_ast_build_get_ctx(build); + + if (isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out)) + id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out); + else + id = isl_id_alloc(ctx, "", NULL); + + expr = isl_ast_expr_from_id(id); + return isl_ast_build_with_arguments(build, type, expr, mpa); +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "pma". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the internal schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_pw_multi_aff_internal( + __isl_keep isl_ast_build *build, enum isl_ast_op_type type, + __isl_take isl_pw_multi_aff *pma) +{ + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_from_pw_multi_aff(pma); + return isl_ast_build_from_multi_pw_aff_internal(build, type, mpa); +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "mpa". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * The domain of "mpa" is assumed to live in the external schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_multi_pw_aff( + __isl_keep isl_ast_build *build, enum isl_ast_op_type type, + __isl_take isl_multi_pw_aff *mpa) { int is_domain; isl_ast_expr *expr; - isl_space *space_build, *space_pma; + isl_space *space_build, *space_mpa; space_build = isl_ast_build_get_space(build, 0); - space_pma = isl_pw_multi_aff_get_space(pma); - is_domain = isl_space_tuple_match(space_build, isl_dim_set, - space_pma, isl_dim_in); + space_mpa = isl_multi_pw_aff_get_space(mpa); + is_domain = isl_space_tuple_is_equal(space_build, isl_dim_set, + space_mpa, isl_dim_in); isl_space_free(space_build); - isl_space_free(space_pma); + isl_space_free(space_mpa); if (is_domain < 0) - return isl_pw_multi_aff_free(pma); + goto error; if (!is_domain) isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, - "spaces don't match", - return isl_pw_multi_aff_free(pma)); + "spaces don't match", goto error); if (isl_ast_build_need_schedule_map(build)) { isl_multi_aff *ma; ma = isl_ast_build_get_schedule_map_multi_aff(build); - pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma); + mpa = isl_multi_pw_aff_pullback_multi_aff(mpa, ma); } - expr = isl_ast_build_call_from_pw_multi_aff_internal(build, pma); + expr = isl_ast_build_from_multi_pw_aff_internal(build, type, mpa); return expr; +error: + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Construct an isl_ast_expr that calls the domain element specified by "mpa". + * The name of the function is obtained from the output tuple name. + * The arguments are given by the piecewise affine expressions. + * + * The domain of "mpa" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_call_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_ast_build_from_multi_pw_aff(build, isl_ast_op_call, mpa); +} + +/* Construct an isl_ast_expr that accesses the array element specified by "mpa". + * The name of the array is obtained from the output tuple name. + * The index expressions are given by the piecewise affine expressions. + * + * The domain of "mpa" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_access_from_multi_pw_aff( + __isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_ast_build_from_multi_pw_aff(build, isl_ast_op_access, mpa); +} + +/* Construct an isl_ast_expr of type "type" that calls or accesses + * the element specified by "pma". + * The first argument is obtained from the output tuple name. + * The remaining arguments are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the external schedule domain. + */ +static __isl_give isl_ast_expr *isl_ast_build_from_pw_multi_aff( + __isl_keep isl_ast_build *build, enum isl_ast_op_type type, + __isl_take isl_pw_multi_aff *pma) +{ + isl_multi_pw_aff *mpa; + + mpa = isl_multi_pw_aff_from_pw_multi_aff(pma); + return isl_ast_build_from_multi_pw_aff(build, type, mpa); +} + +/* Construct an isl_ast_expr that calls the domain element specified by "pma". + * The name of the function is obtained from the output tuple name. + * The arguments are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_call_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +{ + return isl_ast_build_from_pw_multi_aff(build, isl_ast_op_call, pma); +} + +/* Construct an isl_ast_expr that accesses the array element specified by "pma". + * The name of the array is obtained from the output tuple name. + * The index expressions are given by the piecewise affine expressions. + * + * The domain of "pma" is assumed to live in the external schedule domain. + */ +__isl_give isl_ast_expr *isl_ast_build_access_from_pw_multi_aff( + __isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma) +{ + return isl_ast_build_from_pw_multi_aff(build, isl_ast_op_access, pma); } /* Construct an isl_ast_expr that calls the domain element @@ -999,6 +1928,7 @@ iteration = isl_ast_build_compute_gist_pw_multi_aff(build, iteration); iteration = isl_pw_multi_aff_intersect_domain(iteration, isl_ast_build_get_domain(build)); - expr = isl_ast_build_call_from_pw_multi_aff_internal(build, iteration); + expr = isl_ast_build_from_pw_multi_aff_internal(build, isl_ast_op_call, + iteration); return isl_ast_node_alloc_user(expr); } diff -Nru isl-0.12.2/isl_ast_build_expr.h isl-0.15/isl_ast_build_expr.h --- isl-0.12.2/isl_ast_build_expr.h 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/isl_ast_build_expr.h 2015-06-02 09:28:09.000000000 +0000 @@ -6,7 +6,7 @@ __isl_give isl_ast_expr *isl_ast_build_expr_from_basic_set( __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset); -__isl_give isl_ast_expr *isl_ast_build_expr_from_set( +__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal( __isl_keep isl_ast_build *build, __isl_take isl_set *set); __isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff_internal( diff -Nru isl-0.12.2/isl_ast_build_private.h isl-0.15/isl_ast_build_private.h --- isl-0.12.2/isl_ast_build_private.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/isl_ast_build_private.h 2015-06-02 09:28:09.000000000 +0000 @@ -6,12 +6,7 @@ #include #include #include - -enum isl_ast_build_domain_type { - atomic, - unroll, - separate -}; +#include /* An isl_ast_build represents the context in which AST is being * generated. That is, it (mostly) contains information about outer @@ -89,6 +84,17 @@ * domain. It may be NULL if it hasn't been computed yet. * See isl_ast_build_get_schedule_map_multi_aff. * + * "internal2input" maps the internal schedule domain to the original + * input schedule domain. In case of a schedule tree input, the original + * input schedule domain consist of the flat product of all outer + * band node spaces, including the current band node. + * It may be NULL if there no longer is such a uniform mapping + * (because different iterations have been rescheduled differently). + * + * "options" contains the AST build options in case we are generating + * an AST from a flat schedule map. When creating an AST from a schedule + * tree, this field is ignored. + * * The "create_leaf" callback is called for every leaf in the generated AST. * The callback is responsible for creating the node to be placed at those * leaves. If this callback is not set, then isl will generated user @@ -104,6 +110,12 @@ * The "after_each_for" callback is called on each for node after * its children have been created. * + * The "before_each_mark" callback is called before we handle the subtree + * of an isl_schedule_node_mark node. + * + * The "after_each_mark" callback is called after we have handled the subtree + * of an isl_schedule_node_mark node. + * * "executed" contains the inverse schedule at this point * of the AST generation. * It is currently only used in isl_ast_build_get_schedule, which is @@ -116,6 +128,19 @@ * is extended to a single valued inverse schedule. This is mainly used * to avoid an infinite recursion when we fail to detect later on that * the extended inverse schedule is single valued. + * + * "node" points to the current band node in case we are generating + * an AST from a schedule tree. It may be NULL if we are not generating + * an AST from a schedule tree or if we are not inside a band node. + * + * "loop_type" originally constains loop AST generation types for + * the "n" members of "node" and it is updated (along with "n") when + * a schedule dimension is inserted. + * It is NULL if "node" is NULL. + * + * "isolated" is the piece of the schedule domain isolated by the isolate + * option on the current band. This set may be NULL if we have not checked + * for the isolate option yet. */ struct isl_ast_build { int ref; @@ -136,6 +161,7 @@ isl_multi_aff *offsets; isl_multi_aff *schedule_map; + isl_multi_aff *internal2input; isl_union_map *options; @@ -152,12 +178,25 @@ __isl_keep isl_ast_build *context, void *user); void *after_each_for_user; + isl_stat (*before_each_mark)(__isl_keep isl_id *mark, + __isl_keep isl_ast_build *build, void *user); + void *before_each_mark_user; + __isl_give isl_ast_node *(*after_each_mark)( + __isl_take isl_ast_node *node, + __isl_keep isl_ast_build *context, void *user); + void *after_each_mark_user; + __isl_give isl_ast_node *(*create_leaf)( __isl_take isl_ast_build *build, void *user); void *create_leaf_user; isl_union_map *executed; int single_valued; + + isl_schedule_node *node; + int n; + enum isl_ast_loop_type *loop_type; + isl_set *isolated; }; __isl_give isl_ast_build *isl_ast_build_clear_local_info( @@ -165,6 +204,8 @@ __isl_give isl_ast_build *isl_ast_build_increase_depth( __isl_take isl_ast_build *build); int isl_ast_build_get_depth(__isl_keep isl_ast_build *build); +unsigned isl_ast_build_dim(__isl_keep isl_ast_build *build, + enum isl_dim_type type); __isl_give isl_space *isl_ast_build_get_space( __isl_keep isl_ast_build *build, int internal); __isl_give isl_ast_build *isl_ast_build_align_params( @@ -189,14 +230,20 @@ __isl_take isl_union_map *executed); __isl_give isl_ast_build *isl_ast_build_set_single_valued( __isl_take isl_ast_build *build, int sv); +__isl_give isl_multi_aff *isl_ast_build_get_internal2input( + __isl_keep isl_ast_build *build); __isl_give isl_set *isl_ast_build_get_domain( __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_pending( + __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_generated( + __isl_keep isl_ast_build *build); __isl_give isl_ast_build *isl_ast_build_restrict_generated( __isl_take isl_ast_build *build, __isl_take isl_set *set); +__isl_give isl_ast_build *isl_ast_build_replace_pending_by_guard( + __isl_take isl_ast_build *build, __isl_take isl_set *guard); __isl_give isl_ast_build *isl_ast_build_restrict_pending( __isl_take isl_ast_build *build, __isl_take isl_set *set); -__isl_give isl_ast_build *isl_ast_build_set_enforced( - __isl_take isl_ast_build *build, __isl_take isl_basic_set *enforced); __isl_give int isl_ast_build_need_schedule_map( __isl_keep isl_ast_build *build); __isl_give isl_multi_aff *isl_ast_build_get_schedule_map_multi_aff( @@ -208,8 +255,25 @@ __isl_give isl_id *isl_ast_build_get_iterator_id( __isl_keep isl_ast_build *build, int pos); +int isl_ast_build_has_schedule_node(__isl_keep isl_ast_build *build); +__isl_give isl_schedule_node *isl_ast_build_get_schedule_node( + __isl_keep isl_ast_build *build); +__isl_give isl_ast_build *isl_ast_build_set_schedule_node( + __isl_take isl_ast_build *build, + __isl_take isl_schedule_node *node); +__isl_give isl_ast_build *isl_ast_build_reset_schedule_node( + __isl_take isl_ast_build *build); + +__isl_give isl_ast_build *isl_ast_build_extract_isolated( + __isl_take isl_ast_build *build); +int isl_ast_build_has_isolated(__isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_build_get_isolated( + __isl_keep isl_ast_build *build); + __isl_give isl_basic_set *isl_ast_build_compute_gist_basic_set( __isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_ast_build_specialize(__isl_keep isl_ast_build *build, + __isl_take isl_set *set); __isl_give isl_set *isl_ast_build_compute_gist( __isl_keep isl_ast_build *build, __isl_take isl_set *set); __isl_give isl_map *isl_ast_build_compute_gist_map_domain( @@ -240,8 +304,7 @@ void isl_ast_build_dump(__isl_keep isl_ast_build *build); __isl_give isl_set *isl_ast_build_get_option_domain( - __isl_keep isl_ast_build *build, - enum isl_ast_build_domain_type type); + __isl_keep isl_ast_build *build, enum isl_ast_loop_type type); __isl_give isl_map *isl_ast_build_get_separation_class( __isl_keep isl_ast_build *build); __isl_give isl_set *isl_ast_build_eliminate( @@ -251,6 +314,9 @@ __isl_give isl_set *isl_ast_build_eliminate_divs( __isl_keep isl_ast_build *build, __isl_take isl_set *set); +enum isl_ast_loop_type isl_ast_build_get_loop_type( + __isl_keep isl_ast_build *build, int isolated); + __isl_give isl_map *isl_ast_build_map_to_iterator( __isl_keep isl_ast_build *build, __isl_take isl_set *set); diff -Nru isl-0.12.2/isl_ast.c isl-0.15/isl_ast.c --- isl-0.12.2/isl_ast.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ast.c 2015-06-10 18:25:33.000000000 +0000 @@ -1,5 +1,13 @@ +/* + * Copyright 2012-2013 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + #include -#include #undef BASE #define BASE ast_expr @@ -76,7 +84,8 @@ return options; } -void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options) +__isl_null isl_ast_print_options *isl_ast_print_options_free( + __isl_take isl_ast_print_options *options) { if (!options) return NULL; @@ -189,7 +198,7 @@ return isl_ast_expr_dup(expr); } -void *isl_ast_expr_free(__isl_take isl_ast_expr *expr) +__isl_null isl_ast_expr *isl_ast_expr_free(__isl_take isl_ast_expr *expr) { int i; @@ -209,8 +218,9 @@ isl_id_free(expr->u.id); break; case isl_ast_expr_op: - for (i = 0; i < expr->u.op.n_arg; ++i) - isl_ast_expr_free(expr->u.op.args[i]); + if (expr->u.op.args) + for (i = 0; i < expr->u.op.n_arg; ++i) + isl_ast_expr_free(expr->u.op.args[i]); free(expr->u.op.args); break; case isl_ast_expr_error: @@ -231,16 +241,6 @@ return expr ? expr->type : isl_ast_expr_error; } -int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v) -{ - if (!expr) - return -1; - if (expr->type != isl_ast_expr_int) - isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, - "expression not an int", return -1); - return isl_val_get_num_isl_int(expr->u.v, v); -} - /* Return the integer value represented by "expr". */ __isl_give isl_val *isl_ast_expr_get_val(__isl_keep isl_ast_expr *expr) @@ -323,6 +323,46 @@ return isl_ast_expr_free(expr); } +/* Is "expr1" equal to "expr2"? + */ +isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1, + __isl_keep isl_ast_expr *expr2) +{ + int i; + + if (!expr1 || !expr2) + return isl_bool_error; + + if (expr1 == expr2) + return isl_bool_true; + if (expr1->type != expr2->type) + return isl_bool_false; + switch (expr1->type) { + case isl_ast_expr_int: + return isl_val_eq(expr1->u.v, expr2->u.v); + case isl_ast_expr_id: + return expr1->u.id == expr2->u.id; + case isl_ast_expr_op: + if (expr1->u.op.op != expr2->u.op.op) + return isl_bool_false; + if (expr1->u.op.n_arg != expr2->u.op.n_arg) + return isl_bool_false; + for (i = 0; i < expr1->u.op.n_arg; ++i) { + isl_bool equal; + equal = isl_ast_expr_is_equal(expr1->u.op.args[i], + expr2->u.op.args[i]); + if (equal < 0 || !equal) + return equal; + } + return 1; + case isl_ast_expr_error: + return isl_bool_error; + } + + isl_die(isl_ast_expr_get_ctx(expr1), isl_error_internal, + "unhandled case", return isl_bool_error); +} + /* Create a new operation expression of operation type "op", * with "n_arg" as yet unspecified arguments. */ @@ -362,7 +402,7 @@ ctx = isl_id_get_ctx(id); expr = isl_calloc_type(ctx, isl_ast_expr); if (!expr) - return isl_id_free(id); + goto error; expr->ctx = ctx; isl_ctx_ref(ctx); @@ -371,6 +411,9 @@ expr->u.id = id; return expr; +error: + isl_id_free(id); + return NULL; } /* Create a new integer expression representing "i". @@ -405,12 +448,12 @@ return NULL; if (!isl_val_is_int(v)) isl_die(isl_val_get_ctx(v), isl_error_invalid, - "expecting integer value", return isl_val_free(v)); + "expecting integer value", goto error); ctx = isl_val_get_ctx(v); expr = isl_calloc_type(ctx, isl_ast_expr); if (!expr) - return isl_val_free(v); + goto error; expr->ctx = ctx; isl_ctx_ref(ctx); @@ -419,11 +462,16 @@ expr->u.v = v; return expr; +error: + isl_val_free(v); + return NULL; } -/* Create an expression representing the negation of "arg". +/* Create an expression representing the unary operation "type" applied to + * "arg". */ -__isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg) +__isl_give isl_ast_expr *isl_ast_expr_alloc_unary(enum isl_ast_op_type type, + __isl_take isl_ast_expr *arg) { isl_ctx *ctx; isl_ast_expr *expr = NULL; @@ -432,7 +480,7 @@ return NULL; ctx = isl_ast_expr_get_ctx(arg); - expr = isl_ast_expr_alloc_op(ctx, isl_ast_op_minus, 1); + expr = isl_ast_expr_alloc_op(ctx, type, 1); if (!expr) goto error; @@ -444,6 +492,29 @@ return NULL; } +/* Create an expression representing the negation of "arg". + */ +__isl_give isl_ast_expr *isl_ast_expr_neg(__isl_take isl_ast_expr *arg) +{ + return isl_ast_expr_alloc_unary(isl_ast_op_minus, arg); +} + +/* Create an expression representing the address of "expr". + */ +__isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr) +{ + if (!expr) + return NULL; + + if (isl_ast_expr_get_type(expr) != isl_ast_expr_op || + isl_ast_expr_get_op_type(expr) != isl_ast_op_access) + isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, + "can only take address of access expressions", + return isl_ast_expr_free(expr)); + + return isl_ast_expr_alloc_unary(isl_ast_op_address_of, expr); +} + /* Create an expression representing the binary operation "type" * applied to "expr1" and "expr2". */ @@ -503,6 +574,26 @@ return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2); } +/* Create an expression representing the quotient of the integer + * division of "expr1" by "expr2", where "expr1" is known to be + * non-negative. + */ +__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_q, expr1, expr2); +} + +/* Create an expression representing the remainder of the integer + * division of "expr1" by "expr2", where "expr1" is known to be + * non-negative. + */ +__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_r, expr1, expr2); +} + /* Create an expression representing the conjunction of "expr1" and "expr2". */ __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1, @@ -511,6 +602,15 @@ return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2); } +/* Create an expression representing the conjunction of "expr1" and "expr2", + * where "expr2" is evaluated only if "expr1" is evaluated to true. + */ +__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_and_then, expr1, expr2); +} + /* Create an expression representing the disjunction of "expr1" and "expr2". */ __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1, @@ -519,6 +619,167 @@ return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2); } +/* Create an expression representing the disjunction of "expr1" and "expr2", + * where "expr2" is evaluated only if "expr1" is evaluated to false. + */ +__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_or_else, expr1, expr2); +} + +/* Create an expression representing "expr1" less than or equal to "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_le, expr1, expr2); +} + +/* Create an expression representing "expr1" less than "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_lt, expr1, expr2); +} + +/* Create an expression representing "expr1" greater than or equal to "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_ge(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_ge, expr1, expr2); +} + +/* Create an expression representing "expr1" greater than "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_gt(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_gt, expr1, expr2); +} + +/* Create an expression representing "expr1" equal to "expr2". + */ +__isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1, + __isl_take isl_ast_expr *expr2) +{ + return isl_ast_expr_alloc_binary(isl_ast_op_eq, expr1, expr2); +} + +/* Create an expression of type "type" with as arguments "arg0" followed + * by "arguments". + */ +static __isl_give isl_ast_expr *ast_expr_with_arguments( + enum isl_ast_op_type type, __isl_take isl_ast_expr *arg0, + __isl_take isl_ast_expr_list *arguments) +{ + int i, n; + isl_ctx *ctx; + isl_ast_expr *res = NULL; + + if (!arg0 || !arguments) + goto error; + + ctx = isl_ast_expr_get_ctx(arg0); + n = isl_ast_expr_list_n_ast_expr(arguments); + res = isl_ast_expr_alloc_op(ctx, type, 1 + n); + if (!res) + goto error; + for (i = 0; i < n; ++i) { + isl_ast_expr *arg; + arg = isl_ast_expr_list_get_ast_expr(arguments, i); + res->u.op.args[1 + i] = arg; + if (!arg) + goto error; + } + res->u.op.args[0] = arg0; + + isl_ast_expr_list_free(arguments); + return res; +error: + isl_ast_expr_free(arg0); + isl_ast_expr_list_free(arguments); + isl_ast_expr_free(res); + return NULL; +} + +/* Create an expression representing an access to "array" with index + * expressions "indices". + */ +__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array, + __isl_take isl_ast_expr_list *indices) +{ + return ast_expr_with_arguments(isl_ast_op_access, array, indices); +} + +/* Create an expression representing a call to "function" with argument + * expressions "arguments". + */ +__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function, + __isl_take isl_ast_expr_list *arguments) +{ + return ast_expr_with_arguments(isl_ast_op_call, function, arguments); +} + +/* For each subexpression of "expr" of type isl_ast_expr_id, + * if it appears in "id2expr", then replace it by the corresponding + * expression. + */ +__isl_give isl_ast_expr *isl_ast_expr_substitute_ids( + __isl_take isl_ast_expr *expr, __isl_take isl_id_to_ast_expr *id2expr) +{ + int i; + isl_id *id; + + if (!expr || !id2expr) + goto error; + + switch (expr->type) { + case isl_ast_expr_int: + break; + case isl_ast_expr_id: + if (!isl_id_to_ast_expr_has(id2expr, expr->u.id)) + break; + id = isl_id_copy(expr->u.id); + isl_ast_expr_free(expr); + expr = isl_id_to_ast_expr_get(id2expr, id); + break; + case isl_ast_expr_op: + for (i = 0; i < expr->u.op.n_arg; ++i) { + isl_ast_expr *arg; + arg = isl_ast_expr_copy(expr->u.op.args[i]); + arg = isl_ast_expr_substitute_ids(arg, + isl_id_to_ast_expr_copy(id2expr)); + if (arg == expr->u.op.args[i]) { + isl_ast_expr_free(arg); + continue; + } + if (!arg) + expr = isl_ast_expr_free(expr); + expr = isl_ast_expr_cow(expr); + if (!expr) { + isl_ast_expr_free(arg); + break; + } + isl_ast_expr_free(expr->u.op.args[i]); + expr->u.op.args[i] = arg; + } + break; + case isl_ast_expr_error: + expr = isl_ast_expr_free(expr); + break; + } + + isl_id_to_ast_expr_free(id2expr); + return expr; +error: + isl_ast_expr_free(expr); + isl_id_to_ast_expr_free(id2expr); + return NULL; +} + isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node) { return node ? node->ctx : NULL; @@ -583,13 +844,42 @@ ctx = isl_id_get_ctx(id); node = isl_ast_node_alloc(ctx, isl_ast_node_for); if (!node) - return NULL; + goto error; node->u.f.iterator = isl_ast_expr_from_id(id); if (!node->u.f.iterator) return isl_ast_node_free(node); return node; +error: + isl_id_free(id); + return NULL; +} + +/* Create a mark node, marking "node" with "id". + */ +__isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id, + __isl_take isl_ast_node *node) +{ + isl_ctx *ctx; + isl_ast_node *mark; + + if (!id || !node) + goto error; + + ctx = isl_id_get_ctx(id); + mark = isl_ast_node_alloc(ctx, isl_ast_node_mark); + if (!mark) + goto error; + + mark->u.m.mark = id; + mark->u.m.node = node; + + return mark; +error: + isl_id_free(id); + isl_ast_node_free(node); + return NULL; } /* Create a user node evaluating "expr". @@ -701,6 +991,12 @@ if (!dup->u.b.children) return isl_ast_node_free(dup); break; + case isl_ast_node_mark: + dup->u.m.mark = isl_id_copy(node->u.m.mark); + dup->u.m.node = isl_ast_node_copy(node->u.m.node); + if (!dup->u.m.mark || !dup->u.m.node) + return isl_ast_node_free(dup); + break; case isl_ast_node_user: dup->u.e.expr = isl_ast_expr_copy(node->u.e.expr); if (!dup->u.e.expr) @@ -724,7 +1020,7 @@ return isl_ast_node_dup(node); } -void *isl_ast_node_free(__isl_take isl_ast_node *node) +__isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node) { if (!node) return NULL; @@ -748,6 +1044,10 @@ case isl_ast_node_block: isl_ast_node_list_free(node->u.b.children); break; + case isl_ast_node_mark: + isl_id_free(node->u.m.mark); + isl_ast_node_free(node->u.m.node); + break; case isl_ast_node_user: isl_ast_expr_free(node->u.e.expr); break; @@ -807,13 +1107,13 @@ return node; } -int isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node) +isl_bool isl_ast_node_for_is_degenerate(__isl_keep isl_ast_node *node) { if (!node) - return -1; + return isl_bool_error; if (node->type != isl_ast_node_for) isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, - "not a for node", return -1); + "not a for node", return isl_bool_error); return node->u.f.degenerate; } @@ -913,14 +1213,14 @@ return isl_ast_node_copy(node->u.i.then); } -int isl_ast_node_if_has_else( +isl_bool isl_ast_node_if_has_else( __isl_keep isl_ast_node *node) { if (!node) - return -1; + return isl_bool_error; if (node->type != isl_ast_node_if) isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, - "not an if node", return -1); + "not an if node", return isl_bool_error); return node->u.i.else_node != NULL; } @@ -962,10 +1262,40 @@ { if (!node) return NULL; + if (node->type != isl_ast_node_user) + isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, + "not a user node", return NULL); return isl_ast_expr_copy(node->u.e.expr); } +/* Return the mark identifier of the mark node "node". + */ +__isl_give isl_id *isl_ast_node_mark_get_id(__isl_keep isl_ast_node *node) +{ + if (!node) + return NULL; + if (node->type != isl_ast_node_mark) + isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, + "not a mark node", return NULL); + + return isl_id_copy(node->u.m.mark); +} + +/* Return the node marked by mark node "node". + */ +__isl_give isl_ast_node *isl_ast_node_mark_get_node( + __isl_keep isl_ast_node *node) +{ + if (!node) + return NULL; + if (node->type != isl_ast_node_mark) + isl_die(isl_ast_node_get_ctx(node), isl_error_invalid, + "not a mark node", return NULL); + + return isl_ast_node_copy(node->u.m.node); +} + __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node) { return node ? isl_id_copy(node->annotation) : NULL; @@ -1004,12 +1334,15 @@ [isl_ast_op_mul] = "*", [isl_ast_op_pdiv_q] = "/", [isl_ast_op_pdiv_r] = "%", + [isl_ast_op_zdiv_r] = "%", [isl_ast_op_div] = "/", [isl_ast_op_eq] = "==", [isl_ast_op_le] = "<=", [isl_ast_op_ge] = ">=", [isl_ast_op_lt] = "<", - [isl_ast_op_gt] = ">" + [isl_ast_op_gt] = ">", + [isl_ast_op_member] = ".", + [isl_ast_op_address_of] = "&" }; /* Precedence in C of the various operators. @@ -1031,6 +1364,7 @@ [isl_ast_op_fdiv_q] = 2, [isl_ast_op_pdiv_q] = 5, [isl_ast_op_pdiv_r] = 5, + [isl_ast_op_zdiv_r] = 5, [isl_ast_op_cond] = 15, [isl_ast_op_select] = 15, [isl_ast_op_eq] = 9, @@ -1038,7 +1372,10 @@ [isl_ast_op_ge] = 8, [isl_ast_op_lt] = 8, [isl_ast_op_gt] = 8, - [isl_ast_op_call] = 2 + [isl_ast_op_call] = 2, + [isl_ast_op_access] = 2, + [isl_ast_op_member] = 2, + [isl_ast_op_address_of] = 3 }; /* Is the operator left-to-right associative? @@ -1058,6 +1395,7 @@ [isl_ast_op_fdiv_q] = 1, [isl_ast_op_pdiv_q] = 1, [isl_ast_op_pdiv_r] = 1, + [isl_ast_op_zdiv_r] = 1, [isl_ast_op_cond] = 0, [isl_ast_op_select] = 0, [isl_ast_op_eq] = 1, @@ -1065,7 +1403,10 @@ [isl_ast_op_ge] = 1, [isl_ast_op_lt] = 1, [isl_ast_op_gt] = 1, - [isl_ast_op_call] = 1 + [isl_ast_op_call] = 1, + [isl_ast_op_access] = 1, + [isl_ast_op_member] = 1, + [isl_ast_op_address_of] = 0 }; static int is_and(enum isl_ast_op_type op) @@ -1085,7 +1426,9 @@ static int is_div_mod(enum isl_ast_op_type op) { - return op == isl_ast_op_div || op == isl_ast_op_pdiv_r; + return op == isl_ast_op_div || + op == isl_ast_op_pdiv_r || + op == isl_ast_op_zdiv_r; } /* Do we need/want parentheses around "expr" as a subexpression of @@ -1188,6 +1531,25 @@ return p; } +/* Print an array access "expr". + * + * The first argument represents the array being accessed. + */ +static __isl_give isl_printer *print_access(__isl_take isl_printer *p, + __isl_keep isl_ast_expr *expr) +{ + int i = 0; + + p = isl_printer_print_ast_expr(p, expr->u.op.args[0]); + for (i = 1; i < expr->u.op.n_arg; ++i) { + p = isl_printer_print_str(p, "["); + p = isl_printer_print_ast_expr(p, expr->u.op.args[i]); + p = isl_printer_print_str(p, "]"); + } + + return p; +} + /* Print "expr" to "p". * * If we are printing in isl format, then we also print an indication @@ -1207,6 +1569,10 @@ p = print_call(p, expr); break; } + if (expr->u.op.op == isl_ast_op_access) { + p = print_access(p, expr); + break; + } if (expr->u.op.n_arg == 1) { p = isl_printer_print_str(p, op_str[expr->u.op.op]); p = print_sub_expr(p, expr->u.op.op, @@ -1240,9 +1606,11 @@ "operation should have two arguments", goto error); p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[0], 1); - p = isl_printer_print_str(p, " "); + if (expr->u.op.op != isl_ast_op_member) + p = isl_printer_print_str(p, " "); p = isl_printer_print_str(p, op_str[expr->u.op.op]); - p = isl_printer_print_str(p, " "); + if (expr->u.op.op != isl_ast_op_member) + p = isl_printer_print_str(p, " "); p = print_sub_expr(p, expr->u.op.op, expr->u.op.args[1], 0); break; case isl_ast_expr_id: @@ -1287,6 +1655,11 @@ p = isl_printer_print_ast_node(p, node->u.f.body); } break; + case isl_ast_node_mark: + p = isl_printer_print_str(p, "mark: "); + p = isl_printer_print_id(p, node->u.m.mark); + p = isl_printer_print_str(p, "node: "); + p = isl_printer_print_ast_node(p, node->u.m.node); case isl_ast_node_user: p = isl_printer_print_ast_expr(p, node->u.e.expr); break; @@ -1307,7 +1680,7 @@ case isl_ast_node_block: p = isl_printer_print_ast_node_list(p, node->u.b.children); break; - default: + case isl_ast_node_error: break; } p = isl_printer_print_str(p, ")"); @@ -1320,14 +1693,29 @@ * Also if the node is a degenerate for then we will print it as * an assignment followed by the body of the for loop, so we need a block * as well. + * If the node is an if node with an else, then we print a block + * to avoid spurious dangling else warnings emitted by some compilers. + * If the node is a mark, then in principle, we would have to check + * the child of the mark node. However, even if the child would not + * require us to print a block, for readability it is probably best + * to print a block anyway. + * If the ast_always_print_block option has been set, then we print a block. */ static int need_block(__isl_keep isl_ast_node *node) { + isl_ctx *ctx; + if (node->type == isl_ast_node_block) return 1; if (node->type == isl_ast_node_for && node->u.f.degenerate) return 1; - return 0; + if (node->type == isl_ast_node_if && node->u.i.else_node) + return 1; + if (node->type == isl_ast_node_mark) + return 1; + + ctx = isl_ast_node_get_ctx(node); + return isl_options_get_ast_always_print_block(ctx); } static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p, @@ -1531,6 +1919,13 @@ if (!in_block) p = end_block(p); break; + case isl_ast_node_mark: + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, "// "); + p = isl_printer_print_str(p, isl_id_get_name(node->u.m.mark)); + p = isl_printer_end_line(p); + p = print_ast_node_c(p, node->u.m.node, options, 0, in_list); + break; case isl_ast_node_user: if (options->print_user) return options->print_user(p, @@ -1713,6 +2108,9 @@ macros = ast_node_list_required_macros(node->u.b.children, macros); break; + case isl_ast_node_mark: + macros = ast_node_required_macros(node->u.m.node, macros); + break; case isl_ast_node_user: macros = ast_expr_required_macros(node->u.e.expr, macros); break; @@ -1772,33 +2170,33 @@ /* Call "fn" for each type of operation that appears in "node" * and that requires a macro definition. */ -int isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, - int (*fn)(enum isl_ast_op_type type, void *user), void *user) +isl_stat isl_ast_node_foreach_ast_op_type(__isl_keep isl_ast_node *node, + isl_stat (*fn)(enum isl_ast_op_type type, void *user), void *user) { int macros; if (!node) - return -1; + return isl_stat_error; macros = ast_node_required_macros(node, 0); if (macros & ISL_AST_MACRO_MIN && fn(isl_ast_op_min, user) < 0) - return -1; + return isl_stat_error; if (macros & ISL_AST_MACRO_MAX && fn(isl_ast_op_max, user) < 0) - return -1; + return isl_stat_error; if (macros & ISL_AST_MACRO_FLOORD && fn(isl_ast_op_fdiv_q, user) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } -static int ast_op_type_print_macro(enum isl_ast_op_type type, void *user) +static isl_stat ast_op_type_print_macro(enum isl_ast_op_type type, void *user) { isl_printer **p = user; *p = isl_ast_op_type_print_macro(type, *p); - return 0; + return isl_stat_ok; } /* Print macro definitions for all the macros used in the result diff -Nru isl-0.12.2/isl_ast_codegen.c isl-0.15/isl_ast_codegen.c --- isl-0.12.2/isl_ast_codegen.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ast_codegen.c 2015-06-10 18:25:33.000000000 +0000 @@ -1,17 +1,23 @@ /* - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include #include +#include #include #include +#include #include +#include #include #include #include @@ -19,47 +25,6 @@ #include #include -/* Add the constraint to the list that "user" points to, if it is not - * a div constraint. - */ -static int collect_constraint(__isl_take isl_constraint *constraint, - void *user) -{ - isl_constraint_list **list = user; - - if (isl_constraint_is_div_constraint(constraint)) - isl_constraint_free(constraint); - else - *list = isl_constraint_list_add(*list, constraint); - - return 0; -} - -/* Extract the constraints of "bset" (except the div constraints) - * and collect them in an isl_constraint_list. - */ -static __isl_give isl_constraint_list *isl_constraint_list_from_basic_set( - __isl_take isl_basic_set *bset) -{ - int n; - isl_ctx *ctx; - isl_constraint_list *list; - - if (!bset) - return NULL; - - ctx = isl_basic_set_get_ctx(bset); - - n = isl_basic_set_n_constraint(bset); - list = isl_constraint_list_alloc(ctx, n); - if (isl_basic_set_foreach_constraint(bset, - &collect_constraint, &list) < 0) - list = isl_constraint_list_free(list); - - isl_basic_set_free(bset); - return list; -} - /* Data used in generate_domain. * * "build" is the input build. @@ -97,7 +62,7 @@ * but will instead create calls to all elements of D that need * to be executed from the current schedule domain. */ -static int generate_non_single_valued(__isl_take isl_map *executed, +static isl_stat generate_non_single_valued(__isl_take isl_map *executed, struct isl_generate_domain_data *data) { isl_map *identity; @@ -114,7 +79,7 @@ data->list = isl_ast_graft_list_concat(data->list, list); - return 0; + return isl_stat_ok; } /* Call the at_each_domain callback, if requested by the user, @@ -145,7 +110,7 @@ } /* Generate an AST for a single domain based on - * the inverse schedule "executed". + * the inverse schedule "executed" and add it to data->list. * * If there is more than one domain element associated to the current * schedule "time", then we need to continue the generation process @@ -153,7 +118,12 @@ * Note that the inverse schedule being single-valued may depend * on constraints that are only available in the original context * domain specified by the user. We therefore first introduce - * the constraints from data->build->domain. + * some of the constraints of data->build->domain. In particular, + * we intersect with a single-disjunct approximation of this set. + * We perform this approximation to avoid further splitting up + * the executed relation, possibly introducing a disjunctive guard + * on the statement. + * * On the other hand, we only perform the test after having taken the gist * of the domain as the resulting map is the one from which the call * expression is constructed. Using this map to construct the call @@ -171,20 +141,38 @@ * domain element and put a guard around it based on the (simplified) * domain of "executed". * + * At this stage, any pending constraints in the build can no longer + * be simplified with respect to any enforced constraints since + * the call node does not have any enforced constraints. + * We therefore turn all pending constraints into guards + * (after simplifying them with respect to the already generated + * constraints) and add them to both the generated constraints + * and the guard of the constructed graft. This guard will ensure + * that the constraints are effectively generated. + * * If the user has set an at_each_domain callback, it is called * on the constructed call expression node. */ -static int generate_domain(__isl_take isl_map *executed, void *user) +static isl_stat generate_domain(__isl_take isl_map *executed, void *user) { struct isl_generate_domain_data *data = user; + isl_ast_build *build; isl_ast_graft *graft; isl_ast_graft_list *list; - isl_set *guard; - isl_map *map; - int sv; - - executed = isl_map_intersect_domain(executed, - isl_set_copy(data->build->domain)); + isl_set *guard, *domain; + isl_map *map = NULL; + int empty, sv; + + domain = isl_ast_build_get_domain(data->build); + domain = isl_set_from_basic_set(isl_set_simple_hull(domain)); + executed = isl_map_intersect_domain(executed, domain); + empty = isl_map_is_empty(executed); + if (empty < 0) + goto error; + if (empty) { + isl_map_free(executed); + return isl_stat_ok; + } executed = isl_map_coalesce(executed); map = isl_map_copy(executed); @@ -200,22 +188,30 @@ return generate_non_single_valued(executed, data); } guard = isl_map_domain(isl_map_copy(map)); + guard = isl_set_compute_divs(guard); + guard = isl_set_intersect(guard, + isl_ast_build_get_pending(data->build)); guard = isl_set_coalesce(guard); - guard = isl_ast_build_compute_gist(data->build, guard); - graft = isl_ast_graft_alloc_domain(map, data->build); - graft = at_each_domain(graft, executed, data->build); + guard = isl_ast_build_specialize(data->build, guard); + guard = isl_set_gist(guard, isl_ast_build_get_generated(data->build)); + build = isl_ast_build_copy(data->build); + build = isl_ast_build_replace_pending_by_guard(build, + isl_set_copy(guard)); + graft = isl_ast_graft_alloc_domain(map, build); + graft = at_each_domain(graft, executed, build); + isl_ast_build_free(build); isl_map_free(executed); graft = isl_ast_graft_add_guard(graft, guard, data->build); list = isl_ast_graft_list_from_ast_graft(graft); data->list = isl_ast_graft_list_concat(data->list, list); - return 0; + return isl_stat_ok; error: isl_map_free(map); isl_map_free(executed); - return -1; + return isl_stat_error; } /* Call build->create_leaf to a create "leaf" node in the AST, @@ -224,6 +220,10 @@ * * Note that the node returned by the user may be an entire tree. * + * Since the node itself cannot enforce any constraints, we turn + * all pending constraints into guards and add them to the resulting + * graft to ensure that they will be generated. + * * Before we pass control to the user, we first clear some information * from the build that is (presumbably) only meaningful * for the current code generation. @@ -233,11 +233,15 @@ static __isl_give isl_ast_graft_list *call_create_leaf( __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) { + isl_set *guard; isl_ast_node *node; isl_ast_graft *graft; isl_ast_build *user_build; + guard = isl_ast_build_get_pending(build); user_build = isl_ast_build_copy(build); + user_build = isl_ast_build_replace_pending_by_guard(user_build, + isl_set_copy(guard)); user_build = isl_ast_build_set_executed(user_build, executed); user_build = isl_ast_build_clear_local_info(user_build); if (!user_build) @@ -245,12 +249,20 @@ else node = build->create_leaf(user_build, build->create_leaf_user); graft = isl_ast_graft_alloc(node, build); + graft = isl_ast_graft_add_guard(graft, guard, build); isl_ast_build_free(build); return isl_ast_graft_list_from_ast_graft(graft); } +static __isl_give isl_ast_graft_list *build_ast_from_child( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed); + /* Generate an AST after having handled the complete schedule - * of this call to the code generator. + * of this call to the code generator or the complete band + * if we are generating an AST from a schedule tree. + * + * If we are inside a band node, then move on to the child of the band. * * If the user has specified a create_leaf callback, control * is passed to the user in call_create_leaf. @@ -267,6 +279,13 @@ if (!build || !executed) goto error; + if (isl_ast_build_has_schedule_node(build)) { + isl_schedule_node *node; + node = isl_ast_build_get_schedule_node(build); + build = isl_ast_build_reset_schedule_node(build); + return build_ast_from_child(build, node, executed); + } + if (build->create_leaf) return call_create_leaf(executed, build); @@ -300,7 +319,7 @@ /* Call the after_each_for callback, if requested by the user. */ -static __isl_give isl_ast_graft *after_each_for(__isl_keep isl_ast_graft *graft, +static __isl_give isl_ast_graft *after_each_for(__isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build) { if (!graft || !build) @@ -439,10 +458,95 @@ return pa; } +/* Callback for sorting the isl_pw_aff_list passed to reduce_list and + * remove_redundant_lower_bounds. + */ +static int reduce_list_cmp(__isl_keep isl_pw_aff *a, __isl_keep isl_pw_aff *b, + void *user) +{ + return isl_pw_aff_plain_cmp(a, b); +} + +/* Given a list of lower bounds "list", remove those that are redundant + * with respect to the other bounds in "list" and the domain of "build". + * + * We first sort the bounds in the same way as they would be sorted + * by set_for_node_expressions so that we can try and remove the last + * bounds first. + * + * For a lower bound to be effective, there needs to be at least + * one domain element for which it is larger than all other lower bounds. + * For each lower bound we therefore intersect the domain with + * the conditions that it is larger than all other bounds and + * check whether the result is empty. If so, the bound can be removed. + */ +static __isl_give isl_pw_aff_list *remove_redundant_lower_bounds( + __isl_take isl_pw_aff_list *list, __isl_keep isl_ast_build *build) +{ + int i, j, n; + isl_set *domain; + + list = isl_pw_aff_list_sort(list, &reduce_list_cmp, NULL); + if (!list) + return NULL; + + n = isl_pw_aff_list_n_pw_aff(list); + if (n <= 1) + return list; + + domain = isl_ast_build_get_domain(build); + + for (i = n - 1; i >= 0; --i) { + isl_pw_aff *pa_i; + isl_set *domain_i; + int empty; + + domain_i = isl_set_copy(domain); + pa_i = isl_pw_aff_list_get_pw_aff(list, i); + + for (j = 0; j < n; ++j) { + isl_pw_aff *pa_j; + isl_set *better; + + if (j == i) + continue; + + pa_j = isl_pw_aff_list_get_pw_aff(list, j); + better = isl_pw_aff_gt_set(isl_pw_aff_copy(pa_i), pa_j); + domain_i = isl_set_intersect(domain_i, better); + } + + empty = isl_set_is_empty(domain_i); + + isl_set_free(domain_i); + isl_pw_aff_free(pa_i); + + if (empty < 0) + goto error; + if (!empty) + continue; + list = isl_pw_aff_list_drop(list, i, 1); + n--; + } + + isl_set_free(domain); + + return list; +error: + isl_set_free(domain); + return isl_pw_aff_list_free(list); +} + /* Extract a lower bound on dimension "pos" from each constraint * in "constraints" and return the list of lower bounds. * If "constraints" has zero elements, then we extract a lower bound * from "domain" instead. + * + * If the current dimension is strided, then the lower bound + * is adjusted by lower_bound to match the stride information. + * This modification may make one or more lower bounds redundant + * with respect to the other lower bounds. We therefore check + * for this condition and remove the redundant lower bounds. */ static __isl_give isl_pw_aff_list *lower_bounds( __isl_keep isl_constraint_list *constraints, int pos, @@ -475,6 +579,9 @@ list = isl_pw_aff_list_add(list, isl_pw_aff_from_aff(aff)); } + if (isl_ast_build_has_stride(build, pos)) + list = remove_redundant_lower_bounds(list, build); + return list; } @@ -521,6 +628,8 @@ * The list is assumed to contain at least one element. * If the list contains exactly one element, then the returned isl_ast_expr * simply computes that affine expression. + * If the list contains more than one element, then we sort it + * using a fairly abitrary but hopefully reasonably stable order. */ static __isl_give isl_ast_expr *reduce_list(enum isl_ast_op_type type, __isl_keep isl_pw_aff_list *list, __isl_keep isl_ast_build *build) @@ -543,83 +652,89 @@ if (!expr) return NULL; + list = isl_pw_aff_list_copy(list); + list = isl_pw_aff_list_sort(list, &reduce_list_cmp, NULL); + if (!list) + return isl_ast_expr_free(expr); + for (i = 0; i < n; ++i) { isl_ast_expr *expr_i; expr_i = isl_ast_build_expr_from_pw_aff_internal(build, isl_pw_aff_list_get_pw_aff(list, i)); if (!expr_i) - return isl_ast_expr_free(expr); + goto error; expr->u.op.args[i] = expr_i; } + isl_pw_aff_list_free(list); return expr; +error: + isl_pw_aff_list_free(list); + isl_ast_expr_free(expr); + return NULL; } -/* Add a guard to "graft" based on "bound" in the case of a degenerate - * level (including the special case of an eliminated level). - * - * We eliminate the current dimension, simplify the result in the current - * build and add the result as guards to the graft. - * - * Note that we cannot simply drop the constraints on the current dimension - * even in the eliminated case, because the single affine expression may - * not be explicitly available in "bounds". Moreover, the single affine - * expression may only be defined on a subset of the build domain, - * so we do in some cases need to insert a guard even in the eliminated case. +/* Add guards implied by the "generated constraints", + * but not (necessarily) enforced by the generated AST to "guard". + * In particular, if there is any stride constraints, + * then add the guard implied by those constraints. + * If we have generated a degenerate loop, then add the guard + * implied by "bounds" on the outer dimensions, i.e., the guard + * that ensures that the single value actually exists. + * Since there may also be guards implied by a combination + * of these constraints, we first combine them before + * deriving the implied constraints. */ -static __isl_give isl_ast_graft *add_degenerate_guard( - __isl_take isl_ast_graft *graft, __isl_keep isl_basic_set *bounds, +static __isl_give isl_set *add_implied_guards(__isl_take isl_set *guard, + int degenerate, __isl_keep isl_basic_set *bounds, __isl_keep isl_ast_build *build) { - int depth; - isl_set *dom; + int depth, has_stride; + isl_space *space; + isl_set *dom, *set; depth = isl_ast_build_get_depth(build); - - dom = isl_set_from_basic_set(isl_basic_set_copy(bounds)); - if (isl_ast_build_has_stride(build, depth)) { - isl_set *stride; - - stride = isl_ast_build_get_stride_constraint(build); - dom = isl_set_intersect(dom, stride); + has_stride = isl_ast_build_has_stride(build, depth); + if (!has_stride && !degenerate) + return guard; + + space = isl_basic_set_get_space(bounds); + dom = isl_set_universe(space); + + if (degenerate) { + bounds = isl_basic_set_copy(bounds); + bounds = isl_basic_set_drop_constraints_not_involving_dims( + bounds, isl_dim_set, depth, 1); + set = isl_set_from_basic_set(bounds); + dom = isl_set_intersect(dom, set); + } + + if (has_stride) { + set = isl_ast_build_get_stride_constraint(build); + dom = isl_set_intersect(dom, set); } + dom = isl_set_eliminate(dom, isl_dim_set, depth, 1); dom = isl_ast_build_compute_gist(build, dom); + guard = isl_set_intersect(guard, dom); - graft = isl_ast_graft_add_guard(graft, dom, build); - - return graft; -} - -/* Update "graft" based on "bounds" for the eliminated case. - * - * In the eliminated case, no for node is created, so we only need - * to check if "bounds" imply any guards that need to be inserted. - */ -static __isl_give isl_ast_graft *refine_eliminated( - __isl_take isl_ast_graft *graft, __isl_keep isl_basic_set *bounds, - __isl_keep isl_ast_build *build) -{ - return add_degenerate_guard(graft, bounds, build); + return guard; } -/* Update "graft" based on "bounds" and "sub_build" for the degenerate case. +/* Update "graft" based on "sub_build" for the degenerate case. * * "build" is the build in which graft->node was created * "sub_build" contains information about the current level itself, * including the single value attained. * - * We first set the initialization part of the for loop to the single + * We set the initialization part of the for loop to the single * value attained by the current dimension. * The increment and condition are not strictly needed as the are known * to be "1" and "iterator <= value" respectively. - * Then we set the size of the iterator and - * check if "bounds" imply any guards that need to be inserted. */ static __isl_give isl_ast_graft *refine_degenerate( - __isl_take isl_ast_graft *graft, __isl_keep isl_basic_set *bounds, - __isl_keep isl_ast_build *build, + __isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build, __isl_keep isl_ast_build *sub_build) { isl_pw_aff *value; @@ -634,8 +749,6 @@ if (!graft->node->u.f.init) return isl_ast_graft_free(graft); - graft = add_degenerate_guard(graft, bounds, build); - return graft; } @@ -761,7 +874,7 @@ /* Does "aff" have a negative constant term? */ -static int aff_constant_is_negative(__isl_take isl_set *set, +static isl_stat aff_constant_is_negative(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user) { int *neg = user; @@ -773,20 +886,21 @@ isl_set_free(set); isl_aff_free(aff); - return *neg ? 0 : -1; + return *neg ? isl_stat_ok : isl_stat_error; } /* Does "pa" have a negative constant term over its entire domain? */ -static int pw_aff_constant_is_negative(__isl_take isl_pw_aff *pa, void *user) +static isl_stat pw_aff_constant_is_negative(__isl_take isl_pw_aff *pa, + void *user) { - int r; + isl_stat r; int *neg = user; r = isl_pw_aff_foreach_piece(pa, &aff_constant_is_negative, user); isl_pw_aff_free(pa); - return *neg ? 0 : -1; + return (*neg && r >= 0) ? isl_stat_ok : isl_stat_error; } /* Does each element in "list" have a negative constant term? @@ -890,7 +1004,7 @@ if (!graft) return NULL; - cond = isl_ast_build_expr_from_set(build, isl_set_copy(set)); + cond = isl_ast_build_expr_from_set_internal(build, isl_set_copy(set)); graft->node->u.f.cond = cond; if (!graft->node->u.f.cond) return isl_ast_graft_free(graft); @@ -950,7 +1064,6 @@ * * In particular, * - set the initialization part of the loop to the maximum of the lower bounds - * - set the size of the iterator based on the values attained by the iterator * - extract the increment from the stride of the current dimension * - construct the for condition either based on a list of upper bounds * or on a set of upper bound constraints. @@ -966,8 +1079,6 @@ return NULL; build = isl_ast_build_copy(build); - build = isl_ast_build_set_enforced(build, - isl_ast_graft_get_enforced(graft)); node = graft->node; node->u.f.init = reduce_list(isl_ast_op_max, lower, build); @@ -1091,7 +1202,7 @@ * on whether "c" is independenct of dimensions data->pos, * a lower bound or an upper bound. */ -static int count_constraints(__isl_take isl_constraint *c, void *user) +static isl_stat count_constraints(__isl_take isl_constraint *c, void *user) { struct isl_ast_count_constraints_data *data = user; @@ -1104,14 +1215,16 @@ isl_constraint_free(c); - return 0; + return isl_stat_ok; } /* Update "graft" based on "bounds" and "domain" for the generic, * non-degenerate, case. * * "list" respresent the list of bounds that need to be encoded by - * the for loop (or a guard around the for loop). + * the for loop. Only the constraints that involve the iterator + * are relevant here. The other constraints are taken care of by + * the caller and are included in the generated constraints of "build". * "domain" is the subset of the intersection of the constraints * for which some code is executed. * "build" is the build in which graft->node was created. @@ -1120,17 +1233,11 @@ * are independent of the loop iterator. * * The actual for loop bounds are generated in refine_generic_bounds. - * If there are any constraints that are independent of the loop iterator, - * we need to put a guard around the for loop (which may get hoisted up - * to higher levels) and we call refine_generic_bounds in a build - * where this guard is enforced. */ static __isl_give isl_ast_graft *refine_generic_split( __isl_take isl_ast_graft *graft, __isl_take isl_constraint_list *list, __isl_keep isl_set *domain, __isl_keep isl_ast_build *build) { - isl_ast_build *for_build; - isl_set *guard; struct isl_ast_count_constraints_data data; isl_constraint_list *lower; isl_constraint_list *upper; @@ -1150,54 +1257,12 @@ return isl_ast_graft_free(graft); } - lower = isl_constraint_list_copy(list); - lower = isl_constraint_list_drop(lower, 0, data.n_indep); + lower = isl_constraint_list_drop(list, 0, data.n_indep); upper = isl_constraint_list_copy(lower); lower = isl_constraint_list_drop(lower, data.n_lower, data.n_upper); upper = isl_constraint_list_drop(upper, 0, data.n_lower); - if (data.n_indep == 0) { - isl_constraint_list_free(list); - return refine_generic_bounds(graft, lower, upper, - domain, build); - } - - list = isl_constraint_list_drop(list, data.n_indep, - data.n_lower + data.n_upper); - guard = intersect_constraints(list); - isl_constraint_list_free(list); - - for_build = isl_ast_build_copy(build); - for_build = isl_ast_build_restrict_pending(for_build, - isl_set_copy(guard)); - graft = refine_generic_bounds(graft, lower, upper, domain, for_build); - isl_ast_build_free(for_build); - - graft = isl_ast_graft_add_guard(graft, guard, build); - - return graft; -} - -/* Add the guard implied by the current stride constraint (if any), - * but not (necessarily) enforced by the generated AST to "graft". - */ -static __isl_give isl_ast_graft *add_stride_guard( - __isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build) -{ - int depth; - isl_set *dom; - - depth = isl_ast_build_get_depth(build); - if (!isl_ast_build_has_stride(build, depth)) - return graft; - - dom = isl_ast_build_get_stride_constraint(build); - dom = isl_set_eliminate(dom, isl_dim_set, depth, 1); - dom = isl_ast_build_compute_gist(build, dom); - - graft = isl_ast_graft_add_guard(graft, dom, build); - - return graft; + return refine_generic_bounds(graft, lower, upper, domain, build); } /* Update "graft" based on "bounds" and "domain" for the generic, @@ -1221,12 +1286,9 @@ if (!build || !graft) return isl_ast_graft_free(graft); - bounds = isl_basic_set_copy(bounds); - bounds = isl_ast_build_compute_gist_basic_set(build, bounds); - list = isl_constraint_list_from_basic_set(bounds); + list = isl_basic_set_get_constraint_list(bounds); graft = refine_generic_split(graft, list, domain, build); - graft = add_stride_guard(graft, build); return graft; } @@ -1254,6 +1316,43 @@ return node; } +/* If the ast_build_exploit_nested_bounds option is set, then return + * the constraints enforced by all elements in "list". + * Otherwise, return the universe. + */ +static __isl_give isl_basic_set *extract_shared_enforced( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + isl_ctx *ctx; + isl_space *space; + + if (!list) + return NULL; + + ctx = isl_ast_graft_list_get_ctx(list); + if (isl_options_get_ast_build_exploit_nested_bounds(ctx)) + return isl_ast_graft_list_extract_shared_enforced(list, build); + + space = isl_ast_build_get_space(build, 1); + return isl_basic_set_universe(space); +} + +/* Return the pending constraints of "build" that are not already taken + * care of (by a combination of "enforced" and the generated constraints + * of "build"). + */ +static __isl_give isl_set *extract_pending(__isl_keep isl_ast_build *build, + __isl_keep isl_basic_set *enforced) +{ + isl_set *guard, *context; + + guard = isl_ast_build_get_pending(build); + context = isl_set_from_basic_set(isl_basic_set_copy(enforced)); + context = isl_set_intersect(context, + isl_ast_build_get_generated(build)); + return isl_set_gist(guard, context); +} + /* Create an AST node for the current dimension based on * the schedule domain "bounds" and return the node encapsulated * in an isl_ast_graft. @@ -1283,12 +1382,13 @@ * about the strides at the current level, but this information is not * reflected in the build->domain. * We first add this information and the "bounds" to the sub_build->domain. - * isl_ast_build_set_loop_bounds checks whether the current dimension attains + * isl_ast_build_set_loop_bounds adds the stride information and + * checks whether the current dimension attains * only a single value and whether this single value can be represented using * a single affine expression. * In the first case, the current level is considered "degenerate". * In the second, sub-case, the current level is considered "eliminated". - * Eliminated level don't need to be reflected in the AST since we can + * Eliminated levels don't need to be reflected in the AST since we can * simply plug in the affine expression. For degenerate, but non-eliminated, * levels, we do introduce a for node, but mark is as degenerate so that * it can be printed as an assignment of the single value to the loop @@ -1308,10 +1408,22 @@ * We then generate a sequence of grafts for the next level, * create a surrounding graft for the current level and insert * the for node we created (if the current level is not eliminated). - * - * Finally, we set the bounds of the for loop and insert guards - * (either in the AST or in the graft) in one of - * refine_eliminated, refine_degenerate or refine_generic. + * Before creating a graft for the current level, we first extract + * hoistable constraints from the child guards and combine them + * with the pending constraints in the build. These constraints + * are used to simplify the child guards and then added to the guard + * of the current graft to ensure that they will be generated. + * If the hoisted guard is a disjunction, then we use it directly + * to gist the guards on the children before intersect it with the + * pending constraints. We do so because this disjunction is typically + * identical to the guards on the children such that these guards + * can be effectively removed completely. After the intersection, + * the gist operation would have a harder time figuring this out. + * + * Finally, we set the bounds of the for loop in either + * refine_degenerate or refine_generic. + * We do so in a context where the pending constraints of the build + * have been replaced by the guard of the current graft. */ static __isl_give isl_ast_graft *create_node_scaled( __isl_take isl_union_map *executed, @@ -1321,6 +1433,8 @@ int depth; int degenerate, eliminated; isl_basic_set *hull; + isl_basic_set *enforced; + isl_set *guard, *hoisted; isl_ast_node *node = NULL; isl_ast_graft *graft; isl_ast_graft_list *children; @@ -1335,7 +1449,6 @@ depth = isl_ast_build_get_depth(build); sub_build = isl_ast_build_copy(build); - sub_build = isl_ast_build_include_stride(sub_build); sub_build = isl_ast_build_set_loop_bounds(sub_build, isl_basic_set_copy(bounds)); degenerate = isl_ast_build_has_value(sub_build); @@ -1354,15 +1467,36 @@ children = generate_next_level(executed, isl_ast_build_copy(body_build)); - graft = isl_ast_graft_alloc_level(children, build, sub_build); + enforced = extract_shared_enforced(children, build); + guard = extract_pending(sub_build, enforced); + hoisted = isl_ast_graft_list_extract_hoistable_guard(children, build); + if (isl_set_n_basic_set(hoisted) > 1) + children = isl_ast_graft_list_gist_guards(children, + isl_set_copy(hoisted)); + guard = isl_set_intersect(guard, hoisted); if (!eliminated) + guard = add_implied_guards(guard, degenerate, bounds, build); + + graft = isl_ast_graft_alloc_from_children(children, + isl_set_copy(guard), enforced, build, sub_build); + + if (!degenerate) + bounds = isl_ast_build_compute_gist_basic_set(build, bounds); + if (!eliminated) { + isl_ast_build *for_build; + graft = isl_ast_graft_insert_for(graft, node); - if (eliminated) - graft = refine_eliminated(graft, bounds, build); - else if (degenerate) - graft = refine_degenerate(graft, bounds, build, sub_build); - else - graft = refine_generic(graft, bounds, domain, build); + for_build = isl_ast_build_copy(build); + for_build = isl_ast_build_replace_pending_by_guard(for_build, + isl_set_copy(guard)); + if (degenerate) + graft = refine_degenerate(graft, for_build, sub_build); + else + graft = refine_generic(graft, bounds, + domain, for_build); + isl_ast_build_free(for_build); + } + isl_set_free(guard); if (!eliminated) graft = after_each_for(graft, body_build); @@ -1391,7 +1525,8 @@ * reducing data->m if needed. * Break out of the iteration if data->m has become equal to "1". */ -static int constraint_check_scaled(__isl_take isl_constraint *c, void *user) +static isl_stat constraint_check_scaled(__isl_take isl_constraint *c, + void *user) { struct isl_check_scaled_data *data = user; int i, j, n; @@ -1400,7 +1535,7 @@ if (!isl_constraint_involves_dims(c, isl_dim_in, data->depth, 1)) { isl_constraint_free(c); - return 0; + return isl_stat_ok; } for (i = 0; i < 4; ++i) { @@ -1423,7 +1558,7 @@ isl_constraint_free(c); - return i < 4 ? -1 : 0; + return i < 4 ? isl_stat_error : isl_stat_ok; } /* For each constraint of "bmap" that involves the input dimension data->depth, @@ -1431,9 +1566,10 @@ * reducing data->m if needed. * Break out of the iteration if data->m has become equal to "1". */ -static int basic_map_check_scaled(__isl_take isl_basic_map *bmap, void *user) +static isl_stat basic_map_check_scaled(__isl_take isl_basic_map *bmap, + void *user) { - int r; + isl_stat r; r = isl_basic_map_foreach_constraint(bmap, &constraint_check_scaled, user); @@ -1447,9 +1583,9 @@ * reducing data->m if needed. * Break out of the iteration if data->m has become equal to "1". */ -static int map_check_scaled(__isl_take isl_map *map, void *user) +static isl_stat map_check_scaled(__isl_take isl_map *map, void *user) { - int r; + isl_stat r; r = isl_map_foreach_basic_map(map, &basic_map_check_scaled, user); isl_map_free(map); @@ -1475,7 +1611,7 @@ * * f + s a * - * with a an integer. We check if we can find an integer m that (obviouly) + * with a an integer. We check if we can find an integer m that (obviously) * divides both f and s. * * If so, we check if the current dimension only appears in constraints @@ -1570,13 +1706,13 @@ /* Add the basic set to the list that "user" points to. */ -static int collect_basic_set(__isl_take isl_basic_set *bset, void *user) +static isl_stat collect_basic_set(__isl_take isl_basic_set *bset, void *user) { isl_basic_set_list **list = user; *list = isl_basic_set_list_add(*list, bset); - return 0; + return isl_stat_ok; } /* Extract the basic sets of "set" and collect them in an isl_basic_set_list. @@ -1605,7 +1741,8 @@ /* Generate code for the schedule domain "bounds" * and add the result to "list". * - * We mainly detect strides and additional equalities here + * We mainly detect strides here and check if the bounds do not + * conflict with the current build domain * and then pass over control to create_node. * * "bounds" reflects the bounds on the current dimension and possibly @@ -1622,7 +1759,7 @@ isl_ast_graft *graft; isl_set *domain = NULL; isl_union_set *uset; - int empty; + int empty, disjoint; uset = isl_union_set_from_basic_set(isl_basic_set_copy(bounds)); executed = isl_union_map_intersect_domain(executed, uset); @@ -1634,14 +1771,16 @@ uset = isl_union_map_domain(isl_union_map_copy(executed)); domain = isl_set_from_union_set(uset); - domain = isl_ast_build_compute_gist(build, domain); - empty = isl_set_is_empty(domain); - if (empty < 0) + domain = isl_ast_build_specialize(build, domain); + + domain = isl_set_compute_divs(domain); + domain = isl_ast_build_eliminate_inner(build, domain); + disjoint = isl_set_is_disjoint(domain, build->domain); + if (disjoint < 0) goto error; - if (empty) + if (disjoint) goto done; - domain = isl_ast_build_eliminate_inner(build, domain); build = isl_ast_build_detect_strides(build, isl_set_copy(domain)); graft = create_node(executed, bounds, domain, @@ -1662,12 +1801,12 @@ /* Does any element of i follow or coincide with any element of j * at the current depth for equal values of the outer dimensions? */ -static int domain_follows_at_depth(__isl_keep isl_basic_set *i, +static isl_bool domain_follows_at_depth(__isl_keep isl_basic_set *i, __isl_keep isl_basic_set *j, void *user) { int depth = *(int *) user; isl_basic_map *test; - int empty; + isl_bool empty; int l; test = isl_basic_map_from_domain_and_range(isl_basic_set_copy(i), @@ -1680,7 +1819,7 @@ empty = isl_basic_map_is_empty(test); isl_basic_map_free(test); - return empty < 0 ? -1 : !empty; + return empty < 0 ? isl_bool_error : !empty; } /* Split up each element of "list" into a part that is related to "bset" @@ -1694,6 +1833,9 @@ int i, n; isl_basic_set_list *res; + if (!list) + bset = isl_basic_set_free(bset); + gt = isl_basic_map_copy(gt); gt = isl_basic_map_intersect_domain(gt, isl_basic_set_copy(bset)); n = isl_basic_set_list_n_basic_set(list); @@ -1776,12 +1918,16 @@ * we split off that part of the basic set i that shares the outer dimensions * with j and lies before j in the current dimension. * We collect all the pieces in a new list that replaces "scc". + * + * While the elements in "scc" should be disjoint, we double-check + * this property to avoid running into an infinite recursion in case + * they intersect due to some internal error. */ -static int add_nodes(__isl_take isl_basic_set_list *scc, void *user) +static isl_stat add_nodes(__isl_take isl_basic_set_list *scc, void *user) { struct isl_add_nodes_data *data = user; int i, n, depth; - isl_basic_set *bset; + isl_basic_set *bset, *first; isl_basic_set_list *list; isl_space *space; isl_basic_map *gt; @@ -1793,7 +1939,7 @@ data->list = add_node(data->list, isl_union_map_copy(data->executed), bset, isl_ast_build_copy(data->build)); - return data->list ? 0 : -1; + return data->list ? isl_stat_ok : isl_stat_error; } depth = isl_ast_build_get_depth(data->build); @@ -1804,11 +1950,25 @@ gt = isl_basic_map_equate(gt, isl_dim_in, i, isl_dim_out, i); gt = isl_basic_map_order_gt(gt, isl_dim_in, depth, isl_dim_out, depth); + first = isl_basic_set_copy(bset); list = isl_basic_set_list_from_basic_set(bset); for (i = 1; i < n; ++i) { + int disjoint; + bset = isl_basic_set_list_get_basic_set(scc, i); + + disjoint = isl_basic_set_is_disjoint(bset, first); + if (disjoint < 0) + list = isl_basic_set_list_free(list); + else if (!disjoint) + isl_die(isl_basic_set_list_get_ctx(scc), + isl_error_internal, + "basic sets in scc are assumed to be disjoint", + list = isl_basic_set_list_free(list)); + list = add_split_on(list, bset, gt); } + isl_basic_set_free(first); isl_basic_map_free(gt); isl_basic_set_list_free(scc); scc = list; @@ -1816,7 +1976,7 @@ generate_sorted_domains(scc, data->executed, data->build)); isl_basic_set_list_free(scc); - return data->list ? 0 : -1; + return data->list ? isl_stat_ok : isl_stat_error; } /* Sort the domains in "domain_list" according to the execution order @@ -1867,12 +2027,12 @@ /* Do i and j share any values for the outer dimensions? */ -static int shared_outer(__isl_keep isl_basic_set *i, +static isl_bool shared_outer(__isl_keep isl_basic_set *i, __isl_keep isl_basic_set *j, void *user) { int depth = *(int *) user; isl_basic_map *test; - int empty; + isl_bool empty; int l; test = isl_basic_map_from_domain_and_range(isl_basic_set_copy(i), @@ -1883,7 +2043,7 @@ empty = isl_basic_map_is_empty(test); isl_basic_map_free(test); - return empty < 0 ? -1 : !empty; + return empty < 0 ? isl_bool_error : !empty; } /* Internal data structure for generate_sorted_domains_wrap. @@ -1914,7 +2074,7 @@ * then data->single is set to 1 and the result of generate_sorted_domains * is not fused. */ -static int generate_sorted_domains_wrap(__isl_take isl_basic_set_list *scc, +static isl_stat generate_sorted_domains_wrap(__isl_take isl_basic_set_list *scc, void *user) { struct isl_ast_generate_parallel_domains_data *data = user; @@ -1931,9 +2091,9 @@ isl_basic_set_list_free(scc); if (!data->list) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Look for any (weakly connected) components in the "domain_list" @@ -2045,7 +2205,7 @@ * and then add that part of the range of "map" that does not intersect * with data->domain. */ -static int separate_domain(__isl_take isl_map *map, void *user) +static isl_stat separate_domain(__isl_take isl_map *map, void *user) { struct isl_separate_domain_data *data = user; isl_set *domain; @@ -2064,7 +2224,7 @@ data->domain = isl_set_union(data->domain, d1); data->domain = isl_set_union(data->domain, d2); - return 0; + return isl_stat_ok; } /* Separate the schedule domains of "executed". @@ -2095,22 +2255,143 @@ /* Temporary data used during the search for a lower bound for unrolling. * + * "build" is the build in which the unrolling will be performed * "domain" is the original set for which to find a lower bound * "depth" is the dimension for which to find a lower boudn + * "expansion" is the expansion that needs to be applied to "domain" + * in the unrolling that will be performed * * "lower" is the best lower bound found so far. It is NULL if we have not * found any yet. * "n" is the corresponding size. If lower is NULL, then the value of n * is undefined. + * "n_div" is the maximal number of integer divisions in the first + * unrolled iteration (after expansion). It is set to -1 if it hasn't + * been computed yet. */ struct isl_find_unroll_data { + isl_ast_build *build; isl_set *domain; int depth; + isl_basic_map *expansion; isl_aff *lower; int *n; + int n_div; }; +/* Return the constraint + * + * i_"depth" = aff + offset + */ +static __isl_give isl_constraint *at_offset(int depth, __isl_keep isl_aff *aff, + int offset) +{ + aff = isl_aff_copy(aff); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, depth, -1); + aff = isl_aff_add_constant_si(aff, offset); + return isl_equality_from_aff(aff); +} + +/* Update *user to the number of integer divsions in the first element + * of "ma", if it is larger than the current value. + */ +static isl_stat update_n_div(__isl_take isl_set *set, + __isl_take isl_multi_aff *ma, void *user) +{ + isl_aff *aff; + int *n = user; + int n_div; + + aff = isl_multi_aff_get_aff(ma, 0); + n_div = isl_aff_dim(aff, isl_dim_div); + isl_aff_free(aff); + isl_multi_aff_free(ma); + isl_set_free(set); + + if (n_div > *n) + *n = n_div; + + return aff ? isl_stat_ok : isl_stat_error; +} + +/* Get the number of integer divisions in the expression for the iterator + * value at the first slice in the unrolling based on lower bound "lower", + * taking into account the expansion that needs to be performed on this slice. + */ +static int get_expanded_n_div(struct isl_find_unroll_data *data, + __isl_keep isl_aff *lower) +{ + isl_constraint *c; + isl_set *set; + isl_map *it_map, *expansion; + isl_pw_multi_aff *pma; + int n; + + c = at_offset(data->depth, lower, 0); + set = isl_set_copy(data->domain); + set = isl_set_add_constraint(set, c); + expansion = isl_map_from_basic_map(isl_basic_map_copy(data->expansion)); + set = isl_set_apply(set, expansion); + it_map = isl_ast_build_map_to_iterator(data->build, set); + pma = isl_pw_multi_aff_from_map(it_map); + n = 0; + if (isl_pw_multi_aff_foreach_piece(pma, &update_n_div, &n) < 0) + n = -1; + isl_pw_multi_aff_free(pma); + + return n; +} + +/* Is the lower bound "lower" with corresponding iteration count "n" + * better than the one stored in "data"? + * If there is no upper bound on the iteration count ("n" is infinity) or + * if the count is too large, then we cannot use this lower bound. + * Otherwise, if there was no previous lower bound or + * if the iteration count of the new lower bound is smaller than + * the iteration count of the previous lower bound, then we consider + * the new lower bound to be better. + * If the iteration count is the same, then compare the number + * of integer divisions that would be needed to express + * the iterator value at the first slice in the unrolling + * according to the lower bound. If we end up computing this + * number, then store the lowest value in data->n_div. + */ +static int is_better_lower_bound(struct isl_find_unroll_data *data, + __isl_keep isl_aff *lower, __isl_keep isl_val *n) +{ + int cmp; + int n_div; + + if (!n) + return -1; + if (isl_val_is_infty(n)) + return 0; + if (isl_val_cmp_si(n, INT_MAX) > 0) + return 0; + if (!data->lower) + return 1; + cmp = isl_val_cmp_si(n, *data->n); + if (cmp < 0) + return 1; + if (cmp > 0) + return 0; + if (data->n_div < 0) + data->n_div = get_expanded_n_div(data, data->lower); + if (data->n_div < 0) + return -1; + if (data->n_div == 0) + return 0; + n_div = get_expanded_n_div(data, lower); + if (n_div < 0) + return -1; + if (n_div >= data->n_div) + return 0; + data->n_div = n_div; + + return 1; +} + /* Check if we can use "c" as a lower bound and if it is better than * any previously found lower bound. * @@ -2134,17 +2415,18 @@ * * meaning that we can use ceil(f(j)/a)) as a lower bound for unrolling. * We just need to check if we have found any lower bound before and - * if the new lower bound is better (smaller n) than the previously found - * lower bounds. + * if the new lower bound is better (smaller n or fewer integer divisions) + * than the previously found lower bounds. */ -static int update_unrolling_lower_bound(struct isl_find_unroll_data *data, +static isl_stat update_unrolling_lower_bound(struct isl_find_unroll_data *data, __isl_keep isl_constraint *c) { isl_aff *aff, *lower; isl_val *max; + int better; if (!isl_constraint_is_lower_bound(c, isl_dim_set, data->depth)) - return 0; + return isl_stat_ok; lower = isl_constraint_get_bound(c, isl_dim_set, data->depth); lower = isl_aff_ceil(lower); @@ -2155,36 +2437,28 @@ max = isl_set_max_val(data->domain, aff); isl_aff_free(aff); - if (!max) - goto error; - if (isl_val_is_infty(max)) { + better = is_better_lower_bound(data, lower, max); + if (better < 0 || !better) { isl_val_free(max); isl_aff_free(lower); - return 0; + return better < 0 ? isl_stat_error : isl_stat_ok; } - if (isl_val_cmp_si(max, INT_MAX) <= 0 && - (!data->lower || isl_val_cmp_si(max, *data->n) < 0)) { - isl_aff_free(data->lower); - data->lower = lower; - *data->n = isl_val_get_num_si(max); - } else - isl_aff_free(lower); + isl_aff_free(data->lower); + data->lower = lower; + *data->n = isl_val_get_num_si(max); isl_val_free(max); - return 1; -error: - isl_aff_free(lower); - return -1; + return isl_stat_ok; } /* Check if we can use "c" as a lower bound and if it is better than * any previously found lower bound. */ -static int constraint_find_unroll(__isl_take isl_constraint *c, void *user) +static isl_stat constraint_find_unroll(__isl_take isl_constraint *c, void *user) { struct isl_find_unroll_data *data; - int r; + isl_stat r; data = (struct isl_find_unroll_data *) user; r = update_unrolling_lower_bound(data, c); @@ -2201,6 +2475,9 @@ * where d is "depth" and l(i) depends only on earlier dimensions. * Furthermore, try and find a lower bound such that n is as small as possible. * In particular, "n" needs to be finite. + * "build" is the build in which the unrolling will be performed. + * "expansion" is the expansion that needs to be applied to "domain" + * in the unrolling that will be performed. * * Inner dimensions have been eliminated from "domain" by the caller. * @@ -2214,10 +2491,12 @@ * If we cannot find a suitable lower bound, then we consider that * to be an error. */ -static __isl_give isl_aff *find_unroll_lower_bound(__isl_keep isl_set *domain, - int depth, int *n) +static __isl_give isl_aff *find_unroll_lower_bound( + __isl_keep isl_ast_build *build, __isl_keep isl_set *domain, + int depth, __isl_keep isl_basic_map *expansion, int *n) { - struct isl_find_unroll_data data = { domain, depth, NULL, n }; + struct isl_find_unroll_data data = + { build, domain, depth, expansion, NULL, n, -1 }; isl_basic_set *hull; hull = isl_set_simple_hull(isl_set_copy(domain)); @@ -2238,56 +2517,10 @@ return isl_aff_free(data.lower); } -/* Return the constraint - * - * i_"depth" = aff + offset - */ -static __isl_give isl_constraint *at_offset(int depth, __isl_keep isl_aff *aff, - int offset) -{ - aff = isl_aff_copy(aff); - aff = isl_aff_add_coefficient_si(aff, isl_dim_in, depth, -1); - aff = isl_aff_add_constant_si(aff, offset); - return isl_equality_from_aff(aff); -} - -/* Data structure for storing the results and the intermediate objects - * of compute_domains. - * - * "list" is the main result of the function and contains a list - * of disjoint basic sets for which code should be generated. - * - * "executed" and "build" are inputs to compute_domains. - * "schedule_domain" is the domain of "executed". - * - * "option" constains the domains at the current depth that should by - * atomic, separated or unrolled. These domains are as specified by - * the user, except that inner dimensions have been eliminated and - * that they have been made pair-wise disjoint. - * - * "sep_class" contains the user-specified split into separation classes - * specialized to the current depth. - * "done" contains the union of the separation domains that have already - * been handled. - */ -struct isl_codegen_domains { - isl_basic_set_list *list; - - isl_union_map *executed; - isl_ast_build *build; - isl_set *schedule_domain; - - isl_set *option[3]; - - isl_map *sep_class; - isl_set *done; -}; - -/* Extend domains->list with a list of basic sets, one for each value - * of the current dimension in "domain" and remove the corresponding - * sets from the class domain. Return the updated class domain. - * The divs that involve the current dimension have not been projected out - * from this domain. +/* Call "fn" on each iteration of the current dimension of "domain". + * If "init" is not NULL, then it is called with the number of + * iterations before any call to "fn". + * Return -1 on failure. * * Since we are going to be iterating over the individual values, * we first check if there are any strides on the current dimension. @@ -2315,52 +2548,44 @@ * will be taken into account at the next level, as in the case of the * atomic option. * - * Finally, we map i' back to i and add each basic set to the list. - * Since we may have dropped some constraints, we intersect with - * the class domain again to ensure that each element in the list - * is disjoint from the other class domains. + * Finally, we map i' back to i and call "fn". */ -static __isl_give isl_set *do_unroll(struct isl_codegen_domains *domains, - __isl_take isl_set *domain, __isl_take isl_set *class_domain) +static int foreach_iteration(__isl_take isl_set *domain, + __isl_keep isl_ast_build *build, int (*init)(int n, void *user), + int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user) { int i, n; int depth; - isl_ctx *ctx; - isl_aff *lower; isl_multi_aff *expansion; isl_basic_map *bmap; - isl_set *unroll_domain; - isl_ast_build *build; + isl_aff *lower; + isl_ast_build *stride_build; - if (!domain) - return isl_set_free(class_domain); + depth = isl_ast_build_get_depth(build); - ctx = isl_set_get_ctx(domain); - depth = isl_ast_build_get_depth(domains->build); - build = isl_ast_build_copy(domains->build); domain = isl_ast_build_eliminate_inner(build, domain); - build = isl_ast_build_detect_strides(build, isl_set_copy(domain)); - expansion = isl_ast_build_get_stride_expansion(build); + domain = isl_set_intersect(domain, isl_ast_build_get_domain(build)); + stride_build = isl_ast_build_copy(build); + stride_build = isl_ast_build_detect_strides(stride_build, + isl_set_copy(domain)); + expansion = isl_ast_build_get_stride_expansion(stride_build); domain = isl_set_preimage_multi_aff(domain, isl_multi_aff_copy(expansion)); - domain = isl_ast_build_eliminate_divs(build, domain); - - isl_ast_build_free(build); - - lower = find_unroll_lower_bound(domain, depth, &n); - if (!lower) - class_domain = isl_set_free(class_domain); + domain = isl_ast_build_eliminate_divs(stride_build, domain); + isl_ast_build_free(stride_build); bmap = isl_basic_map_from_multi_aff(expansion); - unroll_domain = isl_set_empty(isl_set_get_space(domain)); - - for (i = 0; class_domain && i < n; ++i) { + lower = find_unroll_lower_bound(build, domain, depth, bmap, &n); + if (!lower) + n = -1; + else if (init && init(n, user) < 0) + n = -1; + for (i = 0; i < n; ++i) { isl_set *set; isl_basic_set *bset; isl_constraint *slice; - isl_basic_set_list *list; slice = at_offset(depth, lower, i); set = isl_set_copy(domain); @@ -2368,20 +2593,117 @@ bset = isl_set_unshifted_simple_hull(set); bset = isl_basic_set_add_constraint(bset, slice); bset = isl_basic_set_apply(bset, isl_basic_map_copy(bmap)); - set = isl_set_from_basic_set(bset); - unroll_domain = isl_set_union(unroll_domain, isl_set_copy(set)); - set = isl_set_intersect(set, isl_set_copy(class_domain)); - set = isl_set_make_disjoint(set); - list = isl_basic_set_list_from_set(set); - domains->list = isl_basic_set_list_concat(domains->list, list); - } - class_domain = isl_set_subtract(class_domain, unroll_domain); + if (fn(bset, user) < 0) + break; + } isl_aff_free(lower); isl_set_free(domain); isl_basic_map_free(bmap); + return n < 0 || i < n ? -1 : 0; +} + +/* Data structure for storing the results and the intermediate objects + * of compute_domains. + * + * "list" is the main result of the function and contains a list + * of disjoint basic sets for which code should be generated. + * + * "executed" and "build" are inputs to compute_domains. + * "schedule_domain" is the domain of "executed". + * + * "option" constains the domains at the current depth that should by + * atomic, separated or unrolled. These domains are as specified by + * the user, except that inner dimensions have been eliminated and + * that they have been made pair-wise disjoint. + * + * "sep_class" contains the user-specified split into separation classes + * specialized to the current depth. + * "done" contains the union of the separation domains that have already + * been handled. + */ +struct isl_codegen_domains { + isl_basic_set_list *list; + + isl_union_map *executed; + isl_ast_build *build; + isl_set *schedule_domain; + + isl_set *option[4]; + + isl_map *sep_class; + isl_set *done; +}; + +/* Internal data structure for do_unroll. + * + * "domains" stores the results of compute_domains. + * "class_domain" is the original class domain passed to do_unroll. + * "unroll_domain" collects the unrolled iterations. + */ +struct isl_ast_unroll_data { + struct isl_codegen_domains *domains; + isl_set *class_domain; + isl_set *unroll_domain; +}; + +/* Given an iteration of an unrolled domain represented by "bset", + * add it to data->domains->list. + * Since we may have dropped some constraints, we intersect with + * the class domain again to ensure that each element in the list + * is disjoint from the other class domains. + */ +static int do_unroll_iteration(__isl_take isl_basic_set *bset, void *user) +{ + struct isl_ast_unroll_data *data = user; + isl_set *set; + isl_basic_set_list *list; + + set = isl_set_from_basic_set(bset); + data->unroll_domain = isl_set_union(data->unroll_domain, + isl_set_copy(set)); + set = isl_set_intersect(set, isl_set_copy(data->class_domain)); + set = isl_set_make_disjoint(set); + list = isl_basic_set_list_from_set(set); + data->domains->list = isl_basic_set_list_concat(data->domains->list, + list); + + return 0; +} + +/* Extend domains->list with a list of basic sets, one for each value + * of the current dimension in "domain" and remove the corresponding + * sets from the class domain. Return the updated class domain. + * The divs that involve the current dimension have not been projected out + * from this domain. + * + * We call foreach_iteration to iterate over the individual values and + * in do_unroll_iteration we collect the individual basic sets in + * domains->list and their union in data->unroll_domain, which is then + * used to update the class domain. + */ +static __isl_give isl_set *do_unroll(struct isl_codegen_domains *domains, + __isl_take isl_set *domain, __isl_take isl_set *class_domain) +{ + struct isl_ast_unroll_data data; + + if (!domain) + return isl_set_free(class_domain); + if (!class_domain) + return isl_set_free(domain); + + data.domains = domains; + data.class_domain = class_domain; + data.unroll_domain = isl_set_empty(isl_set_get_space(domain)); + + if (foreach_iteration(domain, domains->build, NULL, + &do_unroll_iteration, &data) < 0) + data.unroll_domain = isl_set_free(data.unroll_domain); + + class_domain = isl_set_subtract(class_domain, data.unroll_domain); + return class_domain; } @@ -2409,13 +2731,13 @@ int i, n; int empty; - empty = isl_set_is_empty(domains->option[unroll]); + empty = isl_set_is_empty(domains->option[isl_ast_loop_unroll]); if (empty < 0) return isl_set_free(class_domain); if (empty) return class_domain; - unroll_domain = isl_set_copy(domains->option[unroll]); + unroll_domain = isl_set_copy(domains->option[isl_ast_loop_unroll]); unroll_list = isl_basic_set_list_from_set(unroll_domain); n = isl_basic_set_list_n_basic_set(unroll_list); @@ -2468,7 +2790,7 @@ isl_set *domain, *atomic_domain; int empty; - domain = isl_set_copy(domains->option[atomic]); + domain = isl_set_copy(domains->option[isl_ast_loop_atomic]); domain = isl_set_intersect(domain, isl_set_copy(class_domain)); domain = isl_set_intersect(domain, isl_set_copy(domains->schedule_domain)); @@ -2515,7 +2837,7 @@ isl_basic_set_list *list; int empty; - domain = isl_set_copy(domains->option[separate]); + domain = isl_set_copy(domains->option[isl_ast_loop_separate]); domain = isl_set_intersect(domain, isl_set_copy(class_domain)); executed = isl_union_map_copy(domains->executed); executed = isl_union_map_intersect_domain(executed, @@ -2572,7 +2894,7 @@ * If anything is left after handling separate, unroll and atomic, * we split it up into basic sets and append the basic sets to domains->list. */ -static int compute_partial_domains(struct isl_codegen_domains *domains, +static isl_stat compute_partial_domains(struct isl_codegen_domains *domains, __isl_take isl_set *class_domain) { isl_basic_set_list *list; @@ -2591,7 +2913,7 @@ if (compute_separate_domain(domains, domain) < 0) goto error; domain = isl_set_subtract(domain, - isl_set_copy(domains->option[separate])); + isl_set_copy(domains->option[isl_ast_loop_separate])); domain = isl_set_intersect(domain, isl_set_copy(domains->schedule_domain)); @@ -2607,11 +2929,11 @@ isl_set_free(class_domain); - return 0; + return isl_stat_ok; error: isl_set_free(domain); isl_set_free(class_domain); - return -1; + return isl_stat_error; } /* Split up the domain at the current depth into disjoint @@ -2621,7 +2943,7 @@ * We extract the corresponding class domain from domains->sep_class, * eliminate inner dimensions and pass control to compute_partial_domains. */ -static int compute_class_domains(__isl_take isl_point *pnt, void *user) +static isl_stat compute_class_domains(__isl_take isl_point *pnt, void *user) { struct isl_codegen_domains *domains = user; isl_set *class_set; @@ -2636,10 +2958,10 @@ disjoint = isl_set_plain_is_disjoint(domain, domains->schedule_domain); if (disjoint < 0) - return -1; + return isl_stat_error; if (disjoint) { isl_set_free(domain); - return 0; + return isl_stat_ok; } return compute_partial_domains(domains, domain); @@ -2651,20 +2973,24 @@ * The domains specified by the user might overlap, so we make * them disjoint by subtracting earlier domains from later domains. */ -static void compute_domains_init_options(isl_set *option[3], +static void compute_domains_init_options(isl_set *option[4], __isl_keep isl_ast_build *build) { - enum isl_ast_build_domain_type type, type2; + enum isl_ast_loop_type type, type2; + isl_set *unroll; - for (type = atomic; type <= separate; ++type) { + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { option[type] = isl_ast_build_get_option_domain(build, type); - for (type2 = atomic; type2 < type; ++type2) + for (type2 = isl_ast_loop_atomic; type2 < type; ++type2) option[type] = isl_set_subtract(option[type], isl_set_copy(option[type2])); } - option[unroll] = isl_set_coalesce(option[unroll]); - option[unroll] = isl_set_make_disjoint(option[unroll]); + unroll = option[isl_ast_loop_unroll]; + unroll = isl_set_coalesce(unroll); + unroll = isl_set_make_disjoint(unroll); + option[isl_ast_loop_unroll] = unroll; } /* Split up the domain at the current depth into disjoint @@ -2698,7 +3024,7 @@ isl_set *classes; isl_space *space; int n_param; - enum isl_ast_build_domain_type type; + enum isl_ast_loop_type type; int empty; if (!executed) @@ -2743,20 +3069,20 @@ isl_set_free(domains.schedule_domain); isl_set_free(domains.done); isl_map_free(domains.sep_class); - for (type = atomic; type <= separate; ++type) + for (type = isl_ast_loop_atomic; type <= isl_ast_loop_separate; ++type) isl_set_free(domains.option[type]); return domains.list; } /* Generate code for a single component, after shifting (if any) - * has been applied. + * has been applied, in case the schedule was specified as a union map. * * We first split up the domain at the current depth into disjoint * basic sets based on the user-specified options. * Then we generated code for each of them and concatenate the results. */ -static __isl_give isl_ast_graft_list *generate_shifted_component( +static __isl_give isl_ast_graft_list *generate_shifted_component_flat( __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) { isl_basic_set_list *domain_list; @@ -2772,124 +3098,426 @@ return list; } -struct isl_set_map_pair { - isl_set *set; - isl_map *map; -}; - -/* Given an array "domain" of isl_set_map_pairs and an array "order" - * of indices into the "domain" array, - * return the union of the "map" fields of the elements - * indexed by the first "n" elements of "order". +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree + * and the separate option was specified. + * + * We perform separation on the domain of "executed" and then generate + * an AST for each of the resulting disjoint basic sets. */ -static __isl_give isl_union_map *construct_component_executed( - struct isl_set_map_pair *domain, int *order, int n) +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_separate( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) { - int i; - isl_map *map; - isl_union_map *executed; + isl_space *space; + isl_set *domain; + isl_basic_set_list *domain_list; + isl_ast_graft_list *list; - map = isl_map_copy(domain[order[0]].map); - executed = isl_union_map_from_map(map); - for (i = 1; i < n; ++i) { - map = isl_map_copy(domain[order[i]].map); - executed = isl_union_map_add_map(executed, map); - } + space = isl_ast_build_get_space(build, 1); + domain = separate_schedule_domains(space, + isl_union_map_copy(executed), build); + domain_list = isl_basic_set_list_from_set(domain); - return executed; + list = generate_parallel_domains(domain_list, executed, build); + + isl_basic_set_list_free(domain_list); + isl_union_map_free(executed); + isl_ast_build_free(build); + + return list; } -/* Generate code for a single component, after shifting (if any) - * has been applied. +/* Internal data structure for generate_shifted_component_tree_unroll. * - * The component inverse schedule is specified as the "map" fields - * of the elements of "domain" indexed by the first "n" elements of "order". + * "executed" and "build" are inputs to generate_shifted_component_tree_unroll. + * "list" collects the constructs grafts. */ -static __isl_give isl_ast_graft_list *generate_shifted_component_from_list( - struct isl_set_map_pair *domain, int *order, int n, - __isl_take isl_ast_build *build) -{ +struct isl_ast_unroll_tree_data { isl_union_map *executed; + isl_ast_build *build; + isl_ast_graft_list *list; +}; - executed = construct_component_executed(domain, order, n); - return generate_shifted_component(executed, build); -} - -/* Does set dimension "pos" of "set" have an obviously fixed value? +/* Initialize data->list to a list of "n" elements. */ -static int dim_is_fixed(__isl_keep isl_set *set, int pos) +static int init_unroll_tree(int n, void *user) { - int fixed; - isl_val *v; + struct isl_ast_unroll_tree_data *data = user; + isl_ctx *ctx; - v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, pos); - if (!v) - return -1; - fixed = !isl_val_is_nan(v); - isl_val_free(v); + ctx = isl_ast_build_get_ctx(data->build); + data->list = isl_ast_graft_list_alloc(ctx, n); - return fixed; + return 0; } -/* Given an array "domain" of isl_set_map_pairs and an array "order" - * of indices into the "domain" array, - * do all (except for at most one) of the "set" field of the elements - * indexed by the first "n" elements of "order" have a fixed value - * at position "depth"? +/* Given an iteration of an unrolled domain represented by "bset", + * generate the corresponding AST and add the result to data->list. */ -static int at_most_one_non_fixed(struct isl_set_map_pair *domain, - int *order, int n, int depth) +static int do_unroll_tree_iteration(__isl_take isl_basic_set *bset, void *user) { - int i; - int non_fixed = -1; - - for (i = 0; i < n; ++i) { - int f; + struct isl_ast_unroll_tree_data *data = user; - f = dim_is_fixed(domain[order[i]].set, depth); - if (f < 0) - return -1; - if (f) - continue; - if (non_fixed >= 0) - return 0; - non_fixed = i; - } + data->list = add_node(data->list, isl_union_map_copy(data->executed), + bset, isl_ast_build_copy(data->build)); - return 1; + return 0; } -/* Given an array "domain" of isl_set_map_pairs and an array "order" - * of indices into the "domain" array, - * eliminate the inner dimensions from the "set" field of the elements - * indexed by the first "n" elements of "order", provided the current - * dimension does not have a fixed value. +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree + * and the unroll option was specified. * - * Return the index of the first element in "order" with a corresponding - * "set" field that does not have an (obviously) fixed value. + * We call foreach_iteration to iterate over the individual values and + * construct and collect the corresponding grafts in do_unroll_tree_iteration. */ -static int eliminate_non_fixed(struct isl_set_map_pair *domain, - int *order, int n, int depth, __isl_keep isl_ast_build *build) +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_unroll( + __isl_take isl_union_map *executed, __isl_take isl_set *domain, + __isl_take isl_ast_build *build) { - int i; - int base = -1; + struct isl_ast_unroll_tree_data data = { executed, build, NULL }; - for (i = n - 1; i >= 0; --i) { - int f; - f = dim_is_fixed(domain[order[i]].set, depth); - if (f < 0) - return -1; - if (f) - continue; - domain[order[i]].set = isl_ast_build_eliminate_inner(build, - domain[order[i]].set); - base = i; - } + if (foreach_iteration(domain, build, &init_unroll_tree, + &do_unroll_tree_iteration, &data) < 0) + data.list = isl_ast_graft_list_free(data.list); - return base; + isl_union_map_free(executed); + isl_ast_build_free(build); + + return data.list; } -/* Given an array "domain" of isl_set_map_pairs and an array "order" +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * In particular, handle the base case where there is either no isolated + * set or we are within the isolated set (in which case "isolated" is set) + * or the iterations that precede or follow the isolated set. + * + * The schedule domain is broken up or combined into basic sets + * according to the AST generation option specified in the current + * schedule node, which may be either atomic, separate, unroll or + * unspecified. If the option is unspecified, then we currently simply + * split the schedule domain into disjoint basic sets. + * + * In case the separate option is specified, the AST generation is + * handled by generate_shifted_component_tree_separate. + * In the other cases, we need the global schedule domain. + * In the unroll case, the AST generation is then handled by + * generate_shifted_component_tree_unroll which needs the actual + * schedule domain (with divs that may refer to the current dimension) + * so that stride detection can be performed. + * In the atomic or unspecified case, inner dimensions and divs involving + * the current dimensions should be eliminated. + * The result is then either combined into a single basic set or + * split up into disjoint basic sets. + * Finally an AST is generated for each basic set and the results are + * concatenated. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_base( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build, + int isolated) +{ + isl_union_set *schedule_domain; + isl_set *domain; + isl_basic_set_list *domain_list; + isl_ast_graft_list *list; + enum isl_ast_loop_type type; + + type = isl_ast_build_get_loop_type(build, isolated); + if (type < 0) + goto error; + + if (type == isl_ast_loop_separate) + return generate_shifted_component_tree_separate(executed, + build); + + schedule_domain = isl_union_map_domain(isl_union_map_copy(executed)); + domain = isl_set_from_union_set(schedule_domain); + + if (type == isl_ast_loop_unroll) + return generate_shifted_component_tree_unroll(executed, domain, + build); + + domain = isl_ast_build_eliminate(build, domain); + domain = isl_set_coalesce(domain); + + if (type == isl_ast_loop_atomic) { + isl_basic_set *hull; + hull = isl_set_unshifted_simple_hull(domain); + domain_list = isl_basic_set_list_from_basic_set(hull); + } else { + domain = isl_set_make_disjoint(domain); + domain_list = isl_basic_set_list_from_set(domain); + } + + list = generate_parallel_domains(domain_list, executed, build); + + isl_basic_set_list_free(domain_list); + isl_union_map_free(executed); + isl_ast_build_free(build); + + return list; +error: + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * In particular, do so for the specified subset of the schedule domain. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree_part( + __isl_keep isl_union_map *executed, __isl_take isl_set *domain, + __isl_keep isl_ast_build *build, int isolated) +{ + isl_union_set *uset; + int empty; + + uset = isl_union_set_from_set(domain); + executed = isl_union_map_copy(executed); + executed = isl_union_map_intersect_domain(executed, uset); + empty = isl_union_map_is_empty(executed); + if (empty < 0) + goto error; + if (empty) { + isl_ctx *ctx; + isl_union_map_free(executed); + ctx = isl_ast_build_get_ctx(build); + return isl_ast_graft_list_alloc(ctx, 0); + } + + build = isl_ast_build_copy(build); + return generate_shifted_component_tree_base(executed, build, isolated); +error: + isl_union_map_free(executed); + return NULL; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied, in case the schedule was specified as a schedule tree. + * + * We first check if the user has specified an isolated schedule domain + * and that we are not already outside of this isolated schedule domain. + * If so, we break up the schedule domain into iterations that + * precede the isolated domain, the isolated domain itself, + * the iterations that follow the isolated domain and + * the remaining iterations (those that are incomparable + * to the isolated domain). + * We generate an AST for each piece and concatenate the results. + * If no isolated set has been specified, then we generate an + * AST for the entire inverse schedule. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_tree( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + int i, depth; + int empty, has_isolate; + isl_space *space; + isl_union_set *schedule_domain; + isl_set *domain; + isl_basic_set *hull; + isl_set *isolated, *before, *after, *test; + isl_map *gt, *lt; + isl_ast_graft_list *list, *res; + + build = isl_ast_build_extract_isolated(build); + has_isolate = isl_ast_build_has_isolated(build); + if (has_isolate < 0) + executed = isl_union_map_free(executed); + else if (!has_isolate) + return generate_shifted_component_tree_base(executed, build, 0); + + schedule_domain = isl_union_map_domain(isl_union_map_copy(executed)); + domain = isl_set_from_union_set(schedule_domain); + + isolated = isl_ast_build_get_isolated(build); + isolated = isl_set_intersect(isolated, isl_set_copy(domain)); + test = isl_ast_build_specialize(build, isl_set_copy(isolated)); + empty = isl_set_is_empty(test); + isl_set_free(test); + if (empty < 0) + goto error; + if (empty) { + isl_set_free(isolated); + isl_set_free(domain); + return generate_shifted_component_tree_base(executed, build, 0); + } + isolated = isl_ast_build_eliminate(build, isolated); + hull = isl_set_unshifted_simple_hull(isolated); + isolated = isl_set_from_basic_set(hull); + + depth = isl_ast_build_get_depth(build); + space = isl_space_map_from_set(isl_set_get_space(isolated)); + gt = isl_map_universe(space); + for (i = 0; i < depth; ++i) + gt = isl_map_equate(gt, isl_dim_in, i, isl_dim_out, i); + gt = isl_map_order_gt(gt, isl_dim_in, depth, isl_dim_out, depth); + lt = isl_map_reverse(isl_map_copy(gt)); + before = isl_set_apply(isl_set_copy(isolated), gt); + after = isl_set_apply(isl_set_copy(isolated), lt); + + domain = isl_set_subtract(domain, isl_set_copy(isolated)); + domain = isl_set_subtract(domain, isl_set_copy(before)); + domain = isl_set_subtract(domain, isl_set_copy(after)); + after = isl_set_subtract(after, isl_set_copy(isolated)); + after = isl_set_subtract(after, isl_set_copy(before)); + before = isl_set_subtract(before, isl_set_copy(isolated)); + + res = generate_shifted_component_tree_part(executed, before, build, 0); + list = generate_shifted_component_tree_part(executed, isolated, + build, 1); + res = isl_ast_graft_list_concat(res, list); + list = generate_shifted_component_tree_part(executed, after, build, 0); + res = isl_ast_graft_list_concat(res, list); + list = generate_shifted_component_tree_part(executed, domain, build, 0); + res = isl_ast_graft_list_concat(res, list); + + isl_union_map_free(executed); + isl_ast_build_free(build); + + return res; +error: + isl_set_free(domain); + isl_set_free(isolated); + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied. + * + * Call generate_shifted_component_tree or generate_shifted_component_flat + * depending on whether the schedule was specified as a schedule tree. + */ +static __isl_give isl_ast_graft_list *generate_shifted_component( + __isl_take isl_union_map *executed, __isl_take isl_ast_build *build) +{ + if (isl_ast_build_has_schedule_node(build)) + return generate_shifted_component_tree(executed, build); + else + return generate_shifted_component_flat(executed, build); +} + +struct isl_set_map_pair { + isl_set *set; + isl_map *map; +}; + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * return the union of the "map" fields of the elements + * indexed by the first "n" elements of "order". + */ +static __isl_give isl_union_map *construct_component_executed( + struct isl_set_map_pair *domain, int *order, int n) +{ + int i; + isl_map *map; + isl_union_map *executed; + + map = isl_map_copy(domain[order[0]].map); + executed = isl_union_map_from_map(map); + for (i = 1; i < n; ++i) { + map = isl_map_copy(domain[order[i]].map); + executed = isl_union_map_add_map(executed, map); + } + + return executed; +} + +/* Generate code for a single component, after shifting (if any) + * has been applied. + * + * The component inverse schedule is specified as the "map" fields + * of the elements of "domain" indexed by the first "n" elements of "order". + */ +static __isl_give isl_ast_graft_list *generate_shifted_component_from_list( + struct isl_set_map_pair *domain, int *order, int n, + __isl_take isl_ast_build *build) +{ + isl_union_map *executed; + + executed = construct_component_executed(domain, order, n); + return generate_shifted_component(executed, build); +} + +/* Does set dimension "pos" of "set" have an obviously fixed value? + */ +static int dim_is_fixed(__isl_keep isl_set *set, int pos) +{ + int fixed; + isl_val *v; + + v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, pos); + if (!v) + return -1; + fixed = !isl_val_is_nan(v); + isl_val_free(v); + + return fixed; +} + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * do all (except for at most one) of the "set" field of the elements + * indexed by the first "n" elements of "order" have a fixed value + * at position "depth"? + */ +static int at_most_one_non_fixed(struct isl_set_map_pair *domain, + int *order, int n, int depth) +{ + int i; + int non_fixed = -1; + + for (i = 0; i < n; ++i) { + int f; + + f = dim_is_fixed(domain[order[i]].set, depth); + if (f < 0) + return -1; + if (f) + continue; + if (non_fixed >= 0) + return 0; + non_fixed = i; + } + + return 1; +} + +/* Given an array "domain" of isl_set_map_pairs and an array "order" + * of indices into the "domain" array, + * eliminate the inner dimensions from the "set" field of the elements + * indexed by the first "n" elements of "order", provided the current + * dimension does not have a fixed value. + * + * Return the index of the first element in "order" with a corresponding + * "set" field that does not have an (obviously) fixed value. + */ +static int eliminate_non_fixed(struct isl_set_map_pair *domain, + int *order, int n, int depth, __isl_keep isl_ast_build *build) +{ + int i; + int base = -1; + + for (i = n - 1; i >= 0; --i) { + int f; + f = dim_is_fixed(domain[order[i]].set, depth); + if (f < 0) + return -1; + if (f) + continue; + domain[order[i]].set = isl_ast_build_eliminate_inner(build, + domain[order[i]].set); + base = i; + } + + return base; +} + +/* Given an array "domain" of isl_set_map_pairs and an array "order" * of indices into the "domain" array, * find the element of "domain" (amongst those indexed by the first "n" * elements of "order") with the "set" field that has the smallest @@ -3046,7 +3674,7 @@ map = isl_map_insert_dims(map, isl_dim_out, depth + 1, 1); space = isl_space_insert_dims(space, isl_dim_out, depth + 1, 1); - c = isl_equality_alloc(isl_local_space_from_space(space)); + c = isl_constraint_alloc_equality(isl_local_space_from_space(space)); c = isl_constraint_set_coefficient_si(c, isl_dim_in, depth, 1); c = isl_constraint_set_coefficient_si(c, isl_dim_out, depth, -1); @@ -3112,19 +3740,17 @@ isl_ast_graft_list *list; int first; int depth; - isl_ctx *ctx; isl_val *val; isl_multi_val *mv; isl_space *space; isl_multi_aff *ma, *zero; isl_union_map *executed; - ctx = isl_ast_build_get_ctx(build); depth = isl_ast_build_get_depth(build); first = first_offset(domain, order, n, build); if (first < 0) - return isl_ast_build_free(build); + goto error; mv = isl_multi_val_copy(offset); val = isl_multi_val_get_val(offset, first); @@ -3149,6 +3775,24 @@ isl_multi_val_free(mv); return list; +error: + isl_ast_build_free(build); + return NULL; +} + +/* Does any node in the schedule tree rooted at the current schedule node + * of "build" depend on outer schedule nodes? + */ +static int has_anchored_subtree(__isl_keep isl_ast_build *build) +{ + isl_schedule_node *node; + int dependent = 0; + + node = isl_ast_build_get_schedule_node(build); + dependent = isl_schedule_node_is_subtree_anchored(node); + isl_schedule_node_free(node); + + return dependent; } /* Generate code for a single component. @@ -3182,11 +3826,15 @@ * a fixed value for almost all domains then there is nothing to be done. * In particular, we need at least two domains where the current schedule * dimension does not have a fixed value. - * Finally, if any of the options refer to the current schedule dimension, + * Finally, in case of a schedule map input, + * if any of the options refer to the current schedule dimension, * then we bail out as well. It would be possible to reformulate the options * in terms of the new schedule domain, but that would introduce constraints * that separate the domains in the options and that is something we would * like to avoid. + * In the case of a schedule tree input, we bail out if any of + * the descendants of the current schedule node refer to outer + * schedule nodes in any way. * * * To see if there is any shifted stride, we look at the differences @@ -3238,17 +3886,21 @@ skip = n == 1; if (skip >= 0 && !skip) skip = at_most_one_non_fixed(domain, order, n, depth); - if (skip >= 0 && !skip) - skip = isl_ast_build_options_involve_depth(build); + if (skip >= 0 && !skip) { + if (isl_ast_build_has_schedule_node(build)) + skip = has_anchored_subtree(build); + else + skip = isl_ast_build_options_involve_depth(build); + } if (skip < 0) - return isl_ast_build_free(build); + goto error; if (skip) return generate_shifted_component_from_list(domain, order, n, build); base = eliminate_non_fixed(domain, order, n, depth, build); if (base < 0) - return isl_ast_build_free(build); + goto error; ctx = isl_ast_build_get_ctx(build); @@ -3312,12 +3964,15 @@ isl_multi_val_free(mv); return list; +error: + isl_ast_build_free(build); + return NULL; } /* Store both "map" itself and its domain in the * structure pointed to by *next and advance to the next array element. */ -static int extract_domain(__isl_take isl_map *map, void *user) +static isl_stat extract_domain(__isl_take isl_map *map, void *user) { struct isl_set_map_pair **next = user; @@ -3325,33 +3980,416 @@ (*next)->set = isl_map_domain(map); (*next)++; - return 0; + return isl_stat_ok; } -/* Internal data for any_scheduled_after. - * - * "depth" is the number of loops that have already been generated - * "group_coscheduled" is a local copy of options->ast_build_group_coscheduled - * "domain" is an array of set-map pairs corresponding to the different - * iteration domains. The set is the schedule domain, i.e., the domain - * of the inverse schedule, while the map is the inverse schedule itself. +static int after_in_tree(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node); + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the child of "node"? */ -struct isl_any_scheduled_after_data { - int depth; - int group_coscheduled; - struct isl_set_map_pair *domain; -}; +static int after_in_child(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_schedule_node *child; + int after; -/* Is any element of domain "i" scheduled after any element of domain "j" + child = isl_schedule_node_get_child(node, 0); + after = after_in_tree(umap, child); + isl_schedule_node_free(child); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the band node "node"? + * + * We first check if any domain element is scheduled after any + * of the corresponding image elements by the band node itself. + * If not, we restrict "map" to those pairs of element that + * are scheduled together by the band node and continue with + * the child of the band node. + * If there are no such pairs then the map passed to after_in_child + * will be empty causing it to return 0. + */ +static int after_in_band(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_multi_union_pw_aff *mupa; + isl_union_map *partial, *test, *gt, *universe, *umap1, *umap2; + isl_union_set *domain, *range; + isl_space *space; + int empty; + int after; + + if (isl_schedule_node_band_n_member(node) == 0) + return after_in_child(umap, node); + + mupa = isl_schedule_node_band_get_partial_schedule(node); + space = isl_multi_union_pw_aff_get_space(mupa); + partial = isl_union_map_from_multi_union_pw_aff(mupa); + test = isl_union_map_copy(umap); + test = isl_union_map_apply_domain(test, isl_union_map_copy(partial)); + test = isl_union_map_apply_range(test, isl_union_map_copy(partial)); + gt = isl_union_map_from_map(isl_map_lex_gt(space)); + test = isl_union_map_intersect(test, gt); + empty = isl_union_map_is_empty(test); + isl_union_map_free(test); + + if (empty < 0 || !empty) { + isl_union_map_free(partial); + return empty < 0 ? -1 : 1; + } + + universe = isl_union_map_universe(isl_union_map_copy(umap)); + domain = isl_union_map_domain(isl_union_map_copy(universe)); + range = isl_union_map_range(universe); + umap1 = isl_union_map_copy(partial); + umap1 = isl_union_map_intersect_domain(umap1, domain); + umap2 = isl_union_map_intersect_domain(partial, range); + test = isl_union_map_apply_range(umap1, isl_union_map_reverse(umap2)); + test = isl_union_map_intersect(test, isl_union_map_copy(umap)); + after = after_in_child(test, node); + isl_union_map_free(test); + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the context node "node"? + * + * The context constraints apply to the schedule domain, + * so we cannot apply them directly to "umap", which contains + * pairs of statement instances. Instead, we add them + * to the range of the prefix schedule for both domain and + * range of "umap". + */ +static int after_in_context(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_union_map *prefix, *universe, *umap1, *umap2; + isl_union_set *domain, *range; + isl_set *context; + int after; + + umap = isl_union_map_copy(umap); + context = isl_schedule_node_context_get_context(node); + prefix = isl_schedule_node_get_prefix_schedule_union_map(node); + universe = isl_union_map_universe(isl_union_map_copy(umap)); + domain = isl_union_map_domain(isl_union_map_copy(universe)); + range = isl_union_map_range(universe); + umap1 = isl_union_map_copy(prefix); + umap1 = isl_union_map_intersect_domain(umap1, domain); + umap2 = isl_union_map_intersect_domain(prefix, range); + umap1 = isl_union_map_intersect_range(umap1, + isl_union_set_from_set(context)); + umap1 = isl_union_map_apply_range(umap1, isl_union_map_reverse(umap2)); + umap = isl_union_map_intersect(umap, umap1); + + after = after_in_child(umap, node); + + isl_union_map_free(umap); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the expansion node "node"? + * + * We apply the expansion to domain and range of "umap" and + * continue with its child. + */ +static int after_in_expansion(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_union_map *expansion; + int after; + + expansion = isl_schedule_node_expansion_get_expansion(node); + umap = isl_union_map_copy(umap); + umap = isl_union_map_apply_domain(umap, isl_union_map_copy(expansion)); + umap = isl_union_map_apply_range(umap, expansion); + + after = after_in_child(umap, node); + + isl_union_map_free(umap); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the extension node "node"? + * + * Since the extension node may add statement instances before or + * after the pairs of statement instances in "umap", we return 1 + * to ensure that these pairs are not broken up. + */ +static int after_in_extension(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + return 1; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the filter node "node"? + * + * We intersect domain and range of "umap" with the filter and + * continue with its child. + */ +static int after_in_filter(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + isl_union_set *filter; + int after; + + umap = isl_union_map_copy(umap); + filter = isl_schedule_node_filter_get_filter(node); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(filter)); + umap = isl_union_map_intersect_range(umap, filter); + + after = after_in_child(umap, node); + + isl_union_map_free(umap); + + return after; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the set node "node"? + * + * This is only the case if this condition holds in any + * of the (filter) children of the set node. + * In particular, if the domain and the range of "umap" + * are contained in different children, then the condition + * does not hold. + */ +static int after_in_set(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + int i, n; + + n = isl_schedule_node_n_children(node); + for (i = 0; i < n; ++i) { + isl_schedule_node *child; + int after; + + child = isl_schedule_node_get_child(node, i); + after = after_in_tree(umap, child); + isl_schedule_node_free(child); + + if (after < 0 || after) + return after; + } + + return 0; +} + +/* Return the filter of child "i" of "node". + */ +static __isl_give isl_union_set *child_filter( + __isl_keep isl_schedule_node *node, int i) +{ + isl_schedule_node *child; + isl_union_set *filter; + + child = isl_schedule_node_get_child(node, i); + filter = isl_schedule_node_filter_get_filter(child); + isl_schedule_node_free(child); + + return filter; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at + * the sequence node "node"? + * + * This happens in particular if any domain element is + * contained in a later child than one containing a range element or + * if the condition holds within a given child in the sequence. + * The later part of the condition is checked by after_in_set. + */ +static int after_in_sequence(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + int i, j, n; + isl_union_map *umap_i; + int empty, after = 0; + + n = isl_schedule_node_n_children(node); + for (i = 1; i < n; ++i) { + isl_union_set *filter_i; + + umap_i = isl_union_map_copy(umap); + filter_i = child_filter(node, i); + umap_i = isl_union_map_intersect_domain(umap_i, filter_i); + empty = isl_union_map_is_empty(umap_i); + if (empty < 0) + goto error; + if (empty) { + isl_union_map_free(umap_i); + continue; + } + + for (j = 0; j < i; ++j) { + isl_union_set *filter_j; + isl_union_map *umap_ij; + + umap_ij = isl_union_map_copy(umap_i); + filter_j = child_filter(node, j); + umap_ij = isl_union_map_intersect_range(umap_ij, + filter_j); + empty = isl_union_map_is_empty(umap_ij); + isl_union_map_free(umap_ij); + + if (empty < 0) + goto error; + if (!empty) + after = 1; + if (after) + break; + } + + isl_union_map_free(umap_i); + if (after) + break; + } + + if (after < 0 || after) + return after; + + return after_in_set(umap, node); +error: + isl_union_map_free(umap_i); + return -1; +} + +/* Is any domain element of "umap" scheduled after any of + * the corresponding image elements by the tree rooted at "node"? + * + * If "umap" is empty, then clearly there is no such element. + * Otherwise, consider the different types of nodes separately. + */ +static int after_in_tree(__isl_keep isl_union_map *umap, + __isl_keep isl_schedule_node *node) +{ + int empty; + enum isl_schedule_node_type type; + + empty = isl_union_map_is_empty(umap); + if (empty < 0) + return -1; + if (empty) + return 0; + if (!node) + return -1; + + type = isl_schedule_node_get_type(node); + switch (type) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_leaf: + return 0; + case isl_schedule_node_band: + return after_in_band(umap, node); + case isl_schedule_node_domain: + isl_die(isl_schedule_node_get_ctx(node), isl_error_internal, + "unexpected internal domain node", return -1); + case isl_schedule_node_context: + return after_in_context(umap, node); + case isl_schedule_node_expansion: + return after_in_expansion(umap, node); + case isl_schedule_node_extension: + return after_in_extension(umap, node); + case isl_schedule_node_filter: + return after_in_filter(umap, node); + case isl_schedule_node_guard: + case isl_schedule_node_mark: + return after_in_child(umap, node); + case isl_schedule_node_set: + return after_in_set(umap, node); + case isl_schedule_node_sequence: + return after_in_sequence(umap, node); + } + + return 1; +} + +/* Is any domain element of "map1" scheduled after any domain + * element of "map2" by the subtree underneath the current band node, + * while at the same time being scheduled together by the current + * band node, i.e., by "map1" and "map2? + * + * If the child of the current band node is a leaf, then + * no element can be scheduled after any other element. + * + * Otherwise, we construct a relation between domain elements + * of "map1" and domain elements of "map2" that are scheduled + * together and then check if the subtree underneath the current + * band node determines their relative order. + */ +static int after_in_subtree(__isl_keep isl_ast_build *build, + __isl_keep isl_map *map1, __isl_keep isl_map *map2) +{ + isl_schedule_node *node; + isl_map *map; + isl_union_map *umap; + int after; + + node = isl_ast_build_get_schedule_node(build); + if (!node) + return -1; + node = isl_schedule_node_child(node, 0); + if (isl_schedule_node_get_type(node) == isl_schedule_node_leaf) { + isl_schedule_node_free(node); + return 0; + } + map = isl_map_copy(map2); + map = isl_map_apply_domain(map, isl_map_copy(map1)); + umap = isl_union_map_from_map(map); + after = after_in_tree(umap, node); + isl_union_map_free(umap); + isl_schedule_node_free(node); + return after; +} + +/* Internal data for any_scheduled_after. + * + * "build" is the build in which the AST is constructed. + * "depth" is the number of loops that have already been generated + * "group_coscheduled" is a local copy of options->ast_build_group_coscheduled + * "domain" is an array of set-map pairs corresponding to the different + * iteration domains. The set is the schedule domain, i.e., the domain + * of the inverse schedule, while the map is the inverse schedule itself. + */ +struct isl_any_scheduled_after_data { + isl_ast_build *build; + int depth; + int group_coscheduled; + struct isl_set_map_pair *domain; +}; + +/* Is any element of domain "i" scheduled after any element of domain "j" * (for a common iteration of the first data->depth loops)? * * data->domain[i].set contains the domain of the inverse schedule * for domain "i", i.e., elements in the schedule domain. * + * If we are inside a band of a schedule tree and there is a pair + * of elements in the two domains that is schedule together by + * the current band, then we check if any element of "i" may be schedule + * after element of "j" by the descendants of the band node. + * * If data->group_coscheduled is set, then we also return 1 if there * is any pair of elements in the two domains that are scheduled together. */ -static int any_scheduled_after(int i, int j, void *user) +static isl_bool any_scheduled_after(int i, int j, void *user) { struct isl_any_scheduled_after_data *data = user; int dim = isl_set_dim(data->domain[i].set, isl_dim_set); @@ -3364,11 +4402,20 @@ data->domain[j].set, pos); if (follows < -1) - return -1; + return isl_bool_error; if (follows > 0) - return 1; + return isl_bool_true; if (follows < 0) - return 0; + return isl_bool_false; + } + + if (isl_ast_build_has_schedule_node(data->build)) { + int after; + + after = after_in_subtree(data->build, data->domain[i].map, + data->domain[j].map); + if (after < 0 || after) + return after; } return data->group_coscheduled; @@ -3417,9 +4464,12 @@ if (!build) goto error; + data.build = build; data.depth = isl_ast_build_get_depth(build); data.group_coscheduled = isl_options_get_ast_build_group_coscheduled(ctx); g = isl_tarjan_graph_init(ctx, n, &any_scheduled_after, &data); + if (!g) + goto error; list = isl_ast_graft_list_alloc(ctx, 0); @@ -3488,7 +4538,7 @@ } depth = isl_ast_build_get_depth(build); - if (depth >= isl_set_dim(build->domain, isl_dim_set)) + if (depth >= isl_ast_build_dim(build, isl_dim_set)) return generate_inner_level(executed, build); if (isl_union_map_n_map(executed) == 1) @@ -3501,7 +4551,7 @@ return NULL; } -/* Internal data structure used by isl_ast_build_ast_from_schedule. +/* Internal data structure used by isl_ast_build_node_from_schedule_map. * internal, executed and build are the inputs to generate_code. * list collects the output. */ @@ -3550,8 +4600,8 @@ } /* Generate an AST that visits the elements in the range of data->executed - * in the relative order specified by the corresponding image element(s) - * for those image elements that belong to "set". + * in the relative order specified by the corresponding domain element(s) + * for those domain elements that belong to "set". * Add the result to data->list. * * The caller ensures that "set" is a universe domain. @@ -3559,11 +4609,19 @@ * It is equal to the space of "set" if build->domain is parametric. * Otherwise, it is equal to the range of the wrapped space of "set". * - * If the build space is not parametric and if isl_ast_build_ast_from_schedule + * If the build space is not parametric and + * if isl_ast_build_node_from_schedule_map * was called from an outside user (data->internal not set), then * the (inverse) schedule refers to the external build domain and needs to * be transformed to refer to the internal build domain. * + * If the build space is parametric, then we add some of the parameter + * constraints to the executed relation. Adding these constraints + * allows for an earlier detection of conflicts in some cases. + * However, we do not want to divide the executed relation into + * more disjuncts than necessary. We therefore approximate + * the constraints on the parameters by a single disjunct set. + * * The build is extended to include the additional part of the schedule. * If the original build space was not parametric, then the options * in data->build refer only to the additional part of the schedule @@ -3578,7 +4636,7 @@ * on the resulting isl_ast_node_list so that it can be used within * the outer AST build. */ -static int generate_code_in_space(struct isl_generate_code_data *data, +static isl_stat generate_code_in_space(struct isl_generate_code_data *data, __isl_take isl_set *set, __isl_take isl_space *space) { isl_union_map *executed; @@ -3593,6 +4651,12 @@ embed = !isl_set_is_params(data->build->domain); if (embed && !data->internal) executed = internal_executed(executed, space, data->build); + if (!embed) { + isl_set *domain; + domain = isl_ast_build_get_domain(data->build); + domain = isl_set_from_basic_set(isl_set_simple_hull(domain)); + executed = isl_union_map_intersect_params(executed, domain); + } build = isl_ast_build_copy(data->build); build = isl_ast_build_product(build, space); @@ -3603,7 +4667,7 @@ data->list = isl_ast_graft_list_concat(data->list, list); - return 0; + return isl_stat_ok; } /* Generate an AST that visits the elements in the range of data->executed @@ -3623,7 +4687,7 @@ * passing along T. * If the build space is not parametric, then T is the space of "set". */ -static int generate_code_set(__isl_take isl_set *set, void *user) +static isl_stat generate_code_set(__isl_take isl_set *set, void *user) { struct isl_generate_code_data *data = user; isl_space *space, *build_space; @@ -3650,7 +4714,7 @@ error: isl_set_free(set); isl_space_free(space); - return -1; + return isl_stat_error; } /* Generate an AST that visits the elements in the range of "executed" @@ -3747,7 +4811,7 @@ * the schedule domain in the domain and the elements to be executed * in the range) called "executed". */ -__isl_give isl_ast_node *isl_ast_build_ast_from_schedule( +__isl_give isl_ast_node *isl_ast_build_node_from_schedule_map( __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule) { isl_ast_graft_list *list; @@ -3756,6 +4820,8 @@ build = isl_ast_build_copy(build); build = isl_ast_build_set_single_valued(build, 0); + schedule = isl_union_map_coalesce(schedule); + schedule = isl_union_map_remove_redundancies(schedule); executed = isl_union_map_reverse(schedule); list = generate_code(executed, isl_ast_build_copy(build), 0); node = isl_ast_node_from_graft_list(list, build); @@ -3763,3 +4829,688 @@ return node; } + +/* The old name for isl_ast_build_node_from_schedule_map. + * It is being kept for backward compatibility, but + * it will be removed in the future. + */ +__isl_give isl_ast_node *isl_ast_build_ast_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_union_map *schedule) +{ + return isl_ast_build_node_from_schedule_map(build, schedule); +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the band node "node" and its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * If the band is empty, we continue with its descendants. + * Otherwise, we extend the build and the inverse schedule with + * the additional space/partial schedule and continue generating + * an AST in generate_next_level. + * As soon as we have extended the inverse schedule with the additional + * partial schedule, we look for equalities that may exists between + * the old and the new part. + */ +static __isl_give isl_ast_graft_list *build_ast_from_band( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_space *space; + isl_multi_union_pw_aff *extra; + isl_union_map *extra_umap; + isl_ast_graft_list *list; + unsigned n1, n2; + + if (!build || !node || !executed) + goto error; + + if (isl_schedule_node_band_n_member(node) == 0) + return build_ast_from_child(build, node, executed); + + extra = isl_schedule_node_band_get_partial_schedule(node); + extra = isl_multi_union_pw_aff_align_params(extra, + isl_ast_build_get_space(build, 1)); + space = isl_multi_union_pw_aff_get_space(extra); + + extra_umap = isl_union_map_from_multi_union_pw_aff(extra); + extra_umap = isl_union_map_reverse(extra_umap); + + executed = isl_union_map_domain_product(executed, extra_umap); + executed = isl_union_map_detect_equalities(executed); + + n1 = isl_ast_build_dim(build, isl_dim_param); + build = isl_ast_build_product(build, space); + n2 = isl_ast_build_dim(build, isl_dim_param); + if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "band node is not allowed to introduce new parameters", + build = isl_ast_build_free(build)); + build = isl_ast_build_set_schedule_node(build, node); + + list = generate_next_level(executed, build); + + list = isl_ast_graft_list_unembed(list, 1); + + return list; +error: + isl_schedule_node_free(node); + isl_union_map_free(executed); + isl_ast_build_free(build); + return NULL; +} + +/* Hoist a list of grafts (in practice containing a single graft) + * from "sub_build" (which includes extra context information) + * to "build". + * + * In particular, project out all additional parameters introduced + * by the context node from the enforced constraints and the guard + * of the single graft. + */ +static __isl_give isl_ast_graft_list *hoist_out_of_context( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build) +{ + isl_ast_graft *graft; + isl_basic_set *enforced; + isl_set *guard; + unsigned n_param, extra_param; + + if (!build || !sub_build) + return isl_ast_graft_list_free(list); + + n_param = isl_ast_build_dim(build, isl_dim_param); + extra_param = isl_ast_build_dim(sub_build, isl_dim_param); + + if (extra_param == n_param) + return list; + + extra_param -= n_param; + enforced = isl_ast_graft_list_extract_shared_enforced(list, sub_build); + enforced = isl_basic_set_project_out(enforced, isl_dim_param, + n_param, extra_param); + enforced = isl_basic_set_remove_unknown_divs(enforced); + guard = isl_ast_graft_list_extract_hoistable_guard(list, sub_build); + guard = isl_set_remove_divs_involving_dims(guard, isl_dim_param, + n_param, extra_param); + guard = isl_set_project_out(guard, isl_dim_param, n_param, extra_param); + guard = isl_set_compute_divs(guard); + graft = isl_ast_graft_alloc_from_children(list, guard, enforced, + build, sub_build); + list = isl_ast_graft_list_from_ast_graft(graft); + + return list; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the context node "node" + * and its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * The context node may introduce additional parameters as well as + * constraints on the outer schedule dimenions or original parameters. + * + * We add the extra parameters to a new build and the context + * constraints to both the build and (as a single disjunct) + * to the domain of "executed". Since the context constraints + * are specified in terms of the input schedule, we first need + * to map them to the internal schedule domain. + * + * After constructing the AST from the descendants of "node", + * we combine the list of grafts into a single graft within + * the new build, in order to be able to exploit the additional + * context constraints during this combination. + * + * Additionally, if the current node is the outermost node in + * the schedule tree (apart from the root domain node), we generate + * all pending guards, again to be able to exploit the additional + * context constraints. We currently do not do this for internal + * context nodes since we may still want to hoist conditions + * to outer AST nodes. + * + * If the context node introduced any new parameters, then they + * are removed from the set of enforced constraints and guard + * in hoist_out_of_context. + */ +static __isl_give isl_ast_graft_list *build_ast_from_context( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_set *context; + isl_space *space; + isl_multi_aff *internal2input; + isl_ast_build *sub_build; + isl_ast_graft_list *list; + int n, depth; + + depth = isl_schedule_node_get_tree_depth(node); + space = isl_ast_build_get_space(build, 1); + context = isl_schedule_node_context_get_context(node); + context = isl_set_align_params(context, space); + sub_build = isl_ast_build_copy(build); + space = isl_set_get_space(context); + sub_build = isl_ast_build_align_params(sub_build, space); + internal2input = isl_ast_build_get_internal2input(sub_build); + context = isl_set_preimage_multi_aff(context, internal2input); + sub_build = isl_ast_build_restrict_generated(sub_build, + isl_set_copy(context)); + context = isl_set_from_basic_set(isl_set_simple_hull(context)); + executed = isl_union_map_intersect_domain(executed, + isl_union_set_from_set(context)); + + list = build_ast_from_child(isl_ast_build_copy(sub_build), + node, executed); + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + list = isl_ast_graft_list_free(list); + + list = isl_ast_graft_list_fuse(list, sub_build); + if (depth == 1) + list = isl_ast_graft_list_insert_pending_guard_nodes(list, + sub_build); + if (n >= 1) + list = hoist_out_of_context(list, build, sub_build); + + isl_ast_build_free(build); + isl_ast_build_free(sub_build); + + return list; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the expansion node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * We expand the domain elements by the expansion and + * continue with the descendants of the node. + */ +static __isl_give isl_ast_graft_list *build_ast_from_expansion( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_union_map *expansion; + unsigned n1, n2; + + expansion = isl_schedule_node_expansion_get_expansion(node); + expansion = isl_union_map_align_params(expansion, + isl_union_map_get_space(executed)); + + n1 = isl_union_map_dim(executed, isl_dim_param); + executed = isl_union_map_apply_range(executed, expansion); + n2 = isl_union_map_dim(executed, isl_dim_param); + if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "expansion node is not allowed to introduce " + "new parameters", goto error); + + return build_ast_from_child(build, node, executed); +error: + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the extension node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * Extend the inverse schedule with the extension applied to current + * set of generated constraints. Since the extension if formulated + * in terms of the input schedule, it first needs to be transformed + * to refer to the internal schedule. + */ +static __isl_give isl_ast_graft_list *build_ast_from_extension( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_union_set *schedule_domain; + isl_union_map *extension; + isl_set *set; + + set = isl_ast_build_get_generated(build); + schedule_domain = isl_union_set_from_set(set); + + extension = isl_schedule_node_extension_get_extension(node); + + extension = isl_union_map_preimage_domain_multi_aff(extension, + isl_multi_aff_copy(build->internal2input)); + extension = isl_union_map_intersect_domain(extension, schedule_domain); + extension = isl_ast_build_substitute_values_union_map_domain(build, + extension); + executed = isl_union_map_union(executed, extension); + + return build_ast_from_child(build, node, executed); +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the filter node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * We simply intersect the iteration domain (i.e., the range of "executed") + * with the filter and continue with the descendants of the node, + * unless the resulting inverse schedule is empty, in which + * case we return an empty list. + */ +static __isl_give isl_ast_graft_list *build_ast_from_filter( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_ctx *ctx; + isl_union_set *filter; + isl_ast_graft_list *list; + int empty; + unsigned n1, n2; + + if (!build || !node || !executed) + goto error; + + filter = isl_schedule_node_filter_get_filter(node); + filter = isl_union_set_align_params(filter, + isl_union_map_get_space(executed)); + n1 = isl_union_map_dim(executed, isl_dim_param); + executed = isl_union_map_intersect_range(executed, filter); + n2 = isl_union_map_dim(executed, isl_dim_param); + if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "filter node is not allowed to introduce " + "new parameters", goto error); + + empty = isl_union_map_is_empty(executed); + if (empty < 0) + goto error; + if (!empty) + return build_ast_from_child(build, node, executed); + + ctx = isl_ast_build_get_ctx(build); + list = isl_ast_graft_list_alloc(ctx, 0); + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + return list; +error: + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the guard node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * Ensure that the associated guard is enforced by the outer AST + * constructs by adding it to the guard of the graft. + * Since we know that we will enforce the guard, we can also include it + * in the generated constraints used to construct an AST for + * the descendant nodes. + */ +static __isl_give isl_ast_graft_list *build_ast_from_guard( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_space *space; + isl_set *guard, *hoisted; + isl_basic_set *enforced; + isl_ast_build *sub_build; + isl_ast_graft *graft; + isl_ast_graft_list *list; + unsigned n1, n2; + + space = isl_ast_build_get_space(build, 1); + guard = isl_schedule_node_guard_get_guard(node); + n1 = isl_space_dim(space, isl_dim_param); + guard = isl_set_align_params(guard, space); + n2 = isl_set_dim(guard, isl_dim_param); + if (n2 > n1) + isl_die(isl_ast_build_get_ctx(build), isl_error_invalid, + "guard node is not allowed to introduce " + "new parameters", guard = isl_set_free(guard)); + guard = isl_set_preimage_multi_aff(guard, + isl_multi_aff_copy(build->internal2input)); + guard = isl_ast_build_specialize(build, guard); + guard = isl_set_gist(guard, isl_set_copy(build->generated)); + + sub_build = isl_ast_build_copy(build); + sub_build = isl_ast_build_restrict_generated(sub_build, + isl_set_copy(guard)); + + list = build_ast_from_child(isl_ast_build_copy(sub_build), + node, executed); + + hoisted = isl_ast_graft_list_extract_hoistable_guard(list, sub_build); + if (isl_set_n_basic_set(hoisted) > 1) + list = isl_ast_graft_list_gist_guards(list, + isl_set_copy(hoisted)); + guard = isl_set_intersect(guard, hoisted); + enforced = extract_shared_enforced(list, build); + graft = isl_ast_graft_alloc_from_children(list, guard, enforced, + build, sub_build); + + isl_ast_build_free(sub_build); + isl_ast_build_free(build); + return isl_ast_graft_list_from_ast_graft(graft); +} + +/* Call the before_each_mark callback, if requested by the user. + * + * Return 0 on success and -1 on error. + * + * The caller is responsible for recording the current inverse schedule + * in "build". + */ +static isl_stat before_each_mark(__isl_keep isl_id *mark, + __isl_keep isl_ast_build *build) +{ + if (!build) + return isl_stat_error; + if (!build->before_each_mark) + return isl_stat_ok; + return build->before_each_mark(mark, build, + build->before_each_mark_user); +} + +/* Call the after_each_mark callback, if requested by the user. + * + * The caller is responsible for recording the current inverse schedule + * in "build". + */ +static __isl_give isl_ast_graft *after_each_mark( + __isl_take isl_ast_graft *graft, __isl_keep isl_ast_build *build) +{ + if (!graft || !build) + return isl_ast_graft_free(graft); + if (!build->after_each_mark) + return graft; + graft->node = build->after_each_mark(graft->node, build, + build->after_each_mark_user); + if (!graft->node) + return isl_ast_graft_free(graft); + return graft; +} + + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the mark node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + + * Since we may be calling before_each_mark and after_each_mark + * callbacks, we record the current inverse schedule in the build. + * + * We generate an AST for the child of the mark node, combine + * the graft list into a single graft and then insert the mark + * in the AST of that single graft. + */ +static __isl_give isl_ast_graft_list *build_ast_from_mark( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + isl_id *mark; + isl_ast_graft *graft; + isl_ast_graft_list *list; + int n; + + build = isl_ast_build_set_executed(build, isl_union_map_copy(executed)); + + mark = isl_schedule_node_mark_get_id(node); + if (before_each_mark(mark, build) < 0) + node = isl_schedule_node_free(node); + + list = build_ast_from_child(isl_ast_build_copy(build), node, executed); + list = isl_ast_graft_list_fuse(list, build); + n = isl_ast_graft_list_n_ast_graft(list); + if (n < 0) + list = isl_ast_graft_list_free(list); + if (n == 0) { + isl_id_free(mark); + } else { + graft = isl_ast_graft_list_get_ast_graft(list, 0); + graft = isl_ast_graft_insert_mark(graft, mark); + graft = after_each_mark(graft, build); + list = isl_ast_graft_list_set_ast_graft(list, 0, graft); + } + isl_ast_build_free(build); + + return list; +} + +static __isl_give isl_ast_graft_list *build_ast_from_schedule_node( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed); + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the sequence (or set) node "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * We simply generate an AST for each of the children and concatenate + * the results. + */ +static __isl_give isl_ast_graft_list *build_ast_from_sequence( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + int i, n; + isl_ctx *ctx; + isl_ast_graft_list *list; + + ctx = isl_ast_build_get_ctx(build); + list = isl_ast_graft_list_alloc(ctx, 0); + + n = isl_schedule_node_n_children(node); + for (i = 0; i < n; ++i) { + isl_schedule_node *child; + isl_ast_graft_list *list_i; + + child = isl_schedule_node_get_child(node, i); + list_i = build_ast_from_schedule_node(isl_ast_build_copy(build), + child, isl_union_map_copy(executed)); + list = isl_ast_graft_list_concat(list, list_i); + } + isl_ast_build_free(build); + isl_schedule_node_free(node); + isl_union_map_free(executed); + + return list; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the node "node" and its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * If the node is a leaf, then we pass control to generate_inner_level. + * Note that the current build does not refer to any band node, so + * that generate_inner_level will not try to visit the child of + * the leaf node. + * + * The other node types are handled in separate functions. + * Set nodes are currently treated in the same way as sequence nodes. + * The children of a set node may be executed in any order, + * including the order of the children. + */ +static __isl_give isl_ast_graft_list *build_ast_from_schedule_node( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + enum isl_schedule_node_type type; + + type = isl_schedule_node_get_type(node); + + switch (type) { + case isl_schedule_node_error: + goto error; + case isl_schedule_node_leaf: + isl_schedule_node_free(node); + return generate_inner_level(executed, build); + case isl_schedule_node_band: + return build_ast_from_band(build, node, executed); + case isl_schedule_node_context: + return build_ast_from_context(build, node, executed); + case isl_schedule_node_domain: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "unexpected internal domain node", goto error); + case isl_schedule_node_expansion: + return build_ast_from_expansion(build, node, executed); + case isl_schedule_node_extension: + return build_ast_from_extension(build, node, executed); + case isl_schedule_node_filter: + return build_ast_from_filter(build, node, executed); + case isl_schedule_node_guard: + return build_ast_from_guard(build, node, executed); + case isl_schedule_node_mark: + return build_ast_from_mark(build, node, executed); + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return build_ast_from_sequence(build, node, executed); + } + + isl_die(isl_ast_build_get_ctx(build), isl_error_internal, + "unhandled type", goto error); +error: + isl_union_map_free(executed); + isl_schedule_node_free(node); + isl_ast_build_free(build); + + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "executed" + * in the relative order specified by the (single) child of "node" and + * its descendants. + * + * The relation "executed" maps the outer generated loop iterators + * to the domain elements executed by those iterations. + * + * This function is never called on a leaf, set or sequence node, + * so the node always has exactly one child. + */ +static __isl_give isl_ast_graft_list *build_ast_from_child( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node, + __isl_take isl_union_map *executed) +{ + node = isl_schedule_node_child(node, 0); + return build_ast_from_schedule_node(build, node, executed); +} + +/* Generate an AST that visits the elements in the domain of the domain + * node "node" in the relative order specified by its descendants. + * + * An initial inverse schedule is created that maps a zero-dimensional + * schedule space to the node domain. + * The input "build" is assumed to have a parametric domain and + * is replaced by the same zero-dimensional schedule space. + * + * We also add some of the parameter constraints in the build domain + * to the executed relation. Adding these constraints + * allows for an earlier detection of conflicts in some cases. + * However, we do not want to divide the executed relation into + * more disjuncts than necessary. We therefore approximate + * the constraints on the parameters by a single disjunct set. + */ +static __isl_give isl_ast_node *build_ast_from_domain( + __isl_take isl_ast_build *build, __isl_take isl_schedule_node *node) +{ + isl_ctx *ctx; + isl_union_set *domain, *schedule_domain; + isl_union_map *executed; + isl_space *space; + isl_set *set; + isl_ast_graft_list *list; + isl_ast_node *ast; + int is_params; + + if (!build) + goto error; + + ctx = isl_ast_build_get_ctx(build); + space = isl_ast_build_get_space(build, 1); + is_params = isl_space_is_params(space); + isl_space_free(space); + if (is_params < 0) + goto error; + if (!is_params) + isl_die(ctx, isl_error_unsupported, + "expecting parametric initial context", goto error); + + domain = isl_schedule_node_domain_get_domain(node); + domain = isl_union_set_coalesce(domain); + + space = isl_union_set_get_space(domain); + space = isl_space_set_from_params(space); + build = isl_ast_build_product(build, space); + + set = isl_ast_build_get_domain(build); + set = isl_set_from_basic_set(isl_set_simple_hull(set)); + schedule_domain = isl_union_set_from_set(set); + + executed = isl_union_map_from_domain_and_range(schedule_domain, domain); + list = build_ast_from_child(isl_ast_build_copy(build), node, executed); + ast = isl_ast_node_from_graft_list(list, build); + isl_ast_build_free(build); + + return ast; +error: + isl_schedule_node_free(node); + isl_ast_build_free(build); + return NULL; +} + +/* Generate an AST that visits the elements in the domain of "schedule" + * in the relative order specified by the schedule tree. + * + * "build" is an isl_ast_build that has been created using + * isl_ast_build_alloc or isl_ast_build_from_context based + * on a parametric set. + * + * The construction starts at the root node of the schedule, + * which is assumed to be a domain node. + */ +__isl_give isl_ast_node *isl_ast_build_node_from_schedule( + __isl_keep isl_ast_build *build, __isl_take isl_schedule *schedule) +{ + isl_ctx *ctx; + isl_schedule_node *node; + + if (!build || !schedule) + goto error; + + ctx = isl_ast_build_get_ctx(build); + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + + build = isl_ast_build_copy(build); + build = isl_ast_build_set_single_valued(build, 0); + if (isl_schedule_node_get_type(node) != isl_schedule_node_domain) + isl_die(ctx, isl_error_unsupported, + "expecting root domain node", + build = isl_ast_build_free(build)); + return build_ast_from_domain(build, node); +error: + isl_schedule_free(schedule); + return NULL; +} diff -Nru isl-0.12.2/isl_ast_graft.c isl-0.15/isl_ast_graft.c --- isl-0.12.2/isl_ast_graft.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ast_graft.c 2015-06-02 09:28:09.000000000 +0000 @@ -1,10 +1,13 @@ /* * Copyright 2012 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include @@ -111,7 +114,11 @@ return -1; depth = isl_ast_build_get_depth(build); - skip = isl_set_involves_dims(graft_0->guard, isl_dim_set, depth, 1); + if (isl_set_dim(graft_0->guard, isl_dim_set) <= depth) + skip = 0; + else + skip = isl_set_involves_dims(graft_0->guard, + isl_dim_set, depth, 1); if (skip < 0 || skip) { isl_ast_graft_free(graft_0); return skip < 0 ? -1 : 0; @@ -135,26 +142,61 @@ return equal; } +/* Hoist "guard" out of the current level (given by "build"). + * + * In particular, eliminate the dimension corresponding to the current depth. + */ +static __isl_give isl_set *hoist_guard(__isl_take isl_set *guard, + __isl_keep isl_ast_build *build) +{ + int depth; + + depth = isl_ast_build_get_depth(build); + if (depth < isl_set_dim(guard, isl_dim_set)) { + guard = isl_set_remove_divs_involving_dims(guard, + isl_dim_set, depth, 1); + guard = isl_set_eliminate(guard, isl_dim_set, depth, 1); + guard = isl_set_compute_divs(guard); + } + + return guard; +} + /* Extract a common guard from the grafts in "list" that can be hoisted * out of the current level. If no such guard can be found, then return * a universal set. * * If all the grafts in the list have the same guard and if this guard * is independent of the current level, then it can be hoisted out. + * If there is only one graft in the list and if its guard + * depends on the current level, then we eliminate this level and + * return the result. + * * Otherwise, we return the unshifted simple hull of the guards. + * In order to be able to hoist as many constraints as possible, + * but at the same time avoid hoisting constraints that did not + * appear in the guards in the first place, we intersect the guards + * with all the information that is available (i.e., the domain + * from the build and the enforced constraints of the graft) and + * compute the unshifted hull of the result using only constraints + * from the original guards. + * In particular, intersecting the guards with other known information + * allows us to hoist guards that are only explicit is some of + * the grafts and implicit in the others. * * The special case for equal guards is needed in case those guards * are non-convex. Taking the simple hull would remove information * and would not allow for these guards to be hoisted completely. */ -static __isl_give isl_set *extract_hoistable_guard( +__isl_give isl_set *isl_ast_graft_list_extract_hoistable_guard( __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build) { int i, n; - int depth; - isl_ast_graft *graft_0; int equal; + isl_ctx *ctx; isl_set *guard; + isl_set_list *set_list; + isl_basic_set *hull; if (!list || !build) return NULL; @@ -167,45 +209,41 @@ if (equal < 0) return NULL; - graft_0 = isl_ast_graft_list_get_ast_graft(list, 0); - if (!graft_0) - return NULL; - guard = isl_set_copy(graft_0->guard); - isl_ast_graft_free(graft_0); - if (equal) - return guard; + if (equal || n == 1) { + isl_ast_graft *graft_0; - depth = isl_ast_build_get_depth(build); - if (depth < isl_set_dim(guard, isl_dim_set)) { - guard = isl_set_remove_divs_involving_dims(guard, - isl_dim_set, depth, 1); - guard = isl_set_eliminate(guard, isl_dim_set, depth, 1); - guard = isl_set_compute_divs(guard); + graft_0 = isl_ast_graft_list_get_ast_graft(list, 0); + if (!graft_0) + return NULL; + guard = isl_set_copy(graft_0->guard); + if (!equal) + guard = hoist_guard(guard, build); + isl_ast_graft_free(graft_0); + return guard; } - for (i = 1; i < n; ++i) { + ctx = isl_ast_build_get_ctx(build); + set_list = isl_set_list_alloc(ctx, n); + guard = isl_set_empty(isl_ast_build_get_space(build, 1)); + for (i = 0; i < n; ++i) { isl_ast_graft *graft; - isl_basic_set *hull; - int is_universe; - - is_universe = isl_set_plain_is_universe(guard); - if (is_universe < 0) - guard = isl_set_free(guard); - if (is_universe) - break; + isl_basic_set *enforced; + isl_set *guard_i; graft = isl_ast_graft_list_get_ast_graft(list, i); - if (!graft) { - guard = isl_set_free(guard); - break; - } - guard = isl_set_union(guard, isl_set_copy(graft->guard)); - hull = isl_set_unshifted_simple_hull(guard); - guard = isl_set_from_basic_set(hull); + enforced = isl_ast_graft_get_enforced(graft); + guard_i = isl_set_copy(graft->guard); isl_ast_graft_free(graft); + set_list = isl_set_list_add(set_list, isl_set_copy(guard_i)); + guard_i = isl_set_intersect(guard_i, + isl_set_from_basic_set(enforced)); + guard_i = isl_set_intersect(guard_i, + isl_ast_build_get_domain(build)); + guard = isl_set_union(guard, guard_i); } - - return guard; + hull = isl_set_unshifted_simple_hull_from_set_list(guard, set_list); + guard = isl_set_from_basic_set(hull); + return hoist_guard(guard, build); } /* Internal data structure used inside insert_if. @@ -220,7 +258,7 @@ isl_ast_build *build; }; -static int insert_if(__isl_take isl_basic_set *bset, void *user); +static isl_stat insert_if(__isl_take isl_basic_set *bset, void *user); /* Insert an if node around "node" testing the condition encoded * in guard "guard". @@ -244,7 +282,7 @@ isl_ast_node *if_node; isl_ast_expr *expr; - expr = isl_ast_build_expr_from_set(build, guard); + expr = isl_ast_build_expr_from_set_internal(build, guard); if_node = isl_ast_node_alloc_if(expr); return isl_ast_node_if_set_then(if_node, node); @@ -266,7 +304,7 @@ /* Insert an if node around a copy of "data->node" testing the condition * encoded in guard "bset" and add the result to data->list. */ -static int insert_if(__isl_take isl_basic_set *bset, void *user) +static isl_stat insert_if(__isl_take isl_basic_set *bset, void *user) { struct isl_insert_if_data *data = user; isl_ast_node *node; @@ -277,7 +315,7 @@ node = ast_node_insert_if(node, set, data->build); data->list = isl_ast_node_list_add(data->list, node); - return 0; + return isl_stat_ok; } /* Insert an if node around graft->node testing the condition encoded @@ -301,8 +339,6 @@ } build = isl_ast_build_copy(build); - build = isl_ast_build_set_enforced(build, - isl_ast_graft_get_enforced(graft)); graft->node = ast_node_insert_if(graft->node, guard, build); isl_ast_build_free(build); @@ -617,6 +653,42 @@ return res; } +/* For each graft in "list", + * insert an if node around graft->node testing the condition encoded + * in graft->guard, assuming graft->guard involves any conditions. + * Subsequently remove the guards from the grafts. + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_insert_pending_guard_nodes( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build) +{ + int i, n; + isl_set *universe; + + list = insert_pending_guard_nodes(list, build); + if (!list) + return NULL; + + universe = isl_set_universe(isl_ast_build_get_space(build, 1)); + n = isl_ast_graft_list_n_ast_graft(list); + for (i = 0; i < n; ++i) { + isl_ast_graft *graft; + + graft = isl_ast_graft_list_get_ast_graft(list, i); + if (!graft) + break; + isl_set_free(graft->guard); + graft->guard = isl_set_copy(universe); + if (!graft->guard) + graft = isl_ast_graft_free(graft); + list = isl_ast_graft_list_set_ast_graft(list, i, graft); + } + isl_set_free(universe); + if (i < n) + return isl_ast_graft_list_free(list); + + return list; +} + /* Collect the nodes contained in the grafts in "list" in a node list. */ static __isl_give isl_ast_node_list *extract_node_list( @@ -649,7 +721,7 @@ * * We assume that the number of children is at least one. */ -static __isl_give isl_basic_set *extract_shared_enforced( +__isl_give isl_basic_set *isl_ast_graft_list_extract_shared_enforced( __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build) { @@ -685,7 +757,9 @@ /* Record "guard" in "graft" so that it will be enforced somewhere * up the tree. If the graft already has a guard, then it may be partially * redundant in combination with the new guard and in the context - * of build->domain. We therefore (re)compute the gist of the intersection + * the generated constraints of "build". In fact, the new guard + * may in itself have some redundant constraints. + * We therefore (re)compute the gist of the intersection * and coalesce the result. */ static __isl_give isl_ast_graft *store_guard(__isl_take isl_ast_graft *graft, @@ -705,7 +779,8 @@ } graft->guard = isl_set_intersect(graft->guard, guard); - graft->guard = isl_ast_build_compute_gist(build, graft->guard); + graft->guard = isl_set_gist(graft->guard, + isl_ast_build_get_generated(build)); graft->guard = isl_set_coalesce(graft->guard); if (!graft->guard) return isl_ast_graft_free(graft); @@ -746,12 +821,57 @@ return list; } -/* Combine the grafts in the list into a single graft. +/* For each graft in "list", replace its guard with the gist with + * respect to "context". + */ +__isl_give isl_ast_graft_list *isl_ast_graft_list_gist_guards( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *context) +{ + list = gist_guards(list, context); + isl_set_free(context); + + return list; +} + +/* Allocate a graft in "build" based on the list of grafts in "sub_build". + * "guard" and "enforced" are the guard and enforced constraints + * of the allocated graft. The guard is used to simplify the guards + * of the elements in "list". * - * If "up" is set then the resulting graft will be used at an outer level. - * In this case, "build" refers to the outer level, while "sub_build" - * refers to the inner level. If "up" is not set, then the same build - * should be passed to both arguments. + * The node is initialized to either a block containing the nodes of "children" + * or, if there is only a single child, the node of that child. + * If the current level requires a for node, it should be inserted by + * a subsequent call to isl_ast_graft_insert_for. + */ +__isl_give isl_ast_graft *isl_ast_graft_alloc_from_children( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *guard, + __isl_take isl_basic_set *enforced, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build) +{ + isl_ast_build *guard_build; + isl_ast_node *node; + isl_ast_node_list *node_list; + isl_ast_graft *graft; + + guard_build = isl_ast_build_copy(sub_build); + guard_build = isl_ast_build_replace_pending_by_guard(guard_build, + isl_set_copy(guard)); + list = gist_guards(list, guard); + list = insert_pending_guard_nodes(list, guard_build); + isl_ast_build_free(guard_build); + + node_list = extract_node_list(list); + node = isl_ast_node_from_ast_node_list(node_list); + isl_ast_graft_list_free(list); + + graft = isl_ast_graft_alloc(node, build); + graft = store_guard(graft, guard, build); + graft = isl_ast_graft_enforce(graft, enforced); + + return graft; +} + +/* Combine the grafts in the list into a single graft. * * The guard is initialized to the shared guard of the list elements (if any), * provided it does not depend on the current dimension. @@ -767,37 +887,20 @@ * or, if there is only a single element, the node of that element. */ static __isl_give isl_ast_graft *ast_graft_list_fuse( - __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build, - __isl_keep isl_ast_build *sub_build, int up) + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build) { - isl_ctx *ctx; - isl_ast_node *node; isl_ast_graft *graft; - isl_ast_node_list *node_list; + isl_basic_set *enforced; isl_set *guard; if (!list) return NULL; - ctx = isl_ast_build_get_ctx(build); - guard = extract_hoistable_guard(list, build); - list = gist_guards(list, guard); - list = insert_pending_guard_nodes(list, sub_build); - - node_list = extract_node_list(list); - node = isl_ast_node_from_ast_node_list(node_list); - - graft = isl_ast_graft_alloc(node, build); - - if (!up || isl_options_get_ast_build_exploit_nested_bounds(ctx)) { - isl_basic_set *enforced; - enforced = extract_shared_enforced(list, build); - graft = isl_ast_graft_enforce(graft, enforced); - } + enforced = isl_ast_graft_list_extract_shared_enforced(list, build); + guard = isl_ast_graft_list_extract_hoistable_guard(list, build); + graft = isl_ast_graft_alloc_from_children(list, guard, enforced, + build, build); - graft = store_guard(graft, guard, build); - - isl_ast_graft_list_free(list); return graft; } @@ -815,7 +918,7 @@ return NULL; if (isl_ast_graft_list_n_ast_graft(list) <= 1) return list; - graft = ast_graft_list_fuse(list, build, build, 0); + graft = ast_graft_list_fuse(list, build); return isl_ast_graft_list_from_ast_graft(graft); } @@ -835,24 +938,7 @@ list = isl_ast_graft_list_add(list, graft1); list = isl_ast_graft_list_add(list, graft2); - return ast_graft_list_fuse(list, build, build, 0); -} - -/* Allocate a graft for the current level based on the list of grafts - * of the inner level. - * "build" represents the context of the current level. - * "sub_build" represents the context of the inner level. - * - * The node is initialized to either a block containing the nodes of "children" - * or, if there is only a single child, the node of that child. - * If the current level requires a for node, it should be inserted by - * a subsequent call to isl_ast_graft_insert_for. - */ -__isl_give isl_ast_graft *isl_ast_graft_alloc_level( - __isl_take isl_ast_graft_list *children, - __isl_keep isl_ast_build *build, __isl_keep isl_ast_build *sub_build) -{ - return ast_graft_list_fuse(children, build, sub_build, 1); + return ast_graft_list_fuse(list, build); } /* Insert a for node enclosing the current graft->node. @@ -874,6 +960,25 @@ return NULL; } +/* Insert a mark governing the current graft->node. + */ +__isl_give isl_ast_graft *isl_ast_graft_insert_mark( + __isl_take isl_ast_graft *graft, __isl_take isl_id *mark) +{ + if (!graft) + goto error; + + graft->node = isl_ast_node_alloc_mark(mark, graft->node); + if (!graft->node) + return isl_ast_graft_free(graft); + + return graft; +error: + isl_id_free(mark); + isl_ast_graft_free(graft); + return NULL; +} + /* Represent the graft list as an AST node. * This operation drops the information about guards in the grafts, so * if there are any pending guards, then they are materialized as if nodes. @@ -942,30 +1047,12 @@ } /* Record that "guard" needs to be inserted in "graft". - * - * We first simplify the guard in the context of the enforced set and - * then we store the guard in case we may be able - * to hoist it to higher levels and/or combine it with those of other grafts. */ __isl_give isl_ast_graft *isl_ast_graft_add_guard( __isl_take isl_ast_graft *graft, __isl_take isl_set *guard, __isl_keep isl_ast_build *build) { - isl_basic_set *enforced; - - if (!graft || !build) - goto error; - - enforced = isl_basic_set_copy(graft->enforced); - guard = isl_set_gist(guard, isl_set_from_basic_set(enforced)); - - graft = store_guard(graft, guard, build); - - return graft; -error: - isl_set_free(guard); - isl_ast_graft_free(graft); - return NULL; + return store_guard(graft, guard, build); } /* Reformulate the "graft", which was generated in the context diff -Nru isl-0.12.2/isl_ast_graft_private.h isl-0.15/isl_ast_graft_private.h --- isl-0.12.2/isl_ast_graft_private.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/isl_ast_graft_private.h 2015-06-02 09:28:09.000000000 +0000 @@ -15,7 +15,7 @@ * "guard" contains conditions that should still be enforced by * some ancestor of the current tree. In particular, the already * generated tree assumes that these conditions hold, but may not - * enforced them itself. + * have enforced them itself. * The guard should not contain any unknown divs as it will be used * to generate an if condition. * @@ -44,9 +44,10 @@ __isl_give isl_ast_graft *isl_ast_graft_alloc( __isl_take isl_ast_node *node, __isl_keep isl_ast_build *build); -__isl_give isl_ast_graft *isl_ast_graft_alloc_level( - __isl_take isl_ast_graft_list *children, - __isl_keep isl_ast_build *build, __isl_keep isl_ast_build *sub_build); +__isl_give isl_ast_graft *isl_ast_graft_alloc_from_children( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *guard, + __isl_take isl_basic_set *enforced, __isl_keep isl_ast_build *build, + __isl_keep isl_ast_build *sub_build); __isl_give isl_ast_graft_list *isl_ast_graft_list_fuse( __isl_take isl_ast_graft_list *children, __isl_keep isl_ast_build *build); @@ -75,14 +76,26 @@ __isl_give isl_ast_graft *isl_ast_graft_enforce( __isl_take isl_ast_graft *graft, __isl_take isl_basic_set *enforced); +__isl_give isl_ast_graft *isl_ast_graft_insert_mark( + __isl_take isl_ast_graft *graft, __isl_take isl_id *mark); + __isl_give isl_ast_graft_list *isl_ast_graft_list_unembed( __isl_take isl_ast_graft_list *list, int product); __isl_give isl_ast_graft_list *isl_ast_graft_list_preimage_multi_aff( __isl_take isl_ast_graft_list *list, __isl_take isl_multi_aff *ma); +__isl_give isl_ast_graft_list *isl_ast_graft_list_insert_pending_guard_nodes( + __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build); __isl_give isl_ast_node *isl_ast_node_from_graft_list( __isl_take isl_ast_graft_list *list, __isl_keep isl_ast_build *build); +__isl_give isl_basic_set *isl_ast_graft_list_extract_shared_enforced( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build); +__isl_give isl_set *isl_ast_graft_list_extract_hoistable_guard( + __isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build); +__isl_give isl_ast_graft_list *isl_ast_graft_list_gist_guards( + __isl_take isl_ast_graft_list *list, __isl_take isl_set *context); + __isl_give isl_printer *isl_printer_print_ast_graft(__isl_take isl_printer *p, __isl_keep isl_ast_graft *graft); diff -Nru isl-0.12.2/isl_ast_int.c isl-0.15/isl_ast_int.c --- isl-0.12.2/isl_ast_int.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_ast_int.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,13 @@ +#include +#include +#include + +int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v) +{ + if (!expr) + return -1; + if (expr->type != isl_ast_expr_int) + isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid, + "expression not an int", return -1); + return isl_val_get_num_isl_int(expr->u.v, v); +} diff -Nru isl-0.12.2/isl_ast_private.h isl-0.15/isl_ast_private.h --- isl-0.12.2/isl_ast_private.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/isl_ast_private.h 2015-06-02 09:28:09.000000000 +0000 @@ -45,9 +45,10 @@ #include -/* A node is either a block, an if, a for or a user node. +/* A node is either a block, an if, a for, a user node or a mark node. * "else_node" is NULL if the if node does not have an else branch. * "cond" and "inc" are NULL for degenerate for nodes. + * In case of a mark node, "mark" is the mark and "node" is the marked node. */ struct isl_ast_node { int ref; @@ -75,6 +76,10 @@ struct { isl_ast_expr *expr; } e; + struct { + isl_id *mark; + isl_ast_node *node; + } m; } u; isl_id *annotation; @@ -86,6 +91,8 @@ __isl_give isl_ast_node *isl_ast_node_alloc_if(__isl_take isl_ast_expr *guard); __isl_give isl_ast_node *isl_ast_node_alloc_block( __isl_take isl_ast_node_list *list); +__isl_give isl_ast_node *isl_ast_node_alloc_mark(__isl_take isl_id *id, + __isl_take isl_ast_node *node); __isl_give isl_ast_node *isl_ast_node_from_ast_node_list( __isl_take isl_ast_node_list *list); __isl_give isl_ast_node *isl_ast_node_for_set_body( diff -Nru isl-0.12.2/isl_band.c isl-0.15/isl_band.c --- isl-0.12.2/isl_band.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_band.c 2015-06-02 09:28:09.000000000 +0000 @@ -55,12 +55,12 @@ return NULL; dup->n = band->n; - dup->zero = isl_alloc_array(ctx, int, band->n); - if (band->n && !dup->zero) + dup->coincident = isl_alloc_array(ctx, int, band->n); + if (band->n && !dup->coincident) goto error; for (i = 0; i < band->n; ++i) - dup->zero[i] = band->zero[i]; + dup->coincident[i] = band->coincident[i]; dup->pma = isl_union_pw_multi_aff_copy(band->pma); dup->schedule = band->schedule; @@ -96,17 +96,19 @@ * schedule), then we also need to decrement the reference count of the * containing schedule as it was incremented in isl_band_copy. */ -void *isl_band_free(__isl_take isl_band *band) +__isl_null isl_band *isl_band_free(__isl_take isl_band *band) { if (!band) return NULL; - if (--band->ref > 0) - return isl_schedule_free(band->schedule); + if (--band->ref > 0) { + isl_schedule_free(band->schedule); + return NULL; + } isl_union_pw_multi_aff_free(band->pma); isl_band_list_free(band->children); - free(band->zero); + free(band->coincident); free(band); return NULL; @@ -136,10 +138,10 @@ return band ? band->n : 0; } -/* Is the given scheduling dimension zero distance within the band and - * with respect to the proximity dependences. +/* Is the given scheduling dimension coincident within the band and + * with respect to the coincidence constraints. */ -int isl_band_member_is_zero_distance(__isl_keep isl_band *band, int pos) +int isl_band_member_is_coincident(__isl_keep isl_band *band, int pos) { if (!band) return -1; @@ -148,7 +150,7 @@ isl_die(isl_band_get_ctx(band), isl_error_invalid, "invalid member position", return -1); - return band->zero[pos]; + return band->coincident[pos]; } /* Return the schedule that leads up to this band. @@ -230,7 +232,7 @@ suffix_i = isl_band_get_suffix_schedule_union_pw_multi_aff(el); suffix_i = isl_union_pw_multi_aff_flat_range_product( partial, suffix_i); - suffix = isl_union_pw_multi_aff_add(suffix, suffix_i); + suffix = isl_union_pw_multi_aff_union_add(suffix, suffix_i); isl_band_free(el); } @@ -359,7 +361,7 @@ * floor(s_i(x) / m_i) * */ -static int multi_aff_tile(__isl_take isl_set *set, +static isl_stat multi_aff_tile(__isl_take isl_set *set, __isl_take isl_multi_aff *ma, void *user) { struct isl_band_tile_data *data = user; @@ -387,14 +389,14 @@ pma = isl_pw_multi_aff_alloc(set, ma); data->tiled = isl_pw_multi_aff_union_add(data->tiled, pma); - return 0; + return isl_stat_ok; } /* Given part of the schedule of a band, construct the corresponding * schedule for the tile loops based on the tile sizes in data->sizes * and add the result to data->res. */ -static int pw_multi_aff_tile(__isl_take isl_pw_multi_aff *pma, void *user) +static isl_stat pw_multi_aff_tile(__isl_take isl_pw_multi_aff *pma, void *user) { struct isl_band_tile_data *data = user; @@ -407,11 +409,11 @@ data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, data->tiled); - return 0; + return isl_stat_ok; error: isl_pw_multi_aff_free(pma); isl_pw_multi_aff_free(data->tiled); - return -1; + return isl_stat_error; } /* Given the schedule of a band, construct the corresponding @@ -448,14 +450,15 @@ * All entries are expected to have the same range space, so we can * stop after extracting the range space from the first entry. */ -static int extract_range_space(__isl_take isl_pw_multi_aff *pma, void *user) +static isl_stat extract_range_space(__isl_take isl_pw_multi_aff *pma, + void *user) { isl_space **space = user; *space = isl_space_range(isl_pw_multi_aff_get_space(pma)); isl_pw_multi_aff_free(pma); - return -1; + return isl_stat_error; } /* Extract the range space of "band". All entries in band->pma should @@ -601,7 +604,7 @@ /* Drop the data->n output dimensions starting at data->pos from "pma" * and add the result to data->res. */ -static int pw_multi_aff_drop(__isl_take isl_pw_multi_aff *pma, void *user) +static isl_stat pw_multi_aff_drop(__isl_take isl_pw_multi_aff *pma, void *user) { struct isl_union_pw_multi_aff_drop_data *data = user; @@ -609,9 +612,9 @@ data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); if (!data->res) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Drop the "n" output dimensions starting at "pos" from "sched". @@ -654,7 +657,7 @@ band->pma = sched; for (i = pos + n; i < band->n; ++i) - band->zero[i - n] = band->zero[i]; + band->coincident[i - n] = band->coincident[i]; band->n -= n; diff -Nru isl-0.12.2/isl_band_private.h isl-0.15/isl_band_private.h --- isl-0.12.2/isl_band_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_band_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -9,8 +9,9 @@ /* Information about a band within a schedule. * * n is the number of scheduling dimensions within the band. - * zero is an array of length n, indicating whether a scheduling dimension - * results in zero dependence distances for the proximity dependences. + * coincident is an array of length n, indicating whether a scheduling dimension + * satisfies the coincidence constraints in the sense that + * the corresponding dependence distances are zero. * pma is the partial schedule corresponding to this band. * schedule is the schedule that contains this band. * parent is the parent of this band (or NULL if the band is a root). @@ -25,7 +26,7 @@ int ref; int n; - int *zero; + int *coincident; isl_union_pw_multi_aff *pma; isl_schedule *schedule; diff -Nru isl-0.12.2/isl_bernstein.c isl-0.15/isl_bernstein.c --- isl-0.12.2/isl_bernstein.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_bernstein.c 2015-04-19 12:02:52.000000000 +0000 @@ -16,12 +16,13 @@ #include #include #include -#include +#include #include #include #include #include #include +#include #include struct bernstein_data { diff -Nru isl-0.12.2/isl_blk.c isl-0.15/isl_blk.c --- isl-0.12.2/isl_blk.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_blk.c 2015-04-21 11:36:25.000000000 +0000 @@ -7,7 +7,7 @@ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium */ -#include +#include #include /* The maximal number of cache misses before first element is evicted */ diff -Nru isl-0.12.2/isl_blk.h isl-0.15/isl_blk.h --- isl-0.12.2/isl_blk.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_blk.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,40 @@ +/* + * 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_BLK_H +#define ISL_BLK_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_blk { + size_t size; + isl_int *data; +}; + +#define ISL_BLK_CACHE_SIZE 20 + +struct isl_ctx; + +struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n); +struct isl_blk isl_blk_empty(void); +int isl_blk_is_error(struct isl_blk block); +struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block, + size_t new_n); +void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block); +void isl_blk_clear_cache(struct isl_ctx *ctx); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/isl_bound.c isl-0.15/isl_bound.c --- isl-0.12.2/isl_bound.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/isl_bound.c 2015-06-02 09:28:09.000000000 +0000 @@ -153,10 +153,10 @@ return r; } -static int guarded_qp(__isl_take isl_qpolynomial *qp, void *user) +static isl_stat guarded_qp(__isl_take isl_qpolynomial *qp, void *user) { struct isl_bound *bound = (struct isl_bound *)user; - int r; + isl_stat r; r = isl_qpolynomial_as_polynomial_on_domain(qp, bound->bset, &guarded_poly_bound, user); @@ -164,10 +164,10 @@ return r; } -static int basic_guarded_fold(__isl_take isl_basic_set *bset, void *user) +static isl_stat basic_guarded_fold(__isl_take isl_basic_set *bset, void *user) { struct isl_bound *bound = (struct isl_bound *)user; - int r; + isl_stat r; bound->bset = bset; r = isl_qpolynomial_fold_foreach_qpolynomial(bound->fold, @@ -176,7 +176,7 @@ return r; } -static int guarded_fold(__isl_take isl_set *set, +static isl_stat guarded_fold(__isl_take isl_set *set, __isl_take isl_qpolynomial_fold *fold, void *user) { struct isl_bound *bound = (struct isl_bound *)user; @@ -195,11 +195,11 @@ isl_set_free(set); isl_qpolynomial_fold_free(fold); - return 0; + return isl_stat_ok; error: isl_set_free(set); isl_qpolynomial_fold_free(fold); - return -1; + return isl_stat_error; } __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_bound( @@ -287,7 +287,7 @@ isl_union_pw_qpolynomial_fold *res; }; -static int bound_pw(__isl_take isl_pw_qpolynomial *pwqp, void *user) +static isl_stat bound_pw(__isl_take isl_pw_qpolynomial *pwqp, void *user) { struct isl_union_bound_data *data = user; isl_pw_qpolynomial_fold *pwf; @@ -297,7 +297,7 @@ data->res = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold( data->res, pwf); - return 0; + return isl_stat_ok; } __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_bound( diff -Nru isl-0.12.2/isl_coalesce.c isl-0.15/isl_coalesce.c --- isl-0.12.2/isl_coalesce.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_coalesce.c 2015-06-10 18:25:33.000000000 +0000 @@ -2,6 +2,7 @@ * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2010 INRIA Saclay * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * @@ -10,14 +11,18 @@ * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include "isl_map_private.h" -#include +#include #include #include "isl_tab.h" #include #include +#include +#include #define STATUS_ERROR -1 #define STATUS_REDUNDANT 1 @@ -54,6 +59,9 @@ int *eq = isl_calloc_array(bmap_i->ctx, int, 2 * bmap_i->n_eq); unsigned dim; + if (!eq) + return NULL; + dim = isl_basic_map_total_dim(bmap_i); for (k = 0; k < bmap_i->n_eq; ++k) { for (l = 0; l < 2; ++l) { @@ -84,6 +92,9 @@ unsigned n_eq = bmap_i->n_eq; int *ineq = isl_calloc_array(bmap_i->ctx, int, bmap_i->n_ineq); + if (!ineq) + return NULL; + for (k = 0; k < bmap_i->n_ineq; ++k) { if (tab_i && isl_tab_is_redundant(tab_i, n_eq + k)) { ineq[k] = STATUS_REDUNDANT; @@ -136,83 +147,252 @@ return 1; } -static void drop(struct isl_map *map, int i, struct isl_tab **tabs) +/* Internal information associated to a basic map in a map + * that is to be coalesced by isl_map_coalesce. + * + * "bmap" is the basic map itself (or NULL if "removed" is set) + * "tab" is the corresponding tableau (or NULL if "removed" is set) + * "hull_hash" identifies the affine space in which "bmap" lives. + * "removed" is set if this basic map has been removed from the map + * "simplify" is set if this basic map may have some unknown integer + * divisions that were not present in the input basic maps. The basic + * map should then be simplified such that we may be able to find + * a definition among the constraints. + * + * "eq" and "ineq" are only set if we are currently trying to coalesce + * this basic map with another basic map, in which case they represent + * the position of the inequalities of this basic map with respect to + * the other basic map. The number of elements in the "eq" array + * is twice the number of equalities in the "bmap", corresponding + * to the two inequalities that make up each equality. + */ +struct isl_coalesce_info { + isl_basic_map *bmap; + struct isl_tab *tab; + uint32_t hull_hash; + int removed; + int simplify; + int *eq; + int *ineq; +}; + +/* Compute the hash of the (apparent) affine hull of info->bmap (with + * the existentially quantified variables removed) and store it + * in info->hash. + */ +static int coalesce_info_set_hull_hash(struct isl_coalesce_info *info) +{ + isl_basic_map *hull; + unsigned n_div; + + hull = isl_basic_map_copy(info->bmap); + hull = isl_basic_map_plain_affine_hull(hull); + n_div = isl_basic_map_dim(hull, isl_dim_div); + hull = isl_basic_map_drop_constraints_involving_dims(hull, + isl_dim_div, 0, n_div); + info->hull_hash = isl_basic_map_get_hash(hull); + isl_basic_map_free(hull); + + return hull ? 0 : -1; +} + +/* Free all the allocated memory in an array + * of "n" isl_coalesce_info elements. + */ +static void clear_coalesce_info(int n, struct isl_coalesce_info *info) { - isl_basic_map_free(map->p[i]); - isl_tab_free(tabs[i]); + int i; + + if (!info) + return; - if (i != map->n - 1) { - map->p[i] = map->p[map->n - 1]; - tabs[i] = tabs[map->n - 1]; + for (i = 0; i < n; ++i) { + isl_basic_map_free(info[i].bmap); + isl_tab_free(info[i].tab); } - tabs[map->n - 1] = NULL; - map->n--; + + free(info); } -/* Replace the pair of basic maps i and j by the basic map bounded - * by the valid constraints in both basic maps and the constraint - * in extra (if not NULL). +/* Drop the basic map represented by "info". + * That is, clear the memory associated to the entry and + * mark it as having been removed. + */ +static void drop(struct isl_coalesce_info *info) +{ + info->bmap = isl_basic_map_free(info->bmap); + isl_tab_free(info->tab); + info->tab = NULL; + info->removed = 1; +} + +/* Exchange the information in "info1" with that in "info2". */ -static int fuse(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j, - __isl_keep isl_mat *extra) +static void exchange(struct isl_coalesce_info *info1, + struct isl_coalesce_info *info2) +{ + struct isl_coalesce_info info; + + info = *info1; + *info1 = *info2; + *info2 = info; +} + +/* This type represents the kind of change that has been performed + * while trying to coalesce two basic maps. + * + * isl_change_none: nothing was changed + * isl_change_drop_first: the first basic map was removed + * isl_change_drop_second: the second basic map was removed + * isl_change_fuse: the two basic maps were replaced by a new basic map. + */ +enum isl_change { + isl_change_error = -1, + isl_change_none = 0, + isl_change_drop_first, + isl_change_drop_second, + isl_change_fuse, +}; + +/* Update "change" based on an interchange of the first and the second + * basic map. That is, interchange isl_change_drop_first and + * isl_change_drop_second. + */ +static enum isl_change invert_change(enum isl_change change) +{ + switch (change) { + case isl_change_error: + return isl_change_error; + case isl_change_none: + return isl_change_none; + case isl_change_drop_first: + return isl_change_drop_second; + case isl_change_drop_second: + return isl_change_drop_first; + case isl_change_fuse: + return isl_change_fuse; + } + + return isl_change_error; +} + +/* Add the valid constraints of the basic map represented by "info" + * to "bmap". "len" is the size of the constraints. + * If only one of the pair of inequalities that make up an equality + * is valid, then add that inequality. + */ +static __isl_give isl_basic_map *add_valid_constraints( + __isl_take isl_basic_map *bmap, struct isl_coalesce_info *info, + unsigned len) { int k, l; - struct isl_basic_map *fused = NULL; - struct isl_tab *fused_tab = NULL; - unsigned total = isl_basic_map_total_dim(map->p[i]); - unsigned extra_rows = extra ? extra->n_row : 0; - fused = isl_basic_map_alloc_space(isl_space_copy(map->p[i]->dim), - map->p[i]->n_div, - map->p[i]->n_eq + map->p[j]->n_eq, - map->p[i]->n_ineq + map->p[j]->n_ineq + extra_rows); - if (!fused) - goto error; + if (!bmap) + return NULL; - for (k = 0; k < map->p[i]->n_eq; ++k) { - if (eq_i && (eq_i[2 * k] != STATUS_VALID || - eq_i[2 * k + 1] != STATUS_VALID)) - continue; - l = isl_basic_map_alloc_equality(fused); - if (l < 0) - goto error; - isl_seq_cpy(fused->eq[l], map->p[i]->eq[k], 1 + total); + for (k = 0; k < info->bmap->n_eq; ++k) { + if (info->eq[2 * k] == STATUS_VALID && + info->eq[2 * k + 1] == STATUS_VALID) { + l = isl_basic_map_alloc_equality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->eq[l], info->bmap->eq[k], len); + } else if (info->eq[2 * k] == STATUS_VALID) { + l = isl_basic_map_alloc_inequality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_neg(bmap->ineq[l], info->bmap->eq[k], len); + } else if (info->eq[2 * k + 1] == STATUS_VALID) { + l = isl_basic_map_alloc_inequality(bmap); + if (l < 0) + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->ineq[l], info->bmap->eq[k], len); + } } - for (k = 0; k < map->p[j]->n_eq; ++k) { - if (eq_j && (eq_j[2 * k] != STATUS_VALID || - eq_j[2 * k + 1] != STATUS_VALID)) + for (k = 0; k < info->bmap->n_ineq; ++k) { + if (info->ineq[k] != STATUS_VALID) continue; - l = isl_basic_map_alloc_equality(fused); + l = isl_basic_map_alloc_inequality(bmap); if (l < 0) - goto error; - isl_seq_cpy(fused->eq[l], map->p[j]->eq[k], 1 + total); + return isl_basic_map_free(bmap); + isl_seq_cpy(bmap->ineq[l], info->bmap->ineq[k], len); } - for (k = 0; k < map->p[i]->n_ineq; ++k) { - if (ineq_i[k] != STATUS_VALID) - continue; - l = isl_basic_map_alloc_inequality(fused); - if (l < 0) - goto error; - isl_seq_cpy(fused->ineq[l], map->p[i]->ineq[k], 1 + total); - } + return bmap; +} - for (k = 0; k < map->p[j]->n_ineq; ++k) { - if (ineq_j[k] != STATUS_VALID) - continue; - l = isl_basic_map_alloc_inequality(fused); - if (l < 0) - goto error; - isl_seq_cpy(fused->ineq[l], map->p[j]->ineq[k], 1 + total); - } +/* Is "bmap" defined by a number of (non-redundant) constraints that + * is greater than the number of constraints of basic maps i and j combined? + * Equalities are counted as two inequalities. + */ +static int number_of_constraints_increases(int i, int j, + struct isl_coalesce_info *info, + __isl_keep isl_basic_map *bmap, struct isl_tab *tab) +{ + int k, n_old, n_new; + + n_old = 2 * info[i].bmap->n_eq + info[i].bmap->n_ineq; + n_old += 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq; + + n_new = 2 * bmap->n_eq; + for (k = 0; k < bmap->n_ineq; ++k) + if (!isl_tab_is_redundant(tab, bmap->n_eq + k)) + ++n_new; + + return n_new > n_old; +} - for (k = 0; k < map->p[i]->n_div; ++k) { +/* Replace the pair of basic maps i and j by the basic map bounded + * by the valid constraints in both basic maps and the constraints + * in extra (if not NULL). + * Place the fused basic map in the position that is the smallest of i and j. + * + * If "detect_equalities" is set, then look for equalities encoded + * as pairs of inequalities. + * If "check_number" is set, then the original basic maps are only + * replaced if the total number of constraints does not increase. + * While the number of integer divisions in the two basic maps + * is assumed to be the same, the actual definitions may be different. + * We only copy the definition from one of the basic map if it is + * the same as that of the other basic map. Otherwise, we mark + * the integer division as unknown and schedule for the basic map + * to be simplified in an attempt to recover the integer division definition. + */ +static enum isl_change fuse(int i, int j, struct isl_coalesce_info *info, + __isl_keep isl_mat *extra, int detect_equalities, int check_number) +{ + int k, l; + struct isl_basic_map *fused = NULL; + struct isl_tab *fused_tab = NULL; + unsigned total = isl_basic_map_total_dim(info[i].bmap); + unsigned extra_rows = extra ? extra->n_row : 0; + unsigned n_eq, n_ineq; + + if (j < i) + return fuse(j, i, info, extra, detect_equalities, check_number); + + n_eq = info[i].bmap->n_eq + info[j].bmap->n_eq; + n_ineq = info[i].bmap->n_ineq + info[j].bmap->n_ineq; + fused = isl_basic_map_alloc_space(isl_space_copy(info[i].bmap->dim), + info[i].bmap->n_div, n_eq, n_eq + n_ineq + extra_rows); + fused = add_valid_constraints(fused, &info[i], 1 + total); + fused = add_valid_constraints(fused, &info[j], 1 + total); + if (!fused) + goto error; + + for (k = 0; k < info[i].bmap->n_div; ++k) { int l = isl_basic_map_alloc_div(fused); if (l < 0) goto error; - isl_seq_cpy(fused->div[l], map->p[i]->div[k], 1 + 1 + total); + if (isl_seq_eq(info[i].bmap->div[k], info[j].bmap->div[k], + 1 + 1 + total)) { + isl_seq_cpy(fused->div[l], info[i].bmap->div[k], + 1 + 1 + total); + } else { + isl_int_set_si(fused->div[l][0], 0); + info[i].simplify = 1; + } } for (k = 0; k < extra_rows; ++k) { @@ -222,27 +402,37 @@ isl_seq_cpy(fused->ineq[l], extra->row[k], 1 + total); } + if (detect_equalities) + fused = isl_basic_map_detect_inequality_pairs(fused, NULL); fused = isl_basic_map_gauss(fused, NULL); ISL_F_SET(fused, ISL_BASIC_MAP_FINAL); - if (ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_RATIONAL) && - ISL_F_ISSET(map->p[j], ISL_BASIC_MAP_RATIONAL)) + if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) && + ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL)) ISL_F_SET(fused, ISL_BASIC_MAP_RATIONAL); fused_tab = isl_tab_from_basic_map(fused, 0); if (isl_tab_detect_redundant(fused_tab) < 0) goto error; - isl_basic_map_free(map->p[i]); - map->p[i] = fused; - isl_tab_free(tabs[i]); - tabs[i] = fused_tab; - drop(map, j, tabs); + if (check_number && + number_of_constraints_increases(i, j, info, fused, fused_tab)) { + isl_tab_free(fused_tab); + isl_basic_map_free(fused); + return isl_change_none; + } + + info[i].simplify |= info[j].simplify; + isl_basic_map_free(info[i].bmap); + info[i].bmap = fused; + isl_tab_free(info[i].tab); + info[i].tab = fused_tab; + drop(&info[j]); - return 1; + return isl_change_fuse; error: isl_tab_free(fused_tab); isl_basic_map_free(fused); - return -1; + return isl_change_error; } /* Given a pair of basic maps i and j such that all constraints are either @@ -250,79 +440,107 @@ * constraints of i lie entirely within basic map j. * If so, replace the pair by the basic map consisting of the valid * constraints in both basic maps. + * Checking whether the facet lies entirely within basic map j + * is performed by checking whether the constraints of basic map j + * are valid for the facet. These tests are performed on a rational + * tableau to avoid the theoretical possibility that a constraint + * that was considered to be a cut constraint for the entire basic map i + * happens to be considered to be a valid constraint for the facet, + * even though it cuts off the same rational points. * * To see that we are not introducing any extra points, call the * two basic maps A and B and the resulting map U and let x * be an element of U \setminus ( A \cup B ). - * Then there is a pair of cut constraints c_1 and c_2 in A and B such that x - * violates them. Let X be the intersection of U with the opposites - * of these constraints. Then x \in X. - * The facet corresponding to c_1 contains the corresponding facet of A. - * This facet is entirely contained in B, so c_2 is valid on the facet. - * However, since it is also (part of) a facet of X, -c_2 is also valid - * on the facet. This means c_2 is saturated on the facet, so c_1 and - * c_2 must be opposites of each other, but then x could not violate - * both of them. + * A line connecting x with an element of A \cup B meets a facet F + * of either A or B. Assume it is a facet of B and let c_1 be + * the corresponding facet constraint. We have c_1(x) < 0 and + * so c_1 is a cut constraint. This implies that there is some + * (possibly rational) point x' satisfying the constraints of A + * and the opposite of c_1 as otherwise c_1 would have been marked + * valid for A. The line connecting x and x' meets a facet of A + * in a (possibly rational) point that also violates c_1, but this + * is impossible since all cut constraints of B are valid for all + * cut facets of A. + * In case F is a facet of A rather than B, then we can apply the + * above reasoning to find a facet of B separating x from A \cup B first. */ -static int check_facets(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *ineq_i, int *ineq_j) +static enum isl_change check_facets(int i, int j, + struct isl_coalesce_info *info) { int k, l; - struct isl_tab_undo *snap; - unsigned n_eq = map->p[i]->n_eq; + struct isl_tab_undo *snap, *snap2; + unsigned n_eq = info[i].bmap->n_eq; - snap = isl_tab_snap(tabs[i]); + snap = isl_tab_snap(info[i].tab); + if (isl_tab_mark_rational(info[i].tab) < 0) + return isl_change_error; + snap2 = isl_tab_snap(info[i].tab); - for (k = 0; k < map->p[i]->n_ineq; ++k) { - if (ineq_i[k] != STATUS_CUT) + for (k = 0; k < info[i].bmap->n_ineq; ++k) { + if (info[i].ineq[k] != STATUS_CUT) continue; - if (isl_tab_select_facet(tabs[i], n_eq + k) < 0) - return -1; - for (l = 0; l < map->p[j]->n_ineq; ++l) { + if (isl_tab_select_facet(info[i].tab, n_eq + k) < 0) + return isl_change_error; + for (l = 0; l < info[j].bmap->n_ineq; ++l) { int stat; - if (ineq_j[l] != STATUS_CUT) + if (info[j].ineq[l] != STATUS_CUT) continue; - stat = status_in(map->p[j]->ineq[l], tabs[i]); + stat = status_in(info[j].bmap->ineq[l], info[i].tab); + if (stat < 0) + return isl_change_error; if (stat != STATUS_VALID) break; } - if (isl_tab_rollback(tabs[i], snap) < 0) - return -1; - if (l < map->p[j]->n_ineq) + if (isl_tab_rollback(info[i].tab, snap2) < 0) + return isl_change_error; + if (l < info[j].bmap->n_ineq) break; } - if (k < map->p[i]->n_ineq) - /* BAD CUT PAIR */ - return 0; - return fuse(map, i, j, tabs, NULL, ineq_i, NULL, ineq_j, NULL); + if (k < info[i].bmap->n_ineq) { + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; + return isl_change_none; + } + return fuse(i, j, info, NULL, 0, 0); } -/* Check if basic map "i" contains the basic map represented +/* Check if info->bmap contains the basic map represented * by the tableau "tab". + * For each equality, we check both the constraint itself + * (as an inequality) and its negation. Make sure the + * equality is returned to its original state before returning. */ -static int contains(struct isl_map *map, int i, int *ineq_i, - struct isl_tab *tab) +static int contains(struct isl_coalesce_info *info, struct isl_tab *tab) { - int k, l; + int k; unsigned dim; + isl_basic_map *bmap = info->bmap; - dim = isl_basic_map_total_dim(map->p[i]); - for (k = 0; k < map->p[i]->n_eq; ++k) { - for (l = 0; l < 2; ++l) { - int stat; - isl_seq_neg(map->p[i]->eq[k], map->p[i]->eq[k], 1+dim); - stat = status_in(map->p[i]->eq[k], tab); - if (stat != STATUS_VALID) - return 0; - } + dim = isl_basic_map_total_dim(bmap); + for (k = 0; k < bmap->n_eq; ++k) { + int stat; + isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim); + stat = status_in(bmap->eq[k], tab); + isl_seq_neg(bmap->eq[k], bmap->eq[k], 1 + dim); + if (stat < 0) + return -1; + if (stat != STATUS_VALID) + return 0; + stat = status_in(bmap->eq[k], tab); + if (stat < 0) + return -1; + if (stat != STATUS_VALID) + return 0; } - for (k = 0; k < map->p[i]->n_ineq; ++k) { + for (k = 0; k < bmap->n_ineq; ++k) { int stat; - if (ineq_i[k] == STATUS_REDUNDANT) + if (info->ineq[k] == STATUS_REDUNDANT) continue; - stat = status_in(map->p[i]->ineq[k], tab); + stat = status_in(bmap->ineq[k], tab); + if (stat < 0) + return -1; if (stat != STATUS_VALID) return 0; } @@ -366,53 +584,57 @@ * | || | | | * |__||_/ |_____/ */ -static int is_adj_ineq_extension(__isl_keep isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change is_adj_ineq_extension(int i, int j, + struct isl_coalesce_info *info) { int k; struct isl_tab_undo *snap; - unsigned n_eq = map->p[i]->n_eq; - unsigned total = isl_basic_map_total_dim(map->p[i]); + unsigned n_eq = info[i].bmap->n_eq; + unsigned total = isl_basic_map_total_dim(info[i].bmap); int r; + int super; - if (isl_tab_extend_cons(tabs[i], 1 + map->p[j]->n_ineq) < 0) - return -1; + if (isl_tab_extend_cons(info[i].tab, 1 + info[j].bmap->n_ineq) < 0) + return isl_change_error; - for (k = 0; k < map->p[i]->n_ineq; ++k) - if (ineq_i[k] == STATUS_ADJ_INEQ) + for (k = 0; k < info[i].bmap->n_ineq; ++k) + if (info[i].ineq[k] == STATUS_ADJ_INEQ) break; - if (k >= map->p[i]->n_ineq) - isl_die(isl_map_get_ctx(map), isl_error_internal, - "ineq_i should have exactly one STATUS_ADJ_INEQ", - return -1); - - snap = isl_tab_snap(tabs[i]); - - if (isl_tab_unrestrict(tabs[i], n_eq + k) < 0) - return -1; - - isl_seq_neg(map->p[i]->ineq[k], map->p[i]->ineq[k], 1 + total); - isl_int_sub_ui(map->p[i]->ineq[k][0], map->p[i]->ineq[k][0], 1); - r = isl_tab_add_ineq(tabs[i], map->p[i]->ineq[k]); - isl_seq_neg(map->p[i]->ineq[k], map->p[i]->ineq[k], 1 + total); - isl_int_sub_ui(map->p[i]->ineq[k][0], map->p[i]->ineq[k][0], 1); + if (k >= info[i].bmap->n_ineq) + isl_die(isl_basic_map_get_ctx(info[i].bmap), isl_error_internal, + "info[i].ineq should have exactly one STATUS_ADJ_INEQ", + return isl_change_error); + + snap = isl_tab_snap(info[i].tab); + + if (isl_tab_unrestrict(info[i].tab, n_eq + k) < 0) + return isl_change_error; + + isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total); + isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1); + r = isl_tab_add_ineq(info[i].tab, info[i].bmap->ineq[k]); + isl_seq_neg(info[i].bmap->ineq[k], info[i].bmap->ineq[k], 1 + total); + isl_int_sub_ui(info[i].bmap->ineq[k][0], info[i].bmap->ineq[k][0], 1); if (r < 0) - return -1; + return isl_change_error; - for (k = 0; k < map->p[j]->n_ineq; ++k) { - if (ineq_j[k] != STATUS_VALID) + for (k = 0; k < info[j].bmap->n_ineq; ++k) { + if (info[j].ineq[k] != STATUS_VALID) continue; - if (isl_tab_add_ineq(tabs[i], map->p[j]->ineq[k]) < 0) - return -1; + if (isl_tab_add_ineq(info[i].tab, info[j].bmap->ineq[k]) < 0) + return isl_change_error; } - if (contains(map, j, ineq_j, tabs[i])) - return fuse(map, i, j, tabs, eq_i, ineq_i, eq_j, ineq_j, NULL); + super = contains(&info[j], info[i].tab); + if (super < 0) + return isl_change_error; + if (super) + return fuse(i, j, info, NULL, 0, 0); - if (isl_tab_rollback(tabs[i], snap) < 0) - return -1; + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; - return 0; + return isl_change_none; } @@ -447,35 +669,33 @@ * still be able to fuse the two basic maps, but we need to perform * some additional checks in is_adj_ineq_extension. */ -static int check_adj_ineq(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change check_adj_ineq(int i, int j, + struct isl_coalesce_info *info) { int count_i, count_j; int cut_i, cut_j; - count_i = count(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_INEQ); - count_j = count(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_INEQ); + count_i = count(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ); + count_j = count(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ); if (count_i != 1 && count_j != 1) - return 0; + return isl_change_none; - cut_i = any(eq_i, 2 * map->p[i]->n_eq, STATUS_CUT) || - any(ineq_i, map->p[i]->n_ineq, STATUS_CUT); - cut_j = any(eq_j, 2 * map->p[j]->n_eq, STATUS_CUT) || - any(ineq_j, map->p[j]->n_ineq, STATUS_CUT); + cut_i = any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT) || + any(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT); + cut_j = any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_CUT) || + any(info[j].ineq, info[j].bmap->n_ineq, STATUS_CUT); if (!cut_i && !cut_j && count_i == 1 && count_j == 1) - return fuse(map, i, j, tabs, NULL, ineq_i, NULL, ineq_j, NULL); + return fuse(i, j, info, NULL, 0, 0); if (count_i == 1 && !cut_i) - return is_adj_ineq_extension(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j); + return is_adj_ineq_extension(i, j, info); if (count_j == 1 && !cut_j) - return is_adj_ineq_extension(map, j, i, tabs, - eq_j, ineq_j, eq_i, ineq_i); + return is_adj_ineq_extension(j, i, info); - return 0; + return isl_change_none; } /* Basic map "i" has an inequality "k" that is adjacent to some equality @@ -489,6 +709,11 @@ * other basic map is included in the extension, because there * were no "cut" inequalities in "i") and we can replace the * two basic maps by this extension. + * Each integer division that does not have exactly the same + * definition in "i" and "j" is marked unknown and the basic map + * is scheduled to be simplified in an attempt to recover + * the integer division definition. + * Place this extension in the position that is the smallest of i and j. * ____ _____ * / || / | * / || / | @@ -496,38 +721,54 @@ * \ || \ | * \___|| \____| */ -static int is_adj_eq_extension(struct isl_map *map, int i, int j, int k, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change is_adj_eq_extension(int i, int j, int k, + struct isl_coalesce_info *info) { - int changed = 0; + int change = isl_change_none; int super; struct isl_tab_undo *snap, *snap2; - unsigned n_eq = map->p[i]->n_eq; + unsigned n_eq = info[i].bmap->n_eq; - if (isl_tab_is_equality(tabs[i], n_eq + k)) - return 0; + if (isl_tab_is_equality(info[i].tab, n_eq + k)) + return isl_change_none; - snap = isl_tab_snap(tabs[i]); - tabs[i] = isl_tab_relax(tabs[i], n_eq + k); - snap2 = isl_tab_snap(tabs[i]); - if (isl_tab_select_facet(tabs[i], n_eq + k) < 0) - return -1; - super = contains(map, j, ineq_j, tabs[i]); + snap = isl_tab_snap(info[i].tab); + if (isl_tab_relax(info[i].tab, n_eq + k) < 0) + return isl_change_error; + snap2 = isl_tab_snap(info[i].tab); + if (isl_tab_select_facet(info[i].tab, n_eq + k) < 0) + return isl_change_error; + super = contains(&info[j], info[i].tab); + if (super < 0) + return isl_change_error; if (super) { - if (isl_tab_rollback(tabs[i], snap2) < 0) - return -1; - map->p[i] = isl_basic_map_cow(map->p[i]); - if (!map->p[i]) - return -1; - isl_int_add_ui(map->p[i]->ineq[k][0], map->p[i]->ineq[k][0], 1); - ISL_F_SET(map->p[i], ISL_BASIC_MAP_FINAL); - drop(map, j, tabs); - changed = 1; + int l; + unsigned total; + + if (isl_tab_rollback(info[i].tab, snap2) < 0) + return isl_change_error; + info[i].bmap = isl_basic_map_cow(info[i].bmap); + if (!info[i].bmap) + return isl_change_error; + total = isl_basic_map_total_dim(info[i].bmap); + for (l = 0; l < info[i].bmap->n_div; ++l) + if (!isl_seq_eq(info[i].bmap->div[l], + info[j].bmap->div[l], 1 + 1 + total)) { + isl_int_set_si(info[i].bmap->div[l][0], 0); + info[i].simplify = 1; + } + isl_int_add_ui(info[i].bmap->ineq[k][0], + info[i].bmap->ineq[k][0], 1); + ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_FINAL); + drop(&info[j]); + if (j < i) + exchange(&info[i], &info[j]); + change = isl_change_fuse; } else - if (isl_tab_rollback(tabs[i], snap) < 0) - return -1; + if (isl_tab_rollback(info[i].tab, snap) < 0) + return isl_change_error; - return changed; + return change; } /* Data structure that keeps track of the wrapping constraints @@ -544,31 +785,32 @@ }; /* Update wraps->max to be greater than or equal to the coefficients - * in the equalities and inequalities of bmap that can be removed if we end up - * applying wrapping. + * in the equalities and inequalities of info->bmap that can be removed + * if we end up applying wrapping. */ static void wraps_update_max(struct isl_wraps *wraps, - __isl_keep isl_basic_map *bmap, int *eq, int *ineq) + struct isl_coalesce_info *info) { int k; isl_int max_k; - unsigned total = isl_basic_map_total_dim(bmap); + unsigned total = isl_basic_map_total_dim(info->bmap); isl_int_init(max_k); - for (k = 0; k < bmap->n_eq; ++k) { - if (eq[2 * k] == STATUS_VALID && - eq[2 * k + 1] == STATUS_VALID) + for (k = 0; k < info->bmap->n_eq; ++k) { + if (info->eq[2 * k] == STATUS_VALID && + info->eq[2 * k + 1] == STATUS_VALID) continue; - isl_seq_abs_max(bmap->eq[k] + 1, total, &max_k); + isl_seq_abs_max(info->bmap->eq[k] + 1, total, &max_k); if (isl_int_abs_gt(max_k, wraps->max)) isl_int_set(wraps->max, max_k); } - for (k = 0; k < bmap->n_ineq; ++k) { - if (ineq[k] == STATUS_VALID || ineq[k] == STATUS_REDUNDANT) + for (k = 0; k < info->bmap->n_ineq; ++k) { + if (info->ineq[k] == STATUS_VALID || + info->ineq[k] == STATUS_REDUNDANT) continue; - isl_seq_abs_max(bmap->ineq[k] + 1, total, &max_k); + isl_seq_abs_max(info->bmap->ineq[k] + 1, total, &max_k); if (isl_int_abs_gt(max_k, wraps->max)) isl_int_set(wraps->max, max_k); } @@ -583,8 +825,7 @@ * applying wrapping. */ static void wraps_init(struct isl_wraps *wraps, __isl_take isl_mat *mat, - __isl_keep isl_map *map, int i, int j, - int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) + struct isl_coalesce_info *info, int i, int j) { isl_ctx *ctx; @@ -598,8 +839,8 @@ return; isl_int_init(wraps->max); isl_int_set_si(wraps->max, 0); - wraps_update_max(wraps, map->p[i], eq_i, ineq_i); - wraps_update_max(wraps, map->p[j], eq_j, ineq_j); + wraps_update_max(wraps, &info[i]); + wraps_update_max(wraps, &info[j]); } /* Free the contents of the isl_wraps data structure. @@ -630,9 +871,40 @@ return 1; } -/* For each non-redundant constraint in "bmap" (as determined by "tab"), +/* Wrap "ineq" (or its opposite if "negate" is set) around "bound" + * to include "set" and add the result in position "w" of "wraps". + * "len" is the total number of coefficients in "bound" and "ineq". + * Return 1 on success, 0 on failure and -1 on error. + * Wrapping can fail if the result of wrapping is equal to "bound" + * or if we want to bound the sizes of the coefficients and + * the wrapped constraint does not satisfy this bound. + */ +static int add_wrap(struct isl_wraps *wraps, int w, isl_int *bound, + isl_int *ineq, unsigned len, __isl_keep isl_set *set, int negate) +{ + isl_seq_cpy(wraps->mat->row[w], bound, len); + if (negate) { + isl_seq_neg(wraps->mat->row[w + 1], ineq, len); + ineq = wraps->mat->row[w + 1]; + } + if (!isl_set_wrap_facet(set, wraps->mat->row[w], ineq)) + return -1; + if (isl_seq_eq(wraps->mat->row[w], bound, len)) + return 0; + if (!allow_wrap(wraps, w)) + return 0; + return 1; +} + +/* For each constraint in info->bmap that is not redundant (as determined + * by info->tab) and that is not a valid constraint for the other basic map, * wrap the constraint around "bound" such that it includes the whole * set "set" and append the resulting constraint to "wraps". + * Note that the constraints that are valid for the other basic map + * will be added to the combined basic map by default, so there is + * no need to wrap them. + * The caller wrap_in_facets even relies on this function not wrapping + * any constraints that are already valid. * "wraps" is assumed to have been pre-allocated to the appropriate size. * wraps->n_row is the number of actual wrapped constraints that have * been added. @@ -644,57 +916,52 @@ * constraints and a newly added wrapping constraint does not * satisfy the bound, then wraps->n_row is also reset to zero. */ -static int add_wraps(struct isl_wraps *wraps, __isl_keep isl_basic_map *bmap, - struct isl_tab *tab, isl_int *bound, __isl_keep isl_set *set) +static int add_wraps(struct isl_wraps *wraps, struct isl_coalesce_info *info, + isl_int *bound, __isl_keep isl_set *set) { - int l; + int l, m; int w; - unsigned total = isl_basic_map_total_dim(bmap); + int added; + isl_basic_map *bmap = info->bmap; + unsigned len = 1 + isl_basic_map_total_dim(bmap); w = wraps->mat->n_row; for (l = 0; l < bmap->n_ineq; ++l) { - if (isl_seq_is_neg(bound, bmap->ineq[l], 1 + total)) + if (info->ineq[l] == STATUS_VALID || + info->ineq[l] == STATUS_REDUNDANT) continue; - if (isl_seq_eq(bound, bmap->ineq[l], 1 + total)) + if (isl_seq_is_neg(bound, bmap->ineq[l], len)) continue; - if (isl_tab_is_redundant(tab, bmap->n_eq + l)) + if (isl_seq_eq(bound, bmap->ineq[l], len)) + continue; + if (isl_tab_is_redundant(info->tab, bmap->n_eq + l)) continue; - isl_seq_cpy(wraps->mat->row[w], bound, 1 + total); - if (!isl_set_wrap_facet(set, wraps->mat->row[w], bmap->ineq[l])) + added = add_wrap(wraps, w, bound, bmap->ineq[l], len, set, 0); + if (added < 0) return -1; - if (isl_seq_eq(wraps->mat->row[w], bound, 1 + total)) - goto unbounded; - if (!allow_wrap(wraps, w)) + if (!added) goto unbounded; ++w; } for (l = 0; l < bmap->n_eq; ++l) { - if (isl_seq_is_neg(bound, bmap->eq[l], 1 + total)) + if (isl_seq_is_neg(bound, bmap->eq[l], len)) continue; - if (isl_seq_eq(bound, bmap->eq[l], 1 + total)) + if (isl_seq_eq(bound, bmap->eq[l], len)) continue; - isl_seq_cpy(wraps->mat->row[w], bound, 1 + total); - isl_seq_neg(wraps->mat->row[w + 1], bmap->eq[l], 1 + total); - if (!isl_set_wrap_facet(set, wraps->mat->row[w], - wraps->mat->row[w + 1])) - return -1; - if (isl_seq_eq(wraps->mat->row[w], bound, 1 + total)) - goto unbounded; - if (!allow_wrap(wraps, w)) - goto unbounded; - ++w; - - isl_seq_cpy(wraps->mat->row[w], bound, 1 + total); - if (!isl_set_wrap_facet(set, wraps->mat->row[w], bmap->eq[l])) - return -1; - if (isl_seq_eq(wraps->mat->row[w], bound, 1 + total)) - goto unbounded; - if (!allow_wrap(wraps, w)) - goto unbounded; - ++w; + for (m = 0; m < 2; ++m) { + if (info->eq[2 * l + m] == STATUS_VALID) + continue; + added = add_wrap(wraps, w, bound, bmap->eq[l], len, + set, !m); + if (added < 0) + return -1; + if (!added) + goto unbounded; + ++w; + } } wraps->mat->n_row = w; @@ -727,7 +994,7 @@ return 0; } -/* Return a set that corresponds to the non-redudant constraints +/* Return a set that corresponds to the non-redundant constraints * (as recorded in tab) of bmap. * * It's important to remove the redundant constraints as some @@ -738,34 +1005,73 @@ * and should therefore continue to be ignored ever after. * Otherwise, the relaxation might be thwarted by some of * these constraints. + * + * Update the underlying set to ensure that the dimension doesn't change. + * Otherwise the integer divisions could get dropped if the tab + * turns out to be empty. */ static __isl_give isl_set *set_from_updated_bmap(__isl_keep isl_basic_map *bmap, struct isl_tab *tab) { + isl_basic_set *bset; + bmap = isl_basic_map_copy(bmap); - bmap = isl_basic_map_cow(bmap); - bmap = isl_basic_map_update_from_tab(bmap, tab); - return isl_set_from_basic_set(isl_basic_map_underlying_set(bmap)); + bset = isl_basic_map_underlying_set(bmap); + bset = isl_basic_set_cow(bset); + bset = isl_basic_set_update_from_tab(bset, tab); + return isl_set_from_basic_set(bset); +} + +/* Wrap the constraints of info->bmap that bound the facet defined + * by inequality "k" around (the opposite of) this inequality to + * include "set". "bound" may be used to store the negated inequality. + * Since the wrapped constraints are not guaranteed to contain the whole + * of info->bmap, we check them in check_wraps. + * If any of the wrapped constraints turn out to be invalid, then + * check_wraps will reset wrap->n_row to zero. + */ +static int add_wraps_around_facet(struct isl_wraps *wraps, + struct isl_coalesce_info *info, int k, isl_int *bound, + __isl_keep isl_set *set) +{ + struct isl_tab_undo *snap; + int n; + unsigned total = isl_basic_map_total_dim(info->bmap); + + snap = isl_tab_snap(info->tab); + + if (isl_tab_select_facet(info->tab, info->bmap->n_eq + k) < 0) + return -1; + if (isl_tab_detect_redundant(info->tab) < 0) + return -1; + + isl_seq_neg(bound, info->bmap->ineq[k], 1 + total); + + n = wraps->mat->n_row; + if (add_wraps(wraps, info, bound, set) < 0) + return -1; + + if (isl_tab_rollback(info->tab, snap) < 0) + return -1; + if (check_wraps(wraps->mat, n, info->tab) < 0) + return -1; + + return 0; } -/* Given a basic set i with a constraint k that is adjacent to either the - * whole of basic set j or a facet of basic set j, check if we can wrap - * both the facet corresponding to k and the facet of j (or the whole of j) - * around their ridges to include the other set. +/* Given a basic set i with a constraint k that is adjacent to + * basic set j, check if we can wrap + * both the facet corresponding to k (if "wrap_facet" is set) and basic map j + * (always) around their ridges to include the other set. * If so, replace the pair of basic sets by their union. * - * All constraints of i (except k) are assumed to be valid for j. - * - * However, the constraints of j may not be valid for i and so - * we have to check that the wrapping constraints for j are valid for i. - * - * In the case where j has a facet adjacent to i, tab[j] is assumed - * to have been restricted to this facet, so that the non-redundant - * constraints in tab[j] are the ridges of the facet. - * Note that for the purpose of wrapping, it does not matter whether - * we wrap the ridges of i around the whole of j or just around - * the facet since all the other constraints are assumed to be valid for j. - * In practice, we wrap to include the whole of j. + * All constraints of i (except k) are assumed to be valid or + * cut constraints for j. + * Wrapping the cut constraints to include basic map j may result + * in constraints that are no longer valid of basic map i + * we have to check that the resulting wrapping constraints are valid for i. + * If "wrap_facet" is not set, then all constraints of i (except k) + * are assumed to be valid for j. * ____ _____ * / | / \ * / || / | @@ -774,61 +1080,49 @@ * \___|| \____| * */ -static int can_wrap_in_facet(struct isl_map *map, int i, int j, int k, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change can_wrap_in_facet(int i, int j, int k, + struct isl_coalesce_info *info, int wrap_facet) { - int changed = 0; + enum isl_change change = isl_change_none; struct isl_wraps wraps; + isl_ctx *ctx; isl_mat *mat; struct isl_set *set_i = NULL; struct isl_set *set_j = NULL; struct isl_vec *bound = NULL; - unsigned total = isl_basic_map_total_dim(map->p[i]); - struct isl_tab_undo *snap; - int n; + unsigned total = isl_basic_map_total_dim(info[i].bmap); - set_i = set_from_updated_bmap(map->p[i], tabs[i]); - set_j = set_from_updated_bmap(map->p[j], tabs[j]); - mat = isl_mat_alloc(map->ctx, 2 * (map->p[i]->n_eq + map->p[j]->n_eq) + - map->p[i]->n_ineq + map->p[j]->n_ineq, - 1 + total); - wraps_init(&wraps, mat, map, i, j, eq_i, ineq_i, eq_j, ineq_j); - bound = isl_vec_alloc(map->ctx, 1 + total); + set_i = set_from_updated_bmap(info[i].bmap, info[i].tab); + set_j = set_from_updated_bmap(info[j].bmap, info[j].tab); + ctx = isl_basic_map_get_ctx(info[i].bmap); + mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) + + info[i].bmap->n_ineq + info[j].bmap->n_ineq, + 1 + total); + wraps_init(&wraps, mat, info, i, j); + bound = isl_vec_alloc(ctx, 1 + total); if (!set_i || !set_j || !wraps.mat || !bound) goto error; - isl_seq_cpy(bound->el, map->p[i]->ineq[k], 1 + total); + isl_seq_cpy(bound->el, info[i].bmap->ineq[k], 1 + total); isl_int_add_ui(bound->el[0], bound->el[0], 1); isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total); wraps.mat->n_row = 1; - if (add_wraps(&wraps, map->p[j], tabs[j], bound->el, set_i) < 0) + if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0) goto error; if (!wraps.mat->n_row) goto unbounded; - snap = isl_tab_snap(tabs[i]); - - if (isl_tab_select_facet(tabs[i], map->p[i]->n_eq + k) < 0) - goto error; - if (isl_tab_detect_redundant(tabs[i]) < 0) - goto error; - - isl_seq_neg(bound->el, map->p[i]->ineq[k], 1 + total); - - n = wraps.mat->n_row; - if (add_wraps(&wraps, map->p[i], tabs[i], bound->el, set_j) < 0) - goto error; - - if (isl_tab_rollback(tabs[i], snap) < 0) - goto error; - if (check_wraps(wraps.mat, n, tabs[i]) < 0) - goto error; - if (!wraps.mat->n_row) - goto unbounded; + if (wrap_facet) { + if (add_wraps_around_facet(&wraps, &info[i], k, + bound->el, set_j) < 0) + goto error; + if (!wraps.mat->n_row) + goto unbounded; + } - changed = fuse(map, i, j, tabs, eq_i, ineq_i, eq_j, ineq_j, wraps.mat); + change = fuse(i, j, info, wraps.mat, 0, 0); unbounded: wraps_free(&wraps); @@ -838,38 +1132,13 @@ isl_vec_free(bound); - return changed; + return change; error: wraps_free(&wraps); isl_vec_free(bound); isl_set_free(set_i); isl_set_free(set_j); - return -1; -} - -/* Set the is_redundant property of the "n" constraints in "cuts", - * except "k" to "v". - * This is a fairly tricky operation as it bypasses isl_tab.c. - * The reason we want to temporarily mark some constraints redundant - * is that we want to ignore them in add_wraps. - * - * Initially all cut constraints are non-redundant, but the - * selection of a facet right before the call to this function - * may have made some of them redundant. - * Likewise, the same constraints are marked non-redundant - * in the second call to this function, before they are officially - * made non-redundant again in the subsequent rollback. - */ -static void set_is_redundant(struct isl_tab *tab, unsigned n_eq, - int *cuts, int n, int k, int v) -{ - int l; - - for (l = 0; l < n; ++l) { - if (l == k) - continue; - tab->con[n_eq + cuts[l]].is_redundant = v; - } + return isl_change_error; } /* Given a pair of basic maps i and j such that j sticks out @@ -878,91 +1147,75 @@ * basic maps by a single basic map. * The other constraints of i are assumed to be valid for j. * - * The facets of i corresponding to the cut constraints are - * wrapped around their ridges, except those ridges determined - * by any of the other cut constraints. - * The intersections of cut constraints need to be ignored - * as the result of wrapping one cut constraint around another - * would result in a constraint cutting the union. - * In each case, the facets are wrapped to include the union - * of the two basic maps. - * - * The pieces of j that lie at an offset of exactly one from - * one of the cut constraints of i are wrapped around their edges. - * Here, there is no need to ignore intersections because we - * are wrapping around the union of the two basic maps. + * For each cut constraint t(x) >= 0 of i, we add the relaxed version + * t(x) + 1 >= 0, along with wrapping constraints for all constraints + * of basic map j that bound the part of basic map j that sticks out + * of the cut constraint. + * In particular, we first intersect basic map j with t(x) + 1 = 0. + * If the result is empty, then t(x) >= 0 was actually a valid constraint + * (with respect to the integer points), so we add t(x) >= 0 instead. + * Otherwise, we wrap the constraints of basic map j that are not + * redundant in this intersection and that are not already valid + * for basic map i over basic map i. + * Note that it is sufficient to wrap the constraints to include + * basic map i, because we will only wrap the constraints that do + * not include basic map i already. The wrapped constraint will + * therefore be more relaxed compared to the original constraint. + * Since the original constraint is valid for basic map j, so is + * the wrapped constraint. * * If any wrapping fails, i.e., if we cannot wrap to touch * the union, then we give up. * Otherwise, the pair of basic maps is replaced by their union. */ -static int wrap_in_facets(struct isl_map *map, int i, int j, - int *cuts, int n, struct isl_tab **tabs, - int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change wrap_in_facets(int i, int j, int *cuts, int n, + struct isl_coalesce_info *info) { - int changed = 0; + enum isl_change change = isl_change_none; struct isl_wraps wraps; + isl_ctx *ctx; isl_mat *mat; - isl_set *set = NULL; - isl_vec *bound = NULL; - unsigned total = isl_basic_map_total_dim(map->p[i]); + isl_set *set_i = NULL; + unsigned total = isl_basic_map_total_dim(info[i].bmap); int max_wrap; - int k; - struct isl_tab_undo *snap_i, *snap_j; + int k, w; + struct isl_tab_undo *snap; - if (isl_tab_extend_cons(tabs[j], 1) < 0) + if (isl_tab_extend_cons(info[j].tab, 1) < 0) goto error; - max_wrap = 2 * (map->p[i]->n_eq + map->p[j]->n_eq) + - map->p[i]->n_ineq + map->p[j]->n_ineq; + max_wrap = 1 + 2 * info[j].bmap->n_eq + info[j].bmap->n_ineq; max_wrap *= n; - set = isl_set_union(set_from_updated_bmap(map->p[i], tabs[i]), - set_from_updated_bmap(map->p[j], tabs[j])); - mat = isl_mat_alloc(map->ctx, max_wrap, 1 + total); - wraps_init(&wraps, mat, map, i, j, eq_i, ineq_i, eq_j, ineq_j); - bound = isl_vec_alloc(map->ctx, 1 + total); - if (!set || !wraps.mat || !bound) + set_i = set_from_updated_bmap(info[i].bmap, info[i].tab); + ctx = isl_basic_map_get_ctx(info[i].bmap); + mat = isl_mat_alloc(ctx, max_wrap, 1 + total); + wraps_init(&wraps, mat, info, i, j); + if (!set_i || !wraps.mat) goto error; - snap_i = isl_tab_snap(tabs[i]); - snap_j = isl_tab_snap(tabs[j]); + snap = isl_tab_snap(info[j].tab); wraps.mat->n_row = 0; for (k = 0; k < n; ++k) { - if (isl_tab_select_facet(tabs[i], map->p[i]->n_eq + cuts[k]) < 0) - goto error; - if (isl_tab_detect_redundant(tabs[i]) < 0) - goto error; - set_is_redundant(tabs[i], map->p[i]->n_eq, cuts, n, k, 1); - - isl_seq_neg(bound->el, map->p[i]->ineq[cuts[k]], 1 + total); - if (!tabs[i]->empty && - add_wraps(&wraps, map->p[i], tabs[i], bound->el, set) < 0) - goto error; - - set_is_redundant(tabs[i], map->p[i]->n_eq, cuts, n, k, 0); - if (isl_tab_rollback(tabs[i], snap_i) < 0) - goto error; - - if (tabs[i]->empty) - break; - if (!wraps.mat->n_row) - break; - - isl_seq_cpy(bound->el, map->p[i]->ineq[cuts[k]], 1 + total); - isl_int_add_ui(bound->el[0], bound->el[0], 1); - if (isl_tab_add_eq(tabs[j], bound->el) < 0) + w = wraps.mat->n_row++; + isl_seq_cpy(wraps.mat->row[w], + info[i].bmap->ineq[cuts[k]], 1 + total); + isl_int_add_ui(wraps.mat->row[w][0], wraps.mat->row[w][0], 1); + if (isl_tab_add_eq(info[j].tab, wraps.mat->row[w]) < 0) goto error; - if (isl_tab_detect_redundant(tabs[j]) < 0) + if (isl_tab_detect_redundant(info[j].tab) < 0) goto error; - if (!tabs[j]->empty && - add_wraps(&wraps, map->p[j], tabs[j], bound->el, set) < 0) + if (info[j].tab->empty) + isl_int_sub_ui(wraps.mat->row[w][0], + wraps.mat->row[w][0], 1); + else if (add_wraps(&wraps, &info[j], + wraps.mat->row[w], set_i) < 0) goto error; - if (isl_tab_rollback(tabs[j], snap_j) < 0) + if (isl_tab_rollback(info[j].tab, snap) < 0) goto error; if (!wraps.mat->n_row) @@ -970,19 +1223,16 @@ } if (k == n) - changed = fuse(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j, wraps.mat); + change = fuse(i, j, info, wraps.mat, 0, 1); - isl_vec_free(bound); wraps_free(&wraps); - isl_set_free(set); + isl_set_free(set_i); - return changed; + return change; error: - isl_vec_free(bound); wraps_free(&wraps); - isl_set_free(set); - return -1; + isl_set_free(set_i); + return isl_change_error; } /* Given two basic sets i and j such that i has no cut equalities, @@ -1044,35 +1294,39 @@ * | * \______________________________________________________________________ */ -static int can_wrap_in_set(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change can_wrap_in_set(int i, int j, + struct isl_coalesce_info *info) { - int changed = 0; + enum isl_change change = isl_change_none; int k, m; int n; int *cuts = NULL; + isl_ctx *ctx; - if (ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_RATIONAL) || - ISL_F_ISSET(map->p[j], ISL_BASIC_MAP_RATIONAL)) - return 0; + if (ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_RATIONAL) || + ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL)) + return isl_change_none; - n = count(ineq_i, map->p[i]->n_ineq, STATUS_CUT); + n = count(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT); if (n == 0) - return 0; + return isl_change_none; - cuts = isl_alloc_array(map->ctx, int, n); + ctx = isl_basic_map_get_ctx(info[i].bmap); + cuts = isl_alloc_array(ctx, int, n); if (!cuts) - return -1; + return isl_change_error; for (k = 0, m = 0; m < n; ++k) { enum isl_ineq_type type; - if (ineq_i[k] != STATUS_CUT) + if (info[i].ineq[k] != STATUS_CUT) continue; - isl_int_add_ui(map->p[i]->ineq[k][0], map->p[i]->ineq[k][0], 1); - type = isl_tab_ineq_type(tabs[j], map->p[i]->ineq[k]); - isl_int_sub_ui(map->p[i]->ineq[k][0], map->p[i]->ineq[k][0], 1); + isl_int_add_ui(info[i].bmap->ineq[k][0], + info[i].bmap->ineq[k][0], 1); + type = isl_tab_ineq_type(info[j].tab, info[i].bmap->ineq[k]); + isl_int_sub_ui(info[i].bmap->ineq[k][0], + info[i].bmap->ineq[k][0], 1); if (type == isl_ineq_error) goto error; if (type != isl_ineq_redundant) @@ -1082,36 +1336,32 @@ } if (m == n) - changed = wrap_in_facets(map, i, j, cuts, n, tabs, - eq_i, ineq_i, eq_j, ineq_j); + change = wrap_in_facets(i, j, cuts, n, info); free(cuts); - return changed; + return change; error: free(cuts); - return -1; + return isl_change_error; } -/* Check if either i or j has a single cut constraint that can +/* Check if either i or j has only cut inequalities that can * be used to wrap in (a facet of) the other basic set. * if so, replace the pair by their union. */ -static int check_wrap(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change check_wrap(int i, int j, struct isl_coalesce_info *info) { - int changed = 0; + enum isl_change change = isl_change_none; - if (!any(eq_i, 2 * map->p[i]->n_eq, STATUS_CUT)) - changed = can_wrap_in_set(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j); - if (changed) - return changed; - - if (!any(eq_j, 2 * map->p[j]->n_eq, STATUS_CUT)) - changed = can_wrap_in_set(map, j, i, tabs, - eq_j, ineq_j, eq_i, ineq_i); - return changed; + if (!any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT)) + change = can_wrap_in_set(i, j, info); + if (change != isl_change_none) + return change; + + if (!any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_CUT)) + change = can_wrap_in_set(j, i, info); + return change; } /* At least one of the basic maps has an equality that is adjacent @@ -1122,52 +1372,49 @@ * map that has the equality "j". * If "i" has any "cut" (in)equality, then relaxing the inequality * by one would not result in a basic map that contains the other + * basic map. However, it may still be possible to wrap in the other * basic map. */ -static int check_adj_eq(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change check_adj_eq(int i, int j, + struct isl_coalesce_info *info) { - int changed = 0; + enum isl_change change = isl_change_none; int k; + int any_cut; - if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_INEQ) && - any(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_INEQ)) + if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ) && + any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_INEQ)) /* ADJ EQ TOO MANY */ - return 0; + return isl_change_none; - if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_INEQ)) - return check_adj_eq(map, j, i, tabs, - eq_j, ineq_j, eq_i, ineq_i); + if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ)) + return check_adj_eq(j, i, info); /* j has an equality adjacent to an inequality in i */ - if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_CUT)) - return 0; - if (any(ineq_i, map->p[i]->n_ineq, STATUS_CUT)) - /* ADJ EQ CUT */ - return 0; - if (count(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_EQ) != 1 || - any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_EQ) || - any(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_INEQ) || - any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_INEQ)) + if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT)) + return isl_change_none; + any_cut = any(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT); + if (count(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_EQ) != 1 || + any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_EQ) || + any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ) || + any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ)) /* ADJ EQ TOO MANY */ - return 0; + return isl_change_none; - for (k = 0; k < map->p[i]->n_ineq; ++k) - if (ineq_i[k] == STATUS_ADJ_EQ) + for (k = 0; k < info[i].bmap->n_ineq; ++k) + if (info[i].ineq[k] == STATUS_ADJ_EQ) break; - changed = is_adj_eq_extension(map, i, j, k, tabs, - eq_i, ineq_i, eq_j, ineq_j); - if (changed) - return changed; - - if (count(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_INEQ) != 1) - return 0; + if (!any_cut) { + change = is_adj_eq_extension(i, j, k, info); + if (change != isl_change_none) + return change; + } - changed = can_wrap_in_facet(map, i, j, k, tabs, eq_i, ineq_i, eq_j, ineq_j); + change = can_wrap_in_facet(i, j, k, info, any_cut); - return changed; + return change; } /* The two basic maps lie on adjacent hyperplanes. In particular, @@ -1182,60 +1429,54 @@ * \\ => \\ * \ \| * - * We only allow one equality of "i" to be adjacent to an equality of "j" - * to avoid coalescing - * - * [m, n] -> { [x, y] -> [x, 1 + y] : x >= 1 and y >= 1 and - * x <= 10 and y <= 10; - * [x, y] -> [1 + x, y] : x >= 1 and x <= 20 and - * y >= 5 and y <= 15 } - * - * to - * - * [m, n] -> { [x, y] -> [x2, y2] : x >= 1 and 10y2 <= 20 - x + 10y and - * 4y2 >= 5 + 3y and 5y2 <= 15 + 4y and - * y2 <= 1 + x + y - x2 and y2 >= y and - * y2 >= 1 + x + y - x2 } + * If there is more than one equality of "i" adjacent to an equality of "j", + * then the result will satisfy one or more equalities that are a linear + * combination of these equalities. These will be encoded as pairs + * of inequalities in the wrapping constraints and need to be made + * explicit. */ -static int check_eq_adj_eq(struct isl_map *map, int i, int j, - struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) +static enum isl_change check_eq_adj_eq(int i, int j, + struct isl_coalesce_info *info) { int k; - int changed = 0; + enum isl_change change = isl_change_none; + int detect_equalities = 0; struct isl_wraps wraps; + isl_ctx *ctx; isl_mat *mat; struct isl_set *set_i = NULL; struct isl_set *set_j = NULL; struct isl_vec *bound = NULL; - unsigned total = isl_basic_map_total_dim(map->p[i]); + unsigned total = isl_basic_map_total_dim(info[i].bmap); - if (count(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_EQ) != 1) - return 0; + if (count(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ) != 1) + detect_equalities = 1; - for (k = 0; k < 2 * map->p[i]->n_eq ; ++k) - if (eq_i[k] == STATUS_ADJ_EQ) + for (k = 0; k < 2 * info[i].bmap->n_eq ; ++k) + if (info[i].eq[k] == STATUS_ADJ_EQ) break; - set_i = set_from_updated_bmap(map->p[i], tabs[i]); - set_j = set_from_updated_bmap(map->p[j], tabs[j]); - mat = isl_mat_alloc(map->ctx, 2 * (map->p[i]->n_eq + map->p[j]->n_eq) + - map->p[i]->n_ineq + map->p[j]->n_ineq, - 1 + total); - wraps_init(&wraps, mat, map, i, j, eq_i, ineq_i, eq_j, ineq_j); - bound = isl_vec_alloc(map->ctx, 1 + total); + set_i = set_from_updated_bmap(info[i].bmap, info[i].tab); + set_j = set_from_updated_bmap(info[j].bmap, info[j].tab); + ctx = isl_basic_map_get_ctx(info[i].bmap); + mat = isl_mat_alloc(ctx, 2 * (info[i].bmap->n_eq + info[j].bmap->n_eq) + + info[i].bmap->n_ineq + info[j].bmap->n_ineq, + 1 + total); + wraps_init(&wraps, mat, info, i, j); + bound = isl_vec_alloc(ctx, 1 + total); if (!set_i || !set_j || !wraps.mat || !bound) goto error; if (k % 2 == 0) - isl_seq_neg(bound->el, map->p[i]->eq[k / 2], 1 + total); + isl_seq_neg(bound->el, info[i].bmap->eq[k / 2], 1 + total); else - isl_seq_cpy(bound->el, map->p[i]->eq[k / 2], 1 + total); + isl_seq_cpy(bound->el, info[i].bmap->eq[k / 2], 1 + total); isl_int_add_ui(bound->el[0], bound->el[0], 1); isl_seq_cpy(wraps.mat->row[0], bound->el, 1 + total); wraps.mat->n_row = 1; - if (add_wraps(&wraps, map->p[j], tabs[j], bound->el, set_i) < 0) + if (add_wraps(&wraps, &info[j], bound->el, set_i) < 0) goto error; if (!wraps.mat->n_row) goto unbounded; @@ -1246,15 +1487,15 @@ isl_seq_cpy(wraps.mat->row[wraps.mat->n_row], bound->el, 1 + total); wraps.mat->n_row++; - if (add_wraps(&wraps, map->p[i], tabs[i], bound->el, set_j) < 0) + if (add_wraps(&wraps, &info[i], bound->el, set_j) < 0) goto error; if (!wraps.mat->n_row) goto unbounded; - changed = fuse(map, i, j, tabs, eq_i, ineq_i, eq_j, ineq_j, wraps.mat); + change = fuse(i, j, info, wraps.mat, detect_equalities, 0); if (0) { -error: changed = -1; +error: change = isl_change_error; } unbounded: @@ -1263,13 +1504,14 @@ isl_set_free(set_j); isl_vec_free(bound); - return changed; + return change; } /* Check if the union of the given pair of basic maps * can be represented by a single basic map. - * If so, replace the pair by the single basic map and return 1. - * Otherwise, return 0; + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. * The two basic maps are assumed to live in the same local space. * * We first check the effect of each constraint of one basic map @@ -1348,94 +1590,184 @@ * corresponding to the basic maps. When the basic maps are dropped * or combined, the tableaus are modified accordingly. */ -static int coalesce_local_pair(__isl_keep isl_map *map, int i, int j, - struct isl_tab **tabs) +static enum isl_change coalesce_local_pair(int i, int j, + struct isl_coalesce_info *info) { - int changed = 0; - int *eq_i = NULL; - int *eq_j = NULL; - int *ineq_i = NULL; - int *ineq_j = NULL; + enum isl_change change = isl_change_none; + + info[i].eq = info[i].ineq = NULL; + info[j].eq = info[j].ineq = NULL; - eq_i = eq_status_in(map->p[i], tabs[j]); - if (map->p[i]->n_eq && !eq_i) + info[i].eq = eq_status_in(info[i].bmap, info[j].tab); + if (info[i].bmap->n_eq && !info[i].eq) goto error; - if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ERROR)) + if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ERROR)) goto error; - if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_SEPARATE)) + if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_SEPARATE)) goto done; - eq_j = eq_status_in(map->p[j], tabs[i]); - if (map->p[j]->n_eq && !eq_j) + info[j].eq = eq_status_in(info[j].bmap, info[i].tab); + if (info[j].bmap->n_eq && !info[j].eq) goto error; - if (any(eq_j, 2 * map->p[j]->n_eq, STATUS_ERROR)) + if (any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ERROR)) goto error; - if (any(eq_j, 2 * map->p[j]->n_eq, STATUS_SEPARATE)) + if (any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_SEPARATE)) goto done; - ineq_i = ineq_status_in(map->p[i], tabs[i], tabs[j]); - if (map->p[i]->n_ineq && !ineq_i) + info[i].ineq = ineq_status_in(info[i].bmap, info[i].tab, info[j].tab); + if (info[i].bmap->n_ineq && !info[i].ineq) goto error; - if (any(ineq_i, map->p[i]->n_ineq, STATUS_ERROR)) + if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ERROR)) goto error; - if (any(ineq_i, map->p[i]->n_ineq, STATUS_SEPARATE)) + if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_SEPARATE)) goto done; - ineq_j = ineq_status_in(map->p[j], tabs[j], tabs[i]); - if (map->p[j]->n_ineq && !ineq_j) + info[j].ineq = ineq_status_in(info[j].bmap, info[j].tab, info[i].tab); + if (info[j].bmap->n_ineq && !info[j].ineq) goto error; - if (any(ineq_j, map->p[j]->n_ineq, STATUS_ERROR)) + if (any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ERROR)) goto error; - if (any(ineq_j, map->p[j]->n_ineq, STATUS_SEPARATE)) + if (any(info[j].ineq, info[j].bmap->n_ineq, STATUS_SEPARATE)) goto done; - if (all(eq_i, 2 * map->p[i]->n_eq, STATUS_VALID) && - all(ineq_i, map->p[i]->n_ineq, STATUS_VALID)) { - drop(map, j, tabs); - changed = 1; - } else if (all(eq_j, 2 * map->p[j]->n_eq, STATUS_VALID) && - all(ineq_j, map->p[j]->n_ineq, STATUS_VALID)) { - drop(map, i, tabs); - changed = 1; - } else if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_EQ)) { - changed = check_eq_adj_eq(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j); - } else if (any(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_EQ)) { - changed = check_eq_adj_eq(map, j, i, tabs, - eq_j, ineq_j, eq_i, ineq_i); - } else if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_INEQ) || - any(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_INEQ)) { - changed = check_adj_eq(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j); - } else if (any(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_EQ) || - any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_EQ)) { + if (all(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_VALID) && + all(info[i].ineq, info[i].bmap->n_ineq, STATUS_VALID)) { + drop(&info[j]); + change = isl_change_drop_second; + } else if (all(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_VALID) && + all(info[j].ineq, info[j].bmap->n_ineq, STATUS_VALID)) { + drop(&info[i]); + change = isl_change_drop_first; + } else if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ)) { + change = check_eq_adj_eq(i, j, info); + } else if (any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_EQ)) { + change = check_eq_adj_eq(j, i, info); + } else if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ) || + any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_INEQ)) { + change = check_adj_eq(i, j, info); + } else if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_EQ) || + any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_EQ)) { /* Can't happen */ /* BAD ADJ INEQ */ - } else if (any(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_INEQ) || - any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_INEQ)) { - changed = check_adj_ineq(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j); + } else if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ) || + any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ)) { + change = check_adj_ineq(i, j, info); } else { - if (!any(eq_i, 2 * map->p[i]->n_eq, STATUS_CUT) && - !any(eq_j, 2 * map->p[j]->n_eq, STATUS_CUT)) - changed = check_facets(map, i, j, tabs, ineq_i, ineq_j); - if (!changed) - changed = check_wrap(map, i, j, tabs, - eq_i, ineq_i, eq_j, ineq_j); + if (!any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT) && + !any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_CUT)) + change = check_facets(i, j, info); + if (change == isl_change_none) + change = check_wrap(i, j, info); } done: - free(eq_i); - free(eq_j); - free(ineq_i); - free(ineq_j); - return changed; + free(info[i].eq); + free(info[j].eq); + free(info[i].ineq); + free(info[j].ineq); + return change; error: - free(eq_i); - free(eq_j); - free(ineq_i); - free(ineq_j); - return -1; + free(info[i].eq); + free(info[j].eq); + free(info[i].ineq); + free(info[j].ineq); + return isl_change_error; +} + +/* Shift the integer division at position "div" of the basic map + * represented by "info" by "shift". + * + * That is, if the integer division has the form + * + * floor(f(x)/d) + * + * then replace it by + * + * floor((f(x) + shift * d)/d) - shift + */ +static int shift_div(struct isl_coalesce_info *info, int div, isl_int shift) +{ + unsigned total; + + info->bmap = isl_basic_map_shift_div(info->bmap, div, shift); + if (!info->bmap) + return -1; + + total = isl_basic_map_dim(info->bmap, isl_dim_all); + total -= isl_basic_map_dim(info->bmap, isl_dim_div); + if (isl_tab_shift_var(info->tab, total + div, shift) < 0) + return -1; + + return 0; +} + +/* Check if some of the divs in the basic map represented by "info1" + * are shifts of the corresponding divs in the basic map represented + * by "info2". If so, align them with those of "info2". + * Only do this if "info1" and "info2" have the same number + * of integer divisions. + * + * An integer division is considered to be a shift of another integer + * division if one is equal to the other plus a constant. + * + * In particular, for each pair of integer divisions, if both are known, + * have identical coefficients (apart from the constant term) and + * if the difference between the constant terms (taking into account + * the denominator) is an integer, then move the difference outside. + * That is, if one integer division is of the form + * + * floor((f(x) + c_1)/d) + * + * while the other is of the form + * + * floor((f(x) + c_2)/d) + * + * and n = (c_2 - c_1)/d is an integer, then replace the first + * integer division by + * + * floor((f(x) + c_1 + n * d)/d) - n = floor((f(x) + c_2)/d) - n + */ +static int harmonize_divs(struct isl_coalesce_info *info1, + struct isl_coalesce_info *info2) +{ + int i; + int total; + + if (!info1->bmap || !info2->bmap) + return -1; + + if (info1->bmap->n_div != info2->bmap->n_div) + return 0; + if (info1->bmap->n_div == 0) + return 0; + + total = isl_basic_map_total_dim(info1->bmap); + for (i = 0; i < info1->bmap->n_div; ++i) { + isl_int d; + int r = 0; + + if (isl_int_is_zero(info1->bmap->div[i][0]) || + isl_int_is_zero(info2->bmap->div[i][0])) + continue; + if (isl_int_ne(info1->bmap->div[i][0], info2->bmap->div[i][0])) + continue; + if (isl_int_eq(info1->bmap->div[i][1], info2->bmap->div[i][1])) + continue; + if (!isl_seq_eq(info1->bmap->div[i] + 2, + info2->bmap->div[i] + 2, total)) + continue; + isl_int_init(d); + isl_int_sub(d, info2->bmap->div[i][1], info1->bmap->div[i][1]); + if (isl_int_is_divisible_by(d, info1->bmap->div[i][0])) { + isl_int_divexact(d, d, info1->bmap->div[i][0]); + r = shift_div(info1, i, d); + } + isl_int_clear(d); + if (r < 0) + return -1; + } + + return 0; } /* Do the two basic maps live in the same local space, i.e., @@ -1473,29 +1805,26 @@ return 1; } -/* Given two basic maps "i" and "j", where the divs of "i" form a subset - * of those of "j", check if basic map "j" is a subset of basic map "i" - * and, if so, drop basic map "j". - * - * We first expand the divs of basic map "i" to match those of basic map "j", - * using the divs and expansion computed by the caller. - * Then we check if all constraints of the expanded "i" are valid for "j". +/* Does "bmap" contain the basic map represented by the tableau "tab" + * after expanding the divs of "bmap" to match those of "tab"? + * The expansion is performed using the divs "div" and expansion "exp" + * computed by the caller. + * Then we check if all constraints of the expanded "bmap" are valid for "tab". */ -static int coalesce_subset(__isl_keep isl_map *map, int i, int j, - struct isl_tab **tabs, __isl_keep isl_mat *div, int *exp) +static int contains_with_expanded_divs(__isl_keep isl_basic_map *bmap, + struct isl_tab *tab, __isl_keep isl_mat *div, int *exp) { - isl_basic_map *bmap; - int changed = 0; + int superset = 0; int *eq_i = NULL; int *ineq_i = NULL; - bmap = isl_basic_map_copy(map->p[i]); + bmap = isl_basic_map_copy(bmap); bmap = isl_basic_set_expand_divs(bmap, isl_mat_copy(div), exp); if (!bmap) goto error; - eq_i = eq_status_in(bmap, tabs[j]); + eq_i = eq_status_in(bmap, tab); if (bmap->n_eq && !eq_i) goto error; if (any(eq_i, 2 * bmap->n_eq, STATUS_ERROR)) @@ -1503,7 +1832,7 @@ if (any(eq_i, 2 * bmap->n_eq, STATUS_SEPARATE)) goto done; - ineq_i = ineq_status_in(bmap, NULL, tabs[j]); + ineq_i = ineq_status_in(bmap, NULL, tab); if (bmap->n_ineq && !ineq_i) goto error; if (any(ineq_i, bmap->n_ineq, STATUS_ERROR)) @@ -1511,17 +1840,15 @@ if (any(ineq_i, bmap->n_ineq, STATUS_SEPARATE)) goto done; - if (all(eq_i, 2 * map->p[i]->n_eq, STATUS_VALID) && - all(ineq_i, map->p[i]->n_ineq, STATUS_VALID)) { - drop(map, j, tabs); - changed = 1; - } + if (all(eq_i, 2 * bmap->n_eq, STATUS_VALID) && + all(ineq_i, bmap->n_ineq, STATUS_VALID)) + superset = 1; done: isl_basic_map_free(bmap); free(eq_i); free(ineq_i); - return 0; + return superset; error: isl_basic_map_free(bmap); free(eq_i); @@ -1529,20 +1856,17 @@ return -1; } -/* Check if the basic map "j" is a subset of basic map "i", - * assuming that "i" has fewer divs that "j". - * If not, then we change the order. - * - * If the two basic maps have the same number of divs, then - * they must necessarily be different. Otherwise, we would have - * called coalesce_local_pair. We therefore don't try anything - * in this case. - * - * We first check if the divs of "i" are all known and form a subset - * of those of "j". If so, we pass control over to coalesce_subset. +/* Does "bmap_i" contain the basic map represented by "info_j" + * after aligning the divs of "bmap_i" to those of "info_j". + * Note that this can only succeed if the number of divs of "bmap_i" + * is smaller than (or equal to) the number of divs of "info_j". + * + * We first check if the divs of "bmap_i" are all known and form a subset + * of those of "bmap_j". If so, we pass control over to + * contains_with_expanded_divs. */ -static int check_coalesce_subset(__isl_keep isl_map *map, int i, int j, - struct isl_tab **tabs) +static int contains_after_aligning_divs(__isl_keep isl_basic_map *bmap_i, + struct isl_coalesce_info *info_j) { int known; isl_mat *div_i, *div_j, *div; @@ -1551,19 +1875,14 @@ isl_ctx *ctx; int subset; - if (map->p[i]->n_div == map->p[j]->n_div) - return 0; - if (map->p[j]->n_div < map->p[i]->n_div) - return check_coalesce_subset(map, j, i, tabs); - - known = isl_basic_map_divs_known(map->p[i]); + known = isl_basic_map_divs_known(bmap_i); if (known < 0 || !known) return known; - ctx = isl_map_get_ctx(map); + ctx = isl_basic_map_get_ctx(bmap_i); - div_i = isl_basic_map_get_divs(map->p[i]); - div_j = isl_basic_map_get_divs(map->p[j]); + div_i = isl_basic_map_get_divs(bmap_i); + div_j = isl_basic_map_get_divs(info_j->bmap); if (!div_i || !div_j) goto error; @@ -1578,7 +1897,8 @@ goto error; if (div->n_row == div_j->n_row) - subset = coalesce_subset(map, i, j, tabs, div, exp1); + subset = contains_with_expanded_divs(bmap_i, + info_j->tab, div, exp1); else subset = 0; @@ -1599,53 +1919,683 @@ return -1; } +/* Check if the basic map "j" is a subset of basic map "i", + * if "i" has fewer divs that "j". + * If so, remove basic map "j". + * + * If the two basic maps have the same number of divs, then + * they must necessarily be different. Otherwise, we would have + * called coalesce_local_pair. We therefore don't try anything + * in this case. + */ +static int coalesced_subset(int i, int j, struct isl_coalesce_info *info) +{ + int superset; + + if (info[i].bmap->n_div >= info[j].bmap->n_div) + return 0; + + superset = contains_after_aligning_divs(info[i].bmap, &info[j]); + if (superset < 0) + return -1; + if (superset) + drop(&info[j]); + + return superset; +} + +/* Check if basic map "j" is a subset of basic map "i" after + * exploiting the extra equalities of "j" to simplify the divs of "i". + * If so, remove basic map "j". + * + * If "j" does not have any equalities or if they are the same + * as those of "i", then we cannot exploit them to simplify the divs. + * Similarly, if there are no divs in "i", then they cannot be simplified. + * If, on the other hand, the affine hulls of "i" and "j" do not intersect, + * then "j" cannot be a subset of "i". + * + * Otherwise, we intersect "i" with the affine hull of "j" and then + * check if "j" is a subset of the result after aligning the divs. + * If so, then "j" is definitely a subset of "i" and can be removed. + * Note that if after intersection with the affine hull of "j". + * "i" still has more divs than "j", then there is no way we can + * align the divs of "i" to those of "j". + */ +static int coalesced_subset_with_equalities(int i, int j, + struct isl_coalesce_info *info) +{ + isl_basic_map *hull_i, *hull_j, *bmap_i; + int equal, empty, subset; + + if (info[j].bmap->n_eq == 0) + return 0; + if (info[i].bmap->n_div == 0) + return 0; + + hull_i = isl_basic_map_copy(info[i].bmap); + hull_i = isl_basic_map_plain_affine_hull(hull_i); + hull_j = isl_basic_map_copy(info[j].bmap); + hull_j = isl_basic_map_plain_affine_hull(hull_j); + + hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i)); + equal = isl_basic_map_plain_is_equal(hull_i, hull_j); + empty = isl_basic_map_plain_is_empty(hull_j); + isl_basic_map_free(hull_i); + + if (equal < 0 || equal || empty < 0 || empty) { + isl_basic_map_free(hull_j); + return equal < 0 || empty < 0 ? -1 : 0; + } + + bmap_i = isl_basic_map_copy(info[i].bmap); + bmap_i = isl_basic_map_intersect(bmap_i, hull_j); + if (!bmap_i) + return -1; + + if (bmap_i->n_div > info[j].bmap->n_div) { + isl_basic_map_free(bmap_i); + return 0; + } + + subset = contains_after_aligning_divs(bmap_i, &info[j]); + + isl_basic_map_free(bmap_i); + + if (subset < 0) + return -1; + if (subset) + drop(&info[j]); + + return subset; +} + +/* Check if one of the basic maps is a subset of the other and, if so, + * drop the subset. + * Note that we only perform any test if the number of divs is different + * in the two basic maps. In case the number of divs is the same, + * we have already established that the divs are different + * in the two basic maps. + * In particular, if the number of divs of basic map i is smaller than + * the number of divs of basic map j, then we check if j is a subset of i + * and vice versa. + */ +static enum isl_change check_coalesce_subset(int i, int j, + struct isl_coalesce_info *info) +{ + int changed; + + changed = coalesced_subset(i, j, info); + if (changed < 0 || changed) + return changed < 0 ? isl_change_error : isl_change_drop_second; + + changed = coalesced_subset(j, i, info); + if (changed < 0 || changed) + return changed < 0 ? isl_change_error : isl_change_drop_first; + + changed = coalesced_subset_with_equalities(i, j, info); + if (changed < 0 || changed) + return changed < 0 ? isl_change_error : isl_change_drop_second; + + changed = coalesced_subset_with_equalities(j, i, info); + if (changed < 0 || changed) + return changed < 0 ? isl_change_error : isl_change_drop_first; + + return isl_change_none; +} + +/* Does "bmap" involve any divs that themselves refer to divs? + */ +static int has_nested_div(__isl_keep isl_basic_map *bmap) +{ + int i; + unsigned total; + unsigned n_div; + + total = isl_basic_map_dim(bmap, isl_dim_all); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + total -= n_div; + + for (i = 0; i < n_div; ++i) + if (isl_seq_first_non_zero(bmap->div[i] + 2 + total, + n_div) != -1) + return 1; + + return 0; +} + +/* Return a list of affine expressions, one for each integer division + * in "bmap_i". For each integer division that also appears in "bmap_j", + * the affine expression is set to NaN. The number of NaNs in the list + * is equal to the number of integer divisions in "bmap_j". + * For the other integer divisions of "bmap_i", the corresponding + * element in the list is a purely affine expression equal to the integer + * division in "hull". + * If no such list can be constructed, then the number of elements + * in the returned list is smaller than the number of integer divisions + * in "bmap_i". + */ +static __isl_give isl_aff_list *set_up_substitutions( + __isl_keep isl_basic_map *bmap_i, __isl_keep isl_basic_map *bmap_j, + __isl_take isl_basic_map *hull) +{ + unsigned n_div_i, n_div_j, total; + isl_ctx *ctx; + isl_local_space *ls; + isl_basic_set *wrap_hull; + isl_aff *aff_nan; + isl_aff_list *list; + int i, j; + + if (!hull) + return NULL; + + ctx = isl_basic_map_get_ctx(hull); + + n_div_i = isl_basic_map_dim(bmap_i, isl_dim_div); + n_div_j = isl_basic_map_dim(bmap_j, isl_dim_div); + total = isl_basic_map_total_dim(bmap_i) - n_div_i; + + ls = isl_basic_map_get_local_space(bmap_i); + ls = isl_local_space_wrap(ls); + wrap_hull = isl_basic_map_wrap(hull); + + aff_nan = isl_aff_nan_on_domain(isl_local_space_copy(ls)); + list = isl_aff_list_alloc(ctx, n_div_i); + + j = 0; + for (i = 0; i < n_div_i; ++i) { + isl_aff *aff; + + if (j < n_div_j && + isl_seq_eq(bmap_i->div[i], bmap_j->div[j], 2 + total)) { + ++j; + list = isl_aff_list_add(list, isl_aff_copy(aff_nan)); + continue; + } + if (n_div_i - i <= n_div_j - j) + break; + + aff = isl_local_space_get_div(ls, i); + aff = isl_aff_substitute_equalities(aff, + isl_basic_set_copy(wrap_hull)); + aff = isl_aff_floor(aff); + if (!aff) + goto error; + if (isl_aff_dim(aff, isl_dim_div) != 0) { + isl_aff_free(aff); + break; + } + + list = isl_aff_list_add(list, aff); + } + + isl_aff_free(aff_nan); + isl_local_space_free(ls); + isl_basic_set_free(wrap_hull); + + return list; +error: + isl_aff_free(aff_nan); + isl_local_space_free(ls); + isl_basic_set_free(wrap_hull); + isl_aff_list_free(list); + return NULL; +} + +/* Add variables to "tab" corresponding to the elements in "list" + * that are not set to NaN. + * "dim" is the offset in the variables of "tab" where we should + * start considering the elements in "list". + * When this function returns, the total number of variables in "tab" + * is equal to "dim" plus the number of elements in "list". + */ +static int add_sub_vars(struct isl_tab *tab, __isl_keep isl_aff_list *list, + int dim) +{ + int i, n; + + n = isl_aff_list_n_aff(list); + for (i = 0; i < n; ++i) { + int is_nan; + isl_aff *aff; + + aff = isl_aff_list_get_aff(list, i); + is_nan = isl_aff_is_nan(aff); + isl_aff_free(aff); + if (is_nan < 0) + return -1; + + if (!is_nan && isl_tab_insert_var(tab, dim + i) < 0) + return -1; + } + + return 0; +} + +/* For each element in "list" that is not set to NaN, fix the corresponding + * variable in "tab" to the purely affine expression defined by the element. + * "dim" is the offset in the variables of "tab" where we should + * start considering the elements in "list". + */ +static int add_sub_equalities(struct isl_tab *tab, + __isl_keep isl_aff_list *list, int dim) +{ + int i, n; + isl_ctx *ctx; + isl_vec *sub; + isl_aff *aff; + + n = isl_aff_list_n_aff(list); + + ctx = isl_tab_get_ctx(tab); + sub = isl_vec_alloc(ctx, 1 + dim + n); + if (!sub) + return -1; + isl_seq_clr(sub->el + 1 + dim, n); + + for (i = 0; i < n; ++i) { + aff = isl_aff_list_get_aff(list, i); + if (!aff) + goto error; + if (isl_aff_is_nan(aff)) { + isl_aff_free(aff); + continue; + } + isl_seq_cpy(sub->el, aff->v->el + 1, 1 + dim); + isl_int_neg(sub->el[1 + dim + i], aff->v->el[0]); + if (isl_tab_add_eq(tab, sub->el) < 0) + goto error; + isl_int_set_si(sub->el[1 + dim + i], 0); + isl_aff_free(aff); + } + + isl_vec_free(sub); + return 0; +error: + isl_aff_free(aff); + isl_vec_free(sub); + return -1; +} + +/* Add variables to info->tab corresponding to the elements in "list" + * that are not set to NaN. The value of the added variable + * is fixed to the purely affine expression defined by the element. + * "dim" is the offset in the variables of info->tab where we should + * start considering the elements in "list". + * When this function returns, the total number of variables in info->tab + * is equal to "dim" plus the number of elements in "list". + * Additionally, add the div constraints that have been added info->bmap + * after the tableau was constructed to info->tab. These constraints + * start at position "n_ineq" in info->bmap. + * The constraints need to be added to the tableau before + * the equalities assigning the purely affine expression + * because the position needs to match that in info->bmap. + * They are frozen because the corresponding added equality is a consequence + * of the two div constraints and the other equalities, meaning that + * the div constraints would otherwise get marked as redundant, + * while they are only redundant with respect to the extra equalities + * added to the tableau, which do not appear explicitly in the basic map. + */ +static int add_subs(struct isl_coalesce_info *info, + __isl_keep isl_aff_list *list, int dim, int n_ineq) +{ + int i, extra_var, extra_con; + int n; + unsigned n_eq = info->bmap->n_eq; + + if (!list) + return -1; + + n = isl_aff_list_n_aff(list); + extra_var = n - (info->tab->n_var - dim); + extra_con = info->bmap->n_ineq - n_ineq; + + if (isl_tab_extend_vars(info->tab, extra_var) < 0) + return -1; + if (isl_tab_extend_cons(info->tab, extra_con + 2 * extra_var) < 0) + return -1; + if (add_sub_vars(info->tab, list, dim) < 0) + return -1; + + for (i = n_ineq; i < info->bmap->n_ineq; ++i) { + if (isl_tab_add_ineq(info->tab, info->bmap->ineq[i]) < 0) + return -1; + if (isl_tab_freeze_constraint(info->tab, n_eq + i) < 0) + return -1; + } + + return add_sub_equalities(info->tab, list, dim); +} + +/* Coalesce basic map "j" into basic map "i" after adding the extra integer + * divisions in "i" but not in "j" to basic map "j", with values + * specified by "list". The total number of elements in "list" + * is equal to the number of integer divisions in "i", while the number + * of NaN elements in the list is equal to the number of integer divisions + * in "j". + * Adding extra integer divisions to "j" through isl_basic_map_align_divs + * also adds the corresponding div constraints. These need to be added + * to the corresponding tableau as well in add_subs to maintain consistency. + * + * If no coalescing can be performed, then we need to revert basic map "j" + * to its original state. We do the same if basic map "i" gets dropped + * during the coalescing, even though this should not happen in practice + * since we have already checked for "j" being a subset of "i" + * before we reach this stage. + */ +static enum isl_change coalesce_with_subs(int i, int j, + struct isl_coalesce_info *info, __isl_keep isl_aff_list *list) +{ + isl_basic_map *bmap_j; + struct isl_tab_undo *snap; + unsigned dim; + enum isl_change change; + int n_ineq; + + bmap_j = isl_basic_map_copy(info[j].bmap); + n_ineq = info[j].bmap->n_ineq; + info[j].bmap = isl_basic_map_align_divs(info[j].bmap, info[i].bmap); + if (!info[j].bmap) + goto error; + + snap = isl_tab_snap(info[j].tab); + + dim = isl_basic_map_dim(bmap_j, isl_dim_all); + dim -= isl_basic_map_dim(bmap_j, isl_dim_div); + if (add_subs(&info[j], list, dim, n_ineq) < 0) + goto error; + + change = coalesce_local_pair(i, j, info); + if (change != isl_change_none && change != isl_change_drop_first) { + isl_basic_map_free(bmap_j); + } else { + isl_basic_map_free(info[j].bmap); + info[j].bmap = bmap_j; + + if (isl_tab_rollback(info[j].tab, snap) < 0) + return isl_change_error; + } + + return change; +error: + isl_basic_map_free(bmap_j); + return isl_change_error; +} + +/* Check if we can coalesce basic map "j" into basic map "i" after copying + * those extra integer divisions in "i" that can be simplified away + * using the extra equalities in "j". + * All divs are assumed to be known and not contain any nested divs. + * + * We first check if there are any extra equalities in "j" that we + * can exploit. Then we check if every integer division in "i" + * either already appears in "j" or can be simplified using the + * extra equalities to a purely affine expression. + * If these tests succeed, then we try to coalesce the two basic maps + * by introducing extra dimensions in "j" corresponding to + * the extra integer divsisions "i" fixed to the corresponding + * purely affine expression. + */ +static enum isl_change check_coalesce_into_eq(int i, int j, + struct isl_coalesce_info *info) +{ + unsigned n_div_i, n_div_j; + isl_basic_map *hull_i, *hull_j; + int equal, empty; + isl_aff_list *list; + enum isl_change change; + + n_div_i = isl_basic_map_dim(info[i].bmap, isl_dim_div); + n_div_j = isl_basic_map_dim(info[j].bmap, isl_dim_div); + if (n_div_i <= n_div_j) + return isl_change_none; + if (info[j].bmap->n_eq == 0) + return isl_change_none; + + hull_i = isl_basic_map_copy(info[i].bmap); + hull_i = isl_basic_map_plain_affine_hull(hull_i); + hull_j = isl_basic_map_copy(info[j].bmap); + hull_j = isl_basic_map_plain_affine_hull(hull_j); + + hull_j = isl_basic_map_intersect(hull_j, isl_basic_map_copy(hull_i)); + equal = isl_basic_map_plain_is_equal(hull_i, hull_j); + empty = isl_basic_map_plain_is_empty(hull_j); + isl_basic_map_free(hull_i); + + if (equal < 0 || empty < 0) + goto error; + if (equal || empty) { + isl_basic_map_free(hull_j); + return isl_change_none; + } + + list = set_up_substitutions(info[i].bmap, info[j].bmap, hull_j); + if (!list) + return isl_change_error; + if (isl_aff_list_n_aff(list) < n_div_i) + change = isl_change_none; + else + change = coalesce_with_subs(i, j, info, list); + + isl_aff_list_free(list); + + return change; +error: + isl_basic_map_free(hull_j); + return isl_change_error; +} + +/* Check if we can coalesce basic maps "i" and "j" after copying + * those extra integer divisions in one of the basic maps that can + * be simplified away using the extra equalities in the other basic map. + * We require all divs to be known in both basic maps. + * Furthermore, to simplify the comparison of div expressions, + * we do not allow any nested integer divisions. + */ +static enum isl_change check_coalesce_eq(int i, int j, + struct isl_coalesce_info *info) +{ + int known, nested; + enum isl_change change; + + known = isl_basic_map_divs_known(info[i].bmap); + if (known < 0 || !known) + return known < 0 ? isl_change_error : isl_change_none; + known = isl_basic_map_divs_known(info[j].bmap); + if (known < 0 || !known) + return known < 0 ? isl_change_error : isl_change_none; + nested = has_nested_div(info[i].bmap); + if (nested < 0 || nested) + return nested < 0 ? isl_change_error : isl_change_none; + nested = has_nested_div(info[j].bmap); + if (nested < 0 || nested) + return nested < 0 ? isl_change_error : isl_change_none; + + change = check_coalesce_into_eq(i, j, info); + if (change != isl_change_none) + return change; + change = check_coalesce_into_eq(j, i, info); + if (change != isl_change_none) + return invert_change(change); + + return isl_change_none; +} + /* Check if the union of the given pair of basic maps * can be represented by a single basic map. - * If so, replace the pair by the single basic map and return 1. - * Otherwise, return 0; - * - * We first check if the two basic maps live in the same local space. - * If so, we do the complete check. Otherwise, we check if one is - * an obvious subset of the other. + * If so, replace the pair by the single basic map and return + * isl_change_drop_first, isl_change_drop_second or isl_change_fuse. + * Otherwise, return isl_change_none. + * + * We first check if the two basic maps live in the same local space, + * after aligning the divs that differ by only an integer constant. + * If so, we do the complete check. Otherwise, we check if they have + * the same number of integer divisions and can be coalesced, if one is + * an obvious subset of the other or if the extra integer divisions + * of one basic map can be simplified away using the extra equalities + * of the other basic map. */ -static int coalesce_pair(__isl_keep isl_map *map, int i, int j, - struct isl_tab **tabs) +static enum isl_change coalesce_pair(int i, int j, + struct isl_coalesce_info *info) { int same; + enum isl_change change; - same = same_divs(map->p[i], map->p[j]); + if (harmonize_divs(&info[i], &info[j]) < 0) + return isl_change_error; + same = same_divs(info[i].bmap, info[j].bmap); if (same < 0) - return -1; + return isl_change_error; if (same) - return coalesce_local_pair(map, i, j, tabs); + return coalesce_local_pair(i, j, info); + + if (info[i].bmap->n_div == info[j].bmap->n_div) { + change = coalesce_local_pair(i, j, info); + if (change != isl_change_none) + return change; + } + + change = check_coalesce_subset(i, j, info); + if (change != isl_change_none) + return change; - return check_coalesce_subset(map, i, j, tabs); + return check_coalesce_eq(i, j, info); +} + +/* Return the maximum of "a" and "b". + */ +static inline int max(int a, int b) +{ + return a > b ? a : b; } -static struct isl_map *coalesce(struct isl_map *map, struct isl_tab **tabs) +/* Pairwise coalesce the basic maps in the range [start1, end1[ of "info" + * with those in the range [start2, end2[, skipping basic maps + * that have been removed (either before or within this function). + * + * For each basic map i in the first range, we check if it can be coalesced + * with respect to any previously considered basic map j in the second range. + * If i gets dropped (because it was a subset of some j), then + * we can move on to the next basic map. + * If j gets dropped, we need to continue checking against the other + * previously considered basic maps. + * If the two basic maps got fused, then we recheck the fused basic map + * against the previously considered basic maps, starting at i + 1 + * (even if start2 is greater than i + 1). + */ +static int coalesce_range(isl_ctx *ctx, struct isl_coalesce_info *info, + int start1, int end1, int start2, int end2) { int i, j; - for (i = map->n - 2; i >= 0; --i) -restart: - for (j = i + 1; j < map->n; ++j) { - int changed; - changed = coalesce_pair(map, i, j, tabs); - if (changed < 0) - goto error; - if (changed) - goto restart; + for (i = end1 - 1; i >= start1; --i) { + if (info[i].removed) + continue; + for (j = max(i + 1, start2); j < end2; ++j) { + enum isl_change changed; + + if (info[j].removed) + continue; + if (info[i].removed) + isl_die(ctx, isl_error_internal, + "basic map unexpectedly removed", + return -1); + changed = coalesce_pair(i, j, info); + switch (changed) { + case isl_change_error: + return -1; + case isl_change_none: + case isl_change_drop_second: + continue; + case isl_change_drop_first: + j = end2; + break; + case isl_change_fuse: + j = i; + break; + } + } + } + + return 0; +} + +/* Pairwise coalesce the basic maps described by the "n" elements of "info". + * + * We consider groups of basic maps that live in the same apparent + * affine hull and we first coalesce within such a group before we + * coalesce the elements in the group with elements of previously + * considered groups. If a fuse happens during the second phase, + * then we also reconsider the elements within the group. + */ +static int coalesce(isl_ctx *ctx, int n, struct isl_coalesce_info *info) +{ + int start, end; + + for (end = n; end > 0; end = start) { + start = end - 1; + while (start >= 1 && + info[start - 1].hull_hash == info[start].hull_hash) + start--; + if (coalesce_range(ctx, info, start, end, start, end) < 0) + return -1; + if (coalesce_range(ctx, info, start, end, end, n) < 0) + return -1; + } + + return 0; +} + +/* Update the basic maps in "map" based on the information in "info". + * In particular, remove the basic maps that have been marked removed and + * update the others based on the information in the corresponding tableau. + * Since we detected implicit equalities without calling + * isl_basic_map_gauss, we need to do it now. + * Also call isl_basic_map_simplify if we may have lost the definition + * of one or more integer divisions. + */ +static __isl_give isl_map *update_basic_maps(__isl_take isl_map *map, + int n, struct isl_coalesce_info *info) +{ + int i; + + if (!map) + return NULL; + + for (i = n - 1; i >= 0; --i) { + if (info[i].removed) { + isl_basic_map_free(map->p[i]); + if (i != map->n - 1) + map->p[i] = map->p[map->n - 1]; + map->n--; + continue; } + + info[i].bmap = isl_basic_map_update_from_tab(info[i].bmap, + info[i].tab); + info[i].bmap = isl_basic_map_gauss(info[i].bmap, NULL); + if (info[i].simplify) + info[i].bmap = isl_basic_map_simplify(info[i].bmap); + info[i].bmap = isl_basic_map_finalize(info[i].bmap); + if (!info[i].bmap) + return isl_map_free(map); + ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT); + ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT); + isl_basic_map_free(map->p[i]); + map->p[i] = info[i].bmap; + info[i].bmap = NULL; + } + return map; -error: - isl_map_free(map); - return NULL; } /* For each pair of basic maps in the map, check if the union of the two * can be represented by a single basic map. * If so, replace the pair by the single basic map and start over. * + * We factor out any (hidden) common factor from the constraint + * coefficients to improve the detection of adjacent constraints. + * * Since we are constructing the tableaus of the basic maps anyway, * we exploit them to detect implicit equalities and redundant constraints. * This also helps the coalescing as it can ignore the redundant constraints. @@ -1653,14 +2603,17 @@ * in the basic maps. We don't call isl_basic_map_gauss, though, * as that may affect the number of constraints. * This means that we have to call isl_basic_map_gauss at the end - * of the computation to ensure that the basic maps are not left - * in an unexpected state. + * of the computation (in update_basic_maps) to ensure that + * the basic maps are not left in an unexpected state. + * For each basic map, we also compute the hash of the apparent affine hull + * for use in coalesce. */ struct isl_map *isl_map_coalesce(struct isl_map *map) { int i; unsigned n; - struct isl_tab **tabs = NULL; + isl_ctx *ctx; + struct isl_coalesce_info *info = NULL; map = isl_map_remove_empty_parts(map); if (!map) @@ -1669,58 +2622,54 @@ if (map->n <= 1) return map; + ctx = isl_map_get_ctx(map); map = isl_map_sort_divs(map); map = isl_map_cow(map); - tabs = isl_calloc_array(map->ctx, struct isl_tab *, map->n); - if (!tabs) - goto error; + if (!map) + return NULL; n = map->n; + + info = isl_calloc_array(map->ctx, struct isl_coalesce_info, n); + if (!info) + goto error; + for (i = 0; i < map->n; ++i) { - tabs[i] = isl_tab_from_basic_map(map->p[i], 0); - if (!tabs[i]) + map->p[i] = isl_basic_map_reduce_coefficients(map->p[i]); + if (!map->p[i]) goto error; - if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_NO_IMPLICIT)) - if (isl_tab_detect_implicit_equalities(tabs[i]) < 0) + info[i].bmap = isl_basic_map_copy(map->p[i]); + info[i].tab = isl_tab_from_basic_map(info[i].bmap, 0); + if (!info[i].tab) + goto error; + if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_IMPLICIT)) + if (isl_tab_detect_implicit_equalities(info[i].tab) < 0) goto error; - map->p[i] = isl_tab_make_equalities_explicit(tabs[i], - map->p[i]); - if (!map->p[i]) + info[i].bmap = isl_tab_make_equalities_explicit(info[i].tab, + info[i].bmap); + if (!info[i].bmap) goto error; - if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_NO_REDUNDANT)) - if (isl_tab_detect_redundant(tabs[i]) < 0) + if (!ISL_F_ISSET(info[i].bmap, ISL_BASIC_MAP_NO_REDUNDANT)) + if (isl_tab_detect_redundant(info[i].tab) < 0) goto error; + if (coalesce_info_set_hull_hash(&info[i]) < 0) + goto error; } for (i = map->n - 1; i >= 0; --i) - if (tabs[i]->empty) - drop(map, i, tabs); - - map = coalesce(map, tabs); + if (info[i].tab->empty) + drop(&info[i]); - if (map) - for (i = 0; i < map->n; ++i) { - map->p[i] = isl_basic_map_update_from_tab(map->p[i], - tabs[i]); - map->p[i] = isl_basic_map_gauss(map->p[i], NULL); - map->p[i] = isl_basic_map_finalize(map->p[i]); - if (!map->p[i]) - goto error; - ISL_F_SET(map->p[i], ISL_BASIC_MAP_NO_IMPLICIT); - ISL_F_SET(map->p[i], ISL_BASIC_MAP_NO_REDUNDANT); - } + if (coalesce(ctx, n, info) < 0) + goto error; - for (i = 0; i < n; ++i) - isl_tab_free(tabs[i]); + map = update_basic_maps(map, n, info); - free(tabs); + clear_coalesce_info(n, info); return map; error: - if (tabs) - for (i = 0; i < n; ++i) - isl_tab_free(tabs[i]); - free(tabs); + clear_coalesce_info(n, info); isl_map_free(map); return NULL; } diff -Nru isl-0.12.2/isl_config.h.in isl-0.15/isl_config.h.in --- isl-0.12.2/isl_config.h.in 2014-01-12 11:45:25.000000000 +0000 +++ isl-0.15/isl_config.h.in 2015-06-11 10:47:10.000000000 +0000 @@ -9,9 +9,18 @@ /* Define if CompilerInstance::createDiagnostics takes argc and argv */ #undef CREATEDIAGNOSTICS_TAKES_ARG +/* Define if CompilerInstance::createPreprocessor takes TranslationUnitKind */ +#undef CREATEPREPROCESSOR_TAKES_TUKIND + /* Define if TargetInfo::CreateTargetInfo takes pointer */ #undef CREATETARGETINFO_TAKES_POINTER +/* Define if TargetInfo::CreateTargetInfo takes shared_ptr */ +#undef CREATETARGETINFO_TAKES_SHARED_PTR + +/* Define if Driver constructor takes default image name */ +#undef DRIVER_CTOR_TAKES_DEFAULTIMAGENAME + /* Define to Diagnostic for older versions of clang */ #undef DiagnosticsEngine @@ -19,8 +28,8 @@ */ #undef GCC_WARN_UNUSED_RESULT -/* result of mpz_gcdext needs to be normalized */ -#undef GMP_NORMALIZE_GCDEXT +/* Define if llvm/ADT/OwningPtr.h exists */ +#undef HAVE_ADT_OWNINGPTR_H /* Define if clang/Basic/DiagnosticOptions.h exists */ #undef HAVE_BASIC_DIAGNOSTICOPTIONS_H @@ -54,6 +63,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define if SourceManager has a setMainFileID method */ +#undef HAVE_SETMAINFILEID + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H @@ -84,9 +96,6 @@ /* Return type of HandleTopLevelDeclReturn */ #undef HandleTopLevelDeclReturn -/* piplib is available */ -#undef ISL_PIPLIB - /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR @@ -132,13 +141,28 @@ /* Define if Driver::BuildCompilation takes ArrayRef */ #undef USE_ARRAYREF +/* use gmp to implement isl_int */ +#undef USE_GMP_FOR_MP + +/* use imath to implement isl_int */ +#undef USE_IMATH_FOR_MP + /* Version number of package */ #undef VERSION +/* Define to getParamType for newer versions of clang */ +#undef getArgType + /* Define to getHostTriple for older versions of clang */ #undef getDefaultTargetTriple /* Define to getInstantiationLineNumber for older versions of clang */ #undef getExpansionLineNumber +/* Define to getNumParams for newer versions of clang */ +#undef getNumArgs + +/* Define to getResultType for older versions of clang */ +#undef getReturnType + #include diff -Nru isl-0.12.2/isl_config_post.h isl-0.15/isl_config_post.h --- isl-0.12.2/isl_config_post.h 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_config_post.h 2015-04-19 12:02:52.000000000 +0000 @@ -5,3 +5,9 @@ #if (HAVE_DECL_FFS==0) && (HAVE_DECL___BUILTIN_FFS==1) #define ffs __builtin_ffs #endif + +#ifdef GCC_WARN_UNUSED_RESULT +#define WARN_UNUSED GCC_WARN_UNUSED_RESULT +#else +#define WARN_UNUSED +#endif diff -Nru isl-0.12.2/isl_constraint.c isl-0.15/isl_constraint.c --- isl-0.12.2/isl_constraint.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_constraint.c 2015-06-10 18:25:33.000000000 +0000 @@ -13,10 +13,12 @@ #include #include #include -#include +#include #include #include #include +#include +#include #undef BASE #define BASE constraint @@ -133,12 +135,14 @@ return isl_basic_map_constraint((struct isl_basic_map *)bset, line); } -__isl_give isl_constraint *isl_equality_alloc(__isl_take isl_local_space *ls) +__isl_give isl_constraint *isl_constraint_alloc_equality( + __isl_take isl_local_space *ls) { return isl_constraint_alloc(1, ls); } -__isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls) +__isl_give isl_constraint *isl_constraint_alloc_inequality( + __isl_take isl_local_space *ls) { return isl_constraint_alloc(0, ls); } @@ -172,7 +176,7 @@ return constraint; } -void *isl_constraint_free(struct isl_constraint *c) +__isl_null isl_constraint *isl_constraint_free(__isl_take isl_constraint *c) { if (!c) return NULL; @@ -187,57 +191,122 @@ return NULL; } +/* Return the number of constraints in "bmap", i.e., the + * number of times isl_basic_map_foreach_constraint will + * call the callback. + */ +int isl_basic_map_n_constraint(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return -1; + + return bmap->n_eq + bmap->n_ineq; +} + /* Return the number of constraints in "bset", i.e., the * number of times isl_basic_set_foreach_constraint will * call the callback. */ int isl_basic_set_n_constraint(__isl_keep isl_basic_set *bset) { - if (!bset) - return -1; - - return bset->n_eq + bset->n_ineq; + return isl_basic_map_n_constraint(bset); } -int isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap, - int (*fn)(__isl_take isl_constraint *c, void *user), void *user) +isl_stat isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user) { int i; struct isl_constraint *c; if (!bmap) - return -1; + return isl_stat_error; isl_assert(bmap->ctx, ISL_F_ISSET(bmap, ISL_BASIC_MAP_FINAL), - return -1); + return isl_stat_error); for (i = 0; i < bmap->n_eq; ++i) { c = isl_basic_map_constraint(isl_basic_map_copy(bmap), &bmap->eq[i]); if (!c) - return -1; + return isl_stat_error; if (fn(c, user) < 0) - return -1; + return isl_stat_error; } for (i = 0; i < bmap->n_ineq; ++i) { c = isl_basic_map_constraint(isl_basic_map_copy(bmap), &bmap->ineq[i]); if (!c) - return -1; + return isl_stat_error; if (fn(c, user) < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } -int isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, - int (*fn)(__isl_take isl_constraint *c, void *user), void *user) +isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, + isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user) { return isl_basic_map_foreach_constraint((isl_basic_map *)bset, fn, user); } +/* Add the constraint to the list that "user" points to, if it is not + * a div constraint. + */ +static isl_stat collect_constraint(__isl_take isl_constraint *constraint, + void *user) +{ + isl_constraint_list **list = user; + + if (isl_constraint_is_div_constraint(constraint)) + isl_constraint_free(constraint); + else + *list = isl_constraint_list_add(*list, constraint); + + return isl_stat_ok; +} + +/* Return a list of constraints that, when combined, are equivalent + * to "bmap". The input is required to have only known divs. + * + * There is no need to include the div constraints as they are + * implied by the div expressions. + */ +__isl_give isl_constraint_list *isl_basic_map_get_constraint_list( + __isl_keep isl_basic_map *bmap) +{ + int n; + int known; + isl_ctx *ctx; + isl_constraint_list *list; + + known = isl_basic_map_divs_known(bmap); + if (known < 0) + return NULL; + ctx = isl_basic_map_get_ctx(bmap); + if (!known) + isl_die(ctx, isl_error_invalid, + "input involves unknown divs", return NULL); + + n = isl_basic_map_n_constraint(bmap); + list = isl_constraint_list_alloc(ctx, n); + if (isl_basic_map_foreach_constraint(bmap, + &collect_constraint, &list) < 0) + list = isl_constraint_list_free(list); + + return list; +} + +/* Return a list of constraints that, when combined, are equivalent + * to "bset". The input is required to have only known divs. + */ +__isl_give isl_constraint_list *isl_basic_set_get_constraint_list( + __isl_keep isl_basic_set *bset) +{ + return isl_basic_map_get_constraint_list(bset); +} + int isl_constraint_is_equal(struct isl_constraint *constraint1, struct isl_constraint *constraint2) { @@ -323,23 +392,23 @@ return n(constraint, type); } -int isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, +isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned first, unsigned n) { int i; isl_ctx *ctx; int *active = NULL; - int involves = 0; + isl_bool involves = isl_bool_false; if (!constraint) - return -1; + return isl_bool_error; if (n == 0) - return 0; + return isl_bool_false; ctx = isl_constraint_get_ctx(constraint); if (first + n > isl_constraint_dim(constraint, type)) isl_die(ctx, isl_error_invalid, - "range out of bounds", return -1); + "range out of bounds", return isl_bool_error); active = isl_local_space_get_active(constraint->ls, constraint->v->el + 1); @@ -349,7 +418,7 @@ first += isl_local_space_offset(constraint->ls, type) - 1; for (i = 0; i < n; ++i) if (active[first + i]) { - involves = 1; + involves = isl_bool_true; break; } @@ -358,21 +427,21 @@ return involves; error: free(active); - return -1; + return isl_bool_error; } /* Does the given constraint represent a lower bound on the given * dimension? */ -int isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, +isl_bool isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos) { if (!constraint) - return -1; + return isl_bool_error; if (pos >= isl_local_space_dim(constraint->ls, type)) isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid, - "position out of bounds", return -1); + "position out of bounds", return isl_bool_error); pos += isl_local_space_offset(constraint->ls, type); return isl_int_is_pos(constraint->v->el[pos]); @@ -381,15 +450,15 @@ /* Does the given constraint represent an upper bound on the given * dimension? */ -int isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint, +isl_bool isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos) { if (!constraint) - return -1; + return isl_bool_error; if (pos >= isl_local_space_dim(constraint->ls, type)) isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid, - "position out of bounds", return -1); + "position out of bounds", return isl_bool_error); pos += isl_local_space_offset(constraint->ls, type); return isl_int_is_neg(constraint->v->el[pos]); @@ -548,7 +617,7 @@ */ __isl_give isl_constraint *isl_constraint_set_coefficient_val( __isl_take isl_constraint *constraint, - enum isl_dim_type type, int pos, isl_val *v) + enum isl_dim_type type, int pos, __isl_take isl_val *v) { constraint = isl_constraint_cow(constraint); if (!constraint || !v) @@ -602,11 +671,9 @@ * In particular, this means that the local spaces of "bset" and * "constraint" need to be the same. * - * Since the given constraint may actually be a pointer into the bset, - * we have to be careful not to reorder the constraints as the user - * may be holding on to other constraints from the same bset. - * This should be cleaned up when the internal representation of - * isl_constraint is changed to use isl_aff. + * We manually set ISL_BASIC_SET_FINAL instead of calling + * isl_basic_set_finalize because this function is called by CLooG, + * which does not expect any variables to disappear. */ __isl_give isl_basic_set *isl_basic_set_drop_constraint( __isl_take isl_basic_set *bset, __isl_take isl_constraint *constraint) @@ -617,6 +684,7 @@ unsigned total; isl_local_space *ls1; int equal; + int equality; if (!bset || !constraint) goto error; @@ -631,7 +699,12 @@ return bset; } - if (isl_constraint_is_equality(constraint)) { + bset = isl_basic_set_cow(bset); + if (!bset) + goto error; + + equality = isl_constraint_is_equality(constraint); + if (equality) { n = bset->n_eq; row = bset->eq; } else { @@ -640,11 +713,18 @@ } total = isl_constraint_dim(constraint, isl_dim_all); - for (i = 0; i < n; ++i) - if (isl_seq_eq(row[i], constraint->v->el, 1 + total)) - isl_seq_clr(row[i], 1 + total); + for (i = 0; i < n; ++i) { + if (!isl_seq_eq(row[i], constraint->v->el, 1 + total)) + continue; + if (equality && isl_basic_set_drop_equality(bset, i) < 0) + goto error; + if (!equality && isl_basic_set_drop_inequality(bset, i) < 0) + goto error; + break; + } isl_constraint_free(constraint); + ISL_F_SET(bset, ISL_BASIC_SET_FINAL); return bset; error: isl_constraint_free(constraint); @@ -672,10 +752,10 @@ return constraint; } -int isl_constraint_is_equality(struct isl_constraint *constraint) +isl_bool isl_constraint_is_equality(struct isl_constraint *constraint) { if (!constraint) - return -1; + return isl_bool_error; return constraint->eq; } @@ -750,11 +830,18 @@ if (isl_constraint_dim(constraint, isl_dim_in) != 0) isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid, - "not a set constraint", - return isl_constraint_free(constraint)); + "not a set constraint", goto error); return (isl_basic_set *)isl_basic_map_from_constraint(constraint); +error: + isl_constraint_free(constraint); + return NULL; } +/* Is the variable of "type" at position "pos" of "bmap" defined + * in terms of earlier dimensions through an equality? + * + * If so, and if c is not NULL, then return a copy of this equality in *c. + */ int isl_basic_map_has_defining_equality( __isl_keep isl_basic_map *bmap, enum isl_dim_type type, int pos, __isl_give isl_constraint **c) @@ -768,17 +855,24 @@ offset = basic_map_offset(bmap, type); total = isl_basic_map_total_dim(bmap); isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1); - for (i = 0; i < bmap->n_eq; ++i) - if (!isl_int_is_zero(bmap->eq[i][offset + pos]) && + for (i = 0; i < bmap->n_eq; ++i) { + if (isl_int_is_zero(bmap->eq[i][offset + pos]) || isl_seq_first_non_zero(bmap->eq[i]+offset+pos+1, - 1+total-offset-pos-1) == -1) { + 1+total-offset-pos-1) != -1) + continue; + if (c) *c = isl_basic_map_constraint(isl_basic_map_copy(bmap), &bmap->eq[i]); - return 1; - } + return 1; + } return 0; } +/* Is the variable of "type" at position "pos" of "bset" defined + * in terms of earlier dimensions through an equality? + * + * If so, and if c is not NULL, then return a copy of this equality in *c. + */ int isl_basic_set_has_defining_equality( __isl_keep isl_basic_set *bset, enum isl_dim_type type, int pos, __isl_give isl_constraint **c) @@ -945,10 +1039,10 @@ return context; } -static int foreach_upper_bound(__isl_keep isl_basic_set *bset, +static isl_stat foreach_upper_bound(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned abs_pos, __isl_take isl_basic_set *context, int n_upper, - int (*fn)(__isl_take isl_constraint *lower, + isl_stat (*fn)(__isl_take isl_constraint *lower, __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, void *user), void *user) { @@ -977,20 +1071,20 @@ isl_basic_set_free(context); if (i < bset->n_ineq) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; error: isl_constraint_free(upper); isl_basic_set_free(context_i); isl_basic_set_free(context); - return -1; + return isl_stat_error; } -static int foreach_lower_bound(__isl_keep isl_basic_set *bset, +static isl_stat foreach_lower_bound(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned abs_pos, __isl_take isl_basic_set *context, int n_lower, - int (*fn)(__isl_take isl_constraint *lower, + isl_stat (*fn)(__isl_take isl_constraint *lower, __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, void *user), void *user) { @@ -1019,20 +1113,20 @@ isl_basic_set_free(context); if (i < bset->n_ineq) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; error: isl_constraint_free(lower); isl_basic_set_free(context_i); isl_basic_set_free(context); - return -1; + return isl_stat_error; } -static int foreach_bound_pair(__isl_keep isl_basic_set *bset, +static isl_stat foreach_bound_pair(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned abs_pos, __isl_take isl_basic_set *context, int n_lower, int n_upper, - int (*fn)(__isl_take isl_constraint *lower, + isl_stat (*fn)(__isl_take isl_constraint *lower, __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, void *user), void *user) { @@ -1087,16 +1181,16 @@ isl_basic_set_free(context); if (i < bset->n_ineq) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; error: isl_constraint_free(lower); isl_constraint_free(upper); isl_basic_set_free(context_i); isl_basic_set_free(context_j); isl_basic_set_free(context); - return -1; + return isl_stat_error; } /* For each pair of lower and upper bounds on the variable "pos" @@ -1115,9 +1209,9 @@ * If not, we count the number of lower and upper bounds and * act accordingly. */ -int isl_basic_set_foreach_bound_pair(__isl_keep isl_basic_set *bset, +isl_stat isl_basic_set_foreach_bound_pair(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos, - int (*fn)(__isl_take isl_constraint *lower, + isl_stat (*fn)(__isl_take isl_constraint *lower, __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, void *user), void *user) { @@ -1129,10 +1223,11 @@ int n_lower, n_upper; if (!bset) - return -1; - isl_assert(bset->ctx, pos < isl_basic_set_dim(bset, type), return -1); + return isl_stat_error; + isl_assert(bset->ctx, pos < isl_basic_set_dim(bset, type), + return isl_stat_error); isl_assert(bset->ctx, type == isl_dim_param || type == isl_dim_set, - return -1); + return isl_stat_error); abs_pos = pos; if (type == isl_dim_set) @@ -1286,3 +1381,71 @@ { return isl_constraint_alloc_aff(0, aff); } + +/* Compare two isl_constraints. + * + * Return -1 if "c1" is "smaller" than "c2", 1 if "c1" is "greater" + * than "c2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do consider constraints that only involve + * earlier dimensions as "smaller". + */ +int isl_constraint_plain_cmp(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2) +{ + int cmp; + int last1, last2; + + if (c1 == c2) + return 0; + if (!c1) + return -1; + if (!c2) + return 1; + cmp = isl_local_space_cmp(c1->ls, c2->ls); + if (cmp != 0) + return cmp; + + last1 = isl_seq_last_non_zero(c1->v->el + 1, c1->v->size - 1); + last2 = isl_seq_last_non_zero(c2->v->el + 1, c1->v->size - 1); + if (last1 != last2) + return last1 - last2; + + return isl_seq_cmp(c1->v->el, c2->v->el, c1->v->size); +} + +/* Compare two constraints based on their final (non-zero) coefficients. + * In particular, the constraint that involves later variables or + * that has a larger coefficient for a shared latest variable + * is considered "greater" than the other constraint. + * + * Return -1 if "c1" is "smaller" than "c2", 1 if "c1" is "greater" + * than "c2" and 0 if they are equal. + * + * If the constraints live in different local spaces, then we cannot + * really compare the constraints so we compare the local spaces instead. + */ +int isl_constraint_cmp_last_non_zero(__isl_keep isl_constraint *c1, + __isl_keep isl_constraint *c2) +{ + int cmp; + int last1, last2; + + if (c1 == c2) + return 0; + if (!c1) + return -1; + if (!c2) + return 1; + cmp = isl_local_space_cmp(c1->ls, c2->ls); + if (cmp != 0) + return cmp; + + last1 = isl_seq_last_non_zero(c1->v->el + 1, c1->v->size - 1); + last2 = isl_seq_last_non_zero(c2->v->el + 1, c1->v->size - 1); + if (last1 != last2) + return last1 - last2; + if (last1 == -1) + return 0; + return isl_int_abs_cmp(c1->v->el[1 + last1], c2->v->el[1 + last2]); +} diff -Nru isl-0.12.2/isl_constraint_private.h isl-0.15/isl_constraint_private.h --- isl-0.12.2/isl_constraint_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_constraint_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -21,4 +21,12 @@ struct isl_constraint *isl_basic_set_constraint(struct isl_basic_set *bset, isl_int **line); +void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint, + enum isl_dim_type type, int pos, isl_int *v); +__isl_give isl_constraint *isl_constraint_set_constant( + __isl_take isl_constraint *constraint, isl_int v); +__isl_give isl_constraint *isl_constraint_set_coefficient( + __isl_take isl_constraint *constraint, + enum isl_dim_type type, int pos, isl_int v); + #endif diff -Nru isl-0.12.2/isl_convex_hull.c isl-0.15/isl_convex_hull.c --- isl-0.12.2/isl_convex_hull.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_convex_hull.c 2015-06-02 09:28:09.000000000 +0000 @@ -1,22 +1,27 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2014 INRIA Rocquencourt * * 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 + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include #include -#include +#include #include #include +#include #include -#include +#include #include #include "isl_equalities.h" #include "isl_tab.h" +#include static struct isl_basic_set *uset_convex_hull_wrap_bounded(struct isl_set *set); @@ -590,8 +595,9 @@ set = isl_set_preimage(set, U); facet = uset_convex_hull_wrap_bounded(set); facet = isl_basic_set_preimage(facet, Q); - if (facet) - isl_assert(ctx, facet->n_eq == 0, goto error); + if (facet && facet->n_eq != 0) + isl_die(ctx, isl_error_internal, "unexpected equality", + return isl_basic_set_free(facet)); return facet; error: isl_basic_set_free(facet); @@ -1309,12 +1315,12 @@ if (!bset1 || !bset2) goto error; - ctx = bset1->ctx; + ctx = isl_basic_set_get_ctx(bset1); dir = valid_direction(isl_basic_set_copy(bset1), isl_basic_set_copy(bset2)); if (!dir) goto error; - T = isl_mat_alloc(bset1->ctx, dir->size, dir->size); + T = isl_mat_alloc(ctx, dir->size, dir->size); if (!T) goto error; isl_seq_cpy(T->row[0], dir->block.data, dir->size); @@ -1380,7 +1386,7 @@ goto error; if (bounded1 && bounded2) - uset_convex_hull_wrap(isl_basic_set_union(bset1, bset2)); + return uset_convex_hull_wrap(isl_basic_set_union(bset1, bset2)); if (bounded1 || bounded2) return convex_hull_pair_pointed(bset1, bset2); @@ -1908,6 +1914,18 @@ return NULL; } +/* Return an empty basic map living in the same space as "map". + */ +static __isl_give isl_basic_map *replace_map_by_empty_basic_map( + __isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + return isl_basic_map_empty(space); +} + /* Compute the convex hull of a map. * * The implementation was inspired by "Extended Convex Hull" by Fukuda et al., @@ -1920,22 +1938,15 @@ struct isl_basic_set *affine_hull = NULL; struct isl_basic_map *convex_hull = NULL; struct isl_set *set = NULL; - struct isl_ctx *ctx; - - if (!map) - goto error; - - ctx = map->ctx; - if (map->n == 0) { - convex_hull = isl_basic_map_empty_like_map(map); - isl_map_free(map); - return convex_hull; - } map = isl_map_detect_equalities(map); map = isl_map_align_divs(map); if (!map) goto error; + + if (map->n == 0) + return replace_map_by_empty_basic_map(map); + model = isl_basic_map_copy(map->p[0]); set = isl_map_underlying_set(map); if (!set) @@ -2190,9 +2201,9 @@ return hull; k = isl_basic_set_alloc_inequality(hull); - isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len); if (k < 0) goto error; + isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len); for (j = 0; j < i; ++j) { int bound; @@ -2328,11 +2339,8 @@ if (!map) return NULL; - if (map->n == 0) { - hull = isl_basic_map_empty_like_map(map); - isl_map_free(map); - return hull; - } + if (map->n == 0) + return replace_map_by_empty_basic_map(map); if (map->n == 1) { hull = isl_basic_map_copy(map->p[0]); isl_map_free(map); @@ -2358,6 +2366,8 @@ ISL_F_SET(hull, ISL_BASIC_MAP_NO_IMPLICIT); ISL_F_SET(hull, ISL_BASIC_MAP_ALL_EQUALITIES); + hull = isl_basic_map_finalize(hull); + return hull; } @@ -2390,6 +2400,370 @@ return isl_map_unshifted_simple_hull(set); } +/* Check if "ineq" is a bound on "set" and, if so, add it to "hull". + * + * For each basic set in "set", we first check if the basic set + * contains a translate of "ineq". If this translate is more relaxed, + * then we assume that "ineq" is not a bound on this basic set. + * Otherwise, we know that it is a bound. + * If the basic set does not contain a translate of "ineq", then + * we call is_bound to perform the test. + */ +static __isl_give isl_basic_set *add_bound_from_constraint( + __isl_take isl_basic_set *hull, struct sh_data *data, + __isl_keep isl_set *set, isl_int *ineq) +{ + int i, k; + isl_ctx *ctx; + uint32_t c_hash; + struct ineq_cmp_data v; + + if (!hull || !set) + return isl_basic_set_free(hull); + + v.len = isl_basic_set_total_dim(hull); + v.p = ineq; + c_hash = isl_seq_get_hash(ineq + 1, v.len); + + ctx = isl_basic_set_get_ctx(hull); + for (i = 0; i < set->n; ++i) { + int bound; + struct isl_hash_table_entry *entry; + + entry = isl_hash_table_find(ctx, data->p[i].table, + c_hash, &has_ineq, &v, 0); + if (entry) { + isl_int *ineq_i = entry->data; + int neg, more_relaxed; + + neg = isl_seq_is_neg(ineq_i + 1, ineq + 1, v.len); + if (neg) + isl_int_neg(ineq_i[0], ineq_i[0]); + more_relaxed = isl_int_gt(ineq_i[0], ineq[0]); + if (neg) + isl_int_neg(ineq_i[0], ineq_i[0]); + if (more_relaxed) + break; + else + continue; + } + bound = is_bound(data, set, i, ineq, 0); + if (bound < 0) + return isl_basic_set_free(hull); + if (!bound) + break; + } + if (i < set->n) + return hull; + + k = isl_basic_set_alloc_inequality(hull); + if (k < 0) + return isl_basic_set_free(hull); + isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len); + + return hull; +} + +/* Compute a superset of the convex hull of "set" that is described + * by only some of the "n_ineq" constraints in the list "ineq", where "set" + * has no parameters or integer divisions. + * + * The inequalities in "ineq" are assumed to have been sorted such + * that constraints with the same linear part appear together and + * that among constraints with the same linear part, those with + * smaller constant term appear first. + * + * We reuse the same data structure that is used by uset_simple_hull, + * but we do not need the hull table since we will not consider the + * same constraint more than once. We therefore allocate it with zero size. + * + * We run through the constraints and try to add them one by one, + * skipping identical constraints. If we have added a constraint and + * the next constraint is a more relaxed translate, then we skip this + * next constraint as well. + */ +static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_constraints( + __isl_take isl_set *set, int n_ineq, isl_int **ineq) +{ + int i; + int last_added = 0; + struct sh_data *data = NULL; + isl_basic_set *hull = NULL; + unsigned dim; + + hull = isl_basic_set_alloc_space(isl_set_get_space(set), 0, 0, n_ineq); + if (!hull) + goto error; + + data = sh_data_alloc(set, 0); + if (!data) + goto error; + + dim = isl_set_dim(set, isl_dim_set); + for (i = 0; i < n_ineq; ++i) { + int hull_n_ineq = hull->n_ineq; + int parallel; + + parallel = i > 0 && isl_seq_eq(ineq[i - 1] + 1, ineq[i] + 1, + dim); + if (parallel && + (last_added || isl_int_eq(ineq[i - 1][0], ineq[i][0]))) + continue; + hull = add_bound_from_constraint(hull, data, set, ineq[i]); + if (!hull) + goto error; + last_added = hull->n_ineq > hull_n_ineq; + } + + sh_data_free(data); + isl_set_free(set); + return hull; +error: + sh_data_free(data); + isl_set_free(set); + isl_basic_set_free(hull); + return NULL; +} + +/* Collect pointers to all the inequalities in the elements of "list" + * in "ineq". For equalities, store both a pointer to the equality and + * a pointer to its opposite, which is first copied to "mat". + * "ineq" and "mat" are assumed to have been preallocated to the right size + * (the number of inequalities + 2 times the number of equalites and + * the number of equalities, respectively). + */ +static __isl_give isl_mat *collect_inequalities(__isl_take isl_mat *mat, + __isl_keep isl_basic_set_list *list, isl_int **ineq) +{ + int i, j, n, n_eq, n_ineq; + + if (!mat) + return NULL; + + n_eq = 0; + n_ineq = 0; + n = isl_basic_set_list_n_basic_set(list); + for (i = 0; i < n; ++i) { + isl_basic_set *bset; + bset = isl_basic_set_list_get_basic_set(list, i); + if (!bset) + return isl_mat_free(mat); + for (j = 0; j < bset->n_eq; ++j) { + ineq[n_ineq++] = mat->row[n_eq]; + ineq[n_ineq++] = bset->eq[j]; + isl_seq_neg(mat->row[n_eq++], bset->eq[j], mat->n_col); + } + for (j = 0; j < bset->n_ineq; ++j) + ineq[n_ineq++] = bset->ineq[j]; + isl_basic_set_free(bset); + } + + return mat; +} + +/* Comparison routine for use as an isl_sort callback. + * + * Constraints with the same linear part are sorted together and + * among constraints with the same linear part, those with smaller + * constant term are sorted first. + */ +static int cmp_ineq(const void *a, const void *b, void *arg) +{ + unsigned dim = *(unsigned *) arg; + isl_int * const *ineq1 = a; + isl_int * const *ineq2 = b; + int cmp; + + cmp = isl_seq_cmp((*ineq1) + 1, (*ineq2) + 1, dim); + if (cmp != 0) + return cmp; + return isl_int_cmp((*ineq1)[0], (*ineq2)[0]); +} + +/* Compute a superset of the convex hull of "set" that is described + * by only constraints in the elements of "list", where "set" has + * no parameters or integer divisions. + * + * We collect all the constraints in those elements and then + * sort the constraints such that constraints with the same linear part + * are sorted together and that those with smaller constant term are + * sorted first. + */ +static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_basic_set_list( + __isl_take isl_set *set, __isl_take isl_basic_set_list *list) +{ + int i, n, n_eq, n_ineq; + unsigned dim; + isl_ctx *ctx; + isl_mat *mat = NULL; + isl_int **ineq = NULL; + isl_basic_set *hull; + + if (!set) + goto error; + ctx = isl_set_get_ctx(set); + + n_eq = 0; + n_ineq = 0; + n = isl_basic_set_list_n_basic_set(list); + for (i = 0; i < n; ++i) { + isl_basic_set *bset; + bset = isl_basic_set_list_get_basic_set(list, i); + if (!bset) + goto error; + n_eq += bset->n_eq; + n_ineq += 2 * bset->n_eq + bset->n_ineq; + isl_basic_set_free(bset); + } + + ineq = isl_alloc_array(ctx, isl_int *, n_ineq); + if (n_ineq > 0 && !ineq) + goto error; + + dim = isl_set_dim(set, isl_dim_set); + mat = isl_mat_alloc(ctx, n_eq, 1 + dim); + mat = collect_inequalities(mat, list, ineq); + if (!mat) + goto error; + + if (isl_sort(ineq, n_ineq, sizeof(ineq[0]), &cmp_ineq, &dim) < 0) + goto error; + + hull = uset_unshifted_simple_hull_from_constraints(set, n_ineq, ineq); + + isl_mat_free(mat); + free(ineq); + isl_basic_set_list_free(list); + return hull; +error: + isl_mat_free(mat); + free(ineq); + isl_set_free(set); + isl_basic_set_list_free(list); + return NULL; +} + +/* Compute a superset of the convex hull of "map" that is described + * by only constraints in the elements of "list". + * + * If the list is empty, then we can only describe the universe set. + * If the input map is empty, then all constraints are valid, so + * we return the intersection of the elements in "list". + * + * Otherwise, we align all divs and temporarily treat them + * as regular variables, computing the unshifted simple hull in + * uset_unshifted_simple_hull_from_basic_set_list. + */ +static __isl_give isl_basic_map *map_unshifted_simple_hull_from_basic_map_list( + __isl_take isl_map *map, __isl_take isl_basic_map_list *list) +{ + isl_basic_map *model; + isl_basic_map *hull; + isl_set *set; + isl_basic_set_list *bset_list; + + if (!map || !list) + goto error; + + if (isl_basic_map_list_n_basic_map(list) == 0) { + isl_space *space; + + space = isl_map_get_space(map); + isl_map_free(map); + isl_basic_map_list_free(list); + return isl_basic_map_universe(space); + } + if (isl_map_plain_is_empty(map)) { + isl_map_free(map); + return isl_basic_map_list_intersect(list); + } + + map = isl_map_align_divs_to_basic_map_list(map, list); + if (!map) + goto error; + list = isl_basic_map_list_align_divs_to_basic_map(list, map->p[0]); + + model = isl_basic_map_list_get_basic_map(list, 0); + + set = isl_map_underlying_set(map); + bset_list = isl_basic_map_list_underlying_set(list); + + hull = uset_unshifted_simple_hull_from_basic_set_list(set, bset_list); + hull = isl_basic_map_overlying_set(hull, model); + + return hull; +error: + isl_map_free(map); + isl_basic_map_list_free(list); + return NULL; +} + +/* Return a sequence of the basic maps that make up the maps in "list". + */ +static __isl_give isl_basic_set_list *collect_basic_maps( + __isl_take isl_map_list *list) +{ + int i, n; + isl_ctx *ctx; + isl_basic_map_list *bmap_list; + + if (!list) + return NULL; + n = isl_map_list_n_map(list); + ctx = isl_map_list_get_ctx(list); + bmap_list = isl_basic_map_list_alloc(ctx, 0); + + for (i = 0; i < n; ++i) { + isl_map *map; + isl_basic_map_list *list_i; + + map = isl_map_list_get_map(list, i); + map = isl_map_compute_divs(map); + list_i = isl_map_get_basic_map_list(map); + isl_map_free(map); + bmap_list = isl_basic_map_list_concat(bmap_list, list_i); + } + + isl_map_list_free(list); + return bmap_list; +} + +/* Compute a superset of the convex hull of "map" that is described + * by only constraints in the elements of "list". + * + * If "map" is the universe, then the convex hull (and therefore + * any superset of the convexhull) is the universe as well. + * + * Otherwise, we collect all the basic maps in the map list and + * continue with map_unshifted_simple_hull_from_basic_map_list. + */ +__isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list( + __isl_take isl_map *map, __isl_take isl_map_list *list) +{ + isl_basic_map_list *bmap_list; + int is_universe; + + is_universe = isl_map_plain_is_universe(map); + if (is_universe < 0) + map = isl_map_free(map); + if (is_universe < 0 || is_universe) { + isl_map_list_free(list); + return isl_map_unshifted_simple_hull(map); + } + + bmap_list = collect_basic_maps(list); + return map_unshifted_simple_hull_from_basic_map_list(map, bmap_list); +} + +/* Compute a superset of the convex hull of "set" that is described + * by only constraints in the elements of "list". + */ +__isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list( + __isl_take isl_set *set, __isl_take isl_set_list *list) +{ + return isl_map_unshifted_simple_hull_from_map_list(set, list); +} + /* Given a set "set", return parametric bounds on the dimension "dim". */ static struct isl_basic_set *set_bounds(struct isl_set *set, int dim) diff -Nru isl-0.12.2/isl_ctx.c isl-0.15/isl_ctx.c --- isl-0.12.2/isl_ctx.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ctx.c 2015-06-11 10:46:17.000000000 +0000 @@ -14,6 +14,69 @@ #define __isl_calloc(type,size) ((type *)calloc(1, size)) #define __isl_calloc_type(type) __isl_calloc(type,sizeof(type)) +/* Check that the result of an allocation ("p") is not NULL and + * complain if it is. + * The only exception is when allocation size ("size") is equal to zero. + */ +static void *check_non_null(isl_ctx *ctx, void *p, size_t size) +{ + if (p || size == 0) + return p; + isl_die(ctx, isl_error_alloc, "allocation failure", return NULL); +} + +/* Prepare for performing the next "operation" in the context. + * Return 0 if we are allowed to perform this operation and + * return -1 if we should abort the computation. + * + * In particular, we should stop if the user has explicitly aborted + * the computation or if the maximal number of operations has been exceeded. + */ +int isl_ctx_next_operation(isl_ctx *ctx) +{ + if (!ctx) + return -1; + if (ctx->abort) { + isl_ctx_set_error(ctx, isl_error_abort); + return -1; + } + if (ctx->max_operations && ctx->operations >= ctx->max_operations) + isl_die(ctx, isl_error_quota, + "maximal number of operations exceeded", return -1); + ctx->operations++; + return 0; +} + +/* Call malloc and complain if it fails. + * If ctx is NULL, then return NULL. + */ +void *isl_malloc_or_die(isl_ctx *ctx, size_t size) +{ + if (isl_ctx_next_operation(ctx) < 0) + return NULL; + return ctx ? check_non_null(ctx, malloc(size), size) : NULL; +} + +/* Call calloc and complain if it fails. + * If ctx is NULL, then return NULL. + */ +void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size) +{ + if (isl_ctx_next_operation(ctx) < 0) + return NULL; + return ctx ? check_non_null(ctx, calloc(nmemb, size), nmemb) : NULL; +} + +/* Call realloc and complain if it fails. + * If ctx is NULL, then return NULL. + */ +void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size) +{ + if (isl_ctx_next_operation(ctx) < 0) + return NULL; + return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL; +} + void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg, const char *file, int line) { @@ -133,6 +196,9 @@ ctx->error = isl_error_none; + ctx->operations = 0; + isl_ctx_set_max_operations(ctx, ctx->opt->max_operations); + return ctx; error: isl_args_free(args, user_opt); @@ -162,6 +228,13 @@ ctx->ref--; } +/* Print statistics on usage. + */ +static void print_stats(isl_ctx *ctx) +{ + fprintf(stderr, "operations: %lu\n", ctx->operations); +} + void isl_ctx_free(struct isl_ctx *ctx) { if (!ctx) @@ -171,6 +244,9 @@ "isl_ctx freed, but some objects still reference it", return); + if (ctx->opt->print_stats) + print_stats(ctx); + isl_hash_table_clear(&ctx->id_table); isl_blk_clear_cache(ctx); isl_int_clear(ctx->zero); @@ -231,3 +307,28 @@ return -1; return isl_args_parse(ctx->user_args, argc, argv, ctx->user_opt, flags); } + +/* Set the maximal number of iterations of "ctx" to "max_operations". + */ +void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations) +{ + if (!ctx) + return; + ctx->max_operations = max_operations; +} + +/* Return the maximal number of iterations of "ctx". + */ +unsigned long isl_ctx_get_max_operations(isl_ctx *ctx) +{ + return ctx ? ctx->max_operations : 0; +} + +/* Reset the number of operations performed by "ctx". + */ +void isl_ctx_reset_operations(isl_ctx *ctx) +{ + if (!ctx) + return; + ctx->operations = 0; +} diff -Nru isl-0.12.2/isl_ctx_private.h isl-0.15/isl_ctx_private.h --- isl-0.12.2/isl_ctx_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_ctx_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,5 @@ #include +#include struct isl_ctx { int ref; @@ -25,4 +26,9 @@ enum isl_error error; int abort; + + unsigned long operations; + unsigned long max_operations; }; + +int isl_ctx_next_operation(isl_ctx *ctx); diff -Nru isl-0.12.2/isl_deprecated.c isl-0.15/isl_deprecated.c --- isl-0.12.2/isl_deprecated.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/isl_deprecated.c 2015-06-11 10:46:17.000000000 +0000 @@ -1,3 +1,4 @@ +#include #include /* This function was never documented and has been replaced by @@ -8,3 +9,17 @@ { return isl_basic_set_add_dims(bset, type, n); } + +/* This function was replaced by isl_constraint_alloc_equality. + */ +__isl_give isl_constraint *isl_equality_alloc(__isl_take isl_local_space *ls) +{ + return isl_constraint_alloc_equality(ls); +} + +/* This function was replaced by isl_constraint_alloc_inequality. + */ +__isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls) +{ + return isl_constraint_alloc_inequality(ls); +} diff -Nru isl-0.12.2/isl_dim.c isl-0.15/isl_dim.c --- isl-0.12.2/isl_dim.c 2013-01-08 11:20:44.000000000 +0000 +++ isl-0.15/isl_dim.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,258 +0,0 @@ -#include -#include -#include -#include -#include - -isl_ctx *isl_dim_get_ctx(__isl_keep isl_space *dim) -{ - return isl_space_get_ctx(dim); -} - -__isl_give isl_space *isl_dim_alloc(isl_ctx *ctx, - unsigned nparam, unsigned n_in, unsigned n_out) -{ - return isl_space_alloc(ctx, nparam, n_in, n_out); -} -__isl_give isl_space *isl_dim_set_alloc(isl_ctx *ctx, - unsigned nparam, unsigned dim) -{ - return isl_space_set_alloc(ctx, nparam, dim); -} -__isl_give isl_space *isl_dim_copy(__isl_keep isl_space *dim) -{ - return isl_space_copy(dim); -} -void isl_dim_free(__isl_take isl_space *dim) -{ - isl_space_free(dim); -} - -unsigned isl_dim_size(__isl_keep isl_space *dim, enum isl_dim_type type) -{ - return isl_space_dim(dim, type); -} - -__isl_give isl_space *isl_dim_set_dim_id(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) -{ - return isl_space_set_dim_id(dim, type, pos, id); -} -int isl_dim_has_dim_id(__isl_keep isl_space *dim, - enum isl_dim_type type, unsigned pos) -{ - return isl_space_has_dim_id(dim, type, pos); -} -__isl_give isl_id *isl_dim_get_dim_id(__isl_keep isl_space *dim, - enum isl_dim_type type, unsigned pos) -{ - return isl_space_get_dim_id(dim, type, pos); -} - -int isl_dim_find_dim_by_id(__isl_keep isl_space *dim, - enum isl_dim_type type, __isl_keep isl_id *id) -{ - return isl_space_find_dim_by_id(dim, type, id); -} - -__isl_give isl_space *isl_dim_set_tuple_id(__isl_take isl_space *dim, - enum isl_dim_type type, __isl_take isl_id *id) -{ - return isl_space_set_tuple_id(dim, type, id); -} -__isl_give isl_space *isl_dim_reset_tuple_id(__isl_take isl_space *dim, - enum isl_dim_type type) -{ - return isl_space_reset_tuple_id(dim, type); -} -int isl_dim_has_tuple_id(__isl_keep isl_space *dim, enum isl_dim_type type) -{ - return isl_space_has_tuple_id(dim, type); -} -__isl_give isl_id *isl_dim_get_tuple_id(__isl_keep isl_space *dim, - enum isl_dim_type type) -{ - return isl_space_get_tuple_id(dim, type); -} - -__isl_give isl_space *isl_dim_set_name(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned pos, __isl_keep const char *name) -{ - return isl_space_set_dim_name(dim, type, pos, name); -} -__isl_keep const char *isl_dim_get_name(__isl_keep isl_space *dim, - enum isl_dim_type type, unsigned pos) -{ - return isl_space_get_dim_name(dim, type, pos); -} - -__isl_give isl_space *isl_dim_set_tuple_name(__isl_take isl_space *dim, - enum isl_dim_type type, const char *s) -{ - return isl_space_set_tuple_name(dim, type, s); -} -const char *isl_dim_get_tuple_name(__isl_keep isl_space *dim, - enum isl_dim_type type) -{ - return isl_space_get_tuple_name(dim, type); -} - -int isl_dim_is_wrapping(__isl_keep isl_space *dim) -{ - return isl_space_is_wrapping(dim); -} -__isl_give isl_space *isl_dim_wrap(__isl_take isl_space *dim) -{ - return isl_space_wrap(dim); -} -__isl_give isl_space *isl_dim_unwrap(__isl_take isl_space *dim) -{ - return isl_space_unwrap(dim); -} - -__isl_give isl_space *isl_dim_domain(__isl_take isl_space *dim) -{ - return isl_space_domain(dim); -} -__isl_give isl_space *isl_dim_from_domain(__isl_take isl_space *dim) -{ - return isl_space_from_domain(dim); -} -__isl_give isl_space *isl_dim_range(__isl_take isl_space *dim) -{ - return isl_space_range(dim); -} -__isl_give isl_space *isl_dim_from_range(__isl_take isl_space *dim) -{ - return isl_space_from_range(dim); -} -__isl_give isl_space *isl_dim_reverse(__isl_take isl_space *dim) -{ - return isl_space_reverse(dim); -} -__isl_give isl_space *isl_dim_join(__isl_take isl_space *left, - __isl_take isl_space *right) -{ - return isl_space_join(left, right); -} -__isl_give isl_space *isl_dim_align_params(__isl_take isl_space *dim1, - __isl_take isl_space *dim2) -{ - return isl_space_align_params(dim1, dim2); -} -__isl_give isl_space *isl_dim_insert(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned pos, unsigned n) -{ - return isl_space_insert_dims(dim, type, pos, n); -} -__isl_give isl_space *isl_dim_add(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned n) -{ - return isl_space_add_dims(dim, type, n); -} -__isl_give isl_space *isl_dim_drop(__isl_take isl_space *dim, - enum isl_dim_type type, unsigned first, unsigned n) -{ - return isl_space_drop_dims(dim, type, first, n); -} -__isl_give isl_space *isl_dim_move(__isl_take isl_space *dim, - enum isl_dim_type dst_type, unsigned dst_pos, - enum isl_dim_type src_type, unsigned src_pos, unsigned n) -{ - return isl_space_move_dims(dim, dst_type, dst_pos, src_type, src_pos, n); -} -__isl_give isl_space *isl_dim_map_from_set(__isl_take isl_space *dim) -{ - return isl_space_map_from_set(dim); -} -__isl_give isl_space *isl_dim_zip(__isl_take isl_space *dim) -{ - return isl_space_zip(dim); -} - -__isl_give isl_local_space *isl_local_space_from_dim( - __isl_take isl_space *dim) -{ - return isl_local_space_from_space(dim); -} -__isl_give isl_space *isl_local_space_get_dim( - __isl_keep isl_local_space *ls) -{ - return isl_local_space_get_space(ls); -} - -__isl_give isl_space *isl_aff_get_dim(__isl_keep isl_aff *aff) -{ - return isl_aff_get_space(aff); -} -__isl_give isl_space *isl_pw_aff_get_dim(__isl_keep isl_pw_aff *pwaff) -{ - return isl_pw_aff_get_space(pwaff); -} - -__isl_give isl_space *isl_constraint_get_dim( - __isl_keep isl_constraint *constraint) -{ - return isl_constraint_get_space(constraint); -} - -__isl_give isl_space *isl_basic_map_get_dim(__isl_keep isl_basic_map *bmap) -{ - return isl_basic_map_get_space(bmap); -} -__isl_give isl_space *isl_map_get_dim(__isl_keep isl_map *map) -{ - return isl_map_get_space(map); -} -__isl_give isl_space *isl_union_map_get_dim(__isl_keep isl_union_map *umap) -{ - return isl_union_map_get_space(umap); -} - -__isl_give isl_space *isl_basic_set_get_dim(__isl_keep isl_basic_set *bset) -{ - return isl_basic_set_get_space(bset); -} -__isl_give isl_space *isl_set_get_dim(__isl_keep isl_set *set) -{ - return isl_set_get_space(set); -} -__isl_give isl_space *isl_union_set_get_dim(__isl_keep isl_union_set *uset) -{ - return isl_union_set_get_space(uset); -} - -__isl_give isl_space *isl_point_get_dim(__isl_keep isl_point *pnt) -{ - return isl_point_get_space(pnt); -} - -__isl_give isl_space *isl_qpolynomial_get_dim(__isl_keep isl_qpolynomial *qp) -{ - return isl_qpolynomial_get_space(qp); -} -__isl_give isl_space *isl_pw_qpolynomial_get_dim( - __isl_keep isl_pw_qpolynomial *pwqp) -{ - return isl_pw_qpolynomial_get_space(pwqp); -} -__isl_give isl_space *isl_qpolynomial_fold_get_dim( - __isl_keep isl_qpolynomial_fold *fold) -{ - return isl_qpolynomial_fold_get_space(fold); -} -__isl_give isl_space *isl_pw_qpolynomial_fold_get_dim( - __isl_keep isl_pw_qpolynomial_fold *pwf) -{ - return isl_pw_qpolynomial_fold_get_space(pwf); -} -__isl_give isl_space *isl_union_pw_qpolynomial_get_dim( - __isl_keep isl_union_pw_qpolynomial *upwqp) -{ - return isl_union_pw_qpolynomial_get_space(upwqp); -} -__isl_give isl_space *isl_union_pw_qpolynomial_fold_get_dim( - __isl_keep isl_union_pw_qpolynomial_fold *upwf) -{ - return isl_union_pw_qpolynomial_fold_get_space(upwf); -} diff -Nru isl-0.12.2/isl_equalities.c isl-0.15/isl_equalities.c --- isl-0.12.2/isl_equalities.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_equalities.c 2015-06-02 09:28:09.000000000 +0000 @@ -11,7 +11,8 @@ */ #include -#include +#include +#include #include "isl_map_private.h" #include "isl_equalities.h" #include @@ -637,10 +638,10 @@ return 0; } - ctx = bset->ctx; + ctx = isl_basic_set_get_ctx(bset); total = isl_basic_set_total_dim(bset); nparam = isl_basic_set_n_param(bset); - H = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq, 1, total); + H = isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 1, total); H = isl_mat_left_hermite(H, 0, &U, NULL); if (!H) return -1; @@ -656,11 +657,11 @@ return 0; } - C = isl_mat_alloc(bset->ctx, 1+bset->n_eq, 1); + C = isl_mat_alloc(ctx, 1 + bset->n_eq, 1); if (!C) goto error; isl_int_set_si(C->row[0][0], 1); - isl_mat_sub_neg(C->ctx, C->row+1, bset->eq, bset->n_eq, 0, 0, 1); + isl_mat_sub_neg(ctx, C->row + 1, bset->eq, bset->n_eq, 0, 0, 1); H1 = isl_mat_sub_alloc(H, 0, H->n_row, 0, H->n_row); H1 = isl_mat_lin_to_aff(H1); C = isl_mat_inverse_product(H1, C); @@ -670,7 +671,7 @@ isl_mat_free(U); C = isl_mat_product(U1, C); if (!C) - goto error; + return -1; if (!isl_int_is_divisible_by(C->row[1][0], C->row[0][0])) { bset = isl_basic_set_copy(bset); bset = isl_basic_set_set_to_empty(bset); @@ -757,13 +758,13 @@ * If i_dim does not belong to such a residue class, then *modulo * is set to 1 and *residue is set to 0. */ -int isl_set_dim_residue_class_val(__isl_keep isl_set *set, +isl_stat isl_set_dim_residue_class_val(__isl_keep isl_set *set, int pos, __isl_give isl_val **modulo, __isl_give isl_val **residue) { *modulo = NULL; *residue = NULL; if (!set) - return -1; + return isl_stat_error; *modulo = isl_val_alloc(isl_set_get_ctx(set)); *residue = isl_val_alloc(isl_set_get_ctx(set)); if (!*modulo || !*residue) @@ -773,9 +774,9 @@ goto error; isl_int_set_si((*modulo)->d, 1); isl_int_set_si((*residue)->d, 1); - return 0; + return isl_stat_ok; error: isl_val_free(*modulo); isl_val_free(*residue); - return -1; + return isl_stat_error; } diff -Nru isl-0.12.2/isl_farkas.c isl-0.15/isl_farkas.c --- isl-0.12.2/isl_farkas.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_farkas.c 2015-04-19 12:02:52.000000000 +0000 @@ -11,7 +11,7 @@ #include #include #include -#include +#include /* * Let C be a cone and define @@ -40,16 +40,16 @@ * constraints on P. * This is essentially Farkas' lemma. * - * Let A' = [b A], then, since + * Since * [ 1 0 ] * [ w y ] = [t_0 t] [ b A ] * * we have * - * C' = { w, y | exists t_0, t >= 0 : y = t A' and w = t_0 + t b } + * C' = { w, y | exists t_0, t >= 0 : y = t A and w = t_0 + t b } * or * - * C' = { w, y | exists t >= 0 : y = t A' and w - t b >= 0 } + * C' = { w, y | exists t >= 0 : y = t A and w - t b >= 0 } * * In practice, we introduce an extra variable (w), shifting all * other variables to the right, and an extra inequality @@ -194,23 +194,45 @@ return dim; } +/* Return the rational universe basic set in the given space. + */ +static __isl_give isl_basic_set *rational_universe(__isl_take isl_space *space) +{ + isl_basic_set *bset; + + bset = isl_basic_set_universe(space); + bset = isl_basic_set_set_rational(bset); + + return bset; +} + /* Compute the dual of "bset" by applying Farkas' lemma. * As explained above, we add an extra dimension to represent * the coefficient of the constant term when going from solutions * to coefficients (shift == 1) and we drop the extra dimension when going * in the opposite direction (shift == -1). "dim" is the space in which * the dual should be created. + * + * If "bset" is (obviously) empty, then the way this emptiness + * is represented by the constraints does not allow for the application + * of the standard farkas algorithm. We therefore handle this case + * specifically and return the universe basic set. */ -static __isl_give isl_basic_set *farkas(__isl_take isl_space *dim, +static __isl_give isl_basic_set *farkas(__isl_take isl_space *space, __isl_take isl_basic_set *bset, int shift) { int i, j, k; isl_basic_set *dual = NULL; unsigned total; + if (isl_basic_set_plain_is_empty(bset)) { + isl_basic_set_free(bset); + return rational_universe(space); + } + total = isl_basic_set_total_dim(bset); - dual = isl_basic_set_alloc_space(dim, bset->n_eq + bset->n_ineq, + dual = isl_basic_set_alloc_space(space, bset->n_eq + bset->n_ineq, total, bset->n_ineq + (shift > 0)); dual = isl_basic_set_set_rational(dual); @@ -330,12 +352,10 @@ if (!set) return NULL; if (set->n == 0) { - isl_space *dim = isl_set_get_space(set); - dim = isl_space_coefficients(dim); - coeff = isl_basic_set_universe(dim); - coeff = isl_basic_set_set_rational(coeff); + isl_space *space = isl_set_get_space(set); + space = isl_space_coefficients(space); isl_set_free(set); - return coeff; + return rational_universe(space); } coeff = isl_basic_set_coefficients(isl_basic_set_copy(set->p[0])); @@ -363,12 +383,10 @@ if (!set) return NULL; if (set->n == 0) { - isl_space *dim = isl_set_get_space(set); - dim = isl_space_solutions(dim); - sol = isl_basic_set_universe(dim); - sol = isl_basic_set_set_rational(sol); + isl_space *space = isl_set_get_space(set); + space = isl_space_solutions(space); isl_set_free(set); - return sol; + return rational_universe(space); } sol = isl_basic_set_solutions(isl_basic_set_copy(set->p[0])); diff -Nru isl-0.12.2/isl_flow.c isl-0.15/isl_flow.c --- isl-0.12.2/isl_flow.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_flow.c 2015-06-11 07:55:31.000000000 +0000 @@ -3,6 +3,7 @@ * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2010 INRIA Saclay * Copyright 2012 Universiteit Leiden + * Copyright 2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -12,11 +13,15 @@ * B-3001 Leuven, Belgium * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France */ #include #include +#include +#include #include +#include #include enum isl_restriction_type { @@ -127,7 +132,8 @@ return NULL; } -void *isl_restriction_free(__isl_take isl_restriction *restr) +__isl_null isl_restriction *isl_restriction_free( + __isl_take isl_restriction *restr) { if (!restr) return NULL; @@ -227,7 +233,8 @@ /* Free the given isl_access_info structure. */ -void *isl_access_info_free(__isl_take isl_access_info *acc) +__isl_null isl_access_info *isl_access_info_free( + __isl_take isl_access_info *acc) { int i; @@ -429,24 +436,25 @@ * while the third argument correspond to the final argument of * the isl_flow_foreach call. */ -int isl_flow_foreach(__isl_keep isl_flow *deps, - int (*fn)(__isl_take isl_map *dep, int must, void *dep_user, void *user), +isl_stat isl_flow_foreach(__isl_keep isl_flow *deps, + isl_stat (*fn)(__isl_take isl_map *dep, int must, void *dep_user, + void *user), void *user) { int i; if (!deps) - return -1; + return isl_stat_error; for (i = 0; i < deps->n_source; ++i) { if (isl_map_plain_is_empty(deps->dep[i].map)) continue; if (fn(isl_map_copy(deps->dep[i].map), deps->dep[i].must, deps->dep[i].data, user) < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } /* Return a copy of the subset of the sink for which no source could be found. @@ -736,7 +744,7 @@ * after_level. */ static __isl_give isl_map *all_later_sources(__isl_keep isl_access_info *acc, - __isl_keep isl_map *old_map, + __isl_take isl_map *old_map, int j, int before_level, int k, int after_level) { isl_space *dim; @@ -928,7 +936,7 @@ depth = 2 * isl_map_dim(acc->sink.map, isl_dim_in) + 1; mustdo = isl_map_domain(isl_map_copy(acc->sink.map)); - maydo = isl_set_empty_like(mustdo); + maydo = isl_set_empty(isl_set_get_space(mustdo)); if (!mustdo || !maydo) goto error; if (isl_set_plain_is_empty(mustdo)) @@ -941,7 +949,9 @@ for (level = depth; level >= 1; --level) { for (j = acc->n_must-1; j >=0; --j) { - must_rel[j] = isl_map_empty_like(res->dep[j].map); + isl_space *space; + space = isl_map_get_space(res->dep[2 * j].map); + must_rel[j] = isl_map_empty(space); may_rel[j] = isl_map_copy(must_rel[j]); } @@ -1165,13 +1175,470 @@ return NULL; } -struct isl_compute_flow_data { +/* This structure represents the input for a dependence analysis computation. + * + * "sink" represents the sink accesses. + * "must_source" represents the definite source accesses. + * "may_source" represents the possible source accesses. + * + * "schedule" or "schedule_map" represents the execution order. + * Exactly one of these fields should be NULL. The other field + * determines the execution order. + * + * The domains of these four maps refer to the same iteration spaces(s). + * The ranges of the first three maps also refer to the same data space(s). + * + * After a call to isl_union_access_info_introduce_schedule, + * the "schedule_map" field no longer contains useful information. + */ +struct isl_union_access_info { + isl_union_map *sink; isl_union_map *must_source; isl_union_map *may_source; + + isl_schedule *schedule; + isl_union_map *schedule_map; +}; + +/* Free "access" and return NULL. + */ +__isl_null isl_union_access_info *isl_union_access_info_free( + __isl_take isl_union_access_info *access) +{ + if (!access) + return NULL; + + isl_union_map_free(access->sink); + isl_union_map_free(access->must_source); + isl_union_map_free(access->may_source); + isl_schedule_free(access->schedule); + isl_union_map_free(access->schedule_map); + free(access); + + return NULL; +} + +/* Return the isl_ctx to which "access" belongs. + */ +isl_ctx *isl_union_access_info_get_ctx(__isl_keep isl_union_access_info *access) +{ + return access ? isl_union_map_get_ctx(access->sink) : NULL; +} + +/* Create a new isl_union_access_info with the given sink accesses and + * and no source accesses or schedule information. + * + * By default, we use the schedule field of the isl_union_access_info, + * but this may be overridden by a call + * to isl_union_access_info_set_schedule_map. + */ +__isl_give isl_union_access_info *isl_union_access_info_from_sink( + __isl_take isl_union_map *sink) +{ + isl_ctx *ctx; + isl_space *space; + isl_union_map *empty; + isl_union_access_info *access; + + if (!sink) + return NULL; + ctx = isl_union_map_get_ctx(sink); + access = isl_alloc_type(ctx, isl_union_access_info); + if (!access) + goto error; + + space = isl_union_map_get_space(sink); + empty = isl_union_map_empty(isl_space_copy(space)); + access->sink = sink; + access->must_source = isl_union_map_copy(empty); + access->may_source = empty; + access->schedule = isl_schedule_empty(space); + access->schedule_map = NULL; + + if (!access->sink || !access->must_source || + !access->may_source || !access->schedule) + return isl_union_access_info_free(access); + + return access; +error: + isl_union_map_free(sink); + return NULL; +} + +/* Replace the definite source accesses of "access" by "must_source". + */ +__isl_give isl_union_access_info *isl_union_access_info_set_must_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *must_source) +{ + if (!access || !must_source) + goto error; + + isl_union_map_free(access->must_source); + access->must_source = must_source; + + return access; +error: + isl_union_access_info_free(access); + isl_union_map_free(must_source); + return NULL; +} + +/* Replace the possible source accesses of "access" by "may_source". + */ +__isl_give isl_union_access_info *isl_union_access_info_set_may_source( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *may_source) +{ + if (!access || !may_source) + goto error; + + isl_union_map_free(access->may_source); + access->may_source = may_source; + + return access; +error: + isl_union_access_info_free(access); + isl_union_map_free(may_source); + return NULL; +} + +/* Replace the schedule of "access" by "schedule". + * Also free the schedule_map in case it was set last. + */ +__isl_give isl_union_access_info *isl_union_access_info_set_schedule( + __isl_take isl_union_access_info *access, + __isl_take isl_schedule *schedule) +{ + if (!access || !schedule) + goto error; + + access->schedule_map = isl_union_map_free(access->schedule_map); + isl_schedule_free(access->schedule); + access->schedule = schedule; + + return access; +error: + isl_union_access_info_free(access); + isl_schedule_free(schedule); + return NULL; +} + +/* Replace the schedule map of "access" by "schedule_map". + * Also free the schedule in case it was set last. + */ +__isl_give isl_union_access_info *isl_union_access_info_set_schedule_map( + __isl_take isl_union_access_info *access, + __isl_take isl_union_map *schedule_map) +{ + if (!access || !schedule_map) + goto error; + + isl_union_map_free(access->schedule_map); + access->schedule = isl_schedule_free(access->schedule); + access->schedule_map = schedule_map; + + return access; +error: + isl_union_access_info_free(access); + isl_union_map_free(schedule_map); + return NULL; +} + +__isl_give isl_union_access_info *isl_union_access_info_copy( + __isl_keep isl_union_access_info *access) +{ + isl_union_access_info *copy; + + if (!access) + return NULL; + copy = isl_union_access_info_from_sink( + isl_union_map_copy(access->sink)); + copy = isl_union_access_info_set_must_source(copy, + isl_union_map_copy(access->must_source)); + copy = isl_union_access_info_set_may_source(copy, + isl_union_map_copy(access->may_source)); + if (access->schedule) + copy = isl_union_access_info_set_schedule(copy, + isl_schedule_copy(access->schedule)); + else + copy = isl_union_access_info_set_schedule_map(copy, + isl_union_map_copy(access->schedule_map)); + + return copy; +} + +/* Update the fields of "access" such that they all have the same parameters, + * keeping in mind that the schedule_map field may be NULL and ignoring + * the schedule field. + */ +static __isl_give isl_union_access_info *isl_union_access_info_align_params( + __isl_take isl_union_access_info *access) +{ + isl_space *space; + + if (!access) + return NULL; + + space = isl_union_map_get_space(access->sink); + space = isl_space_align_params(space, + isl_union_map_get_space(access->must_source)); + space = isl_space_align_params(space, + isl_union_map_get_space(access->may_source)); + if (access->schedule_map) + space = isl_space_align_params(space, + isl_union_map_get_space(access->schedule_map)); + access->sink = isl_union_map_align_params(access->sink, + isl_space_copy(space)); + access->must_source = isl_union_map_align_params(access->must_source, + isl_space_copy(space)); + access->may_source = isl_union_map_align_params(access->may_source, + isl_space_copy(space)); + if (!access->schedule_map) { + isl_space_free(space); + } else { + access->schedule_map = + isl_union_map_align_params(access->schedule_map, space); + if (!access->schedule_map) + return isl_union_access_info_free(access); + } + + if (!access->sink || !access->must_source || !access->may_source) + return isl_union_access_info_free(access); + + return access; +} + +/* Prepend the schedule dimensions to the iteration domains. + * + * That is, if the schedule is of the form + * + * D -> S + * + * while the access relations are of the form + * + * D -> A + * + * then the updated access relations are of the form + * + * [S -> D] -> A + * + * The schedule map is also replaced by the map + * + * [S -> D] -> D + * + * that is used during the internal computation. + * Neither the original schedule map nor this updated schedule map + * are used after the call to this function. + */ +static __isl_give isl_union_access_info * +isl_union_access_info_introduce_schedule( + __isl_take isl_union_access_info *access) +{ + isl_union_map *sm; + + if (!access) + return NULL; + + sm = isl_union_map_reverse(access->schedule_map); + sm = isl_union_map_range_map(sm); + access->sink = isl_union_map_apply_range(isl_union_map_copy(sm), + access->sink); + access->may_source = isl_union_map_apply_range(isl_union_map_copy(sm), + access->may_source); + access->must_source = isl_union_map_apply_range(isl_union_map_copy(sm), + access->must_source); + access->schedule_map = sm; + + if (!access->sink || !access->must_source || + !access->may_source || !access->schedule_map) + return isl_union_access_info_free(access); + + return access; +} + +/* This structure epresents the result of a dependence analysis computation. + * + * "must_dep" represents the definite dependences. + * "may_dep" represents the non-definite dependences. + * "must_no_source" represents the subset of the sink accesses for which + * definitely no source was found. + * "may_no_source" represents the subset of the sink accesses for which + * possibly, but not definitely, no source was found. + */ +struct isl_union_flow { isl_union_map *must_dep; isl_union_map *may_dep; isl_union_map *must_no_source; isl_union_map *may_no_source; +}; + +/* Return the isl_ctx to which "flow" belongs. + */ +isl_ctx *isl_union_flow_get_ctx(__isl_keep isl_union_flow *flow) +{ + return flow ? isl_union_map_get_ctx(flow->must_dep) : NULL; +} + +/* Free "flow" and return NULL. + */ +__isl_null isl_union_flow *isl_union_flow_free(__isl_take isl_union_flow *flow) +{ + if (!flow) + return NULL; + isl_union_map_free(flow->must_dep); + isl_union_map_free(flow->may_dep); + isl_union_map_free(flow->must_no_source); + isl_union_map_free(flow->may_no_source); + free(flow); + return NULL; +} + +void isl_union_flow_dump(__isl_keep isl_union_flow *flow) +{ + if (!flow) + return; + + fprintf(stderr, "must dependences: "); + isl_union_map_dump(flow->must_dep); + fprintf(stderr, "may dependences: "); + isl_union_map_dump(flow->may_dep); + fprintf(stderr, "must no source: "); + isl_union_map_dump(flow->must_no_source); + fprintf(stderr, "may no source: "); + isl_union_map_dump(flow->may_no_source); +} + +/* Return the definite dependences in "flow". + */ +__isl_give isl_union_map *isl_union_flow_get_must_dependence( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->must_dep); +} + +/* Return the possible dependences in "flow", including the definite + * dependences. + */ +__isl_give isl_union_map *isl_union_flow_get_may_dependence( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_union(isl_union_map_copy(flow->must_dep), + isl_union_map_copy(flow->may_dep)); +} + +/* Return the non-definite dependences in "flow". + */ +static __isl_give isl_union_map *isl_union_flow_get_non_must_dependence( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->may_dep); +} + +/* Return the subset of the sink accesses for which definitely + * no source was found. + */ +__isl_give isl_union_map *isl_union_flow_get_must_no_source( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->must_no_source); +} + +/* Return the subset of the sink accesses for which possibly + * no source was found, including those for which definitely + * no source was found. + */ +__isl_give isl_union_map *isl_union_flow_get_may_no_source( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_union(isl_union_map_copy(flow->must_no_source), + isl_union_map_copy(flow->may_no_source)); +} + +/* Return the subset of the sink accesses for which possibly, but not + * definitely, no source was found. + */ +static __isl_give isl_union_map *isl_union_flow_get_non_must_no_source( + __isl_keep isl_union_flow *flow) +{ + if (!flow) + return NULL; + return isl_union_map_copy(flow->may_no_source); +} + +/* Create a new isl_union_flow object, initialized with empty + * dependence relations and sink subsets. + */ +static __isl_give isl_union_flow *isl_union_flow_alloc( + __isl_take isl_space *space) +{ + isl_ctx *ctx; + isl_union_map *empty; + isl_union_flow *flow; + + if (!space) + return NULL; + ctx = isl_space_get_ctx(space); + flow = isl_alloc_type(ctx, isl_union_flow); + if (!flow) + goto error; + + empty = isl_union_map_empty(space); + flow->must_dep = isl_union_map_copy(empty); + flow->may_dep = isl_union_map_copy(empty); + flow->must_no_source = isl_union_map_copy(empty); + flow->may_no_source = empty; + + if (!flow->must_dep || !flow->may_dep || + !flow->must_no_source || !flow->may_no_source) + return isl_union_flow_free(flow); + + return flow; +error: + isl_space_free(space); + return NULL; +} + +/* Drop the schedule dimensions from the iteration domains in "flow". + * In particular, the schedule dimensions have been prepended + * to the iteration domains prior to the dependence analysis by + * replacing the iteration domain D, by the wrapped map [S -> D]. + * Replace these wrapped maps by the original D. + */ +static __isl_give isl_union_flow *isl_union_flow_drop_schedule( + __isl_take isl_union_flow *flow) +{ + if (!flow) + return NULL; + + flow->must_dep = isl_union_map_factor_range(flow->must_dep); + flow->may_dep = isl_union_map_factor_range(flow->may_dep); + flow->must_no_source = + isl_union_map_domain_factor_range(flow->must_no_source); + flow->may_no_source = + isl_union_map_domain_factor_range(flow->may_no_source); + + if (!flow->must_dep || !flow->may_dep || + !flow->must_no_source || !flow->may_no_source) + return isl_union_flow_free(flow); + + return flow; +} + +struct isl_compute_flow_data { + isl_union_map *must_source; + isl_union_map *may_source; + isl_union_flow *flow; int count; int must; @@ -1181,7 +1648,7 @@ isl_access_info *accesses; }; -static int count_matching_array(__isl_take isl_map *map, void *user) +static isl_stat count_matching_array(__isl_take isl_map *map, void *user) { int eq; isl_space *dim; @@ -1197,14 +1664,14 @@ isl_map_free(map); if (eq < 0) - return -1; + return isl_stat_error; if (eq) data->count++; - return 0; + return isl_stat_ok; } -static int collect_matching_array(__isl_take isl_map *map, void *user) +static isl_stat collect_matching_array(__isl_take isl_map *map, void *user) { int eq; isl_space *dim; @@ -1223,7 +1690,7 @@ goto error; if (!eq) { isl_map_free(map); - return 0; + return isl_stat_ok; } info = sched_info_alloc(map); @@ -1234,10 +1701,10 @@ data->count++; - return 0; + return isl_stat_ok; error: isl_map_free(map); - return -1; + return isl_stat_error; } /* Determine the shared nesting level and the "textual order" of @@ -1289,14 +1756,16 @@ * the same array and perform dataflow analysis on them using * isl_access_info_compute_flow. */ -static int compute_flow(__isl_take isl_map *map, void *user) +static isl_stat compute_flow(__isl_take isl_map *map, void *user) { int i; isl_ctx *ctx; struct isl_compute_flow_data *data; isl_flow *flow; + isl_union_flow *df; data = (struct isl_compute_flow_data *)user; + df = data->flow; ctx = isl_map_get_ctx(map); @@ -1338,18 +1807,18 @@ if (!flow) goto error; - data->must_no_source = isl_union_map_union(data->must_no_source, + df->must_no_source = isl_union_map_union(df->must_no_source, isl_union_map_from_map(isl_flow_get_no_source(flow, 1))); - data->may_no_source = isl_union_map_union(data->may_no_source, + df->may_no_source = isl_union_map_union(df->may_no_source, isl_union_map_from_map(isl_flow_get_no_source(flow, 0))); for (i = 0; i < flow->n_source; ++i) { isl_union_map *dep; dep = isl_union_map_from_map(isl_map_copy(flow->dep[i].map)); if (flow->dep[i].must) - data->must_dep = isl_union_map_union(data->must_dep, dep); + df->must_dep = isl_union_map_union(df->must_dep, dep); else - data->may_dep = isl_union_map_union(data->may_dep, dep); + df->may_dep = isl_union_map_union(df->may_dep, dep); } isl_flow_free(flow); @@ -1363,7 +1832,7 @@ isl_space_free(data->dim); isl_map_free(map); - return 0; + return isl_stat_ok; error: isl_access_info_free(data->accesses); sched_info_free(data->sink_info); @@ -1375,7 +1844,527 @@ isl_space_free(data->dim); isl_map_free(map); - return -1; + return isl_stat_error; +} + +/* Remove the must accesses from the may accesses. + * + * A must access always trumps a may access, so there is no need + * for a must access to also be considered as a may access. Doing so + * would only cost extra computations only to find out that + * the duplicated may access does not make any difference. + */ +static __isl_give isl_union_access_info *isl_union_access_info_normalize( + __isl_take isl_union_access_info *access) +{ + if (!access) + return NULL; + access->may_source = isl_union_map_subtract(access->may_source, + isl_union_map_copy(access->must_source)); + if (!access->may_source) + return isl_union_access_info_free(access); + + return access; +} + +/* Given a description of the "sink" accesses, the "source" accesses and + * a schedule, compute for each instance of a sink access + * and for each element accessed by that instance, + * the possible or definite source accesses that last accessed the + * element accessed by the sink access before this sink access + * in the sense that there is no intermediate definite source access. + * + * The must_no_source and may_no_source elements of the result + * are subsets of access->sink. The elements must_dep and may_dep + * map domain elements of access->{may,must)_source to + * domain elements of access->sink. + * + * This function is used when only the schedule map representation + * is available. + * + * We first prepend the schedule dimensions to the domain + * of the accesses so that we can easily compare their relative order. + * Then we consider each sink access individually in compute_flow. + */ +static __isl_give isl_union_flow *compute_flow_union_map( + __isl_take isl_union_access_info *access) +{ + struct isl_compute_flow_data data; + + access = isl_union_access_info_align_params(access); + access = isl_union_access_info_introduce_schedule(access); + if (!access) + return NULL; + + data.must_source = access->must_source; + data.may_source = access->may_source; + + data.flow = isl_union_flow_alloc(isl_union_map_get_space(access->sink)); + + if (isl_union_map_foreach_map(access->sink, &compute_flow, &data) < 0) + goto error; + + data.flow = isl_union_flow_drop_schedule(data.flow); + + isl_union_access_info_free(access); + return data.flow; +error: + isl_union_access_info_free(access); + isl_union_flow_free(data.flow); + return NULL; +} + +/* A schedule access relation. + * + * The access relation "access" is of the form [S -> D] -> A, + * where S corresponds to the prefix schedule at "node". + * "must" is only relevant for source accesses and indicates + * whether the access is a must source or a may source. + */ +struct isl_scheduled_access { + isl_map *access; + int must; + isl_schedule_node *node; +}; + +/* Data structure for keeping track of individual scheduled sink and source + * accesses when computing dependence analysis based on a schedule tree. + * + * "n_sink" is the number of used entries in "sink" + * "n_source" is the number of used entries in "source" + * + * "set_sink", "must" and "node" are only used inside collect_sink_source, + * to keep track of the current node and + * of what extract_sink_source needs to do. + */ +struct isl_compute_flow_schedule_data { + isl_union_access_info *access; + + int n_sink; + int n_source; + + struct isl_scheduled_access *sink; + struct isl_scheduled_access *source; + + int set_sink; + int must; + isl_schedule_node *node; +}; + +/* Align the parameters of all sinks with all sources. + * + * If there are no sinks or no sources, then no alignment is needed. + */ +static void isl_compute_flow_schedule_data_align_params( + struct isl_compute_flow_schedule_data *data) +{ + int i; + isl_space *space; + + if (data->n_sink == 0 || data->n_source == 0) + return; + + space = isl_map_get_space(data->sink[0].access); + + for (i = 1; i < data->n_sink; ++i) + space = isl_space_align_params(space, + isl_map_get_space(data->sink[i].access)); + for (i = 0; i < data->n_source; ++i) + space = isl_space_align_params(space, + isl_map_get_space(data->source[i].access)); + + for (i = 0; i < data->n_sink; ++i) + data->sink[i].access = + isl_map_align_params(data->sink[i].access, + isl_space_copy(space)); + for (i = 0; i < data->n_source; ++i) + data->source[i].access = + isl_map_align_params(data->source[i].access, + isl_space_copy(space)); + + isl_space_free(space); +} + +/* Free all the memory referenced from "data". + * Do not free "data" itself as it may be allocated on the stack. + */ +static void isl_compute_flow_schedule_data_clear( + struct isl_compute_flow_schedule_data *data) +{ + int i; + + if (!data->sink) + return; + + for (i = 0; i < data->n_sink; ++i) { + isl_map_free(data->sink[i].access); + isl_schedule_node_free(data->sink[i].node); + } + + for (i = 0; i < data->n_source; ++i) { + isl_map_free(data->source[i].access); + isl_schedule_node_free(data->source[i].node); + } + + free(data->sink); +} + +/* isl_schedule_foreach_schedule_node_top_down callback for counting + * (an upper bound on) the number of sinks and sources. + * + * Sinks and sources are only extracted at leaves of the tree, + * so we skip the node if it is not a leaf. + * Otherwise we increment data->n_sink and data->n_source with + * the number of spaces in the sink and source access domains + * that reach this node. + */ +static isl_bool count_sink_source(__isl_keep isl_schedule_node *node, + void *user) +{ + struct isl_compute_flow_schedule_data *data = user; + isl_union_set *domain; + isl_union_map *umap; + isl_bool r = isl_bool_false; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf) + return isl_bool_true; + + domain = isl_schedule_node_get_universe_domain(node); + + umap = isl_union_map_copy(data->access->sink); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain)); + data->n_sink += isl_union_map_n_map(umap); + isl_union_map_free(umap); + if (!umap) + r = isl_bool_error; + + umap = isl_union_map_copy(data->access->must_source); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain)); + data->n_source += isl_union_map_n_map(umap); + isl_union_map_free(umap); + if (!umap) + r = isl_bool_error; + + umap = isl_union_map_copy(data->access->may_source); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain)); + data->n_source += isl_union_map_n_map(umap); + isl_union_map_free(umap); + if (!umap) + r = isl_bool_error; + + isl_union_set_free(domain); + + return r; +} + +/* Add a single scheduled sink or source (depending on data->set_sink) + * with scheduled access relation "map", must property data->must and + * schedule node data->node to the list of sinks or sources. + */ +static isl_stat extract_sink_source(__isl_take isl_map *map, void *user) +{ + struct isl_compute_flow_schedule_data *data = user; + struct isl_scheduled_access *access; + + if (data->set_sink) + access = data->sink + data->n_sink++; + else + access = data->source + data->n_source++; + + access->access = map; + access->must = data->must; + access->node = isl_schedule_node_copy(data->node); + + return isl_stat_ok; +} + +/* isl_schedule_foreach_schedule_node_top_down callback for collecting + * individual scheduled source and sink accesses. + * + * We only collect accesses at the leaves of the schedule tree. + * We prepend the schedule dimensions at the leaf to the iteration + * domains of the source and sink accesses and then extract + * the individual accesses (per space). + * + * In particular, if the prefix schedule at the node is of the form + * + * D -> S + * + * while the access relations are of the form + * + * D -> A + * + * then the updated access relations are of the form + * + * [S -> D] -> A + * + * Note that S consists of a single space such that introducing S + * in the access relations does not increase the number of spaces. + */ +static isl_bool collect_sink_source(__isl_keep isl_schedule_node *node, + void *user) +{ + struct isl_compute_flow_schedule_data *data = user; + isl_union_map *prefix; + isl_union_map *umap; + isl_bool r = isl_bool_false; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf) + return isl_bool_true; + + data->node = node; + + prefix = isl_schedule_node_get_prefix_schedule_union_map(node); + prefix = isl_union_map_reverse(prefix); + prefix = isl_union_map_range_map(prefix); + + data->set_sink = 1; + umap = isl_union_map_copy(data->access->sink); + umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap); + if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0) + r = isl_bool_error; + isl_union_map_free(umap); + + data->set_sink = 0; + data->must = 1; + umap = isl_union_map_copy(data->access->must_source); + umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap); + if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0) + r = isl_bool_error; + isl_union_map_free(umap); + + data->set_sink = 0; + data->must = 0; + umap = isl_union_map_copy(data->access->may_source); + umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap); + if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0) + r = isl_bool_error; + isl_union_map_free(umap); + + isl_union_map_free(prefix); + + return r; +} + +/* isl_access_info_compute_flow callback for determining whether + * the shared nesting level and the ordering within that level + * for two scheduled accesses for use in compute_single_flow. + * + * The tokens passed to this function refer to the leaves + * in the schedule tree where the accesses take place. + * + * If n is the shared number of loops, then we need to return + * "2 * n + 1" if "first" precedes "second" inside the innermost + * shared loop and "2 * n" otherwise. + * + * The innermost shared ancestor may be the leaves themselves + * if the accesses take place in the same leaf. Otherwise, + * it is either a set node or a sequence node. Only in the case + * of a sequence node do we consider one access to precede the other. + */ +static int before_node(void *first, void *second) +{ + isl_schedule_node *node1 = first; + isl_schedule_node *node2 = second; + isl_schedule_node *shared; + int depth; + int before = 0; + + shared = isl_schedule_node_get_shared_ancestor(node1, node2); + if (!shared) + return -1; + + depth = isl_schedule_node_get_schedule_depth(shared); + if (isl_schedule_node_get_type(shared) == isl_schedule_node_sequence) { + int pos1, pos2; + + pos1 = isl_schedule_node_get_ancestor_child_position(node1, + shared); + pos2 = isl_schedule_node_get_ancestor_child_position(node2, + shared); + before = pos1 < pos2; + } + + isl_schedule_node_free(shared); + + return 2 * depth + before; +} + +/* Add the scheduled sources from "data" that access + * the same data space as "sink" to "access". + */ +static __isl_give isl_access_info *add_matching_sources( + __isl_take isl_access_info *access, struct isl_scheduled_access *sink, + struct isl_compute_flow_schedule_data *data) +{ + int i; + isl_space *space; + + space = isl_space_range(isl_map_get_space(sink->access)); + for (i = 0; i < data->n_source; ++i) { + struct isl_scheduled_access *source; + isl_space *source_space; + int eq; + + source = &data->source[i]; + source_space = isl_map_get_space(source->access); + source_space = isl_space_range(source_space); + eq = isl_space_is_equal(space, source_space); + isl_space_free(source_space); + + if (!eq) + continue; + if (eq < 0) + goto error; + + access = isl_access_info_add_source(access, + isl_map_copy(source->access), source->must, source->node); + } + + isl_space_free(space); + return access; +error: + isl_space_free(space); + isl_access_info_free(access); + return NULL; +} + +/* Given a scheduled sink access relation "sink", compute the corresponding + * dependences on the sources in "data" and add the computed dependences + * to "uf". + */ +static __isl_give isl_union_flow *compute_single_flow( + __isl_take isl_union_flow *uf, struct isl_scheduled_access *sink, + struct isl_compute_flow_schedule_data *data) +{ + int i; + isl_access_info *access; + isl_flow *flow; + isl_map *map; + + if (!uf) + return NULL; + + access = isl_access_info_alloc(isl_map_copy(sink->access), sink->node, + &before_node, data->n_source); + access = add_matching_sources(access, sink, data); + + flow = isl_access_info_compute_flow(access); + if (!flow) + return isl_union_flow_free(uf); + + map = isl_map_domain_factor_range(isl_flow_get_no_source(flow, 1)); + uf->must_no_source = isl_union_map_union(uf->must_no_source, + isl_union_map_from_map(map)); + map = isl_map_domain_factor_range(isl_flow_get_no_source(flow, 0)); + uf->may_no_source = isl_union_map_union(uf->may_no_source, + isl_union_map_from_map(map)); + + for (i = 0; i < flow->n_source; ++i) { + isl_union_map *dep; + + map = isl_map_factor_range(isl_map_copy(flow->dep[i].map)); + dep = isl_union_map_from_map(map); + if (flow->dep[i].must) + uf->must_dep = isl_union_map_union(uf->must_dep, dep); + else + uf->may_dep = isl_union_map_union(uf->may_dep, dep); + } + + isl_flow_free(flow); + + return uf; +} + +/* Given a description of the "sink" accesses, the "source" accesses and + * a schedule, compute for each instance of a sink access + * and for each element accessed by that instance, + * the possible or definite source accesses that last accessed the + * element accessed by the sink access before this sink access + * in the sense that there is no intermediate definite source access. + * + * The must_no_source and may_no_source elements of the result + * are subsets of access->sink. The elements must_dep and may_dep + * map domain elements of access->{may,must)_source to + * domain elements of access->sink. + * + * This function is used when a schedule tree representation + * is available. + * + * We extract the individual scheduled source and sink access relations and + * then compute dependences for each scheduled sink individually. + */ +static __isl_give isl_union_flow *compute_flow_schedule( + __isl_take isl_union_access_info *access) +{ + struct isl_compute_flow_schedule_data data = { access }; + int i, n; + isl_ctx *ctx; + isl_union_flow *flow; + + ctx = isl_union_access_info_get_ctx(access); + + data.n_sink = 0; + data.n_source = 0; + if (isl_schedule_foreach_schedule_node_top_down(access->schedule, + &count_sink_source, &data) < 0) + goto error; + + n = data.n_sink + data.n_source; + data.sink = isl_calloc_array(ctx, struct isl_scheduled_access, n); + if (n && !data.sink) + goto error; + data.source = data.sink + data.n_sink; + + data.n_sink = 0; + data.n_source = 0; + if (isl_schedule_foreach_schedule_node_top_down(access->schedule, + &collect_sink_source, &data) < 0) + goto error; + + flow = isl_union_flow_alloc(isl_union_map_get_space(access->sink)); + + isl_compute_flow_schedule_data_align_params(&data); + + for (i = 0; i < data.n_sink; ++i) + flow = compute_single_flow(flow, &data.sink[i], &data); + + isl_compute_flow_schedule_data_clear(&data); + + isl_union_access_info_free(access); + return flow; +error: + isl_union_access_info_free(access); + isl_compute_flow_schedule_data_clear(&data); + return NULL; +} + +/* Given a description of the "sink" accesses, the "source" accesses and + * a schedule, compute for each instance of a sink access + * and for each element accessed by that instance, + * the possible or definite source accesses that last accessed the + * element accessed by the sink access before this sink access + * in the sense that there is no intermediate definite source access. + * + * The must_no_source and may_no_source elements of the result + * are subsets of access->sink. The elements must_dep and may_dep + * map domain elements of access->{may,must)_source to + * domain elements of access->sink. + * + * We check whether the schedule is available as a schedule tree + * or a schedule map and call the correpsonding function to perform + * the analysis. + */ +__isl_give isl_union_flow *isl_union_access_info_compute_flow( + __isl_take isl_union_access_info *access) +{ + access = isl_union_access_info_normalize(access); + if (!access) + return NULL; + if (access->schedule) + return compute_flow_schedule(access); + else + return compute_flow_union_map(access); } /* Given a collection of "sink" and "source" accesses, @@ -1390,9 +2379,9 @@ * corresponding to those iterations that access an element * not previously accessed. * - * We first prepend the schedule dimensions to the domain - * of the accesses so that we can easily compare their relative order. - * Then we consider each sink access individually in compute_flow. + * We collect the inputs in an isl_union_access_info object, + * call isl_union_access_info_compute_flow and extract + * the outputs from the result. */ int isl_union_map_compute_flow(__isl_take isl_union_map *sink, __isl_take isl_union_map *must_source, @@ -1402,93 +2391,40 @@ __isl_give isl_union_map **must_no_source, __isl_give isl_union_map **may_no_source) { - isl_space *dim; - isl_union_map *range_map = NULL; - struct isl_compute_flow_data data; - - sink = isl_union_map_align_params(sink, - isl_union_map_get_space(must_source)); - sink = isl_union_map_align_params(sink, - isl_union_map_get_space(may_source)); - sink = isl_union_map_align_params(sink, - isl_union_map_get_space(schedule)); - dim = isl_union_map_get_space(sink); - must_source = isl_union_map_align_params(must_source, isl_space_copy(dim)); - may_source = isl_union_map_align_params(may_source, isl_space_copy(dim)); - schedule = isl_union_map_align_params(schedule, isl_space_copy(dim)); - - schedule = isl_union_map_reverse(schedule); - range_map = isl_union_map_range_map(schedule); - schedule = isl_union_map_reverse(isl_union_map_copy(range_map)); - sink = isl_union_map_apply_domain(sink, isl_union_map_copy(schedule)); - must_source = isl_union_map_apply_domain(must_source, - isl_union_map_copy(schedule)); - may_source = isl_union_map_apply_domain(may_source, schedule); - - data.must_source = must_source; - data.may_source = may_source; - data.must_dep = must_dep ? - isl_union_map_empty(isl_space_copy(dim)) : NULL; - data.may_dep = may_dep ? isl_union_map_empty(isl_space_copy(dim)) : NULL; - data.must_no_source = must_no_source ? - isl_union_map_empty(isl_space_copy(dim)) : NULL; - data.may_no_source = may_no_source ? - isl_union_map_empty(isl_space_copy(dim)) : NULL; - - isl_space_free(dim); + isl_union_access_info *access; + isl_union_flow *flow; - if (isl_union_map_foreach_map(sink, &compute_flow, &data) < 0) - goto error; + access = isl_union_access_info_from_sink(sink); + access = isl_union_access_info_set_must_source(access, must_source); + access = isl_union_access_info_set_may_source(access, may_source); + access = isl_union_access_info_set_schedule_map(access, schedule); + flow = isl_union_access_info_compute_flow(access); - isl_union_map_free(sink); - isl_union_map_free(must_source); - isl_union_map_free(may_source); + if (must_dep) + *must_dep = isl_union_flow_get_must_dependence(flow); + if (may_dep) + *may_dep = isl_union_flow_get_non_must_dependence(flow); + if (must_no_source) + *must_no_source = isl_union_flow_get_must_no_source(flow); + if (may_no_source) + *may_no_source = isl_union_flow_get_non_must_no_source(flow); - if (must_dep) { - data.must_dep = isl_union_map_apply_domain(data.must_dep, - isl_union_map_copy(range_map)); - data.must_dep = isl_union_map_apply_range(data.must_dep, - isl_union_map_copy(range_map)); - *must_dep = data.must_dep; - } - if (may_dep) { - data.may_dep = isl_union_map_apply_domain(data.may_dep, - isl_union_map_copy(range_map)); - data.may_dep = isl_union_map_apply_range(data.may_dep, - isl_union_map_copy(range_map)); - *may_dep = data.may_dep; - } - if (must_no_source) { - data.must_no_source = isl_union_map_apply_domain( - data.must_no_source, isl_union_map_copy(range_map)); - *must_no_source = data.must_no_source; - } - if (may_no_source) { - data.may_no_source = isl_union_map_apply_domain( - data.may_no_source, isl_union_map_copy(range_map)); - *may_no_source = data.may_no_source; - } + isl_union_flow_free(flow); - isl_union_map_free(range_map); + if ((must_dep && !*must_dep) || (may_dep && !*may_dep) || + (must_no_source && !*must_no_source) || + (may_no_source && !*may_no_source)) + goto error; return 0; error: - isl_union_map_free(range_map); - isl_union_map_free(sink); - isl_union_map_free(must_source); - isl_union_map_free(may_source); - isl_union_map_free(data.must_dep); - isl_union_map_free(data.may_dep); - isl_union_map_free(data.must_no_source); - isl_union_map_free(data.may_no_source); - if (must_dep) - *must_dep = NULL; + *must_dep = isl_union_map_free(*must_dep); if (may_dep) - *may_dep = NULL; + *may_dep = isl_union_map_free(*may_dep); if (must_no_source) - *must_no_source = NULL; + *must_no_source = isl_union_map_free(*must_no_source); if (may_no_source) - *may_no_source = NULL; + *may_no_source = isl_union_map_free(*may_no_source); return -1; } diff -Nru isl-0.12.2/isl_fold.c isl-0.15/isl_fold.c --- isl-0.12.2/isl_fold.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_fold.c 2015-06-02 09:28:09.000000000 +0000 @@ -14,11 +14,13 @@ #include #include #include -#include -#include +#include +#include #include #include +#include #include +#include enum isl_fold isl_fold_type_negate(enum isl_fold type) { @@ -232,10 +234,23 @@ return NULL; } +/* Determine the sign of the constant quasipolynomial "qp". + * + * Return + * -1 if qp <= 0 + * 1 if qp >= 0 + * 0 if unknown + * + * For qp == 0, we can return either -1 or 1. In practice, we return 1. + * For qp == NaN, the sign is undefined, so we return 0. + */ static int isl_qpolynomial_cst_sign(__isl_keep isl_qpolynomial *qp) { struct isl_upoly_cst *cst; + if (isl_qpolynomial_is_nan(qp)) + return 0; + cst = isl_upoly_as_cst(qp->upoly); if (!cst) return 0; @@ -391,6 +406,14 @@ return sgn; } +/* Combine "fold1" and "fold2" into a single reduction, eliminating + * those elements of one reduction that are already covered by the other + * reduction on "set". + * + * If "fold1" or "fold2" is an empty reduction, then return + * the other reduction. + * If "fold1" or "fold2" is a NaN, then return this NaN. + */ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold_on_domain( __isl_keep isl_set *set, __isl_take isl_qpolynomial_fold *fold1, @@ -410,12 +433,14 @@ better = fold1->type == isl_fold_max ? -1 : 1; - if (isl_qpolynomial_fold_is_empty(fold1)) { + if (isl_qpolynomial_fold_is_empty(fold1) || + isl_qpolynomial_fold_is_nan(fold2)) { isl_qpolynomial_fold_free(fold1); return fold2; } - if (isl_qpolynomial_fold_is_empty(fold2)) { + if (isl_qpolynomial_fold_is_empty(fold2) || + isl_qpolynomial_fold_is_nan(fold1)) { isl_qpolynomial_fold_free(fold2); return fold1; } @@ -436,7 +461,13 @@ for (i = 0; i < fold2->n; ++i) { for (j = n1 - 1; j >= 0; --j) { isl_qpolynomial *d; - int sgn; + int sgn, equal; + equal = isl_qpolynomial_plain_is_equal(res->qp[j], + fold2->qp[i]); + if (equal < 0) + goto error; + if (equal) + break; d = isl_qpolynomial_sub( isl_qpolynomial_copy(res->qp[j]), isl_qpolynomial_copy(fold2->qp[i])); @@ -639,6 +670,7 @@ #define DEFAULT_IS_ZERO 1 #define NO_NEG +#define NO_SUB #define NO_PULLBACK #include @@ -649,7 +681,6 @@ #define PART isl_pw_qpolynomial_fold #undef PARTS #define PARTS pw_qpolynomial_fold -#define ALIGN_DOMAIN #define NO_SUB @@ -754,6 +785,17 @@ return fold->n == 0; } +/* Does "fold" represent max(NaN) or min(NaN)? + */ +isl_bool isl_qpolynomial_fold_is_nan(__isl_keep isl_qpolynomial_fold *fold) +{ + if (!fold) + return isl_bool_error; + if (fold->n != 1) + return isl_bool_false; + return isl_qpolynomial_is_nan(fold->qp[0]); +} + __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold( __isl_take isl_qpolynomial_fold *fold1, __isl_take isl_qpolynomial_fold *fold2) @@ -893,12 +935,14 @@ if (!part || !u) goto error; - isl_assert(u->dim->ctx, isl_space_match(part->dim, isl_dim_param, u->dim, - isl_dim_param), goto error); + isl_assert(u->space->ctx, + isl_space_match(part->dim, isl_dim_param, u->space, isl_dim_param), + goto error); hash = isl_space_get_hash(part->dim); - entry = isl_hash_table_find(u->dim->ctx, &u->table, hash, - &has_dim, part->dim, 1); + entry = isl_hash_table_find(u->space->ctx, &u->table, hash, + &isl_union_pw_qpolynomial_fold_has_same_domain_space, + part->dim, 1); if (!entry) goto error; @@ -919,14 +963,14 @@ return NULL; } -static int fold_part(__isl_take isl_pw_qpolynomial_fold *part, void *user) +static isl_stat fold_part(__isl_take isl_pw_qpolynomial_fold *part, void *user) { isl_union_pw_qpolynomial_fold **u; u = (isl_union_pw_qpolynomial_fold **)user; *u = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(*u, part); - return 0; + return isl_stat_ok; } __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold( @@ -1002,39 +1046,41 @@ return 1; } -__isl_give isl_qpolynomial *isl_qpolynomial_fold_eval( +__isl_give isl_val *isl_qpolynomial_fold_eval( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt) { - isl_qpolynomial *qp; + isl_ctx *ctx; + isl_val *v; if (!fold || !pnt) goto error; + ctx = isl_point_get_ctx(pnt); isl_assert(pnt->dim->ctx, isl_space_is_equal(pnt->dim, fold->dim), goto error); isl_assert(pnt->dim->ctx, fold->type == isl_fold_max || fold->type == isl_fold_min, goto error); if (fold->n == 0) - qp = isl_qpolynomial_zero_on_domain(isl_space_copy(fold->dim)); + v = isl_val_zero(ctx); else { int i; - qp = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]), + v = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]), isl_point_copy(pnt)); for (i = 1; i < fold->n; ++i) { - isl_qpolynomial *qp_i; - qp_i = isl_qpolynomial_eval( + isl_val *v_i; + v_i = isl_qpolynomial_eval( isl_qpolynomial_copy(fold->qp[i]), isl_point_copy(pnt)); if (fold->type == isl_fold_max) - qp = isl_qpolynomial_max_cst(qp, qp_i); + v = isl_val_max(v, v_i); else - qp = isl_qpolynomial_min_cst(qp, qp_i); + v = isl_val_min(v, v_i); } } isl_qpolynomial_fold_free(fold); isl_point_free(pnt); - return qp; + return v; error: isl_qpolynomial_fold_free(fold); isl_point_free(pnt); @@ -1052,33 +1098,33 @@ return n; } -__isl_give isl_qpolynomial *isl_qpolynomial_fold_opt_on_domain( +__isl_give isl_val *isl_qpolynomial_fold_opt_on_domain( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *set, int max) { int i; - isl_qpolynomial *opt; + isl_val *opt; if (!set || !fold) goto error; if (fold->n == 0) { - isl_space *dim = isl_space_copy(fold->dim); + opt = isl_val_zero(isl_set_get_ctx(set)); isl_set_free(set); isl_qpolynomial_fold_free(fold); - return isl_qpolynomial_zero_on_domain(dim); + return opt; } opt = isl_qpolynomial_opt_on_domain(isl_qpolynomial_copy(fold->qp[0]), isl_set_copy(set), max); for (i = 1; i < fold->n; ++i) { - isl_qpolynomial *opt_i; + isl_val *opt_i; opt_i = isl_qpolynomial_opt_on_domain( isl_qpolynomial_copy(fold->qp[i]), isl_set_copy(set), max); if (max) - opt = isl_qpolynomial_max_cst(opt, opt_i); + opt = isl_val_max(opt, opt_i); else - opt = isl_qpolynomial_min_cst(opt, opt_i); + opt = isl_val_min(opt, opt_i); } isl_set_free(set); @@ -1270,20 +1316,20 @@ return NULL; } -int isl_qpolynomial_fold_foreach_qpolynomial( +isl_stat isl_qpolynomial_fold_foreach_qpolynomial( __isl_keep isl_qpolynomial_fold *fold, - int (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user) + isl_stat (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user) { int i; if (!fold) - return -1; + return isl_stat_error; for (i = 0; i < fold->n; ++i) if (fn(isl_qpolynomial_copy(fold->qp[i]), user) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims( @@ -1348,7 +1394,7 @@ return NULL; } -static int add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user) +static isl_stat add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user) { isl_ctx *ctx; isl_pw_qpolynomial_fold *pwf; @@ -1360,8 +1406,9 @@ ctx = pwqp->dim->ctx; hash = isl_space_get_hash(pwqp->dim); - entry = isl_hash_table_find(ctx, &(*upwf)->table, - hash, &has_dim, pwqp->dim, 1); + entry = isl_hash_table_find(ctx, &(*upwf)->table, hash, + &isl_union_pw_qpolynomial_fold_has_same_domain_space, + pwqp->dim, 1); if (!entry) goto error; @@ -1371,17 +1418,17 @@ else { entry->data = isl_pw_qpolynomial_fold_add(entry->data, pwf); if (!entry->data) - return -1; + return isl_stat_error; if (isl_pw_qpolynomial_fold_is_zero(entry->data)) { isl_pw_qpolynomial_fold_free(entry->data); isl_hash_table_remove(ctx, &(*upwf)->table, entry); } } - return 0; + return isl_stat_ok; error: isl_pw_qpolynomial_free(pwqp); - return -1; + return isl_stat_error; } __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_union_pw_qpolynomial( @@ -1416,7 +1463,7 @@ m = isl_space_match(dim1, isl_dim_param, dim2, isl_dim_param); if (m < 0 || !m) return m; - return isl_space_tuple_match(dim1, isl_dim_out, dim2, isl_dim_in); + return isl_space_tuple_is_equal(dim1, isl_dim_out, dim2, isl_dim_in); } /* Compute the intersection of the range of the map and the domain @@ -1483,8 +1530,8 @@ int tight; }; -static int pw_qpolynomial_fold_apply(__isl_take isl_pw_qpolynomial_fold *pwf, - void *user) +static isl_stat pw_qpolynomial_fold_apply( + __isl_take isl_pw_qpolynomial_fold *pwf, void *user) { isl_space *map_dim; isl_space *pwf_dim; @@ -1505,13 +1552,13 @@ } else isl_pw_qpolynomial_fold_free(pwf); - return 0; + return isl_stat_ok; } -static int map_apply(__isl_take isl_map *map, void *user) +static isl_stat map_apply(__isl_take isl_map *map, void *user) { struct isl_apply_fold_data *data = user; - int r; + isl_stat r; data->map = map; r = isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( @@ -1676,5 +1723,31 @@ error: isl_val_free(v); isl_qpolynomial_fold_free(fold); + return NULL; +} + +/* Divide "fold" by "v". + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale_down_val( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_val *v) +{ + if (!fold || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return fold; + } + if (!isl_val_is_rat(v)) + isl_die(isl_qpolynomial_fold_get_ctx(fold), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + return isl_qpolynomial_fold_scale_val(fold, isl_val_inv(v)); +error: + isl_val_free(v); + isl_qpolynomial_fold_free(fold); return NULL; } diff -Nru isl-0.12.2/isl_gmp.c isl-0.15/isl_gmp.c --- isl-0.12.2/isl_gmp.c 2013-09-15 16:01:51.000000000 +0000 +++ isl-0.15/isl_gmp.c 2015-03-19 14:44:56.000000000 +0000 @@ -1,4 +1,3 @@ -#include /* * Copyright 2008-2009 Katholieke Universiteit Leuven * @@ -23,36 +22,3 @@ isl_hash_byte(hash, *data); return hash; } - -/* This function tries to produce outputs that do not depend on - * the version of GMP that is being used. - * - * In particular, when computing the extended gcd of -1 and 9, - * some versions will produce - * - * 1 = -1 * -1 + 0 * 9 - * - * while other versions will produce - * - * 1 = 8 * -1 + 1 * 9 - * - * If configure detects that we are in the former case, then - * mpz_gcdext will be called directly. Otherwise, this function - * is called and then we try to mimic the behavior of the other versions. - */ -void isl_gmp_gcdext(mpz_t G, mpz_t S, mpz_t T, mpz_t A, mpz_t B) -{ - if (mpz_divisible_p(B, A)) { - mpz_set_si(S, mpz_sgn(A)); - mpz_set_si(T, 0); - mpz_abs(G, A); - return; - } - if (mpz_divisible_p(A, B)) { - mpz_set_si(S, 0); - mpz_set_si(T, mpz_sgn(B)); - mpz_abs(G, B); - return; - } - mpz_gcdext(G, S, T, A, B); -} diff -Nru isl-0.12.2/isl_hash.c isl-0.15/isl_hash.c --- isl-0.12.2/isl_hash.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_hash.c 2015-06-02 09:28:09.000000000 +0000 @@ -180,20 +180,22 @@ return &table->entries[h]; } -int isl_hash_table_foreach(struct isl_ctx *ctx, - struct isl_hash_table *table, - int (*fn)(void **entry, void *user), void *user) +isl_stat isl_hash_table_foreach(isl_ctx *ctx, struct isl_hash_table *table, + isl_stat (*fn)(void **entry, void *user), void *user) { size_t size; uint32_t h; + if (!table->entries) + return isl_stat_error; + size = 1 << table->bits; for (h = 0; h < size; ++ h) if (table->entries[h].data && fn(&table->entries[h].data, user) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } void isl_hash_table_remove(struct isl_ctx *ctx, diff -Nru isl-0.12.2/isl_hide_deprecated.h isl-0.15/isl_hide_deprecated.h --- isl-0.12.2/isl_hide_deprecated.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_hide_deprecated.h 2015-06-02 09:28:09.000000000 +0000 @@ -0,0 +1,52 @@ +#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_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 -Nru isl-0.12.2/isl_hmap_map_basic_set.c isl-0.15/isl_hmap_map_basic_set.c --- isl-0.12.2/isl_hmap_map_basic_set.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_hmap_map_basic_set.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -#include - -struct isl_map_basic_set_pair { - isl_map *key; - isl_basic_set *val; -}; - -__isl_give isl_hmap_map_basic_set *isl_hmap_map_basic_set_alloc(isl_ctx *ctx, - int min_size) -{ - return (isl_hmap_map_basic_set *) isl_hash_table_alloc(ctx, min_size); -} - -static int free_pair(void **entry, void *user) -{ - struct isl_map_basic_set_pair *pair = *entry; - isl_map_free(pair->key); - isl_basic_set_free(pair->val); - free(pair); - *entry = NULL; - return 0; -} - -void isl_hmap_map_basic_set_free(isl_ctx *ctx, - __isl_take isl_hmap_map_basic_set *hmap) -{ - if (!hmap) - return; - isl_hash_table_foreach(ctx, &hmap->table, &free_pair, NULL); - isl_hash_table_free(ctx, &hmap->table); -} - -static int has_key(const void *entry, const void *key) -{ - const struct isl_map_basic_set_pair *pair = entry; - isl_map *map = (isl_map *)key; - - return isl_map_plain_is_equal(pair->key, map); -} - -int isl_hmap_map_basic_set_has(isl_ctx *ctx, - __isl_keep isl_hmap_map_basic_set *hmap, __isl_keep isl_map *key) -{ - uint32_t hash; - - hash = isl_map_get_hash(key); - return !!isl_hash_table_find(ctx, &hmap->table, hash, &has_key, key, 0); -} - -__isl_give isl_basic_set *isl_hmap_map_basic_set_get(isl_ctx *ctx, - __isl_keep isl_hmap_map_basic_set *hmap, __isl_take isl_map *key) -{ - struct isl_hash_table_entry *entry; - struct isl_map_basic_set_pair *pair; - uint32_t hash; - - hash = isl_map_get_hash(key); - entry = isl_hash_table_find(ctx, &hmap->table, hash, &has_key, key, 0); - isl_map_free(key); - - if (!entry) - return NULL; - - pair = entry->data; - - return isl_basic_set_copy(pair->val); -} - -int isl_hmap_map_basic_set_set(isl_ctx *ctx, - __isl_keep isl_hmap_map_basic_set *hmap, __isl_take isl_map *key, - __isl_take isl_basic_set *val) -{ - struct isl_hash_table_entry *entry; - struct isl_map_basic_set_pair *pair; - uint32_t hash; - - hash = isl_map_get_hash(key); - entry = isl_hash_table_find(ctx, &hmap->table, hash, &has_key, key, 1); - - if (!entry) - goto error; - - if (entry->data) { - pair = entry->data; - isl_basic_set_free(pair->val); - pair->val = val; - isl_map_free(key); - return 0; - } - - pair = isl_alloc_type(ctx, struct isl_map_basic_set_pair); - if (!pair) - goto error; - - entry->data = pair; - pair->key = key; - pair->val = val; - return 0; -error: - isl_map_free(key); - isl_basic_set_free(val); - return -1; -} diff -Nru isl-0.12.2/isl_hmap_map_basic_set.h isl-0.15/isl_hmap_map_basic_set.h --- isl-0.12.2/isl_hmap_map_basic_set.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_hmap_map_basic_set.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -#ifndef ISL_HMAP_MAP_BASIC_SET_H -#define ISL_HMAP_MAP_BASIC_SET_H - -#include -#include -#include - -struct isl_hmap_map_basic_set { - struct isl_hash_table table; -}; -typedef struct isl_hmap_map_basic_set isl_hmap_map_basic_set; - -__isl_give isl_hmap_map_basic_set *isl_hmap_map_basic_set_alloc( isl_ctx *ctx, - int min_size); -void isl_hmap_map_basic_set_free(isl_ctx *ctx, - __isl_take isl_hmap_map_basic_set *hmap); - -int isl_hmap_map_basic_set_has(isl_ctx *ctx, - __isl_keep isl_hmap_map_basic_set *hmap, __isl_keep isl_map *key); -__isl_give isl_basic_set *isl_hmap_map_basic_set_get(isl_ctx *ctx, - __isl_keep isl_hmap_map_basic_set *hmap, __isl_take isl_map *key); -int isl_hmap_map_basic_set_set(isl_ctx *ctx, - __isl_keep isl_hmap_map_basic_set *hmap, __isl_take isl_map *key, - __isl_take isl_basic_set *val); - -#endif diff -Nru isl-0.12.2/isl_hmap_templ.c isl-0.15/isl_hmap_templ.c --- isl-0.12.2/isl_hmap_templ.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_hmap_templ.c 2015-06-02 09:28:09.000000000 +0000 @@ -0,0 +1,389 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2013 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, + * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, + * 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + +#include +#include + +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#define KEY CAT(isl_,KEY_BASE) +#define VAL CAT(isl_,VAL_BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xHMAP(KEY,VAL_BASE) KEY ## _to_ ## VAL_BASE +#define yHMAP(KEY,VAL_BASE) xHMAP(KEY,VAL_BASE) +#define HMAP yHMAP(KEY,VAL_BASE) +#define HMAP_BASE yHMAP(KEY_BASE,VAL_BASE) +#define xS(TYPE1,TYPE2,NAME) struct isl_ ## TYPE1 ## _ ## TYPE2 ## _ ## NAME +#define yS(TYPE1,TYPE2,NAME) xS(TYPE1,TYPE2,NAME) +#define S(NAME) yS(KEY_BASE,VAL_BASE,NAME) + +struct HMAP { + int ref; + isl_ctx *ctx; + struct isl_hash_table table; +}; + +S(pair) { + KEY *key; + VAL *val; +}; + +__isl_give HMAP *FN(HMAP,alloc)(isl_ctx *ctx, int min_size) +{ + HMAP *hmap; + + hmap = isl_calloc_type(ctx, HMAP); + if (!hmap) + return NULL; + + hmap->ctx = ctx; + isl_ctx_ref(ctx); + hmap->ref = 1; + + if (isl_hash_table_init(ctx, &hmap->table, min_size) < 0) + return FN(HMAP,free)(hmap); + + return hmap; +} + +static isl_stat free_pair(void **entry, void *user) +{ + S(pair) *pair = *entry; + FN(KEY,free)(pair->key); + FN(VAL,free)(pair->val); + free(pair); + *entry = NULL; + return isl_stat_ok; +} + +__isl_null HMAP *FN(HMAP,free)(__isl_take HMAP *hmap) +{ + if (!hmap) + return NULL; + if (--hmap->ref > 0) + return NULL; + isl_hash_table_foreach(hmap->ctx, &hmap->table, &free_pair, NULL); + isl_hash_table_clear(&hmap->table); + isl_ctx_deref(hmap->ctx); + free(hmap); + return NULL; +} + +isl_ctx *FN(HMAP,get_ctx)(__isl_keep HMAP *hmap) +{ + return hmap ? hmap->ctx : NULL; +} + +/* Add a mapping from "key" to "val" to the associative array + * pointed to by user. + */ +static isl_stat add_key_val(__isl_take KEY *key, __isl_take VAL *val, + void *user) +{ + HMAP **hmap = (HMAP **) user; + + *hmap = FN(HMAP,set)(*hmap, key, val); + + if (!*hmap) + return isl_stat_error; + + return isl_stat_ok; +} + +__isl_give HMAP *FN(HMAP,dup)(__isl_keep HMAP *hmap) +{ + HMAP *dup; + + if (!hmap) + return NULL; + + dup = FN(HMAP,alloc)(hmap->ctx, hmap->table.n); + if (FN(HMAP,foreach)(hmap, &add_key_val, &dup) < 0) + return FN(HMAP,free)(dup); + + return dup; +} + +__isl_give HMAP *FN(HMAP,cow)(__isl_take HMAP *hmap) +{ + if (!hmap) + return NULL; + + if (hmap->ref == 1) + return hmap; + hmap->ref--; + return FN(HMAP,dup)(hmap); +} + +__isl_give HMAP *FN(HMAP,copy)(__isl_keep HMAP *hmap) +{ + if (!hmap) + return NULL; + + hmap->ref++; + return hmap; +} + +static int has_key(const void *entry, const void *c_key) +{ + const S(pair) *pair = entry; + KEY *key = (KEY *) c_key; + + return KEY_EQUAL(pair->key, key); +} + +isl_bool FN(HMAP,has)(__isl_keep HMAP *hmap, __isl_keep KEY *key) +{ + uint32_t hash; + + if (!hmap) + return isl_bool_error; + + hash = FN(KEY,get_hash)(key); + return !!isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); +} + +__isl_give VAL *FN(HMAP,get)(__isl_keep HMAP *hmap, __isl_take KEY *key) +{ + struct isl_hash_table_entry *entry; + S(pair) *pair; + uint32_t hash; + + if (!hmap || !key) + goto error; + + hash = FN(KEY,get_hash)(key); + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + FN(KEY,free)(key); + + if (!entry) + return NULL; + + pair = entry->data; + + return FN(VAL,copy)(pair->val); +error: + FN(KEY,free)(key); + return NULL; +} + +/* Remove the mapping between "key" and its associated value (if any) + * from "hmap". + * + * If "key" is not mapped to anything, then we leave "hmap" untouched" + */ +__isl_give HMAP *FN(HMAP,drop)(__isl_take HMAP *hmap, __isl_take KEY *key) +{ + struct isl_hash_table_entry *entry; + S(pair) *pair; + uint32_t hash; + + if (!hmap || !key) + goto error; + + hash = FN(KEY,get_hash)(key); + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + if (!entry) { + FN(KEY,free)(key); + return hmap; + } + + hmap = FN(HMAP,cow)(hmap); + if (!hmap) + goto error; + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + FN(KEY,free)(key); + + if (!entry) + isl_die(hmap->ctx, isl_error_internal, + "missing entry" , goto error); + + pair = entry->data; + isl_hash_table_remove(hmap->ctx, &hmap->table, entry); + FN(KEY,free)(pair->key); + FN(VAL,free)(pair->val); + free(pair); + + return hmap; +error: + FN(KEY,free)(key); + FN(HMAP,free)(hmap); + return NULL; +} + +/* Add a mapping from "key" to "val" to "hmap". + * If "key" was already mapped to something else, then that mapping + * is replaced. + * If key happened to be mapped to "val" already, then we leave + * "hmap" untouched. + */ +__isl_give HMAP *FN(HMAP,set)(__isl_take HMAP *hmap, + __isl_take KEY *key, __isl_take VAL *val) +{ + struct isl_hash_table_entry *entry; + S(pair) *pair; + uint32_t hash; + + if (!hmap || !key || !val) + goto error; + + hash = FN(KEY,get_hash)(key); + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 0); + if (entry) { + int equal; + pair = entry->data; + equal = VAL_EQUAL(pair->val, val); + if (equal < 0) + goto error; + if (equal) { + FN(KEY,free)(key); + FN(VAL,free)(val); + return hmap; + } + } + + hmap = FN(HMAP,cow)(hmap); + if (!hmap) + goto error; + + entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash, + &has_key, key, 1); + + if (!entry) + goto error; + + if (entry->data) { + pair = entry->data; + FN(VAL,free)(pair->val); + pair->val = val; + FN(KEY,free)(key); + return hmap; + } + + pair = isl_alloc_type(hmap->ctx, S(pair)); + if (!pair) + goto error; + + entry->data = pair; + pair->key = key; + pair->val = val; + return hmap; +error: + FN(KEY,free)(key); + FN(VAL,free)(val); + return FN(HMAP,free)(hmap); +} + +/* Internal data structure for isl_map_to_basic_set_foreach. + * + * fn is the function that should be called on each entry. + * user is the user-specified final argument to fn. + */ +S(foreach_data) { + isl_stat (*fn)(__isl_take KEY *key, __isl_take VAL *val, void *user); + void *user; +}; + +/* Call data->fn on a copy of the key and value in *entry. + */ +static isl_stat call_on_copy(void **entry, void *user) +{ + S(pair) *pair = *entry; + S(foreach_data) *data = (S(foreach_data) *) user; + + return data->fn(FN(KEY,copy)(pair->key), FN(VAL,copy)(pair->val), + data->user); +} + +/* Call "fn" on each pair of key and value in "hmap". + */ +isl_stat FN(HMAP,foreach)(__isl_keep HMAP *hmap, + isl_stat (*fn)(__isl_take KEY *key, __isl_take VAL *val, void *user), + void *user) +{ + S(foreach_data) data = { fn, user }; + + if (!hmap) + return isl_stat_error; + + return isl_hash_table_foreach(hmap->ctx, &hmap->table, + &call_on_copy, &data); +} + +/* Internal data structure for print_pair. + * + * p is the printer on which the associative array is being printed. + * first is set if the current key-value pair is the first to be printed. + */ +S(print_data) { + isl_printer *p; + int first; +}; + +/* Print the given key-value pair to data->p. + */ +static isl_stat print_pair(__isl_take KEY *key, __isl_take VAL *val, void *user) +{ + S(print_data) *data = user; + + if (!data->first) + data->p = isl_printer_print_str(data->p, ", "); + data->p = FN(isl_printer_print,KEY_BASE)(data->p, key); + data->p = isl_printer_print_str(data->p, ": "); + data->p = FN(isl_printer_print,VAL_BASE)(data->p, val); + data->first = 0; + + FN(KEY,free)(key); + FN(VAL,free)(val); + return isl_stat_ok; +} + +/* Print the associative array to "p". + */ +__isl_give isl_printer *FN(isl_printer_print,HMAP_BASE)( + __isl_take isl_printer *p, __isl_keep HMAP *hmap) +{ + S(print_data) data; + + if (!p || !hmap) + return isl_printer_free(p); + + p = isl_printer_print_str(p, "{"); + data.p = p; + data.first = 1; + if (FN(HMAP,foreach)(hmap, &print_pair, &data) < 0) + data.p = isl_printer_free(data.p); + p = data.p; + p = isl_printer_print_str(p, "}"); + + return p; +} + +void FN(HMAP,dump)(__isl_keep HMAP *hmap) +{ + isl_printer *printer; + + if (!hmap) + return; + + printer = isl_printer_to_file(FN(HMAP,get_ctx)(hmap), stderr); + printer = FN(isl_printer_print,HMAP_BASE)(printer, hmap); + printer = isl_printer_end_line(printer); + + isl_printer_free(printer); +} diff -Nru isl-0.12.2/isl_id.c isl-0.15/isl_id.c --- isl-0.12.2/isl_id.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_id.c 2015-04-24 11:54:24.000000000 +0000 @@ -71,6 +71,11 @@ return NULL; } +uint32_t isl_id_get_hash(__isl_keep isl_id *id) +{ + return id ? id->hash : 0; +} + struct isl_name_and_user { const char *name; void *user; @@ -83,8 +88,10 @@ if (id->user != nu->user) return 0; - if (!id->name && !nu->name) + if (id->name == nu->name) return 1; + if (!id->name || !nu->name) + return 0; return !strcmp(id->name, nu->name); } @@ -95,6 +102,9 @@ uint32_t id_hash; struct isl_name_and_user nu = { name, user }; + if (!ctx) + return NULL; + id_hash = isl_hash_init(); if (name) id_hash = isl_hash_string(id_hash, name); @@ -127,6 +137,33 @@ return id; } +/* Compare two isl_ids. + * + * The order is fairly arbitrary. We do keep the comparison of + * the user pointers as a last resort since these pointer values + * may not be stable across different systems or even different runs. + */ +int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2) +{ + if (id1 == id2) + return 0; + if (!id1) + return -1; + if (!id2) + return 1; + if (!id1->name != !id2->name) + return !id1->name - !id2->name; + if (id1->name) { + int cmp = strcmp(id1->name, id2->name); + if (cmp != 0) + return cmp; + } + if (id1->user < id2->user) + return -1; + else + return 1; +} + static int isl_id_eq(const void *entry, const void *name) { return entry == name; @@ -156,7 +193,7 @@ /* If the id has a negative refcount, then it is a static isl_id * and should not be freed. */ -void *isl_id_free(__isl_take isl_id *id) +__isl_null isl_id *isl_id_free(__isl_take isl_id *id) { struct isl_hash_table_entry *entry; diff -Nru isl-0.12.2/isl_id_private.h isl-0.15/isl_id_private.h --- isl-0.12.2/isl_id_private.h 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/isl_id_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -34,6 +34,7 @@ #include uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id); +int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2); extern isl_id isl_id_none; diff -Nru isl-0.12.2/isl_id_to_ast_expr.c isl-0.15/isl_id_to_ast_expr.c --- isl-0.12.2/isl_id_to_ast_expr.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_id_to_ast_expr.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,11 @@ +#include +#include + +#define isl_id_is_equal(id1,id2) id1 == id2 + +#define KEY_BASE id +#define KEY_EQUAL isl_id_is_equal +#define VAL_BASE ast_expr +#define VAL_EQUAL isl_ast_expr_is_equal + +#include diff -Nru isl-0.12.2/isl_id_to_pw_aff.c isl-0.15/isl_id_to_pw_aff.c --- isl-0.12.2/isl_id_to_pw_aff.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_id_to_pw_aff.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,11 @@ +#include +#include + +#define isl_id_is_equal(id1,id2) id1 == id2 + +#define KEY_BASE id +#define KEY_EQUAL isl_id_is_equal +#define VAL_BASE pw_aff +#define VAL_EQUAL isl_pw_aff_plain_is_equal + +#include diff -Nru isl-0.12.2/isl_ilp.c isl-0.15/isl_ilp.c --- isl-0.12.2/isl_ilp.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_ilp.c 2015-06-02 09:28:09.000000000 +0000 @@ -11,12 +11,16 @@ #include #include #include "isl_sample.h" -#include +#include #include "isl_equalities.h" #include #include #include #include +#include +#include +#include +#include /* Given a basic set "bset", construct a basic set U such that for * each element x in U, the whole unit box positioned at x is inside @@ -37,9 +41,9 @@ goto error; if (bset->n_eq != 0) { - unit_box = isl_basic_set_empty_like(bset); + isl_space *space = isl_basic_set_get_space(bset); isl_basic_set_free(bset); - return unit_box; + return isl_basic_set_empty(space); } total = isl_basic_set_total_dim(bset); diff -Nru isl-0.12.2/isl_ilp_private.h isl-0.15/isl_ilp_private.h --- isl-0.12.2/isl_ilp_private.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_ilp_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,11 @@ +#ifndef ISL_ILP_PRIVATE_H +#define ISL_ILP_PRIVATE_H + +#include +#include +#include + +enum isl_lp_result isl_basic_set_solve_ilp(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p); + +#endif diff -Nru isl-0.12.2/isl_imath.c isl-0.15/isl_imath.c --- isl-0.12.2/isl_imath.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_imath.c 2015-06-11 10:46:17.000000000 +0000 @@ -0,0 +1,53 @@ +#include + +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) +{ + 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 -Nru isl-0.12.2/isl_imath.h isl-0.15/isl_imath.h --- isl-0.12.2/isl_imath.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_imath.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,8 @@ +#include +#include + +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); diff -Nru isl-0.12.2/isl_input.c isl-0.15/isl_input.c --- isl-0.12.2/isl_input.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_input.c 2015-06-02 09:28:09.000000000 +0000 @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2010 INRIA Saclay - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2013 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -18,13 +18,15 @@ #include #include #include -#include +#include #include #include #include "isl_polynomial_private.h" +#include #include #include #include +#include #include #include @@ -144,7 +146,7 @@ * In particular, evaluate expressions of the form x^y, * with x and y values. */ -static struct isl_token *next_token(struct isl_stream *s) +static struct isl_token *next_token(__isl_keep isl_stream *s) { struct isl_token *tok, *tok2; @@ -181,7 +183,7 @@ * * where n, d and v are integer constants. */ -__isl_give isl_val *isl_stream_read_val(struct isl_stream *s) +__isl_give isl_val *isl_stream_read_val(__isl_keep isl_stream *s) { struct isl_token *tok = NULL; struct isl_token *tok2 = NULL; @@ -241,7 +243,7 @@ const char *str) { isl_val *val; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; val = isl_stream_read_val(s); @@ -249,7 +251,7 @@ return val; } -static int accept_cst_factor(struct isl_stream *s, isl_int *f) +static int accept_cst_factor(__isl_keep isl_stream *s, isl_int *f) { struct isl_token *tok; @@ -279,7 +281,7 @@ * We introduce an integer division q = [aff/d] and the result * is set to aff - d q. */ -static __isl_give isl_pw_aff *affine_mod(struct isl_stream *s, +static __isl_give isl_pw_aff *affine_mod(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_pw_aff *aff) { struct isl_token *tok; @@ -306,12 +308,12 @@ return NULL; } -static __isl_give isl_pw_aff *accept_affine(struct isl_stream *s, - __isl_take isl_space *dim, struct vars *v); -static __isl_give isl_pw_aff_list *accept_affine_list(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v); +static __isl_give isl_pw_aff_list *accept_affine_list(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v); -static __isl_give isl_pw_aff *accept_minmax(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_minmax(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v) { struct isl_token *tok; @@ -371,7 +373,7 @@ * floord(,) * ceild(,) */ -static __isl_give isl_pw_aff *accept_div(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_div(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v) { struct isl_token *tok; @@ -435,7 +437,7 @@ return NULL; } -static __isl_give isl_pw_aff *accept_affine_factor(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_affine_factor(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v) { struct isl_token *tok = NULL; @@ -552,15 +554,26 @@ return isl_pw_aff_add(pwaff, isl_pw_aff_from_aff(aff)); } -static __isl_give isl_pw_aff *accept_affine(struct isl_stream *s, - __isl_take isl_space *dim, struct vars *v) +/* Return a piecewise affine expression defined on the specified domain + * that represents NaN. + */ +static __isl_give isl_pw_aff *nan_on_domain(__isl_keep isl_space *space) +{ + isl_local_space *ls; + + ls = isl_local_space_from_space(isl_space_copy(space)); + return isl_pw_aff_nan_on_domain(ls); +} + +static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v) { struct isl_token *tok = NULL; isl_local_space *ls; isl_pw_aff *res; int sign = 1; - ls = isl_local_space_from_space(isl_space_copy(dim)); + ls = isl_local_space_from_space(isl_space_copy(space)); res = isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls)); if (!res) goto error; @@ -583,7 +596,8 @@ isl_pw_aff *term; isl_stream_push_token(s, tok); tok = NULL; - term = accept_affine_factor(s, isl_space_copy(dim), v); + term = accept_affine_factor(s, + isl_space_copy(space), v); if (sign < 0) res = isl_pw_aff_sub(res, term); else @@ -598,7 +612,7 @@ isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) { isl_pw_aff *term; term = accept_affine_factor(s, - isl_space_copy(dim), v); + isl_space_copy(space), v); term = isl_pw_aff_scale(term, tok->u.v); res = isl_pw_aff_add(res, term); if (!res) @@ -607,11 +621,13 @@ res = add_cst(res, tok->u.v); } sign = 1; + } else if (tok->type == ISL_TOKEN_NAN) { + res = isl_pw_aff_add(res, nan_on_domain(space)); } else { isl_stream_error(s, tok, "unexpected isl_token"); isl_stream_push_token(s, tok); isl_pw_aff_free(res); - isl_space_free(dim); + isl_space_free(space); return NULL; } isl_token_free(tok); @@ -633,10 +649,10 @@ } } - isl_space_free(dim); + isl_space_free(space); return res; error: - isl_space_free(dim); + isl_space_free(space); isl_token_free(tok); isl_pw_aff_free(res); return NULL; @@ -660,14 +676,14 @@ } } -static __isl_give isl_map *read_formula(struct isl_stream *s, +static __isl_give isl_map *read_formula(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational); -static __isl_give isl_pw_aff *accept_extended_affine(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_extended_affine(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v, int rational); /* Accept a ternary operator, given the first argument. */ -static __isl_give isl_pw_aff *accept_ternary(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_ternary(__isl_keep isl_stream *s, __isl_take isl_map *cond, struct vars *v, int rational) { isl_space *dim; @@ -701,13 +717,49 @@ return NULL; } +/* Set *line and *col to those of the next token, if any. + */ +static void set_current_line_col(__isl_keep isl_stream *s, int *line, int *col) +{ + struct isl_token *tok; + + tok = isl_stream_next_token(s); + if (!tok) + return; + + *line = tok->line; + *col = tok->col; + isl_stream_push_token(s, tok); +} + +/* Push a token encapsulating "pa" onto "s", with the given + * line and column. + */ +static int push_aff(__isl_keep isl_stream *s, int line, int col, + __isl_take isl_pw_aff *pa) +{ + struct isl_token *tok; + + tok = isl_token_new(s->ctx, line, col, 0); + if (!tok) + goto error; + tok->type = ISL_TOKEN_AFF; + tok->u.pwaff = pa; + isl_stream_push_token(s, tok); + + return 0; +error: + isl_pw_aff_free(pa); + return -1; +} + /* Accept an affine expression that may involve ternary operators. * We first read an affine expression. * If it is not followed by a comparison operator, we simply return it. - * Otherwise, we assume the affine epxression is part of the first + * Otherwise, we assume the affine expression is part of the first * argument of a ternary operator and try to parse that. */ -static __isl_give isl_pw_aff *accept_extended_affine(struct isl_stream *s, +static __isl_give isl_pw_aff *accept_extended_affine(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v, int rational) { isl_space *space; @@ -717,12 +769,7 @@ int line = -1, col = -1; int is_comp; - tok = isl_stream_next_token(s); - if (tok) { - line = tok->line; - col = tok->col; - isl_stream_push_token(s, tok); - } + set_current_line_col(s, &line, &col); pwaff = accept_affine(s, dim, v); if (rational) @@ -739,23 +786,20 @@ if (!is_comp) return pwaff; - tok = isl_token_new(s->ctx, line, col, 0); - if (!tok) - return isl_pw_aff_free(pwaff); - tok->type = ISL_TOKEN_AFF; - tok->u.pwaff = pwaff; - space = isl_pw_aff_get_domain_space(pwaff); cond = isl_map_universe(isl_space_unwrap(space)); - isl_stream_push_token(s, tok); + if (push_aff(s, line, col, pwaff) < 0) + cond = isl_map_free(cond); + if (!cond) + return NULL; cond = read_formula(s, v, cond, rational); return accept_ternary(s, cond, v, rational); } -static __isl_give isl_map *read_var_def(struct isl_stream *s, +static __isl_give isl_map *read_var_def(__isl_keep isl_stream *s, __isl_take isl_map *map, enum isl_dim_type type, struct vars *v, int rational) { @@ -784,7 +828,7 @@ return map; } -static __isl_give isl_pw_aff_list *accept_affine_list(struct isl_stream *s, +static __isl_give isl_pw_aff_list *accept_affine_list(__isl_keep isl_stream *s, __isl_take isl_space *dim, struct vars *v) { isl_pw_aff *pwaff; @@ -823,7 +867,7 @@ return NULL; } -static __isl_give isl_map *read_defined_var_list(struct isl_stream *s, +static __isl_give isl_map *read_defined_var_list(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { struct isl_token *tok; @@ -868,7 +912,7 @@ return NULL; } -static int next_is_tuple(struct isl_stream *s) +static int next_is_tuple(__isl_keep isl_stream *s) { struct isl_token *tok; int is_tuple; @@ -892,21 +936,6 @@ return is_tuple; } -/* Allocate an initial tuple with zero dimensions and an anonymous, - * unstructured space. - * A tuple is represented as an isl_multi_pw_aff. - * The range space is the space of the tuple. - * The domain space is an anonymous space - * with a dimension for each variable in the set of variables in "v". - * If a given dimension is not defined in terms of earlier dimensions in - * the input, then the corresponding isl_pw_aff is set equal to one time - * the variable corresponding to the dimension being defined. - */ -static __isl_give isl_multi_pw_aff *tuple_alloc(struct vars *v) -{ - return isl_multi_pw_aff_alloc(isl_space_alloc(v->ctx, 0, v->n, 0)); -} - /* Is "pa" an expression in term of earlier dimensions? * The alternative is that the dimension is defined to be equal to itself, * meaning that it has a universe domain and an expression that depends @@ -954,151 +983,186 @@ return has_expr; } -/* Add a dimension to the given tuple. - * The dimension is initially undefined, so it is encoded - * as one times itself. - */ -static __isl_give isl_multi_pw_aff *tuple_add_dim( - __isl_take isl_multi_pw_aff *tuple, struct vars *v) -{ - isl_space *space; - isl_aff *aff; - isl_pw_aff *pa; - - tuple = isl_multi_pw_aff_add_dims(tuple, isl_dim_in, 1); - space = isl_multi_pw_aff_get_domain_space(tuple); - aff = isl_aff_zero_on_domain(isl_local_space_from_space(space)); - aff = isl_aff_add_coefficient_si(aff, isl_dim_in, v->n, 1); - pa = isl_pw_aff_from_aff(aff); - tuple = isl_multi_pw_aff_flat_range_product(tuple, - isl_multi_pw_aff_from_pw_aff(pa)); - - return tuple; -} - -/* Set the name of dimension "pos" in "tuple" to "name". +/* Set the name of dimension "pos" in "space" to "name". * During printing, we add primes if the same name appears more than once * to distinguish the occurrences. Here, we remove those primes from "name" * before setting the name of the dimension. */ -static __isl_give isl_multi_pw_aff *tuple_set_dim_name( - __isl_take isl_multi_pw_aff *tuple, int pos, char *name) +static __isl_give isl_space *space_set_dim_name(__isl_take isl_space *space, + int pos, char *name) { char *prime; if (!name) - return tuple; + return space; prime = strchr(name, '\''); if (prime) *prime = '\0'; - tuple = isl_multi_pw_aff_set_dim_name(tuple, isl_dim_set, pos, name); + space = isl_space_set_dim_name(space, isl_dim_out, pos, name); if (prime) *prime = '\''; - return tuple; + return space; +} + +/* Accept a piecewise affine expression. + * + * At the outer level, the piecewise affine expression may be of the form + * + * aff1 : condition1; aff2 : conditions2; ... + * + * or simply + * + * aff + * + * each of the affine expressions may in turn include ternary operators. + * + * There may be parentheses around some subexpression of "aff1" + * around "aff1" itself, around "aff1 : condition1" and/or + * around the entire piecewise affine expression. + * We therefore remove the opening parenthesis (if any) from the stream + * in case the closing parenthesis follows the colon, but if the closing + * parenthesis is the first thing in the stream after the parsed affine + * expression, we push the parsed expression onto the stream and parse + * again in case the parentheses enclose some subexpression of "aff1". + */ +static __isl_give isl_pw_aff *accept_piecewise_affine(__isl_keep isl_stream *s, + __isl_take isl_space *space, struct vars *v, int rational) +{ + isl_pw_aff *res; + isl_space *res_space; + + res_space = isl_space_from_domain(isl_space_copy(space)); + res_space = isl_space_add_dims(res_space, isl_dim_out, 1); + res = isl_pw_aff_empty(res_space); + do { + isl_pw_aff *pa; + int seen_paren; + int line = -1, col = -1; + + set_current_line_col(s, &line, &col); + seen_paren = isl_stream_eat_if_available(s, '('); + if (seen_paren) + pa = accept_piecewise_affine(s, isl_space_copy(space), + v, rational); + else + pa = accept_extended_affine(s, isl_space_copy(space), + v, rational); + if (seen_paren && isl_stream_eat_if_available(s, ')')) { + seen_paren = 0; + if (push_aff(s, line, col, pa) < 0) + goto error; + pa = accept_extended_affine(s, isl_space_copy(space), + v, rational); + } + if (isl_stream_eat_if_available(s, ':')) { + isl_space *dom_space; + isl_set *dom; + + dom_space = isl_pw_aff_get_domain_space(pa); + dom = isl_set_universe(dom_space); + dom = read_formula(s, v, dom, rational); + pa = isl_pw_aff_intersect_domain(pa, dom); + } + + res = isl_pw_aff_union_add(res, pa); + + if (seen_paren && isl_stream_eat(s, ')')) + goto error; + } while (isl_stream_eat_if_available(s, ';')); + + isl_space_free(space); + + return res; +error: + isl_space_free(space); + return isl_pw_aff_free(res); } -/* Read an affine expression from "s" and replace the definition - * of dimension "pos" in "tuple" by this expression. +/* Read an affine expression from "s" for use in read_tuple. * * accept_extended_affine requires a wrapped space as input. - * The domain space of "tuple", on the other hand is an anonymous space, - * so we have to adjust the space of the isl_pw_aff before adding it - * to "tuple". + * read_tuple on the other hand expects each isl_pw_aff + * to have an anonymous space. We therefore adjust the space + * of the isl_pw_aff before returning it. */ -static __isl_give isl_multi_pw_aff *read_tuple_var_def(struct isl_stream *s, - __isl_take isl_multi_pw_aff *tuple, int pos, struct vars *v, - int rational) +static __isl_give isl_pw_aff *read_tuple_var_def(__isl_keep isl_stream *s, + struct vars *v, int rational) { isl_space *space; isl_pw_aff *def; space = isl_space_wrap(isl_space_alloc(s->ctx, 0, v->n, 0)); - def = accept_extended_affine(s, space, v, rational); + + def = accept_piecewise_affine(s, space, v, rational); + space = isl_space_set_alloc(s->ctx, 0, v->n); def = isl_pw_aff_reset_domain_space(def, space); - tuple = isl_multi_pw_aff_set_pw_aff(tuple, pos, def); - return tuple; + return def; } -/* Read a list of variables and/or affine expressions and return the list - * as an isl_multi_pw_aff. +/* Read a list of tuple elements by calling "read_el" on each of them and + * return a space with the same number of set dimensions derived from + * the parameter space "space" and possibly updated by "read_el". * The elements in the list are separated by either "," or "][". * If "comma" is set then only "," is allowed. */ -static __isl_give isl_multi_pw_aff *read_tuple_var_list(struct isl_stream *s, - struct vars *v, int rational, int comma) +static __isl_give isl_space *read_tuple_list(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, int comma, + __isl_give isl_space *(*read_el)(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, + void *user), + void *user) { - int i = 0; - struct isl_token *tok; - isl_multi_pw_aff *res; + if (!space) + return NULL; - res = tuple_alloc(v); + space = isl_space_set_from_params(space); if (isl_stream_next_token_is(s, ']')) - return res; + return space; - while ((tok = next_token(s)) != NULL) { - int new_name = 0; - - res = tuple_add_dim(res, v); + for (;;) { + struct isl_token *tok; - if (tok->type == ISL_TOKEN_IDENT) { - int n = v->n; - int p = vars_pos(v, tok->u.s, -1); - if (p < 0) - goto error; - new_name = p >= n; - } + space = isl_space_add_dims(space, isl_dim_set, 1); - if (tok->type == '*') { - if (vars_add_anon(v) < 0) - goto error; - isl_token_free(tok); - } else if (new_name) { - res = tuple_set_dim_name(res, i, v->v->name); - isl_token_free(tok); - if (isl_stream_eat_if_available(s, '=')) - res = read_tuple_var_def(s, res, i, v, - rational); - } else { - isl_stream_push_token(s, tok); - tok = NULL; - if (vars_add_anon(v) < 0) - goto error; - res = read_tuple_var_def(s, res, i, v, rational); - } + space = read_el(s, v, space, rational, user); + if (!space) + return NULL; tok = isl_stream_next_token(s); if (!comma && tok && tok->type == ']' && isl_stream_next_token_is(s, '[')) { isl_token_free(tok); tok = isl_stream_next_token(s); - } else if (!tok || tok->type != ',') + } else if (!tok || tok->type != ',') { + if (tok) + isl_stream_push_token(s, tok); break; + } isl_token_free(tok); - i++; } - if (tok) - isl_stream_push_token(s, tok); - return res; -error: - isl_token_free(tok); - return isl_multi_pw_aff_free(res); + return space; } -/* Read a tuple and represent it as an isl_multi_pw_aff. See tuple_alloc. +/* Read a tuple space from "s" derived from the parameter space "space". + * Call "read_el" on each element in the tuples. */ -static __isl_give isl_multi_pw_aff *read_tuple(struct isl_stream *s, - struct vars *v, int rational, int comma) +static __isl_give isl_space *read_tuple_space(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, int comma, + __isl_give isl_space *(*read_el)(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, + void *user), + void *user) { struct isl_token *tok; char *name = NULL; - isl_multi_pw_aff *res = NULL; + isl_space *res = NULL; tok = isl_stream_next_token(s); if (!tok) @@ -1113,50 +1177,168 @@ if (isl_stream_eat(s, '[')) goto error; if (next_is_tuple(s)) { - isl_multi_pw_aff *out; - int n; - res = read_tuple(s, v, rational, comma); + isl_space *out; + res = read_tuple_space(s, v, isl_space_copy(space), + rational, comma, read_el, user); if (isl_stream_eat(s, ISL_TOKEN_TO)) goto error; - out = read_tuple(s, v, rational, comma); - n = isl_multi_pw_aff_dim(out, isl_dim_out); - res = isl_multi_pw_aff_add_dims(res, isl_dim_in, n); - res = isl_multi_pw_aff_range_product(res, out); + out = read_tuple_space(s, v, isl_space_copy(space), + rational, comma, read_el, user); + res = isl_space_range_product(res, out); } else - res = read_tuple_var_list(s, v, rational, comma); + res = read_tuple_list(s, v, isl_space_copy(space), + rational, comma, read_el, user); if (isl_stream_eat(s, ']')) goto error; if (name) { - res = isl_multi_pw_aff_set_tuple_name(res, isl_dim_out, name); + res = isl_space_set_tuple_name(res, isl_dim_set, name); free(name); } + isl_space_free(space); return res; error: free(name); - return isl_multi_pw_aff_free(res); + isl_space_free(res); + isl_space_free(space); + return NULL; } -/* Read a tuple from "s" and add it to "map". - * The tuple is initially represented as an isl_multi_pw_aff. +/* Construct an isl_pw_aff defined on a space with v->n variables + * that is equal to the last of those variables. + */ +static __isl_give isl_pw_aff *identity_tuple_el(struct vars *v) +{ + isl_space *space; + isl_aff *aff; + + space = isl_space_set_alloc(v->ctx, 0, v->n); + aff = isl_aff_zero_on_domain(isl_local_space_from_space(space)); + aff = isl_aff_add_coefficient_si(aff, isl_dim_in, v->n - 1, 1); + return isl_pw_aff_from_aff(aff); +} + +/* This function is called for each element in a tuple inside read_tuple. + * Add a new variable to "v" and construct a corresponding isl_pw_aff defined + * over a space containing all variables in "v" defined so far. + * The isl_pw_aff expresses the new variable in terms of earlier variables + * if a definition is provided. Otherwise, it is represented as being + * equal to itself. + * Add the isl_pw_aff to *list. + * If the new variable was named, then adjust "space" accordingly and + * return the updated space. + */ +static __isl_give isl_space *read_tuple_pw_aff_el(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + isl_pw_aff_list **list = (isl_pw_aff_list **) user; + isl_pw_aff *pa; + struct isl_token *tok; + int new_name = 0; + + tok = next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return isl_space_free(space); + } + + if (tok->type == ISL_TOKEN_IDENT) { + int n = v->n; + int p = vars_pos(v, tok->u.s, -1); + if (p < 0) + goto error; + new_name = p >= n; + } + + if (tok->type == '*') { + if (vars_add_anon(v) < 0) + goto error; + isl_token_free(tok); + pa = identity_tuple_el(v); + } else if (new_name) { + int pos = isl_space_dim(space, isl_dim_out) - 1; + space = space_set_dim_name(space, pos, v->v->name); + isl_token_free(tok); + if (isl_stream_eat_if_available(s, '=')) + pa = read_tuple_var_def(s, v, rational); + else + pa = identity_tuple_el(v); + } else { + isl_stream_push_token(s, tok); + tok = NULL; + if (vars_add_anon(v) < 0) + goto error; + pa = read_tuple_var_def(s, v, rational); + } + + *list = isl_pw_aff_list_add(*list, pa); + if (!*list) + return isl_space_free(space); + + return space; +error: + isl_token_free(tok); + return isl_space_free(space); +} + +/* Read a tuple and represent it as an isl_multi_pw_aff. + * The range space of the isl_multi_pw_aff is the space of the tuple. + * The domain space is an anonymous space + * with a dimension for each variable in the set of variables in "v", + * including the variables in the range. + * If a given dimension is not defined in terms of earlier dimensions in + * the input, then the corresponding isl_pw_aff is set equal to one time + * the variable corresponding to the dimension being defined. + * + * The elements in the tuple are collected in a list by read_tuple_pw_aff_el. + * Each element in this list is defined over a space representing + * the variables defined so far. We need to adjust the earlier + * elements to have as many variables in the domain as the final + * element in the list. + */ +static __isl_give isl_multi_pw_aff *read_tuple(__isl_keep isl_stream *s, + struct vars *v, int rational, int comma) +{ + int i, n; + isl_space *space; + isl_pw_aff_list *list; + + space = isl_space_params_alloc(v->ctx, 0); + list = isl_pw_aff_list_alloc(s->ctx, 0); + space = read_tuple_space(s, v, space, rational, comma, + &read_tuple_pw_aff_el, &list); + n = isl_space_dim(space, isl_dim_set); + for (i = 0; i + 1 < n; ++i) { + isl_pw_aff *pa; + + pa = isl_pw_aff_list_get_pw_aff(list, i); + pa = isl_pw_aff_add_dims(pa, isl_dim_in, n - (i + 1)); + list = isl_pw_aff_list_set_pw_aff(list, i, pa); + } + + space = isl_space_from_range(space); + space = isl_space_add_dims(space, isl_dim_in, v->n); + return isl_multi_pw_aff_from_pw_aff_list(space, list); +} + +/* Add the tuple represented by the isl_multi_pw_aff "tuple" to "map". * We first create the appropriate space in "map" based on the range * space of this isl_multi_pw_aff. Then, we add equalities based * on the affine expressions. These live in an anonymous space, * however, so we first need to reset the space to that of "map". */ -static __isl_give isl_map *read_map_tuple(struct isl_stream *s, +static __isl_give isl_map *map_from_tuple(__isl_take isl_multi_pw_aff *tuple, __isl_take isl_map *map, enum isl_dim_type type, struct vars *v, - int rational, int comma) + int rational) { int i, n; - isl_multi_pw_aff *tuple; + isl_ctx *ctx; isl_space *space = NULL; - tuple = read_tuple(s, v, rational, comma); - if (!tuple) + if (!map || !tuple) goto error; - + ctx = isl_multi_pw_aff_get_ctx(tuple); n = isl_multi_pw_aff_dim(tuple, isl_dim_out); space = isl_space_range(isl_multi_pw_aff_get_space(tuple)); if (!space) @@ -1165,7 +1347,7 @@ if (type == isl_dim_param) { if (isl_space_has_tuple_name(space, isl_dim_set) || isl_space_is_wrapping(space)) { - isl_die(s->ctx, isl_error_invalid, + isl_die(ctx, isl_error_invalid, "parameter tuples cannot be named or nested", goto error); } @@ -1173,7 +1355,7 @@ for (i = 0; i < n; ++i) { isl_id *id; if (!isl_space_has_dim_name(space, isl_dim_set, i)) - isl_die(s->ctx, isl_error_invalid, + isl_die(ctx, isl_error_invalid, "parameters must be named", goto error); id = isl_space_get_dim_id(space, isl_dim_set, i); @@ -1227,6 +1409,23 @@ return NULL; } +/* Read a tuple from "s" and add it to "map". + * The tuple is initially represented as an isl_multi_pw_aff and + * then added to "map". + */ +static __isl_give isl_map *read_map_tuple(__isl_keep isl_stream *s, + __isl_take isl_map *map, enum isl_dim_type type, struct vars *v, + int rational, int comma) +{ + isl_multi_pw_aff *tuple; + + tuple = read_tuple(s, v, rational, comma); + if (!tuple) + return isl_map_free(map); + + return map_from_tuple(tuple, map, type, v, rational); +} + static __isl_give isl_set *construct_constraints( __isl_take isl_set *set, int type, __isl_keep isl_pw_aff_list *left, __isl_keep isl_pw_aff_list *right, @@ -1256,7 +1455,7 @@ return isl_set_intersect(set, cond); } -static __isl_give isl_map *add_constraint(struct isl_stream *s, +static __isl_give isl_map *add_constraint(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { struct isl_token *tok = NULL; @@ -1305,7 +1504,7 @@ return NULL; } -static __isl_give isl_map *read_exists(struct isl_stream *s, +static __isl_give isl_map *read_exists(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { int n = v->n; @@ -1345,7 +1544,7 @@ * Otherwise, we assume that the affine expression is the * start of a condition and continue parsing. */ -static int resolve_paren_expr(struct isl_stream *s, +static int resolve_paren_expr(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { struct isl_token *tok, *tok2; @@ -1417,7 +1616,7 @@ return -1; } -static __isl_give isl_map *read_conjunct(struct isl_stream *s, +static __isl_give isl_map *read_conjunct(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { if (isl_stream_next_token_is(s, '(')) @@ -1453,7 +1652,7 @@ return NULL; } -static __isl_give isl_map *read_conjuncts(struct isl_stream *s, +static __isl_give isl_map *read_conjuncts(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { isl_map *res; @@ -1479,7 +1678,7 @@ return res; } -static struct isl_map *read_disjuncts(struct isl_stream *s, +static struct isl_map *read_disjuncts(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { isl_map *res; @@ -1523,7 +1722,7 @@ * * (map \setminus { [..] : a}) \cup (map \cap { [..] : b }) */ -static __isl_give isl_map *read_formula(struct isl_stream *s, +static __isl_give isl_map *read_formula(__isl_keep isl_stream *s, struct vars *v, __isl_take isl_map *map, int rational) { isl_map *res; @@ -1566,22 +1765,17 @@ } static __isl_give isl_basic_map *basic_map_read_polylib_constraint( - struct isl_stream *s, __isl_take isl_basic_map *bmap) + __isl_keep isl_stream *s, __isl_take isl_basic_map *bmap) { int j; struct isl_token *tok; int type; int k; isl_int *c; - unsigned nparam; - unsigned dim; if (!bmap) return NULL; - nparam = isl_basic_map_dim(bmap, isl_dim_param); - dim = isl_basic_map_dim(bmap, isl_dim_out); - tok = isl_stream_next_token(s); if (!tok || tok->type != ISL_TOKEN_VALUE) { isl_stream_error(s, tok, "expecting coefficient"); @@ -1635,7 +1829,8 @@ return NULL; } -static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s) +static __isl_give isl_basic_map *basic_map_read_polylib( + __isl_keep isl_stream *s) { int i; struct isl_token *tok; @@ -1751,7 +1946,7 @@ return NULL; } -static struct isl_map *map_read_polylib(struct isl_stream *s) +static struct isl_map *map_read_polylib(__isl_keep isl_stream *s) { struct isl_token *tok; struct isl_token *tok2; @@ -1789,7 +1984,7 @@ return map; } -static int optional_power(struct isl_stream *s) +static int optional_power(__isl_keep isl_stream *s) { int pow; struct isl_token *tok; @@ -1814,10 +2009,10 @@ return pow; } -static __isl_give isl_pw_qpolynomial *read_term(struct isl_stream *s, +static __isl_give isl_pw_qpolynomial *read_term(__isl_keep isl_stream *s, __isl_keep isl_map *map, struct vars *v); -static __isl_give isl_pw_qpolynomial *read_factor(struct isl_stream *s, +static __isl_give isl_pw_qpolynomial *read_factor(__isl_keep isl_stream *s, __isl_keep isl_map *map, struct vars *v) { isl_pw_qpolynomial *pwqp; @@ -1925,7 +2120,7 @@ return NULL; } -static __isl_give isl_pw_qpolynomial *read_term(struct isl_stream *s, +static __isl_give isl_pw_qpolynomial *read_term(__isl_keep isl_stream *s, __isl_keep isl_map *map, struct vars *v) { struct isl_token *tok; @@ -1966,7 +2161,7 @@ return pwqp; } -static __isl_give isl_map *read_optional_formula(struct isl_stream *s, +static __isl_give isl_map *read_optional_formula(__isl_keep isl_stream *s, __isl_take isl_map *map, struct vars *v, int rational) { struct isl_token *tok; @@ -1989,7 +2184,7 @@ return NULL; } -static struct isl_obj obj_read_poly(struct isl_stream *s, +static struct isl_obj obj_read_poly(__isl_keep isl_stream *s, __isl_take isl_map *map, struct vars *v, int n) { struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL }; @@ -2008,7 +2203,7 @@ return obj; } -static struct isl_obj obj_read_poly_or_fold(struct isl_stream *s, +static struct isl_obj obj_read_poly_or_fold(__isl_keep isl_stream *s, __isl_take isl_set *set, struct vars *v, int n) { struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL }; @@ -2049,7 +2244,7 @@ return obj; } -static int is_rational(struct isl_stream *s) +static int is_rational(__isl_keep isl_stream *s) { struct isl_token *tok; @@ -2067,7 +2262,7 @@ return 0; } -static struct isl_obj obj_read_body(struct isl_stream *s, +static struct isl_obj obj_read_body(__isl_keep isl_stream *s, __isl_take isl_map *map, struct vars *v) { struct isl_token *tok; @@ -2144,47 +2339,54 @@ return obj; } -static struct isl_obj obj_add(struct isl_ctx *ctx, +static struct isl_obj obj_add(__isl_keep isl_stream *s, struct isl_obj obj1, struct isl_obj obj2) { if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set) - obj1 = to_union(ctx, obj1); + obj1 = to_union(s->ctx, obj1); if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set) - obj2 = to_union(ctx, obj2); + obj2 = to_union(s->ctx, obj2); if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map) - obj1 = to_union(ctx, obj1); + obj1 = to_union(s->ctx, obj1); if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map) - obj2 = to_union(ctx, obj2); + obj2 = to_union(s->ctx, obj2); if (obj1.type == isl_obj_pw_qpolynomial && obj2.type == isl_obj_union_pw_qpolynomial) - obj1 = to_union(ctx, obj1); + obj1 = to_union(s->ctx, obj1); if (obj1.type == isl_obj_union_pw_qpolynomial && obj2.type == isl_obj_pw_qpolynomial) - obj2 = to_union(ctx, obj2); + obj2 = to_union(s->ctx, obj2); if (obj1.type == isl_obj_pw_qpolynomial_fold && obj2.type == isl_obj_union_pw_qpolynomial_fold) - obj1 = to_union(ctx, obj1); + obj1 = to_union(s->ctx, obj1); if (obj1.type == isl_obj_union_pw_qpolynomial_fold && obj2.type == isl_obj_pw_qpolynomial_fold) - obj2 = to_union(ctx, obj2); - isl_assert(ctx, obj1.type == obj2.type, goto error); + obj2 = to_union(s->ctx, obj2); + if (obj1.type != obj2.type) { + isl_stream_error(s, NULL, + "attempt to combine incompatible objects"); + goto error; + } + if (!obj1.type->add) + isl_die(s->ctx, isl_error_internal, + "combination not supported on object type", goto error); if (obj1.type == isl_obj_map && !isl_map_has_equal_space(obj1.v, obj2.v)) { - obj1 = to_union(ctx, obj1); - obj2 = to_union(ctx, obj2); + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); } if (obj1.type == isl_obj_set && !isl_set_has_equal_space(obj1.v, obj2.v)) { - obj1 = to_union(ctx, obj1); - obj2 = to_union(ctx, obj2); + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); } if (obj1.type == isl_obj_pw_qpolynomial && !isl_pw_qpolynomial_has_equal_space(obj1.v, obj2.v)) { - obj1 = to_union(ctx, obj1); - obj2 = to_union(ctx, obj2); + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); } if (obj1.type == isl_obj_pw_qpolynomial_fold && !isl_pw_qpolynomial_fold_has_equal_space(obj1.v, obj2.v)) { - obj1 = to_union(ctx, obj1); - obj2 = to_union(ctx, obj2); + obj1 = to_union(s->ctx, obj1); + obj2 = to_union(s->ctx, obj2); } obj1.v = obj1.type->add(obj1.v, obj2.v); return obj1; @@ -2196,13 +2398,80 @@ return obj1; } -static struct isl_obj obj_read(struct isl_stream *s) +/* Are the first two tokens on "s", "domain" (either as a string + * or as an identifier) followed by ":"? + */ +static int next_is_domain_colon(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + char *name; + int res; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != ISL_TOKEN_IDENT && tok->type != ISL_TOKEN_STRING) { + isl_stream_push_token(s, tok); + return 0; + } + + name = isl_token_get_str(s->ctx, tok); + res = !strcmp(name, "domain") && isl_stream_next_token_is(s, ':'); + free(name); + + isl_stream_push_token(s, tok); + + return res; +} + +/* Do the first tokens on "s" look like a schedule? + * + * The root of a schedule is always a domain node, so the first thing + * we expect in the stream is a domain key, i.e., "domain" followed + * by ":". If the schedule was printed in YAML flow style, then + * we additionally expect a "{" to open the outer mapping. + */ +static int next_is_schedule(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int is_schedule; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '{') { + isl_stream_push_token(s, tok); + return next_is_domain_colon(s); + } + + is_schedule = next_is_domain_colon(s); + isl_stream_push_token(s, tok); + + return is_schedule; +} + +/* Read an isl_schedule from "s" and store it in an isl_obj. + */ +static struct isl_obj schedule_read(__isl_keep isl_stream *s) +{ + struct isl_obj obj; + + obj.type = isl_obj_schedule; + obj.v = isl_stream_read_schedule(s); + + return obj; +} + +static struct isl_obj obj_read(__isl_keep isl_stream *s) { isl_map *map = NULL; struct isl_token *tok; struct vars *v = NULL; struct isl_obj obj = { isl_obj_set, NULL }; + if (next_is_schedule(s)) + return schedule_read(s); + tok = next_token(s); if (!tok) { isl_stream_error(s, NULL, "unexpected EOF"); @@ -2217,8 +2486,8 @@ isl_int_is_neg(tok2->u.v)) { if (tok2) isl_stream_push_token(s, tok2); - obj.type = isl_obj_int; - obj.v = isl_int_obj_alloc(s->ctx, tok->u.v); + obj.type = isl_obj_val; + obj.v = isl_val_int_from_isl_int(s->ctx, tok->u.v); isl_token_free(tok); return obj; } @@ -2291,7 +2560,7 @@ if (!obj.v) obj = o; else { - obj = obj_add(s->ctx, obj, o); + obj = obj_add(s, obj, o); if (obj.type == isl_obj_none || !obj.v) goto error; } @@ -2327,12 +2596,12 @@ return obj; } -struct isl_obj isl_stream_read_obj(struct isl_stream *s) +struct isl_obj isl_stream_read_obj(__isl_keep isl_stream *s) { return obj_read(s); } -__isl_give isl_map *isl_stream_read_map(struct isl_stream *s) +__isl_give isl_map *isl_stream_read_map(__isl_keep isl_stream *s) { struct isl_obj obj; @@ -2350,7 +2619,7 @@ return NULL; } -__isl_give isl_set *isl_stream_read_set(struct isl_stream *s) +__isl_give isl_set *isl_stream_read_set(__isl_keep isl_stream *s) { struct isl_obj obj; @@ -2369,7 +2638,7 @@ return NULL; } -__isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s) +__isl_give isl_union_map *isl_stream_read_union_map(__isl_keep isl_stream *s) { struct isl_obj obj; @@ -2394,7 +2663,7 @@ return NULL; } -__isl_give isl_union_set *isl_stream_read_union_set(struct isl_stream *s) +__isl_give isl_union_set *isl_stream_read_union_set(__isl_keep isl_stream *s) { struct isl_obj obj; @@ -2412,21 +2681,27 @@ return NULL; } -static __isl_give isl_basic_map *basic_map_read(struct isl_stream *s) +static __isl_give isl_basic_map *basic_map_read(__isl_keep isl_stream *s) { struct isl_obj obj; struct isl_map *map; struct isl_basic_map *bmap; obj = obj_read(s); + if (obj.v && (obj.type != isl_obj_map && obj.type != isl_obj_set)) + isl_die(s->ctx, isl_error_invalid, "not a (basic) set or map", + goto error); map = obj.v; if (!map) return NULL; - isl_assert(map->ctx, map->n <= 1, goto error); + if (map->n > 1) + isl_die(s->ctx, isl_error_invalid, + "set or map description involves " + "more than one disjunct", goto error); if (map->n == 0) - bmap = isl_basic_map_empty_like_map(map); + bmap = isl_basic_map_empty(isl_map_get_space(map)); else bmap = isl_basic_map_copy(map->p[0]); @@ -2434,11 +2709,11 @@ return bmap; error: - isl_map_free(map); + obj.type->free(obj.v); return NULL; } -static __isl_give isl_basic_set *basic_set_read(struct isl_stream *s) +static __isl_give isl_basic_set *basic_set_read(__isl_keep isl_stream *s) { isl_basic_map *bmap; bmap = basic_map_read(s); @@ -2457,7 +2732,7 @@ FILE *input) { struct isl_basic_map *bmap; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; bmap = basic_map_read(s); @@ -2469,7 +2744,7 @@ FILE *input) { isl_basic_set *bset; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; bset = basic_set_read(s); @@ -2481,7 +2756,7 @@ const char *str) { struct isl_basic_map *bmap; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; bmap = basic_map_read(s); @@ -2493,7 +2768,7 @@ const char *str) { isl_basic_set *bset; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; bset = basic_set_read(s); @@ -2505,7 +2780,7 @@ FILE *input) { struct isl_map *map; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; map = isl_stream_read_map(s); @@ -2517,7 +2792,7 @@ const char *str) { struct isl_map *map; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; map = isl_stream_read_map(s); @@ -2529,7 +2804,7 @@ FILE *input) { isl_set *set; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; set = isl_stream_read_set(s); @@ -2541,7 +2816,7 @@ const char *str) { isl_set *set; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; set = isl_stream_read_set(s); @@ -2553,7 +2828,7 @@ FILE *input) { isl_union_map *umap; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; umap = isl_stream_read_union_map(s); @@ -2565,7 +2840,7 @@ const char *str) { isl_union_map *umap; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; umap = isl_stream_read_union_map(s); @@ -2577,7 +2852,7 @@ FILE *input) { isl_union_set *uset; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; uset = isl_stream_read_union_set(s); @@ -2589,7 +2864,7 @@ const char *str) { isl_union_set *uset; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; uset = isl_stream_read_union_set(s); @@ -2597,7 +2872,7 @@ return uset; } -static __isl_give isl_vec *isl_vec_read_polylib(struct isl_stream *s) +static __isl_give isl_vec *isl_vec_read_polylib(__isl_keep isl_stream *s) { struct isl_vec *vec = NULL; struct isl_token *tok; @@ -2632,7 +2907,7 @@ return NULL; } -static __isl_give isl_vec *vec_read(struct isl_stream *s) +static __isl_give isl_vec *vec_read(__isl_keep isl_stream *s) { return isl_vec_read_polylib(s); } @@ -2640,7 +2915,7 @@ __isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input) { isl_vec *v; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; v = vec_read(s); @@ -2649,7 +2924,7 @@ } __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial( - struct isl_stream *s) + __isl_keep isl_stream *s) { struct isl_obj obj; @@ -2668,7 +2943,7 @@ const char *str) { isl_pw_qpolynomial *pwqp; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; pwqp = isl_stream_read_pw_qpolynomial(s); @@ -2680,7 +2955,7 @@ FILE *input) { isl_pw_qpolynomial *pwqp; - struct isl_stream *s = isl_stream_new_file(ctx, input); + isl_stream *s = isl_stream_new_file(ctx, input); if (!s) return NULL; pwqp = isl_stream_read_pw_qpolynomial(s); @@ -2690,7 +2965,7 @@ /* Is the next token an identifer not in "v"? */ -static int next_is_fresh_ident(struct isl_stream *s, struct vars *v) +static int next_is_fresh_ident(__isl_keep isl_stream *s, struct vars *v) { int n = v->n; int fresh; @@ -2717,7 +2992,7 @@ * or a new identifier, we again assume it's the domain. * Otherwise, we assume we are reading an affine expression. */ -static __isl_give isl_set *read_aff_domain(struct isl_stream *s, +static __isl_give isl_set *read_aff_domain(__isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v) { struct isl_token *tok; @@ -2747,7 +3022,7 @@ /* Read an affine expression from "s". */ -__isl_give isl_aff *isl_stream_read_aff(struct isl_stream *s) +__isl_give isl_aff *isl_stream_read_aff(__isl_keep isl_stream *s) { isl_aff *aff; isl_multi_aff *ma; @@ -2770,7 +3045,7 @@ /* Read a piecewise affine expression from "s" with domain (space) "dom". */ -static __isl_give isl_pw_aff *read_pw_aff_with_dom(struct isl_stream *s, +static __isl_give isl_pw_aff *read_pw_aff_with_dom(__isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v) { isl_pw_aff *pwaff = NULL; @@ -2796,7 +3071,7 @@ return NULL; } -__isl_give isl_pw_aff *isl_stream_read_pw_aff(struct isl_stream *s) +__isl_give isl_pw_aff *isl_stream_read_pw_aff(__isl_keep isl_stream *s) { struct vars *v; isl_set *dom = NULL; @@ -2849,7 +3124,7 @@ __isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str) { isl_aff *aff; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; aff = isl_stream_read_aff(s); @@ -2860,7 +3135,7 @@ __isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str) { isl_pw_aff *pa; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; pa = isl_stream_read_pw_aff(s); @@ -2874,7 +3149,8 @@ * It would be more efficient if we were to construct the isl_pw_multi_aff * directly. */ -__isl_give isl_pw_multi_aff *isl_stream_read_pw_multi_aff(struct isl_stream *s) +__isl_give isl_pw_multi_aff *isl_stream_read_pw_multi_aff( + __isl_keep isl_stream *s) { struct isl_obj obj; @@ -2896,7 +3172,7 @@ const char *str) { isl_pw_multi_aff *pma; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; pma = isl_stream_read_pw_multi_aff(s); @@ -2911,7 +3187,7 @@ * the isl_union_pw_multi_aff directly. */ __isl_give isl_union_pw_multi_aff *isl_stream_read_union_pw_multi_aff( - struct isl_stream *s) + __isl_keep isl_stream *s) { struct isl_obj obj; @@ -2937,7 +3213,7 @@ isl_ctx *ctx, const char *str) { isl_union_pw_multi_aff *upma; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; upma = isl_stream_read_union_pw_multi_aff(s); @@ -2971,15 +3247,95 @@ return NULL; } +/* This function is called for each element in a tuple inside + * isl_stream_read_multi_val. + * Read an isl_val from "s" and add it to *list. + */ +static __isl_give isl_space *read_val_el(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + isl_val_list **list = (isl_val_list **) user; + isl_val *val; + + val = isl_stream_read_val(s); + *list = isl_val_list_add(*list, val); + if (!*list) + return isl_space_free(space); + + return space; +} + +/* Read an isl_multi_val from "s". + * + * We first read a tuple space, collecting the element values in a list. + * Then we create an isl_multi_val from the space and the isl_val_list. + */ +__isl_give isl_multi_val *isl_stream_read_multi_val(__isl_keep isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_space *space; + isl_multi_val *mv = NULL; + isl_val_list *list; + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 1, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + if (!isl_set_plain_is_universe(dom)) + isl_die(s->ctx, isl_error_invalid, + "expecting universe parameter domain", goto error); + if (isl_stream_eat(s, '{')) + goto error; + + space = isl_set_get_space(dom); + + list = isl_val_list_alloc(s->ctx, 0); + space = read_tuple_space(s, v, space, 1, 0, &read_val_el, &list); + mv = isl_multi_val_from_val_list(space, list); + + if (isl_stream_eat(s, '}')) + goto error; + + vars_free(v); + isl_set_free(dom); + return mv; +error: + vars_free(v); + isl_set_free(dom); + isl_multi_val_free(mv); + return NULL; +} + +/* Read an isl_multi_val from "str". + */ +__isl_give isl_multi_val *isl_multi_val_read_from_str(isl_ctx *ctx, + const char *str) +{ + isl_multi_val *mv; + isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + mv = isl_stream_read_multi_val(s); + isl_stream_free(s); + return mv; +} + /* Read a multi-affine expression from "s". - * If the multi-affine expression has a domain, then then tuple + * If the multi-affine expression has a domain, then the tuple * representing this domain cannot involve any affine expressions. * The tuple representing the actual expressions needs to consist * of only affine expressions. Moreover, these expressions can * only depend on parameters and input dimensions and not on other * output dimensions. */ -__isl_give isl_multi_aff *isl_stream_read_multi_aff(struct isl_stream *s) +__isl_give isl_multi_aff *isl_stream_read_multi_aff(__isl_keep isl_stream *s) { struct vars *v; isl_set *dom = NULL; @@ -3075,7 +3431,7 @@ const char *str) { isl_multi_aff *maff; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; maff = isl_stream_read_multi_aff(s); @@ -3083,8 +3439,317 @@ return maff; } +/* Read an isl_multi_pw_aff from "s". + * + * The input format is similar to that of map, except that any conditions + * on the domains should be specified inside the tuple since each + * piecewise affine expression may have a different domain. + * + * Since we do not know in advance if the isl_multi_pw_aff lives + * in a set or a map space, we first read the first tuple and check + * if it is followed by a "->". If so, we convert the tuple into + * the domain of the isl_multi_pw_aff and read in the next tuple. + * This tuple (or the first tuple if it was not followed by a "->") + * is then converted into the isl_multi_pw_aff. + * + * Note that the function read_tuple accepts tuples where some output or + * set dimensions are defined in terms of other output or set dimensions + * since this function is also used to read maps. As a special case, + * read_tuple also accept dimensions that are defined in terms of themselves + * (i.e., that are not defined). + * These cases are not allowed when reading am isl_multi_pw_aff so we check + * that the definition of the output/set dimensions does not involve any + * output/set dimensions. + * We then drop the output dimensions from the domain of the result + * of read_tuple (which is of the form [input, output] -> [output], + * with anonymous domain) and reset the space. + */ +__isl_give isl_multi_pw_aff *isl_stream_read_multi_pw_aff( + __isl_keep isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_multi_pw_aff *tuple = NULL; + int dim, i, n; + isl_space *space, *dom_space; + isl_multi_pw_aff *mpa = NULL; + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 1, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + if (isl_stream_eat(s, '{')) + goto error; + + tuple = read_tuple(s, v, 0, 0); + if (!tuple) + goto error; + if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) { + isl_map *map = map_from_tuple(tuple, dom, isl_dim_in, v, 0); + dom = isl_map_domain(map); + tuple = read_tuple(s, v, 0, 0); + if (!tuple) + goto error; + } + + if (isl_stream_eat(s, '}')) + goto error; + + n = isl_multi_pw_aff_dim(tuple, isl_dim_out); + dim = isl_set_dim(dom, isl_dim_all); + dom_space = isl_set_get_space(dom); + space = isl_space_range(isl_multi_pw_aff_get_space(tuple)); + space = isl_space_align_params(space, isl_space_copy(dom_space)); + if (!isl_space_is_params(dom_space)) + space = isl_space_map_from_domain_and_range( + isl_space_copy(dom_space), space); + isl_space_free(dom_space); + mpa = isl_multi_pw_aff_alloc(space); + + for (i = 0; i < n; ++i) { + isl_pw_aff *pa; + pa = isl_multi_pw_aff_get_pw_aff(tuple, i); + if (!pa) + goto error; + if (isl_pw_aff_involves_dims(pa, isl_dim_in, dim, i + 1)) { + isl_pw_aff_free(pa); + isl_die(s->ctx, isl_error_invalid, + "not an affine expression", goto error); + } + pa = isl_pw_aff_drop_dims(pa, isl_dim_in, dim, n); + space = isl_multi_pw_aff_get_domain_space(mpa); + pa = isl_pw_aff_reset_domain_space(pa, space); + mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); + } + + isl_multi_pw_aff_free(tuple); + vars_free(v); + mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); + return mpa; +error: + isl_multi_pw_aff_free(tuple); + vars_free(v); + isl_set_free(dom); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Read an isl_multi_pw_aff from "str". + */ +__isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str(isl_ctx *ctx, + const char *str) +{ + isl_multi_pw_aff *mpa; + isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + mpa = isl_stream_read_multi_pw_aff(s); + isl_stream_free(s); + return mpa; +} + +/* Read the body of an isl_union_pw_aff from "s" with parameter domain "dom". + */ +static __isl_give isl_union_pw_aff *read_union_pw_aff_with_dom( + __isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v) +{ + isl_pw_aff *pa; + isl_union_pw_aff *upa = NULL; + isl_set *aff_dom; + int n; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + upa = isl_union_pw_aff_from_pw_aff(pa); + + while (isl_stream_eat_if_available(s, ';')) { + isl_pw_aff *pa_i; + isl_union_pw_aff *upa_i; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa_i = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + upa_i = isl_union_pw_aff_from_pw_aff(pa_i); + upa = isl_union_pw_aff_union_add(upa, upa_i); + } + + isl_set_free(dom); + return upa; +} + +/* This function is called for each element in a tuple inside + * isl_stream_read_multi_union_pw_aff. + * + * Read a '{', the union piecewise affine expression body and a '}' and + * add the isl_union_pw_aff to *list. + */ +static __isl_give isl_space *read_union_pw_aff_el(__isl_keep isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + isl_set *dom; + isl_union_pw_aff *upa; + isl_union_pw_aff_list **list = (isl_union_pw_aff_list **) user; + + dom = isl_set_universe(isl_space_params(isl_space_copy(space))); + if (isl_stream_eat(s, '{')) + goto error; + upa = read_union_pw_aff_with_dom(s, dom, v); + *list = isl_union_pw_aff_list_add(*list, upa); + if (isl_stream_eat(s, '}')) + return isl_space_free(space); + if (!*list) + return isl_space_free(space); + return space; +error: + isl_set_free(dom); + return isl_space_free(space); +} + +/* Do the next tokens in "s" correspond to an empty tuple? + * In particular, does the stream start with a '[', followed by a ']', + * not followed by a "->"? + */ +static int next_is_empty_tuple(__isl_keep isl_stream *s) +{ + struct isl_token *tok, *tok2, *tok3; + int is_empty_tuple = 0; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '[') { + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + if (tok2 && tok2->type == ']') { + tok3 = isl_stream_next_token(s); + is_empty_tuple = !tok || tok->type != ISL_TOKEN_TO; + if (tok3) + isl_stream_push_token(s, tok3); + } + if (tok2) + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + + return is_empty_tuple; +} + +/* Do the next tokens in "s" correspond to a tuple of parameters? + * In particular, does the stream start with a '[' that is not + * followed by a '{' or a nested tuple? + */ +static int next_is_param_tuple(__isl_keep isl_stream *s) +{ + struct isl_token *tok, *tok2; + int is_tuple; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '[' || next_is_tuple(s)) { + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + is_tuple = tok2 && tok2->type != '{'; + if (tok2) + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + + return is_tuple; +} + +/* Read an isl_multi_union_pw_aff from "s". + * + * The input has the form + * + * [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * or + * + * [..] -> [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * We first check for the special case of an empty tuple "[]". + * Then we check if there are any parameters. + * Finally, we read the tuple, collecting the individual isl_union_pw_aff + * elements in a list and construct the result from the tuple space and + * the list. + */ +__isl_give isl_multi_union_pw_aff *isl_stream_read_multi_union_pw_aff( + __isl_keep isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_space *space; + isl_multi_union_pw_aff *mupa = NULL; + isl_union_pw_aff_list *list; + + if (next_is_empty_tuple(s)) { + if (isl_stream_eat(s, '[')) + return NULL; + if (isl_stream_eat(s, ']')) + return NULL; + space = isl_space_set_alloc(s->ctx, 0, 0); + return isl_multi_union_pw_aff_zero(space); + } + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_param_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 1, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + space = isl_set_get_space(dom); + isl_set_free(dom); + list = isl_union_pw_aff_list_alloc(s->ctx, 0); + space = read_tuple_space(s, v, space, 1, 0, + &read_union_pw_aff_el, &list); + mupa = isl_multi_union_pw_aff_from_union_pw_aff_list(space, list); + + vars_free(v); + + return mupa; +error: + vars_free(v); + isl_set_free(dom); + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Read an isl_multi_union_pw_aff from "str". + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str) +{ + isl_multi_union_pw_aff *mupa; + isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + mupa = isl_stream_read_multi_union_pw_aff(s); + isl_stream_free(s); + return mupa; +} + __isl_give isl_union_pw_qpolynomial *isl_stream_read_union_pw_qpolynomial( - struct isl_stream *s) + __isl_keep isl_stream *s) { struct isl_obj obj; @@ -3107,7 +3772,7 @@ isl_ctx *ctx, const char *str) { isl_union_pw_qpolynomial *upwqp; - struct isl_stream *s = isl_stream_new_str(ctx, str); + isl_stream *s = isl_stream_new_str(ctx, str); if (!s) return NULL; upwqp = isl_stream_read_union_pw_qpolynomial(s); diff -Nru isl-0.12.2/isl_int_gmp.h isl-0.15/isl_int_gmp.h --- isl-0.12.2/isl_int_gmp.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_int_gmp.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,88 @@ +#ifndef ISL_INT_GMP_H +#define ISL_INT_GMP_H + +#include + +/* 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; + +#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_si(r,i) mpz_set_si(r,i) +#define isl_int_set_ui(r,i) mpz_set_ui(r,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) +#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_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_cmp(i,j) mpz_cmpabs(i,j) +#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_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) + +#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 -Nru isl-0.12.2/isl_int.h isl-0.15/isl_int.h --- isl-0.12.2/isl_int.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_int.h 2015-06-11 10:46:17.000000000 +0000 @@ -9,105 +9,20 @@ #ifndef ISL_INT_H #define ISL_INT_H +#define ISL_DEPRECATED_INT_H #include +#include #include -#include #include -#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)); +#ifdef USE_GMP_FOR_MP +#include #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) -#ifdef GMP_NORMALIZE_GCDEXT -void isl_gmp_gcdext(mpz_t G, mpz_t S, mpz_t T, mpz_t A, mpz_t B); -#define isl_int_gcdext(g,x,y,i,j) isl_gmp_gcdext(g,x,y,i,j) -#else -#define isl_int_gcdext(g,x,y,i,j) mpz_gcdext(g,x,y,i,j) +#ifdef USE_IMATH_FOR_MP +#include #endif -#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) @@ -116,9 +31,16 @@ #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) +#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) -#endif +__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p, + isl_int i); + +#endif /* ISL_INT_H */ diff -Nru isl-0.12.2/isl_int_imath.h isl-0.15/isl_int_imath.h --- isl-0.12.2/isl_int_imath.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_int_imath.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,76 @@ +#ifndef ISL_INT_IMATH_H +#define ISL_INT_IMATH_H + +#include "isl_hide_deprecated.h" + +#include + +/* 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_cmp(i,j) impz_cmpabs(i,j) +#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 -Nru isl-0.12.2/isl_list_templ.c isl-0.15/isl_list_templ.c --- isl-0.12.2/isl_list_templ.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_list_templ.c 2015-06-02 09:28:09.000000000 +0000 @@ -214,7 +214,7 @@ return NULL; } -void *FN(LIST(EL),free)(__isl_take LIST(EL) *list) +__isl_null LIST(EL) *FN(LIST(EL),free)(__isl_take LIST(EL) *list) { int i; @@ -273,23 +273,23 @@ return NULL; } -int FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list, - int (*fn)(__isl_take EL *el, void *user), void *user) +isl_stat FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list, + isl_stat (*fn)(__isl_take EL *el, void *user), void *user) { int i; if (!list) - return -1; + return isl_stat_error; for (i = 0; i < list->n; ++i) { EL *el = FN(EL,copy(list->p[i])); if (!el) - return -1; + return isl_stat_error; if (fn(el, user) < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } /* Internal data structure for isl_*_list_sort. @@ -344,7 +344,7 @@ */ S(LIST(EL),foreach_scc_data) { LIST(EL) *list; - int (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user); + isl_bool (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user); void *follows_user; }; @@ -352,7 +352,7 @@ * * Use the user provided callback to find out. */ -static int FN(LIST(EL),follows)(int i, int j, void *user) +static isl_bool FN(LIST(EL),follows)(int i, int j, void *user) { S(LIST(EL),foreach_scc_data) *data = user; @@ -363,8 +363,8 @@ /* Call "fn" on the sublist of "list" that consists of the elements * with indices specified by the "n" elements of "pos". */ -static int FN(LIST(EL),call_on_scc)(__isl_keep LIST(EL) *list, int *pos, int n, - int (*fn)(__isl_take LIST(EL) *scc, void *user), void *user) +static isl_stat FN(LIST(EL),call_on_scc)(__isl_keep LIST(EL) *list, int *pos, + int n, isl_stat (*fn)(__isl_take LIST(EL) *scc, void *user), void *user) { int i; isl_ctx *ctx; @@ -394,10 +394,10 @@ * We simply call isl_tarjan_graph_init, extract the SCCs from the result and * call fn on each of them. */ -int FN(LIST(EL),foreach_scc)(__isl_keep LIST(EL) *list, - int (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user), +isl_stat FN(LIST(EL),foreach_scc)(__isl_keep LIST(EL) *list, + isl_bool (*follows)(__isl_keep EL *a, __isl_keep EL *b, void *user), void *follows_user, - int (*fn)(__isl_take LIST(EL) *scc, void *user), void *fn_user) + isl_stat (*fn)(__isl_take LIST(EL) *scc, void *user), void *fn_user) { S(LIST(EL),foreach_scc_data) data = { list, follows, follows_user }; int i, n; @@ -405,9 +405,9 @@ struct isl_tarjan_graph *g; if (!list) - return -1; + return isl_stat_error; if (list->n == 0) - return 0; + return isl_stat_ok; if (list->n == 1) return fn(FN(LIST(EL),copy)(list), fn_user); @@ -415,7 +415,7 @@ n = list->n; g = isl_tarjan_graph_init(ctx, n, &FN(LIST(EL),follows), &data); if (!g) - return -1; + return isl_stat_error; i = 0; do { @@ -440,7 +440,7 @@ isl_tarjan_graph_free(g); - return n > 0 ? -1 : 0; + return n > 0 ? isl_stat_error : isl_stat_ok; } __isl_give LIST(EL) *FN(FN(LIST(EL),from),BASE)(__isl_take EL *el) diff -Nru isl-0.12.2/isl_local_space.c isl-0.15/isl_local_space.c --- isl-0.12.2/isl_local_space.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_local_space.c 2015-06-02 09:28:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2011 INRIA Saclay - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -16,7 +16,8 @@ #include #include #include -#include +#include +#include isl_ctx *isl_local_space_get_ctx(__isl_keep isl_local_space *ls) { @@ -101,7 +102,8 @@ return isl_local_space_dup(ls); } -void *isl_local_space_free(__isl_take isl_local_space *ls) +__isl_null isl_local_space *isl_local_space_free( + __isl_take isl_local_space *ls) { if (!ls) return NULL; @@ -117,36 +119,99 @@ return NULL; } +/* Is the local space that of a parameter domain? + */ +isl_bool isl_local_space_is_params(__isl_keep isl_local_space *ls) +{ + if (!ls) + return isl_bool_error; + return isl_space_is_params(ls->dim); +} + /* Is the local space that of a set? */ -int isl_local_space_is_set(__isl_keep isl_local_space *ls) +isl_bool isl_local_space_is_set(__isl_keep isl_local_space *ls) { - return ls ? isl_space_is_set(ls->dim) : -1; + return ls ? isl_space_is_set(ls->dim) : isl_bool_error; } /* Return true if the two local spaces are identical, with identical * expressions for the integer divisions. */ -int isl_local_space_is_equal(__isl_keep isl_local_space *ls1, +isl_bool isl_local_space_is_equal(__isl_keep isl_local_space *ls1, __isl_keep isl_local_space *ls2) { - int equal; + isl_bool equal; if (!ls1 || !ls2) - return -1; + return isl_bool_error; equal = isl_space_is_equal(ls1->dim, ls2->dim); if (equal < 0 || !equal) return equal; if (!isl_local_space_divs_known(ls1)) - return 0; + return isl_bool_false; if (!isl_local_space_divs_known(ls2)) - return 0; + return isl_bool_false; return isl_mat_is_equal(ls1->div, ls2->div); } +/* Compare two isl_local_spaces. + * + * Return -1 if "ls1" is "smaller" than "ls2", 1 if "ls1" is "greater" + * than "ls2" and 0 if they are equal. + * + * The order is fairly arbitrary. We do "prefer" divs that only involve + * earlier dimensions in the sense that we consider local spaces where + * the first differing div involves earlier dimensions to be smaller. + */ +int isl_local_space_cmp(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2) +{ + int i; + int cmp; + int known1, known2; + int last1, last2; + int n_col; + + if (ls1 == ls2) + return 0; + if (!ls1) + return -1; + if (!ls2) + return 1; + + cmp = isl_space_cmp(ls1->dim, ls2->dim); + if (cmp != 0) + return cmp; + + if (ls1->div->n_row != ls2->div->n_row) + return ls1->div->n_row - ls2->div->n_row; + + n_col = isl_mat_cols(ls1->div); + for (i = 0; i < ls1->div->n_row; ++i) { + known1 = isl_local_space_div_is_known(ls1, i); + known2 = isl_local_space_div_is_known(ls2, i); + if (!known1 && !known2) + continue; + if (!known1) + return 1; + if (!known2) + return -1; + last1 = isl_seq_last_non_zero(ls1->div->row[i] + 1, n_col - 1); + last2 = isl_seq_last_non_zero(ls2->div->row[i] + 1, n_col - 1); + if (last1 != last2) + return last1 - last2; + cmp = isl_seq_cmp(ls1->div->row[i], ls2->div->row[i], n_col); + if (cmp != 0) + return cmp; + } + + return 0; +} + int isl_local_space_dim(__isl_keep isl_local_space *ls, enum isl_dim_type type) { @@ -178,12 +243,26 @@ } } +/* Return the position of the dimension of the given type and name + * in "ls". + * Return -1 if no such dimension can be found. + */ +int isl_local_space_find_dim_by_name(__isl_keep isl_local_space *ls, + enum isl_dim_type type, const char *name) +{ + if (!ls) + return -1; + if (type == isl_dim_div) + return -1; + return isl_space_find_dim_by_name(ls->dim, type, name); +} + /* Does the given dimension have a name? */ -int isl_local_space_has_dim_name(__isl_keep isl_local_space *ls, +isl_bool isl_local_space_has_dim_name(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos) { - return ls ? isl_space_has_dim_name(ls->dim, type, pos) : -1; + return ls ? isl_space_has_dim_name(ls->dim, type, pos) : isl_bool_error; } const char *isl_local_space_get_dim_name(__isl_keep isl_local_space *ls, @@ -192,10 +271,10 @@ return ls ? isl_space_get_dim_name(ls->dim, type, pos) : NULL; } -int isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, +isl_bool isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos) { - return ls ? isl_space_has_dim_id(ls->dim, type, pos) : -1; + return ls ? isl_space_has_dim_id(ls->dim, type, pos) : isl_bool_error; } __isl_give isl_id *isl_local_space_get_dim_id(__isl_keep isl_local_space *ls, @@ -238,6 +317,24 @@ return isl_space_copy(ls->dim); } +/* Replace the identifier of the tuple of type "type" by "id". + */ +__isl_give isl_local_space *isl_local_space_set_tuple_id( + __isl_take isl_local_space *ls, + enum isl_dim_type type, __isl_take isl_id *id) +{ + ls = isl_local_space_cow(ls); + if (!ls) + goto error; + ls->dim = isl_space_set_tuple_id(ls->dim, type, id); + if (!ls->dim) + return isl_local_space_free(ls); + return ls; +error: + isl_id_free(id); + return NULL; +} + __isl_give isl_local_space *isl_local_space_set_dim_name( __isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos, const char *s) @@ -258,12 +355,15 @@ { ls = isl_local_space_cow(ls); if (!ls) - return isl_id_free(id); + goto error; ls->dim = isl_space_set_dim_id(ls->dim, type, pos, id); if (!ls->dim) return isl_local_space_free(ls); return ls; +error: + isl_id_free(id); + return NULL; } __isl_give isl_local_space *isl_local_space_reset_space( @@ -576,6 +676,7 @@ int *exp1 = NULL; int *exp2 = NULL; isl_mat *div; + int equal; if (!ls1 || !ls2) goto error; @@ -604,6 +705,14 @@ if (!div) goto error; + equal = isl_mat_is_equal(ls1->div, div); + if (equal < 0) + goto error; + if (!equal) + ls1 = isl_local_space_cow(ls1); + if (!ls1) + goto error; + free(exp1); free(exp2); isl_local_space_free(ls2); @@ -619,6 +728,18 @@ return NULL; } +/* Does "ls" have an explicit representation for div "div"? + */ +int isl_local_space_div_is_known(__isl_keep isl_local_space *ls, int div) +{ + if (!ls) + return -1; + if (div < 0 || div >= ls->div->n_row) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "position out of bounds", return -1); + return !isl_int_is_zero(ls->div->row[div][0]); +} + int isl_local_space_divs_known(__isl_keep isl_local_space *ls) { int i; @@ -798,7 +919,7 @@ pos += isl_local_space_offset(ls, type); isl_int_init(v); - for (i = first; i < ls->div->n_row; ++i) { + for (i = first; i < first + n; ++i) { if (isl_int_is_zero(ls->div->row[i][1 + pos])) continue; isl_seq_substitute(ls->div->row[i], pos, subs, @@ -1038,8 +1159,7 @@ return NULL; if (!isl_local_space_is_set(ls)) isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, - "lifting only defined on set spaces", - return isl_local_space_free(ls)); + "lifting only defined on set spaces", goto error); bset = isl_basic_set_from_local_space(ls); lifting = isl_basic_set_unwrap(isl_basic_set_lift(bset)); @@ -1047,6 +1167,9 @@ lifting = isl_basic_map_reverse(lifting); return lifting; +error: + isl_local_space_free(ls); + return NULL; } /* Compute the preimage of "ls" under the function represented by "ma". @@ -1130,3 +1253,128 @@ isl_local_space_free(res); return NULL; } + +/* Move the "n" dimensions of "src_type" starting at "src_pos" of "ls" + * to dimensions of "dst_type" at "dst_pos". + * + * Moving to/from local dimensions is not allowed. + * We currently assume that the dimension type changes. + */ +__isl_give isl_local_space *isl_local_space_move_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + unsigned g_dst_pos; + unsigned g_src_pos; + + if (!ls) + return NULL; + if (n == 0 && + !isl_local_space_is_named_or_nested(ls, src_type) && + !isl_local_space_is_named_or_nested(ls, dst_type)) + return ls; + + if (src_pos + n > isl_local_space_dim(ls, src_type)) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "range out of bounds", return isl_local_space_free(ls)); + if (dst_pos > isl_local_space_dim(ls, dst_type)) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "position out of bounds", + return isl_local_space_free(ls)); + if (src_type == isl_dim_div) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "cannot move divs", return isl_local_space_free(ls)); + if (dst_type == isl_dim_div) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "cannot move to divs", return isl_local_space_free(ls)); + if (dst_type == src_type && dst_pos == src_pos) + return ls; + if (dst_type == src_type) + isl_die(isl_local_space_get_ctx(ls), isl_error_unsupported, + "moving dims within the same type not supported", + return isl_local_space_free(ls)); + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + g_src_pos = 1 + isl_local_space_offset(ls, src_type) + src_pos; + g_dst_pos = 1 + isl_local_space_offset(ls, dst_type) + dst_pos; + if (dst_type > src_type) + g_dst_pos -= n; + ls->div = isl_mat_move_cols(ls->div, g_dst_pos, g_src_pos, n); + if (!ls->div) + return isl_local_space_free(ls); + ls->dim = isl_space_move_dims(ls->dim, dst_type, dst_pos, + src_type, src_pos, n); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +/* Remove any internal structure of the domain of "ls". + * If there is any such internal structure in the input, + * then the name of the corresponding space is also removed. + */ +__isl_give isl_local_space *isl_local_space_flatten_domain( + __isl_take isl_local_space *ls) +{ + if (!ls) + return NULL; + + if (!ls->dim->nested[0]) + return ls; + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_flatten_domain(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +/* Remove any internal structure of the range of "ls". + * If there is any such internal structure in the input, + * then the name of the corresponding space is also removed. + */ +__isl_give isl_local_space *isl_local_space_flatten_range( + __isl_take isl_local_space *ls) +{ + if (!ls) + return NULL; + + if (!ls->dim->nested[1]) + return ls; + + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_flatten_range(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + +/* Given the local space "ls" of a map, return the local space of a set + * that lives in a space that wraps the space of "ls" and that has + * the same divs. + */ +__isl_give isl_local_space *isl_local_space_wrap(__isl_take isl_local_space *ls) +{ + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + + ls->dim = isl_space_wrap(ls->dim); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} diff -Nru isl-0.12.2/isl_local_space_private.h isl-0.15/isl_local_space_private.h --- isl-0.12.2/isl_local_space_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_local_space_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -31,6 +31,7 @@ __isl_give isl_local_space *isl_local_space_replace_divs( __isl_take isl_local_space *ls, __isl_take isl_mat *div); +int isl_local_space_div_is_known(__isl_keep isl_local_space *ls, int div); int isl_local_space_divs_known(__isl_keep isl_local_space *ls); __isl_give isl_local_space *isl_local_space_substitute_equalities( @@ -63,4 +64,12 @@ __isl_give isl_local_space *isl_local_space_preimage_multi_aff( __isl_take isl_local_space *ls, __isl_take isl_multi_aff *ma); +__isl_give isl_local_space *isl_local_space_move_dims( + __isl_take isl_local_space *ls, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n); + +int isl_local_space_cmp(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2); + #endif diff -Nru isl-0.12.2/isl_lp.c isl-0.15/isl_lp.c --- isl-0.12.2/isl_lp.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_lp.c 2015-04-19 12:02:52.000000000 +0000 @@ -10,14 +10,14 @@ #include #include #include -#include "isl_lp_piplib.h" -#include +#include #include "isl_tab.h" #include #include #include #include #include +#include enum isl_lp_result isl_tab_solve_lp(struct isl_basic_map *bmap, int maximize, isl_int *f, isl_int denom, isl_int *opt, @@ -70,14 +70,7 @@ if (!bmap) return isl_lp_error; - switch (bmap->ctx->opt->lp_solver) { - case ISL_LP_PIP: - return isl_pip_solve_lp(bmap, max, f, d, opt, opt_denom, sol); - case ISL_LP_TAB: - return isl_tab_solve_lp(bmap, max, f, d, opt, opt_denom, sol); - default: - return isl_lp_error; - } + return isl_tab_solve_lp(bmap, max, f, d, opt, opt_denom, sol); } enum isl_lp_result isl_basic_set_solve_lp(struct isl_basic_set *bset, int max, diff -Nru isl-0.12.2/isl_lp_no_piplib.c isl-0.15/isl_lp_no_piplib.c --- isl-0.12.2/isl_lp_no_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_lp_no_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -/* - * 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 - */ - -#include "isl_lp_piplib.h" - -enum isl_lp_result isl_pip_solve_lp(struct isl_basic_map *bmap, int maximize, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **sol) -{ - return isl_lp_error; -} diff -Nru isl-0.12.2/isl_lp_piplib.c isl-0.15/isl_lp_piplib.c --- isl-0.12.2/isl_lp_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_lp_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include "isl_piplib.h" -#include "isl_map_piplib.h" - -static void copy_solution(struct isl_vec *vec, int maximize, isl_int *opt, - isl_int *opt_denom, PipQuast *sol) -{ - int i; - PipList *list; - isl_int tmp; - - if (opt) { - if (opt_denom) { - isl_seq_cpy_from_pip(opt, - &sol->list->vector->the_vector[0], 1); - isl_seq_cpy_from_pip(opt_denom, - &sol->list->vector->the_deno[0], 1); - } else if (maximize) - mpz_fdiv_q(*opt, sol->list->vector->the_vector[0], - sol->list->vector->the_deno[0]); - else - mpz_cdiv_q(*opt, sol->list->vector->the_vector[0], - sol->list->vector->the_deno[0]); - } - - if (!vec) - return; - - isl_int_init(tmp); - isl_int_set_si(vec->el[0], 1); - for (i = 0, list = sol->list->next; list; ++i, list = list->next) { - isl_seq_cpy_from_pip(&vec->el[1 + i], - &list->vector->the_deno[0], 1); - isl_int_lcm(vec->el[0], vec->el[0], vec->el[1 + i]); - } - for (i = 0, list = sol->list->next; list; ++i, list = list->next) { - isl_seq_cpy_from_pip(&tmp, &list->vector->the_deno[0], 1); - isl_int_divexact(tmp, vec->el[0], tmp); - isl_seq_cpy_from_pip(&vec->el[1 + i], - &list->vector->the_vector[0], 1); - isl_int_mul(vec->el[1 + i], vec->el[1 + i], tmp); - } - isl_int_clear(tmp); -} - -enum isl_lp_result isl_pip_solve_lp(struct isl_basic_map *bmap, int maximize, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **vec) -{ - enum isl_lp_result res = isl_lp_ok; - PipMatrix *domain = NULL; - PipOptions *options; - PipQuast *sol; - unsigned total; - - total = isl_basic_map_total_dim(bmap); - domain = isl_basic_map_to_pip(bmap, 0, 1, 0); - if (!domain) - goto error; - entier_set_si(domain->p[0][1], -1); - isl_int_set(domain->p[0][domain->NbColumns - 1], f[0]); - isl_seq_cpy_to_pip(domain->p[0]+2, f+1, total); - - options = pip_options_init(); - if (!options) - goto error; - options->Urs_unknowns = -1; - options->Maximize = maximize; - options->Nq = 0; - sol = pip_solve(domain, NULL, -1, options); - pip_options_free(options); - if (!sol) - goto error; - - if (vec) { - isl_ctx *ctx = isl_basic_map_get_ctx(bmap); - *vec = isl_vec_alloc(ctx, 1 + total); - } - if (vec && !*vec) - res = isl_lp_error; - else if (!sol->list) - res = isl_lp_empty; - else if (entier_zero_p(sol->list->vector->the_deno[0])) - res = isl_lp_unbounded; - else - copy_solution(*vec, maximize, opt, opt_denom, sol); - pip_matrix_free(domain); - pip_quast_free(sol); - return res; -error: - if (domain) - pip_matrix_free(domain); - return isl_lp_error; -} diff -Nru isl-0.12.2/isl_lp_piplib.h isl-0.15/isl_lp_piplib.h --- isl-0.12.2/isl_lp_piplib.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_lp_piplib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -/* - * 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_LP_PIPLIB_H -#define ISL_LP_PIPLIB_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -enum isl_lp_result isl_pip_solve_lp(struct isl_basic_map *bmap, int maximize, - isl_int *f, isl_int denom, isl_int *opt, - isl_int *opt_denom, - struct isl_vec **sol); - -#if defined(__cplusplus) -} -#endif - -#endif diff -Nru isl-0.12.2/isl_lp_private.h isl-0.15/isl_lp_private.h --- isl-0.12.2/isl_lp_private.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_lp_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,21 @@ +#ifndef ISL_LP_PRIVATE_H +#define ISL_LP_PRIVATE_H + +#include +#include +#include + +enum isl_lp_result isl_basic_map_solve_lp(__isl_keep isl_basic_map *bmap, + int max, isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); +enum isl_lp_result isl_basic_set_solve_lp(__isl_keep isl_basic_set *bset, + int max, isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); +enum isl_lp_result isl_map_solve_lp(__isl_keep isl_map *map, int max, + isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); +enum isl_lp_result isl_set_solve_lp(__isl_keep isl_set *set, int max, + isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, + __isl_give isl_vec **sol); + +#endif diff -Nru isl-0.12.2/isl_map.c isl-0.15/isl_map.c --- isl-0.12.2/isl_map.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_map.c 2015-06-10 18:25:33.000000000 +0000 @@ -1,7 +1,8 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2010 INRIA Saclay - * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * @@ -10,30 +11,36 @@ * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include #include #include -#include +#include +#include #include "isl_space_private.h" #include "isl_equalities.h" -#include -#include +#include +#include #include #include -#include "isl_map_piplib.h" #include #include "isl_sample.h" +#include #include "isl_tab.h" #include #include +#include #include #include #include #include #include #include +#include +#include static unsigned n(__isl_keep isl_space *dim, enum isl_dim_type type) { @@ -188,7 +195,8 @@ m = isl_space_match(map->dim, isl_dim_param, set->dim, isl_dim_param); if (m < 0 || !m) return m; - return isl_space_tuple_match(map->dim, isl_dim_in, set->dim, isl_dim_set); + return isl_space_tuple_is_equal(map->dim, isl_dim_in, + set->dim, isl_dim_set); } int isl_basic_map_compatible_domain(struct isl_basic_map *bmap, @@ -200,7 +208,8 @@ m = isl_space_match(bmap->dim, isl_dim_param, bset->dim, isl_dim_param); if (m < 0 || !m) return m; - return isl_space_tuple_match(bmap->dim, isl_dim_in, bset->dim, isl_dim_set); + return isl_space_tuple_is_equal(bmap->dim, isl_dim_in, + bset->dim, isl_dim_set); } int isl_map_compatible_range(__isl_keep isl_map *map, __isl_keep isl_set *set) @@ -211,7 +220,8 @@ m = isl_space_match(map->dim, isl_dim_param, set->dim, isl_dim_param); if (m < 0 || !m) return m; - return isl_space_tuple_match(map->dim, isl_dim_out, set->dim, isl_dim_set); + return isl_space_tuple_is_equal(map->dim, isl_dim_out, + set->dim, isl_dim_set); } int isl_basic_map_compatible_range(struct isl_basic_map *bmap, @@ -223,7 +233,8 @@ m = isl_space_match(bmap->dim, isl_dim_param, bset->dim, isl_dim_param); if (m < 0 || !m) return m; - return isl_space_tuple_match(bmap->dim, isl_dim_out, bset->dim, isl_dim_set); + return isl_space_tuple_is_equal(bmap->dim, isl_dim_out, + bset->dim, isl_dim_set); } isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap) @@ -416,11 +427,38 @@ return NULL; } +/* Replace the identifier of the tuple of type "type" by "id". + */ +__isl_give isl_basic_map *isl_basic_map_set_tuple_id( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, __isl_take isl_id *id) +{ + bmap = isl_basic_map_cow(bmap); + if (!bmap) + goto error; + bmap->dim = isl_space_set_tuple_id(bmap->dim, type, id); + if (!bmap->dim) + return isl_basic_map_free(bmap); + bmap = isl_basic_map_finalize(bmap); + return bmap; +error: + isl_id_free(id); + return NULL; +} + +/* Replace the identifier of the tuple by "id". + */ +__isl_give isl_basic_set *isl_basic_set_set_tuple_id( + __isl_take isl_basic_set *bset, __isl_take isl_id *id) +{ + return isl_basic_map_set_tuple_id(bset, isl_dim_set, id); +} + /* Does the input or output tuple have a name? */ -int isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type) +isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type) { - return map ? isl_space_has_tuple_name(map->dim, type) : -1; + return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error; } const char *isl_map_get_tuple_name(__isl_keep isl_map *map, @@ -440,11 +478,14 @@ { map = isl_map_cow(map); if (!map) - return isl_id_free(id); + goto error; map->dim = isl_space_set_tuple_id(map->dim, type, id); return isl_map_reset_space(map, isl_space_copy(map->dim)); +error: + isl_id_free(id); + return NULL; } __isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set, @@ -470,9 +511,9 @@ return isl_map_reset_tuple_id(set, isl_dim_set); } -int isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type) +isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type) { - return map ? isl_space_has_tuple_id(map->dim, type) : -1; + return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error; } __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map, @@ -481,7 +522,7 @@ return map ? isl_space_get_tuple_id(map->dim, type) : NULL; } -int isl_set_has_tuple_id(__isl_keep isl_set *set) +isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set) { return isl_map_has_tuple_id(set, isl_dim_set); } @@ -493,9 +534,11 @@ /* Does the set tuple have a name? */ -int isl_set_has_tuple_name(__isl_keep isl_set *set) +isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set) { - return set ? isl_space_has_tuple_name(set->dim, isl_dim_set) : -1; + if (!set) + return isl_bool_error; + return isl_space_has_tuple_name(set->dim, isl_dim_set); } @@ -523,10 +566,12 @@ /* Does the given dimension have a name? */ -int isl_map_has_dim_name(__isl_keep isl_map *map, +isl_bool isl_map_has_dim_name(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos) { - return map ? isl_space_has_dim_name(map->dim, type, pos) : -1; + if (!map) + return isl_bool_error; + return isl_space_has_dim_name(map->dim, type, pos); } const char *isl_map_get_dim_name(__isl_keep isl_map *map, @@ -543,10 +588,12 @@ /* Does the given dimension have a name? */ -int isl_set_has_dim_name(__isl_keep isl_set *set, +isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos) { - return set ? isl_space_has_dim_name(set->dim, type, pos) : -1; + if (!set) + return isl_bool_error; + return isl_space_has_dim_name(set->dim, type, pos); } __isl_give isl_basic_map *isl_basic_map_set_dim_name( @@ -604,10 +651,12 @@ return (isl_set *)isl_map_set_dim_name((isl_map *)set, type, pos, s); } -int isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos) { - return bmap ? isl_space_has_dim_id(bmap->dim, type, pos) : -1; + if (!bmap) + return isl_bool_error; + return isl_space_has_dim_id(bmap->dim, type, pos); } __isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset, @@ -616,10 +665,10 @@ return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL; } -int isl_map_has_dim_id(__isl_keep isl_map *map, +isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos) { - return map ? isl_space_has_dim_id(map->dim, type, pos) : -1; + return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error; } __isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map, @@ -628,7 +677,7 @@ return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL; } -int isl_set_has_dim_id(__isl_keep isl_set *set, +isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos) { return isl_map_has_dim_id(set, type, pos); @@ -645,11 +694,14 @@ { map = isl_map_cow(map); if (!map) - return isl_id_free(id); + goto error; map->dim = isl_space_set_dim_id(map->dim, type, pos, id); return isl_map_reset_space(map, isl_space_copy(map->dim)); +error: + isl_id_free(id); + return NULL; } __isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set, @@ -672,6 +724,18 @@ return isl_map_find_dim_by_id(set, type, id); } +/* Return the position of the dimension of the given type and name + * in "bmap". + * Return -1 if no such dimension can be found. + */ +int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, const char *name) +{ + if (!bmap) + return -1; + return isl_space_find_dim_by_name(bmap->dim, type, name); +} + int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type, const char *name) { @@ -686,6 +750,28 @@ return isl_map_find_dim_by_name(set, type, name); } +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "map". + */ +__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map) +{ + isl_space *space; + + space = isl_map_get_space(map); + space = isl_space_reset_user(space); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "set". + */ +__isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set) +{ + return isl_map_reset_user(set); +} + int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap) { if (!bmap) @@ -779,10 +865,10 @@ /* Is this set a parameter domain? */ -int isl_set_is_params(__isl_keep isl_set *set) +isl_bool isl_set_is_params(__isl_keep isl_set *set) { if (!set) - return -1; + return isl_bool_error; return isl_space_is_params(set->dim); } @@ -1004,7 +1090,7 @@ return map; } -void *isl_basic_map_free(__isl_take isl_basic_map *bmap) +__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap) { if (!bmap) return NULL; @@ -1024,7 +1110,7 @@ return NULL; } -void *isl_basic_set_free(struct isl_basic_set *bset) +__isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset) { return isl_basic_map_free((struct isl_basic_map *)bset); } @@ -1056,20 +1142,20 @@ return NULL; } -int isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1, +isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1, __isl_keep isl_map *map2, - int (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2)) + isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2)) { - int r; + isl_bool r; if (!map1 || !map2) - return -1; + return isl_bool_error; if (isl_space_match(map1->dim, isl_dim_param, map2->dim, isl_dim_param)) return fn(map1, map2); if (!isl_space_has_named_params(map1->dim) || !isl_space_has_named_params(map2->dim)) isl_die(map1->ctx, isl_error_invalid, - "unaligned unnamed parameters", return -1); + "unaligned unnamed parameters", return isl_bool_error); map1 = isl_map_copy(map1); map2 = isl_map_copy(map2); map1 = isl_map_align_params(map1, isl_map_get_space(map2)); @@ -1549,8 +1635,10 @@ bmap->ref--; bmap = isl_basic_map_dup(bmap); } - if (bmap) + if (bmap) { ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL); + ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS); + } return bmap; } @@ -1629,25 +1717,6 @@ return NULL; } -static __isl_give isl_basic_set *isl_basic_set_swap_vars( - __isl_take isl_basic_set *bset, unsigned n) -{ - unsigned dim; - unsigned nparam; - - if (!bset) - return NULL; - - nparam = isl_basic_set_n_param(bset); - dim = isl_basic_set_n_dim(bset); - isl_assert(bset->ctx, n <= dim, goto error); - - return isl_basic_map_swap_vars(bset, 1 + nparam, n, dim - n); -error: - isl_basic_set_free(bset); - return NULL; -} - struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap) { int i = 0; @@ -1929,6 +1998,7 @@ if (!lb && !ub) return bmap; + bmap = isl_basic_map_cow(bmap); bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub); if (lb) { int k = isl_basic_map_alloc_inequality(bmap); @@ -1955,6 +2025,7 @@ isl_int_set_si(bmap->ineq[k][1 + total + div], -1); } + ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED); return bmap; error: isl_basic_map_free(bmap); @@ -2127,64 +2198,64 @@ * in a div definition, they also appear in the defining constraints of that * div. */ -int isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned first, unsigned n) { int i; if (!bmap) - return -1; + return isl_bool_error; if (first + n > isl_basic_map_dim(bmap, type)) isl_die(bmap->ctx, isl_error_invalid, - "index out of bounds", return -1); + "index out of bounds", return isl_bool_error); first += isl_basic_map_offset(bmap, type); for (i = 0; i < bmap->n_eq; ++i) if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0) - return 1; + return isl_bool_true; for (i = 0; i < bmap->n_ineq; ++i) if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0) - return 1; + return isl_bool_true; for (i = 0; i < bmap->n_div; ++i) { if (isl_int_is_zero(bmap->div[i][0])) continue; if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0) - return 1; + return isl_bool_true; } - return 0; + return isl_bool_false; } -int isl_map_involves_dims(__isl_keep isl_map *map, +isl_bool isl_map_involves_dims(__isl_keep isl_map *map, enum isl_dim_type type, unsigned first, unsigned n) { int i; if (!map) - return -1; + return isl_bool_error; if (first + n > isl_map_dim(map, type)) isl_die(map->ctx, isl_error_invalid, - "index out of bounds", return -1); + "index out of bounds", return isl_bool_error); for (i = 0; i < map->n; ++i) { - int involves = isl_basic_map_involves_dims(map->p[i], + isl_bool involves = isl_basic_map_involves_dims(map->p[i], type, first, n); if (involves < 0 || involves) return involves; } - return 0; + return isl_bool_false; } -int isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, +isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned first, unsigned n) { return isl_basic_map_involves_dims(bset, type, first, n); } -int isl_set_involves_dims(__isl_keep isl_set *set, +isl_bool isl_set_involves_dims(__isl_keep isl_set *set, enum isl_dim_type type, unsigned first, unsigned n) { return isl_map_involves_dims(set, type, first, n); @@ -2595,7 +2666,7 @@ (struct isl_basic_map *)bset); } -void *isl_set_free(__isl_take isl_set *set) +__isl_null isl_set *isl_set_free(__isl_take isl_set *set) { int i; @@ -2722,18 +2793,19 @@ return NULL; } -int isl_basic_map_contains(struct isl_basic_map *bmap, struct isl_vec *vec) +isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap, + __isl_keep isl_vec *vec) { int i; unsigned total; isl_int s; if (!bmap || !vec) - return -1; + return isl_bool_error; total = 1 + isl_basic_map_total_dim(bmap); if (total != vec->size) - return -1; + return isl_bool_error; isl_int_init(s); @@ -2741,7 +2813,7 @@ isl_seq_inner_product(vec->el, bmap->eq[i], total, &s); if (!isl_int_is_zero(s)) { isl_int_clear(s); - return 0; + return isl_bool_false; } } @@ -2749,16 +2821,17 @@ isl_seq_inner_product(vec->el, bmap->ineq[i], total, &s); if (isl_int_is_neg(s)) { isl_int_clear(s); - return 0; + return isl_bool_false; } } isl_int_clear(s); - return 1; + return isl_bool_true; } -int isl_basic_set_contains(struct isl_basic_set *bset, struct isl_vec *vec) +isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset, + __isl_keep isl_vec *vec) { return isl_basic_map_contains((struct isl_basic_map *)bset, vec); } @@ -3002,20 +3075,20 @@ struct isl_basic_map *isl_basic_map_reverse(struct isl_basic_map *bmap) { - isl_space *dim; - struct isl_basic_set *bset; - unsigned in; + isl_space *space; + unsigned pos, n1, n2; if (!bmap) return NULL; bmap = isl_basic_map_cow(bmap); if (!bmap) return NULL; - dim = isl_space_reverse(isl_space_copy(bmap->dim)); - in = isl_basic_map_n_in(bmap); - bset = isl_basic_set_from_basic_map(bmap); - bset = isl_basic_set_swap_vars(bset, in); - return isl_basic_map_from_basic_set(bset, dim); + space = isl_space_reverse(isl_space_copy(bmap->dim)); + pos = isl_basic_map_offset(bmap, isl_dim_in); + n1 = isl_basic_map_dim(bmap, isl_dim_in); + n2 = isl_basic_map_dim(bmap, isl_dim_out); + bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2); + return isl_basic_map_reset_space(bmap, space); } static __isl_give isl_basic_map *basic_map_space_reset( @@ -3089,7 +3162,7 @@ return isl_basic_map_insert_dims(bset, type, pos, n); } -__isl_give isl_basic_map *isl_basic_map_add(__isl_take isl_basic_map *bmap, +__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned n) { if (!bmap) @@ -3104,7 +3177,7 @@ if (!bset) return NULL; isl_assert(bset->ctx, type != isl_dim_in, goto error); - return (isl_basic_set *)isl_basic_map_add((isl_basic_map *)bset, type, n); + return isl_basic_map_add_dims(bset, type, n); error: isl_basic_set_free(bset); return NULL; @@ -3543,7 +3616,7 @@ bmap2->dim, isl_dim_param)) isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid, "parameters don't match", goto error); - if (!isl_space_tuple_match(bmap1->dim, isl_dim_out, + if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_out, bmap2->dim, isl_dim_in)) isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid, "spaces don't match", goto error); @@ -4280,25 +4353,6 @@ return NULL; } -struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap) -{ - if (!bmap) - goto error; - if (bmap->dim->n_in == 0) - return (struct isl_basic_set *)bmap; - bmap = isl_basic_map_cow(bmap); - if (!bmap) - goto error; - bmap->dim = isl_space_as_set_space(bmap->dim); - if (!bmap->dim) - goto error; - bmap = isl_basic_map_finalize(bmap); - return (struct isl_basic_set *)bmap; -error: - isl_basic_map_free(bmap); - return NULL; -} - /* For a div d = floor(f/m), add the constraint * * f - m d >= 0 @@ -4374,6 +4428,38 @@ bmap->div[div]); } +/* For each known div d = floor(f/m), add the constraints + * + * f - m d >= 0 + * -(f-(n-1)) + m d >= 0 + */ +__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints( + __isl_take isl_basic_map *bmap) +{ + int i; + unsigned n_div; + + if (!bmap) + return NULL; + n_div = isl_basic_map_dim(bmap, isl_dim_div); + if (n_div == 0) + return bmap; + bmap = isl_basic_map_cow(bmap); + bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div); + if (!bmap) + return NULL; + for (i = 0; i < n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_basic_map_add_div_constraints(bmap, i) < 0) + return isl_basic_map_free(bmap); + } + + bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL, 0); + bmap = isl_basic_map_finalize(bmap); + return bmap; +} + /* Add the div constraint of sign "sign" for div "div" of "bmap". * * In particular, if this div is of the form d = floor(f/m), @@ -4441,6 +4527,30 @@ return isl_basic_map_underlying_set((isl_basic_map *)bset); } +/* Replace each element in "list" by the result of applying + * isl_basic_map_underlying_set to the element. + */ +__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set( + __isl_take isl_basic_map_list *list) +{ + int i, n; + + if (!list) + return NULL; + + n = isl_basic_map_list_n_basic_map(list); + for (i = 0; i < n; ++i) { + isl_basic_map *bmap; + isl_basic_set *bset; + + bmap = isl_basic_map_list_get_basic_map(list, i); + bset = isl_basic_set_underlying_set(bmap); + list = isl_basic_set_list_set_basic_set(list, i, bset); + } + + return list; +} + struct isl_basic_map *isl_basic_map_overlying_set( struct isl_basic_set *bset, struct isl_basic_map *like) { @@ -4491,16 +4601,7 @@ isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal); isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal); } - bmap = isl_basic_map_extend_constraints(bmap, - 0, 2 * like->n_div); - for (i = 0; i < like->n_div; ++i) { - if (!bmap) - break; - if (isl_int_is_zero(bmap->div[i][0])) - continue; - if (isl_basic_map_add_div_constraints(bmap, i) < 0) - bmap = isl_basic_map_free(bmap); - } + bmap = isl_basic_map_add_known_div_constraints(bmap); } isl_basic_map_free(like); bmap = isl_basic_map_simplify(bmap); @@ -4727,23 +4828,17 @@ struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap) { - isl_space *dim; - struct isl_basic_set *domain; - unsigned n_in; + isl_space *space; unsigned n_out; if (!bmap) return NULL; - dim = isl_space_domain(isl_basic_map_get_space(bmap)); + space = isl_space_domain(isl_basic_map_get_space(bmap)); - n_in = isl_basic_map_n_in(bmap); n_out = isl_basic_map_n_out(bmap); - domain = isl_basic_set_from_basic_map(bmap); - domain = isl_basic_set_project_out(domain, isl_dim_set, n_in, n_out); - - domain = isl_basic_set_reset_space(domain, dim); + bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out); - return domain; + return isl_basic_map_reset_space(bmap, space); } int isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap) @@ -4901,15 +4996,12 @@ __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map) { int i; - isl_space *domain_dim; map = isl_map_cow(map); if (!map) return NULL; - domain_dim = isl_space_from_range(isl_space_domain(isl_map_get_space(map))); - map->dim = isl_space_from_domain(isl_space_wrap(map->dim)); - map->dim = isl_space_join(map->dim, domain_dim); + map->dim = isl_space_domain_map(map->dim); if (!map->dim) goto error; for (i = 0; i < map->n; ++i) { @@ -4953,6 +5045,26 @@ return NULL; } +/* Given a wrapped map of the form A[B -> C], + * return the map A[B -> C] -> B. + */ +__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set) +{ + isl_id *id; + isl_map *map; + + if (!set) + return NULL; + if (!isl_set_has_tuple_id(set)) + return isl_map_domain_map(isl_set_unwrap(set)); + + id = isl_set_get_tuple_id(set); + map = isl_map_domain_map(isl_set_unwrap(set)); + map = isl_map_set_tuple_id(map, isl_dim_in, id); + + return map; +} + __isl_give isl_map *isl_map_from_set(__isl_take isl_set *set, __isl_take isl_space *dim) { @@ -4995,7 +5107,11 @@ return (isl_basic_map *)bset; } -struct isl_map *isl_map_from_range(struct isl_set *set) +/* Create a relation with the given set as range. + * The domain of the created relation is a zero-dimensional + * flat anonymous space. + */ +__isl_give isl_map *isl_map_from_range(__isl_take isl_set *set) { isl_space *space; space = isl_set_get_space(set); @@ -5004,6 +5120,10 @@ return (struct isl_map *)set; } +/* Create a relation with the given set as domain. + * The range of the created relation is a zero-dimensional + * flat anonymous space. + */ __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set) { return isl_map_reverse(isl_map_from_range(set)); @@ -5021,31 +5141,6 @@ return isl_map_apply_range(isl_map_reverse(domain), range); } -struct isl_set *isl_set_from_map(struct isl_map *map) -{ - int i; - struct isl_set *set = NULL; - - if (!map) - return NULL; - map = isl_map_cow(map); - if (!map) - return NULL; - map->dim = isl_space_as_set_space(map->dim); - if (!map->dim) - goto error; - set = (struct isl_set *)map; - for (i = 0; i < map->n; ++i) { - set->p[i] = isl_basic_set_from_basic_map(map->p[i]); - if (!set->p[i]) - goto error; - } - return set; -error: - isl_map_free(map); - return NULL; -} - __isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *dim, int n, unsigned flags) { @@ -5106,36 +5201,6 @@ return bset; } -struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model) -{ - struct isl_basic_map *bmap; - if (!model) - return NULL; - bmap = isl_basic_map_alloc_space(isl_space_copy(model->dim), 0, 1, 0); - bmap = isl_basic_map_set_to_empty(bmap); - return bmap; -} - -struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model) -{ - struct isl_basic_map *bmap; - if (!model) - return NULL; - bmap = isl_basic_map_alloc_space(isl_space_copy(model->dim), 0, 1, 0); - bmap = isl_basic_map_set_to_empty(bmap); - return bmap; -} - -struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *model) -{ - struct isl_basic_set *bset; - if (!model) - return NULL; - bset = isl_basic_set_alloc_space(isl_space_copy(model->dim), 0, 1, 0); - bset = isl_basic_set_set_to_empty(bset); - return bset; -} - __isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *dim) { struct isl_basic_map *bmap; @@ -5187,60 +5252,16 @@ return isl_map_nat_universe(dim); } -__isl_give isl_basic_map *isl_basic_map_universe_like( - __isl_keep isl_basic_map *model) -{ - if (!model) - return NULL; - return isl_basic_map_alloc_space(isl_space_copy(model->dim), 0, 0, 0); -} - -struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *model) -{ - if (!model) - return NULL; - return isl_basic_set_alloc_space(isl_space_copy(model->dim), 0, 0, 0); -} - -__isl_give isl_basic_set *isl_basic_set_universe_like_set( - __isl_keep isl_set *model) -{ - if (!model) - return NULL; - return isl_basic_set_alloc_space(isl_space_copy(model->dim), 0, 0, 0); -} - __isl_give isl_map *isl_map_empty(__isl_take isl_space *dim) { return isl_map_alloc_space(dim, 0, ISL_MAP_DISJOINT); } -struct isl_map *isl_map_empty_like(struct isl_map *model) -{ - if (!model) - return NULL; - return isl_map_alloc_space(isl_space_copy(model->dim), 0, ISL_MAP_DISJOINT); -} - -struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model) -{ - if (!model) - return NULL; - return isl_map_alloc_space(isl_space_copy(model->dim), 0, ISL_MAP_DISJOINT); -} - __isl_give isl_set *isl_set_empty(__isl_take isl_space *dim) { return isl_set_alloc_space(dim, 0, ISL_MAP_DISJOINT); } -struct isl_set *isl_set_empty_like(struct isl_set *model) -{ - if (!model) - return NULL; - return isl_set_empty(isl_space_copy(model->dim)); -} - __isl_give isl_map *isl_map_universe(__isl_take isl_space *dim) { struct isl_map *map; @@ -5261,13 +5282,6 @@ return set; } -__isl_give isl_set *isl_set_universe_like(__isl_keep isl_set *model) -{ - if (!model) - return NULL; - return isl_set_universe(isl_space_copy(model->dim)); -} - struct isl_map *isl_map_dup(struct isl_map *map) { int i; @@ -5304,7 +5318,7 @@ return NULL; } -void *isl_map_free(struct isl_map *map) +__isl_null isl_map *isl_map_free(__isl_take isl_map *map) { int i; @@ -5323,37 +5337,6 @@ return NULL; } -struct isl_map *isl_map_extend(struct isl_map *base, - unsigned nparam, unsigned n_in, unsigned n_out) -{ - int i; - - base = isl_map_cow(base); - if (!base) - return NULL; - - base->dim = isl_space_extend(base->dim, nparam, n_in, n_out); - if (!base->dim) - goto error; - for (i = 0; i < base->n; ++i) { - base->p[i] = isl_basic_map_extend_space(base->p[i], - isl_space_copy(base->dim), 0, 0, 0); - if (!base->p[i]) - goto error; - } - return base; -error: - isl_map_free(base); - return NULL; -} - -struct isl_set *isl_set_extend(struct isl_set *base, - unsigned nparam, unsigned dim) -{ - return (struct isl_set *)isl_map_extend((struct isl_map *)base, - nparam, 0, dim); -} - static struct isl_basic_map *isl_basic_map_fix_pos_si( struct isl_basic_map *bmap, unsigned pos, int value) { @@ -5934,18 +5917,7 @@ struct isl_basic_map *bmap, struct isl_basic_set *dom, struct isl_set **empty, int max) { - if (!bmap) - goto error; - if (bmap->ctx->opt->pip == ISL_PIP_PIP) - return isl_pip_basic_map_lexopt(bmap, dom, empty, max); - else - return isl_tab_basic_map_partial_lexopt(bmap, dom, empty, max); -error: - isl_basic_map_free(bmap); - isl_basic_set_free(dom); - if (empty) - *empty = NULL; - return NULL; + return isl_tab_basic_map_partial_lexopt(bmap, dom, empty, max); } struct isl_map *isl_basic_map_partial_lexmax( @@ -6405,7 +6377,6 @@ if (map->n == 0) { isl_space *dim = isl_map_get_space(map); - dim = isl_space_domain(isl_space_from_range(dim)); isl_map_free(map); return isl_pw_aff_empty(dim); } @@ -7054,6 +7025,10 @@ if (!map1 || !map2) goto error; + if (!isl_space_is_equal(map1->dim, map2->dim)) + isl_die(isl_map_get_ctx(map1), isl_error_invalid, + "spaces don't match", goto error); + if (map1->n == 0) { isl_map_free(map1); return map2; @@ -7079,8 +7054,6 @@ return map2; } - isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error); - if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) && ISL_F_ISSET(map2, ISL_MAP_DISJOINT)) ISL_FL_SET(flags, ISL_MAP_DISJOINT); @@ -7111,20 +7084,66 @@ return NULL; } +/* Return the union of "map1" and "map2", where "map1" and "map2" are + * guaranteed to be disjoint by the caller. + * + * Note that this functions is called from within isl_map_make_disjoint, + * so we have to be careful not to touch the constraints of the inputs + * in any way. + */ __isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1, __isl_take isl_map *map2) { return isl_map_align_params_map_map_and(map1, map2, &map_union_disjoint); } -struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2) +/* Return the union of "map1" and "map2", where "map1" and "map2" may + * not be disjoint. The parameters are assumed to have been aligned. + * + * We currently simply call map_union_disjoint, the internal operation + * of which does not really depend on the inputs being disjoint. + * If the result contains more than one basic map, then we clear + * the disjoint flag since the result may contain basic maps from + * both inputs and these are not guaranteed to be disjoint. + * + * As a special case, if "map1" and "map2" are obviously equal, + * then we simply return "map1". + */ +static __isl_give isl_map *map_union_aligned(__isl_take isl_map *map1, + __isl_take isl_map *map2) { - map1 = isl_map_union_disjoint(map1, map2); + int equal; + + if (!map1 || !map2) + goto error; + + equal = isl_map_plain_is_equal(map1, map2); + if (equal < 0) + goto error; + if (equal) { + isl_map_free(map2); + return map1; + } + + map1 = map_union_disjoint(map1, map2); if (!map1) return NULL; if (map1->n > 1) ISL_F_CLR(map1, ISL_MAP_DISJOINT); return map1; +error: + isl_map_free(map1); + isl_map_free(map2); + return NULL; +} + +/* Return the union of "map1" and "map2", where "map1" and "map2" may + * not be disjoint. + */ +__isl_give isl_map *isl_map_union(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + return isl_map_align_params_map_map_and(map1, map2, &map_union_aligned); } struct isl_set *isl_set_union_disjoint( @@ -7294,7 +7313,7 @@ */ struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap) { - isl_space *dims, *target_dim; + isl_space *target_space; struct isl_basic_set *bset; unsigned dim; unsigned nparam; @@ -7302,32 +7321,28 @@ if (!bmap) goto error; - isl_assert(bmap->ctx, isl_space_tuple_match(bmap->dim, isl_dim_in, + isl_assert(bmap->ctx, isl_space_tuple_is_equal(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out), goto error); - target_dim = isl_space_domain(isl_basic_map_get_space(bmap)); + target_space = isl_space_domain(isl_basic_map_get_space(bmap)); dim = isl_basic_map_n_in(bmap); nparam = isl_basic_map_n_param(bmap); - bset = isl_basic_set_from_basic_map(bmap); - bset = isl_basic_set_cow(bset); - dims = isl_basic_set_get_space(bset); - dims = isl_space_add_dims(dims, isl_dim_set, dim); - bset = isl_basic_set_extend_space(bset, dims, 0, dim, 0); - bset = isl_basic_set_swap_vars(bset, 2*dim); + bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap)); + bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim); + bmap = isl_basic_map_extend_constraints(bmap, dim, 0); for (i = 0; i < dim; ++i) { - int j = isl_basic_map_alloc_equality( - (struct isl_basic_map *)bset); + int j = isl_basic_map_alloc_equality(bmap); if (j < 0) { - bset = isl_basic_set_free(bset); + bmap = isl_basic_map_free(bmap); break; } - isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset)); - isl_int_set_si(bset->eq[j][1+nparam+i], 1); - isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1); - isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1); + isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap)); + isl_int_set_si(bmap->eq[j][1+nparam+i], 1); + isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1); + isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1); } - bset = isl_basic_set_project_out(bset, isl_dim_set, dim, 2*dim); - bset = isl_basic_set_reset_space(bset, target_dim); + bset = isl_basic_map_domain(bmap); + bset = isl_basic_set_reset_space(bset, target_space); return bset; error: isl_basic_map_free(bmap); @@ -7346,7 +7361,7 @@ if (!map) return NULL; - isl_assert(map->ctx, isl_space_tuple_match(map->dim, isl_dim_in, + isl_assert(map->ctx, isl_space_tuple_is_equal(map->dim, isl_dim_in, map->dim, isl_dim_out), goto error); dim = isl_map_get_space(map); @@ -7376,7 +7391,8 @@ int nparam, n; unsigned total; - if (!isl_space_tuple_match(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out)) + if (!isl_space_tuple_is_equal(bmap->dim, isl_dim_in, + bmap->dim, isl_dim_out)) isl_die(bmap->ctx, isl_error_invalid, "domain and range don't match", goto error); @@ -7420,7 +7436,8 @@ if (!map) return NULL; - if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out)) + if (!isl_space_tuple_is_equal(map->dim, isl_dim_in, + map->dim, isl_dim_out)) isl_die(map->ctx, isl_error_invalid, "domain and range don't match", goto error); @@ -7489,32 +7506,11 @@ return NULL; } -struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model) -{ - if (!model || !model->dim) - return NULL; - return isl_basic_map_identity(isl_space_copy(model->dim)); -} - __isl_give isl_map *isl_map_identity(__isl_take isl_space *dim) { return isl_map_from_basic_map(isl_basic_map_identity(dim)); } -struct isl_map *isl_map_identity_like(struct isl_map *model) -{ - if (!model || !model->dim) - return NULL; - return isl_map_identity(isl_space_copy(model->dim)); -} - -struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model) -{ - if (!model || !model->dim) - return NULL; - return isl_map_identity(isl_space_copy(model->dim)); -} - __isl_give isl_map *isl_set_identity(__isl_take isl_set *set) { isl_space *dim = isl_set_get_space(set); @@ -7600,6 +7596,7 @@ enum isl_dim_type type, unsigned first, unsigned n) { int i; + unsigned offset; isl_basic_set *nonneg; isl_basic_set *neg; @@ -7610,11 +7607,11 @@ isl_assert(set->ctx, first + n <= isl_set_dim(set, type), goto error); + offset = pos(set->dim, type); for (i = 0; i < n; ++i) { nonneg = nonneg_halfspace(isl_set_get_space(set), - pos(set->dim, type) + first + i); - neg = neg_halfspace(isl_set_get_space(set), - pos(set->dim, type) + first + i); + offset + first + i); + neg = neg_halfspace(isl_set_get_space(set), offset + first + i); set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg)); } @@ -7689,20 +7686,20 @@ return r; } -int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2) +isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2) { return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2); } -int isl_basic_map_is_subset( - struct isl_basic_map *bmap1, struct isl_basic_map *bmap2) +isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) { int is_subset; struct isl_map *map1; struct isl_map *map2; if (!bmap1 || !bmap2) - return -1; + return isl_bool_error; map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1)); map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2)); @@ -7715,71 +7712,61 @@ return is_subset; } -int isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1, +isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2) { return isl_basic_map_is_subset(bset1, bset2); } -int isl_basic_map_is_equal( - struct isl_basic_map *bmap1, struct isl_basic_map *bmap2) +isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) { - int is_subset; + isl_bool is_subset; if (!bmap1 || !bmap2) - return -1; + return isl_bool_error; is_subset = isl_basic_map_is_subset(bmap1, bmap2); - if (is_subset != 1) + if (is_subset != isl_bool_true) return is_subset; is_subset = isl_basic_map_is_subset(bmap2, bmap1); return is_subset; } -int isl_basic_set_is_equal( - struct isl_basic_set *bset1, struct isl_basic_set *bset2) +isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) { return isl_basic_map_is_equal( (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2); } -int isl_map_is_empty(struct isl_map *map) +isl_bool isl_map_is_empty(__isl_keep isl_map *map) { int i; int is_empty; if (!map) - return -1; + return isl_bool_error; for (i = 0; i < map->n; ++i) { is_empty = isl_basic_map_is_empty(map->p[i]); if (is_empty < 0) - return -1; + return isl_bool_error; if (!is_empty) - return 0; + return isl_bool_false; } - return 1; -} - -int isl_map_plain_is_empty(__isl_keep isl_map *map) -{ - return map ? map->n == 0 : -1; -} - -int isl_map_fast_is_empty(__isl_keep isl_map *map) -{ - return isl_map_plain_is_empty(map); + return isl_bool_true; } -int isl_set_plain_is_empty(struct isl_set *set) +isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map) { - return set ? set->n == 0 : -1; + return map ? map->n == 0 : isl_bool_error; } -int isl_set_fast_is_empty(__isl_keep isl_set *set) +isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set) { - return isl_set_plain_is_empty(set); + return set ? set->n == 0 : isl_bool_error; } -int isl_set_is_empty(struct isl_set *set) +isl_bool isl_set_is_empty(__isl_keep isl_set *set) { return isl_map_is_empty((struct isl_map *)set); } @@ -7800,115 +7787,112 @@ return isl_space_is_equal(set1->dim, set2->dim); } -static int map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) { - int is_subset; + isl_bool is_subset; if (!map1 || !map2) - return -1; + return isl_bool_error; is_subset = isl_map_is_subset(map1, map2); - if (is_subset != 1) + if (is_subset != isl_bool_true) return is_subset; is_subset = isl_map_is_subset(map2, map1); return is_subset; } -int isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) { return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal); } -int isl_basic_map_is_strict_subset( +isl_bool isl_basic_map_is_strict_subset( struct isl_basic_map *bmap1, struct isl_basic_map *bmap2) { - int is_subset; + isl_bool is_subset; if (!bmap1 || !bmap2) - return -1; + return isl_bool_error; is_subset = isl_basic_map_is_subset(bmap1, bmap2); - if (is_subset != 1) + if (is_subset != isl_bool_true) return is_subset; is_subset = isl_basic_map_is_subset(bmap2, bmap1); - if (is_subset == -1) + if (is_subset == isl_bool_error) return is_subset; return !is_subset; } -int isl_map_is_strict_subset(struct isl_map *map1, struct isl_map *map2) +isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) { - int is_subset; + isl_bool is_subset; if (!map1 || !map2) - return -1; + return isl_bool_error; is_subset = isl_map_is_subset(map1, map2); - if (is_subset != 1) + if (is_subset != isl_bool_true) return is_subset; is_subset = isl_map_is_subset(map2, map1); - if (is_subset == -1) + if (is_subset == isl_bool_error) return is_subset; return !is_subset; } -int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) { return isl_map_is_strict_subset((isl_map *)set1, (isl_map *)set2); } -int isl_basic_map_is_universe(struct isl_basic_map *bmap) +isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap) { if (!bmap) - return -1; + return isl_bool_error; return bmap->n_eq == 0 && bmap->n_ineq == 0; } -int isl_basic_set_is_universe(struct isl_basic_set *bset) +isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset) { if (!bset) - return -1; + return isl_bool_error; return bset->n_eq == 0 && bset->n_ineq == 0; } -int isl_map_plain_is_universe(__isl_keep isl_map *map) +isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map) { int i; if (!map) - return -1; + return isl_bool_error; for (i = 0; i < map->n; ++i) { - int r = isl_basic_map_is_universe(map->p[i]); + isl_bool r = isl_basic_map_is_universe(map->p[i]); if (r < 0 || r) return r; } - return 0; + return isl_bool_false; } -int isl_set_plain_is_universe(__isl_keep isl_set *set) +isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set) { return isl_map_plain_is_universe((isl_map *) set); } -int isl_set_fast_is_universe(__isl_keep isl_set *set) -{ - return isl_set_plain_is_universe(set); -} - -int isl_basic_map_is_empty(struct isl_basic_map *bmap) +isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap) { struct isl_basic_set *bset = NULL; struct isl_vec *sample = NULL; - int empty; + isl_bool empty; unsigned total; if (!bmap) - return -1; + return isl_bool_error; if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) - return 1; + return isl_bool_true; if (isl_basic_map_is_universe(bmap)) - return 0; + return isl_bool_false; if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) { struct isl_basic_map *copy = isl_basic_map_copy(bmap); @@ -7922,18 +7906,18 @@ if (bmap->sample && bmap->sample->size == total) { int contains = isl_basic_map_contains(bmap, bmap->sample); if (contains < 0) - return -1; + return isl_bool_error; if (contains) - return 0; + return isl_bool_false; } isl_vec_free(bmap->sample); bmap->sample = NULL; bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap)); if (!bset) - return -1; + return isl_bool_error; sample = isl_basic_set_sample_vec(bset); if (!sample) - return -1; + return isl_bool_error; empty = sample->size == 0; isl_vec_free(bmap->sample); bmap->sample = sample; @@ -7943,31 +7927,21 @@ return empty; } -int isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap) +isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap) { if (!bmap) - return -1; + return isl_bool_error; return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY); } -int isl_basic_map_fast_is_empty(__isl_keep isl_basic_map *bmap) -{ - return isl_basic_map_plain_is_empty(bmap); -} - -int isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset) +isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset) { if (!bset) - return -1; + return isl_bool_error; return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY); } -int isl_basic_set_fast_is_empty(__isl_keep isl_basic_set *bset) -{ - return isl_basic_set_plain_is_empty(bset); -} - -int isl_basic_set_is_empty(struct isl_basic_set *bset) +isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset) { return isl_basic_map_is_empty((struct isl_basic_map *)bset); } @@ -8121,48 +8095,63 @@ return -1; } -struct isl_basic_map *isl_basic_map_align_divs( - struct isl_basic_map *dst, struct isl_basic_map *src) +/* Align the divs of "dst" to those of "src", adding divs from "src" + * if needed. That is, make sure that the first src->n_div divs + * of the result are equal to those of src. + * + * The result is not finalized as by design it will have redundant + * divs if any divs from "src" were copied. + */ +__isl_give isl_basic_map *isl_basic_map_align_divs( + __isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src) { int i; + int known, extended; unsigned total; if (!dst || !src) - goto error; + return isl_basic_map_free(dst); if (src->n_div == 0) return dst; - for (i = 0; i < src->n_div; ++i) - isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error); + known = isl_basic_map_divs_known(src); + if (known < 0) + return isl_basic_map_free(dst); + if (!known) + isl_die(isl_basic_map_get_ctx(src), isl_error_invalid, + "some src divs are unknown", + return isl_basic_map_free(dst)); src = isl_basic_map_order_divs(src); - dst = isl_basic_map_cow(dst); - if (!dst) - return NULL; - dst = isl_basic_map_extend_space(dst, isl_space_copy(dst->dim), - src->n_div, 0, 2 * src->n_div); - if (!dst) - return NULL; + + extended = 0; total = isl_space_dim(src->dim, isl_dim_all); for (i = 0; i < src->n_div; ++i) { int j = find_div(dst, src, i); if (j < 0) { + if (!extended) { + int extra = src->n_div - i; + dst = isl_basic_map_cow(dst); + if (!dst) + return NULL; + dst = isl_basic_map_extend_space(dst, + isl_space_copy(dst->dim), + extra, 0, 2 * extra); + extended = 1; + } j = isl_basic_map_alloc_div(dst); if (j < 0) - goto error; + return isl_basic_map_free(dst); isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i); isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i); if (isl_basic_map_add_div_constraints(dst, j) < 0) - goto error; + return isl_basic_map_free(dst); } if (j != i) isl_basic_map_swap_div(dst, i, j); } return dst; -error: - isl_basic_map_free(dst); - return NULL; } struct isl_basic_set *isl_basic_set_align_divs( @@ -8202,6 +8191,59 @@ return (struct isl_set *)isl_map_align_divs((struct isl_map *)set); } +/* Align the divs of the basic maps in "map" to those + * of the basic maps in "list", as well as to the other basic maps in "map". + * The elements in "list" are assumed to have known divs. + */ +__isl_give isl_map *isl_map_align_divs_to_basic_map_list( + __isl_take isl_map *map, __isl_keep isl_basic_map_list *list) +{ + int i, n; + + map = isl_map_compute_divs(map); + map = isl_map_cow(map); + if (!map || !list) + return isl_map_free(map); + if (map->n == 0) + return map; + + n = isl_basic_map_list_n_basic_map(list); + for (i = 0; i < n; ++i) { + isl_basic_map *bmap; + + bmap = isl_basic_map_list_get_basic_map(list, i); + map->p[0] = isl_basic_map_align_divs(map->p[0], bmap); + isl_basic_map_free(bmap); + } + if (!map->p[0]) + return isl_map_free(map); + + return isl_map_align_divs(map); +} + +/* Align the divs of each element of "list" to those of "bmap". + * Both "bmap" and the elements of "list" are assumed to have known divs. + */ +__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map( + __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap) +{ + int i, n; + + if (!list || !bmap) + return isl_basic_map_list_free(list); + + n = isl_basic_map_list_n_basic_map(list); + for (i = 0; i < n; ++i) { + isl_basic_map *bmap_i; + + bmap_i = isl_basic_map_list_get_basic_map(list, i); + bmap_i = isl_basic_map_align_divs(bmap_i, bmap); + list = isl_basic_map_list_set_basic_map(list, i, bmap_i); + } + + return list; +} + static __isl_give isl_set *set_apply( __isl_take isl_set *set, __isl_take isl_map *map) { @@ -8331,7 +8373,7 @@ bmap2->n_div, bmap2->n_eq, bmap2->n_ineq); bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos); if (!bmap1) - goto error; + goto error2; total = isl_basic_map_total_dim(bmap1); ctx = bmap1->ctx; obj = isl_vec_alloc(ctx, 1 + total); @@ -8621,12 +8663,6 @@ return isl_map_plain_is_fixed(set, type, pos, val); } -int isl_map_fast_is_fixed(__isl_keep isl_map *map, - enum isl_dim_type type, unsigned pos, isl_int *val) -{ - return isl_map_plain_is_fixed(map, type, pos, val); -} - /* Check if dimension dim has fixed value and if so and if val is not NULL, * then return this fixed value in *val. */ @@ -8646,12 +8682,6 @@ return isl_set_plain_has_fixed_var(set, isl_set_n_param(set) + dim, val); } -int isl_set_fast_dim_is_fixed(__isl_keep isl_set *set, - unsigned dim, isl_int *val) -{ - return isl_set_plain_dim_is_fixed(set, dim, val); -} - /* Check if input variable in has fixed value and if so and if val is not NULL, * then return this fixed value in *val. */ @@ -8738,57 +8768,41 @@ return fixed; } -struct constraint { - unsigned size; - isl_int *c; -}; - /* uset_gist depends on constraints without existentially quantified * variables sorting first. */ -static int qsort_constraint_cmp(const void *p1, const void *p2) +static int sort_constraint_cmp(const void *p1, const void *p2, void *arg) { - const struct constraint *c1 = (const struct constraint *)p1; - const struct constraint *c2 = (const struct constraint *)p2; + isl_int **c1 = (isl_int **) p1; + isl_int **c2 = (isl_int **) p2; int l1, l2; - unsigned size = isl_min(c1->size, c2->size); + unsigned size = *(unsigned *) arg; - l1 = isl_seq_last_non_zero(c1->c + 1, size); - l2 = isl_seq_last_non_zero(c2->c + 1, size); + l1 = isl_seq_last_non_zero(*c1 + 1, size); + l2 = isl_seq_last_non_zero(*c2 + 1, size); if (l1 != l2) return l1 - l2; - return isl_seq_cmp(c1->c + 1, c2->c + 1, size); + return isl_seq_cmp(*c1 + 1, *c2 + 1, size); } static struct isl_basic_map *isl_basic_map_sort_constraints( struct isl_basic_map *bmap) { - int i; - struct constraint *c; unsigned total; if (!bmap) return NULL; if (bmap->n_ineq == 0) return bmap; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED)) + return bmap; total = isl_basic_map_total_dim(bmap); - c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq); - if (!c) - goto error; - for (i = 0; i < bmap->n_ineq; ++i) { - c[i].size = total; - c[i].c = bmap->ineq[i]; - } - qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp); - for (i = 0; i < bmap->n_ineq; ++i) - bmap->ineq[i] = c[i].c; - free(c); + if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *), + &sort_constraint_cmp, &total) < 0) + return isl_basic_map_free(bmap); return bmap; -error: - isl_basic_map_free(bmap); - return NULL; } __isl_give isl_basic_set *isl_basic_set_sort_constraints( @@ -8823,6 +8837,9 @@ int i, cmp; unsigned total; + if (!bmap1 || !bmap2) + return -1; + if (bmap1 == bmap2) return 0; if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) != @@ -8890,13 +8907,15 @@ return 0; } -int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, +isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) { + if (!bmap1 || !bmap2) + return isl_bool_error; return isl_basic_map_plain_cmp(bmap1, bmap2) == 0; } -int isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1, +isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2) { return isl_basic_map_plain_is_equal((isl_basic_map *)bset1, @@ -8911,13 +8930,73 @@ return isl_basic_map_plain_cmp(bmap1, bmap2); } +/* Sort the basic maps of "map" and remove duplicate basic maps. + * + * While removing basic maps, we make sure that the basic maps remain + * sorted because isl_map_normalize expects the basic maps of the result + * to be sorted. + */ +static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map) +{ + int i, j; + + map = isl_map_remove_empty_parts(map); + if (!map) + return NULL; + qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp); + for (i = map->n - 1; i >= 1; --i) { + if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i])) + continue; + isl_basic_map_free(map->p[i-1]); + for (j = i; j < map->n; ++j) + map->p[j - 1] = map->p[j]; + map->n--; + } + + return map; +} + +/* Remove obvious duplicates among the basic maps of "map". + * + * Unlike isl_map_normalize, this function does not remove redundant + * constraints and only removes duplicates that have exactly the same + * constraints in the input. It does sort the constraints and + * the basic maps to ease the detection of duplicates. + * + * If "map" has already been normalized or if the basic maps are + * disjoint, then there can be no duplicates. + */ +__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map) +{ + int i; + isl_basic_map *bmap; + + if (!map) + return NULL; + if (map->n <= 1) + return map; + if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT)) + return map; + for (i = 0; i < map->n; ++i) { + bmap = isl_basic_map_copy(map->p[i]); + bmap = isl_basic_map_sort_constraints(bmap); + if (!bmap) + return isl_map_free(map); + isl_basic_map_free(map->p[i]); + map->p[i] = bmap; + } + + map = sort_and_remove_duplicates(map); + return map; +} + /* We normalize in place, but if anything goes wrong we need * to return NULL, so we need to make sure we don't change the * meaning of any possible other copies of map. */ -struct isl_map *isl_map_normalize(struct isl_map *map) +__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map) { - int i, j; + int i; struct isl_basic_map *bmap; if (!map) @@ -8931,24 +9010,14 @@ isl_basic_map_free(map->p[i]); map->p[i] = bmap; } - qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp); - ISL_F_SET(map, ISL_MAP_NORMALIZED); - map = isl_map_remove_empty_parts(map); - if (!map) - return NULL; - for (i = map->n - 1; i >= 1; --i) { - if (!isl_basic_map_plain_is_equal(map->p[i-1], map->p[i])) - continue; - isl_basic_map_free(map->p[i-1]); - for (j = i; j < map->n; ++j) - map->p[j-1] = map->p[j]; - map->n--; - } + + map = sort_and_remove_duplicates(map); + if (map) + ISL_F_SET(map, ISL_MAP_NORMALIZED); return map; error: isl_map_free(map); return NULL; - } struct isl_set *isl_set_normalize(struct isl_set *set) @@ -8956,18 +9025,19 @@ return (struct isl_set *)isl_map_normalize((struct isl_map *)set); } -int isl_map_plain_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) { int i; - int equal; + isl_bool equal; if (!map1 || !map2) - return -1; + return isl_bool_error; if (map1 == map2) - return 1; + return isl_bool_true; if (!isl_space_is_equal(map1->dim, map2->dim)) - return 0; + return isl_bool_false; map1 = isl_map_copy(map1); map2 = isl_map_copy(map2); @@ -8987,25 +9057,16 @@ error: isl_map_free(map1); isl_map_free(map2); - return -1; + return isl_bool_error; } -int isl_map_fast_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2) -{ - return isl_map_plain_is_equal(map1, map2); -} - -int isl_set_plain_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1, + __isl_keep isl_set *set2) { return isl_map_plain_is_equal((struct isl_map *)set1, (struct isl_map *)set2); } -int isl_set_fast_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2) -{ - return isl_set_plain_is_equal(set1, set2); -} - /* Return an interval that ranges from min to max (inclusive) */ struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx, @@ -9036,31 +9097,95 @@ return NULL; } -/* Return the Cartesian product of the basic sets in list (in the given order). +/* Return the basic maps in "map" as a list. */ -__isl_give isl_basic_set *isl_basic_set_list_product( - __isl_take struct isl_basic_set_list *list) +__isl_give isl_basic_map_list *isl_map_get_basic_map_list( + __isl_keep isl_map *map) { int i; - unsigned dim; - unsigned nparam; - unsigned extra; - unsigned n_eq; - unsigned n_ineq; - struct isl_basic_set *product = NULL; + isl_ctx *ctx; + isl_basic_map_list *list; - if (!list) - goto error; - isl_assert(list->ctx, list->n > 0, goto error); - isl_assert(list->ctx, list->p[0], goto error); - nparam = isl_basic_set_n_param(list->p[0]); - dim = isl_basic_set_n_dim(list->p[0]); - extra = list->p[0]->n_div; - n_eq = list->p[0]->n_eq; - n_ineq = list->p[0]->n_ineq; - for (i = 1; i < list->n; ++i) { - isl_assert(list->ctx, list->p[i], goto error); - isl_assert(list->ctx, + if (!map) + return NULL; + ctx = isl_map_get_ctx(map); + list = isl_basic_map_list_alloc(ctx, map->n); + + for (i = 0; i < map->n; ++i) { + isl_basic_map *bmap; + + bmap = isl_basic_map_copy(map->p[i]); + list = isl_basic_map_list_add(list, bmap); + } + + return list; +} + +/* Return the intersection of the elements in the non-empty list "list". + * All elements are assumed to live in the same space. + */ +__isl_give isl_basic_map *isl_basic_map_list_intersect( + __isl_take isl_basic_map_list *list) +{ + int i, n; + isl_basic_map *bmap; + + if (!list) + return NULL; + n = isl_basic_map_list_n_basic_map(list); + if (n < 1) + isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid, + "expecting non-empty list", goto error); + + bmap = isl_basic_map_list_get_basic_map(list, 0); + for (i = 1; i < n; ++i) { + isl_basic_map *bmap_i; + + bmap_i = isl_basic_map_list_get_basic_map(list, i); + bmap = isl_basic_map_intersect(bmap, bmap_i); + } + + isl_basic_map_list_free(list); + return bmap; +error: + isl_basic_map_list_free(list); + return NULL; +} + +/* Return the intersection of the elements in the non-empty list "list". + * All elements are assumed to live in the same space. + */ +__isl_give isl_basic_set *isl_basic_set_list_intersect( + __isl_take isl_basic_set_list *list) +{ + return isl_basic_map_list_intersect(list); +} + +/* Return the Cartesian product of the basic sets in list (in the given order). + */ +__isl_give isl_basic_set *isl_basic_set_list_product( + __isl_take struct isl_basic_set_list *list) +{ + int i; + unsigned dim; + unsigned nparam; + unsigned extra; + unsigned n_eq; + unsigned n_ineq; + struct isl_basic_set *product = NULL; + + if (!list) + goto error; + isl_assert(list->ctx, list->n > 0, goto error); + isl_assert(list->ctx, list->p[0], goto error); + nparam = isl_basic_set_n_param(list->p[0]); + dim = isl_basic_set_n_dim(list->p[0]); + extra = list->p[0]->n_div; + n_eq = list->p[0]->n_eq; + n_ineq = list->p[0]->n_ineq; + for (i = 1; i < list->n; ++i) { + isl_assert(list->ctx, list->p[i], goto error); + isl_assert(list->ctx, nparam == isl_basic_set_n_param(list->p[i]), goto error); dim += isl_basic_set_n_dim(list->p[i]); extra += list->p[i]->n_div; @@ -9254,12 +9379,22 @@ return prod; } +/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2" + * and collect the results. + * The result live in the space obtained by calling "space_product" + * on the spaces of "map1" and "map2". + * If "remove_duplicates" is set then the result may contain duplicates + * (even if the inputs do not) and so we try and remove the obvious + * duplicates. + */ static __isl_give isl_map *map_product(__isl_take isl_map *map1, __isl_take isl_map *map2, - __isl_give isl_space *(*dim_product)(__isl_take isl_space *left, + __isl_give isl_space *(*space_product)(__isl_take isl_space *left, __isl_take isl_space *right), __isl_give isl_basic_map *(*basic_map_product)( - __isl_take isl_basic_map *left, __isl_take isl_basic_map *right)) + __isl_take isl_basic_map *left, + __isl_take isl_basic_map *right), + int remove_duplicates) { unsigned flags = 0; struct isl_map *result; @@ -9275,7 +9410,7 @@ ISL_F_ISSET(map2, ISL_MAP_DISJOINT)) ISL_FL_SET(flags, ISL_MAP_DISJOINT); - result = isl_map_alloc_space(dim_product(isl_space_copy(map1->dim), + result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim), isl_space_copy(map2->dim)), map1->n * map2->n, flags); if (!result) @@ -9292,6 +9427,8 @@ if (!result) goto error; } + if (remove_duplicates) + result = isl_map_remove_obvious_duplicates(result); isl_map_free(map1); isl_map_free(map2); return result; @@ -9306,7 +9443,8 @@ static __isl_give isl_map *map_product_aligned(__isl_take isl_map *map1, __isl_take isl_map *map2) { - return map_product(map1, map2, &isl_space_product, &isl_basic_map_product); + return map_product(map1, map2, &isl_space_product, + &isl_basic_map_product, 0); } __isl_give isl_map *isl_map_product(__isl_take isl_map *map1, @@ -9346,7 +9484,7 @@ __isl_take isl_map *map2) { return map_product(map1, map2, &isl_space_domain_product, - &isl_basic_map_domain_product); + &isl_basic_map_domain_product, 1); } /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D] @@ -9355,7 +9493,7 @@ __isl_take isl_map *map2) { return map_product(map1, map2, &isl_space_range_product, - &isl_basic_map_range_product); + &isl_basic_map_range_product, 1); } __isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1, @@ -9372,6 +9510,152 @@ &map_range_product_aligned); } +/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C. + */ +__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map) +{ + isl_space *space; + int total1, keep1, total2, keep2; + + if (!map) + return NULL; + if (!isl_space_domain_is_wrapping(map->dim) || + !isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + total1 = isl_space_dim(space, isl_dim_in); + total2 = isl_space_dim(space, isl_dim_out); + space = isl_space_factor_domain(space); + keep1 = isl_space_dim(space, isl_dim_in); + keep2 = isl_space_dim(space, isl_dim_out); + map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1); + map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D. + */ +__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map) +{ + isl_space *space; + int total1, keep1, total2, keep2; + + if (!map) + return NULL; + if (!isl_space_domain_is_wrapping(map->dim) || + !isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + total1 = isl_space_dim(space, isl_dim_in); + total2 = isl_space_dim(space, isl_dim_out); + space = isl_space_factor_range(space); + keep1 = isl_space_dim(space, isl_dim_in); + keep2 = isl_space_dim(space, isl_dim_out); + map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1); + map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map of the form [A -> B] -> C, return the map A -> C. + */ +__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map) +{ + isl_space *space; + int total, keep; + + if (!map) + return NULL; + if (!isl_space_domain_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "domain is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + total = isl_space_dim(space, isl_dim_in); + space = isl_space_domain_factor_domain(space); + keep = isl_space_dim(space, isl_dim_in); + map = isl_map_project_out(map, isl_dim_in, keep, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map of the form [A -> B] -> C, return the map B -> C. + */ +__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map) +{ + isl_space *space; + int total, keep; + + if (!map) + return NULL; + if (!isl_space_domain_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "domain is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + total = isl_space_dim(space, isl_dim_in); + space = isl_space_domain_factor_range(space); + keep = isl_space_dim(space, isl_dim_in); + map = isl_map_project_out(map, isl_dim_in, 0, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map A -> [B -> C], extract the map A -> B. + */ +__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map) +{ + isl_space *space; + int total, keep; + + if (!map) + return NULL; + if (!isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "range is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + total = isl_space_dim(space, isl_dim_out); + space = isl_space_range_factor_domain(space); + keep = isl_space_dim(space, isl_dim_out); + map = isl_map_project_out(map, isl_dim_out, keep, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + +/* Given a map A -> [B -> C], extract the map A -> C. + */ +__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map) +{ + isl_space *space; + int total, keep; + + if (!map) + return NULL; + if (!isl_space_range_is_wrapping(map->dim)) + isl_die(isl_map_get_ctx(map), isl_error_invalid, + "range is not a product", return isl_map_free(map)); + + space = isl_map_get_space(map); + total = isl_space_dim(space, isl_dim_out); + space = isl_space_range_factor_range(space); + keep = isl_space_dim(space, isl_dim_out); + map = isl_map_project_out(map, isl_dim_out, 0, total - keep); + map = isl_map_reset_space(map, space); + + return map; +} + /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D) */ __isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1, @@ -9506,39 +9790,46 @@ return 1; } +/* Return the number of basic maps in the (current) representation of "map". + */ +int isl_map_n_basic_map(__isl_keep isl_map *map) +{ + return map ? map->n : 0; +} + int isl_set_n_basic_set(__isl_keep isl_set *set) { return set ? set->n : 0; } -int isl_map_foreach_basic_map(__isl_keep isl_map *map, - int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user) +isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, + isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user) { int i; if (!map) - return -1; + return isl_stat_error; for (i = 0; i < map->n; ++i) if (fn(isl_basic_map_copy(map->p[i]), user) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } -int isl_set_foreach_basic_set(__isl_keep isl_set *set, - int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user) +isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user) { int i; if (!set) - return -1; + return isl_stat_error; for (i = 0; i < set->n; ++i) if (fn(isl_basic_set_copy(set->p[i]), user) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset) @@ -9698,15 +9989,16 @@ /* Check if there is any lower bound (if lower == 0) and/or upper * bound (if upper == 0) on the specified dim. */ -static int basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap, +static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos, int lower, int upper) { int i; if (!bmap) - return -1; + return isl_bool_error; - isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1); + isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), + return isl_bool_error); pos += isl_basic_map_offset(bmap, type); @@ -9714,12 +10006,12 @@ if (isl_int_is_zero(bmap->div[i][0])) continue; if (!isl_int_is_zero(bmap->div[i][1 + pos])) - return 1; + return isl_bool_true; } for (i = 0; i < bmap->n_eq; ++i) if (!isl_int_is_zero(bmap->eq[i][pos])) - return 1; + return isl_bool_true; for (i = 0; i < bmap->n_ineq; ++i) { int sgn = isl_int_sgn(bmap->ineq[i][pos]); @@ -9738,13 +10030,13 @@ return basic_map_dim_is_bounded(bmap, type, pos, 0, 0); } -int isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos) { return basic_map_dim_is_bounded(bmap, type, pos, 0, 1); } -int isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos) { return basic_map_dim_is_bounded(bmap, type, pos, 1, 0); @@ -9779,29 +10071,29 @@ /* Does "map" have a bound (according to "fn") for any of its basic maps? */ -static int has_any_bound(__isl_keep isl_map *map, +static isl_bool has_any_bound(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos, - int (*fn)(__isl_keep isl_basic_map *bmap, + isl_bool (*fn)(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos)) { int i; if (!map) - return -1; + return isl_bool_error; for (i = 0; i < map->n; ++i) { - int bounded; + isl_bool bounded; bounded = fn(map->p[i], type, pos); if (bounded < 0 || bounded) return bounded; } - return 0; + return isl_bool_false; } /* Return 1 if the specified dim is involved in any lower bound. */ -int isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos) { return has_any_bound(set, type, pos, @@ -9810,7 +10102,7 @@ /* Return 1 if the specified dim is involved in any upper bound. */ -int isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos) { return has_any_bound(set, type, pos, @@ -9819,29 +10111,29 @@ /* Does "map" have a bound (according to "fn") for all of its basic maps? */ -static int has_bound(__isl_keep isl_map *map, +static isl_bool has_bound(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos, - int (*fn)(__isl_keep isl_basic_map *bmap, + isl_bool (*fn)(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos)) { int i; if (!map) - return -1; + return isl_bool_error; for (i = 0; i < map->n; ++i) { - int bounded; + isl_bool bounded; bounded = fn(map->p[i], type, pos); if (bounded < 0 || !bounded) return bounded; } - return 1; + return isl_bool_true; } /* Return 1 if the specified dim has a lower bound (in each of its basic sets). */ -int isl_set_dim_has_lower_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos) { return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound); @@ -9849,7 +10141,7 @@ /* Return 1 if the specified dim has an upper bound (in each of its basic sets). */ -int isl_set_dim_has_upper_bound(__isl_keep isl_set *set, +isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos) { return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound); @@ -9931,38 +10223,110 @@ return isl_basic_set_vars_get_sign(bset, first, n, signs); } +/* Is it possible for the integer division "div" to depend (possibly + * indirectly) on any output dimensions? + * + * If the div is undefined, then we conservatively assume that it + * may depend on them. + * Otherwise, we check if it actually depends on them or on any integer + * divisions that may depend on them. + */ +static int div_may_involve_output(__isl_keep isl_basic_map *bmap, int div) +{ + int i; + unsigned n_out, o_out; + unsigned n_div, o_div; + + if (isl_int_is_zero(bmap->div[div][0])) + return 1; + + n_out = isl_basic_map_dim(bmap, isl_dim_out); + o_out = isl_basic_map_offset(bmap, isl_dim_out); + + if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1) + return 1; + + n_div = isl_basic_map_dim(bmap, isl_dim_div); + o_div = isl_basic_map_offset(bmap, isl_dim_div); + + for (i = 0; i < n_div; ++i) { + if (isl_int_is_zero(bmap->div[div][1 + o_div + i])) + continue; + if (div_may_involve_output(bmap, i)) + return 1; + } + + return 0; +} + +/* Return the index of the equality of "bmap" that defines + * the output dimension "pos" in terms of earlier dimensions. + * The equality may also involve integer divisions, as long + * as those integer divisions are defined in terms of + * parameters or input dimensions. + * Return bmap->n_eq if there is no such equality. + * Return -1 on error. + */ +int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap, + int pos) +{ + int j, k; + unsigned n_out, o_out; + unsigned n_div, o_div; + + if (!bmap) + return -1; + + n_out = isl_basic_map_dim(bmap, isl_dim_out); + o_out = isl_basic_map_offset(bmap, isl_dim_out); + n_div = isl_basic_map_dim(bmap, isl_dim_div); + o_div = isl_basic_map_offset(bmap, isl_dim_div); + + for (j = 0; j < bmap->n_eq; ++j) { + if (isl_int_is_zero(bmap->eq[j][o_out + pos])) + continue; + if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1, + n_out - (pos + 1)) != -1) + continue; + for (k = 0; k < n_div; ++k) { + if (isl_int_is_zero(bmap->eq[j][o_div + k])) + continue; + if (div_may_involve_output(bmap, k)) + break; + } + if (k >= n_div) + return j; + } + + return bmap->n_eq; +} + /* Check if the given basic map is obviously single-valued. * In particular, for each output dimension, check that there is * an equality that defines the output dimension in terms of * earlier dimensions. */ -int isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap) +isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap) { - int i, j; - unsigned total; + int i; unsigned n_out; - unsigned o_out; if (!bmap) - return -1; + return isl_bool_error; - total = 1 + isl_basic_map_total_dim(bmap); n_out = isl_basic_map_dim(bmap, isl_dim_out); - o_out = isl_basic_map_offset(bmap, isl_dim_out); for (i = 0; i < n_out; ++i) { - for (j = 0; j < bmap->n_eq; ++j) { - if (isl_int_is_zero(bmap->eq[j][o_out + i])) - continue; - if (isl_seq_first_non_zero(bmap->eq[j] + o_out + i + 1, - total - (o_out + i + 1)) == -1) - break; - } - if (j >= bmap->n_eq) - return 0; + int eq; + + eq = isl_basic_map_output_defining_equality(bmap, i); + if (eq < 0) + return isl_bool_error; + if (eq >= bmap->n_eq) + return isl_bool_false; } - return 1; + return isl_bool_true; } /* Check if the given basic map is single-valued. @@ -9972,12 +10336,12 @@ * * and check if the result is a subset of the identity mapping. */ -int isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap) +isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap) { isl_space *space; isl_basic_map *test; isl_basic_map *id; - int sv; + isl_bool sv; sv = isl_basic_map_plain_is_single_valued(bmap); if (sv < 0 || sv) @@ -10000,14 +10364,14 @@ /* Check if the given map is obviously single-valued. */ -int isl_map_plain_is_single_valued(__isl_keep isl_map *map) +isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map) { if (!map) - return -1; + return isl_bool_error; if (map->n == 0) - return 1; + return isl_bool_true; if (map->n >= 2) - return 0; + return isl_bool_false; return isl_basic_map_plain_is_single_valued(map->p[0]); } @@ -10019,12 +10383,12 @@ * * and check if the result is a subset of the identity mapping. */ -int isl_map_is_single_valued(__isl_keep isl_map *map) +isl_bool isl_map_is_single_valued(__isl_keep isl_map *map) { isl_space *dim; isl_map *test; isl_map *id; - int sv; + isl_bool sv; sv = isl_map_plain_is_single_valued(map); if (sv < 0 || sv) @@ -10044,9 +10408,9 @@ return sv; } -int isl_map_is_injective(__isl_keep isl_map *map) +isl_bool isl_map_is_injective(__isl_keep isl_map *map) { - int in; + isl_bool in; map = isl_map_copy(map); map = isl_map_reverse(map); @@ -10058,9 +10422,9 @@ /* Check if the given map is obviously injective. */ -int isl_map_plain_is_injective(__isl_keep isl_map *map) +isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map) { - int in; + isl_bool in; map = isl_map_copy(map); map = isl_map_reverse(map); @@ -10070,9 +10434,9 @@ return in; } -int isl_map_is_bijective(__isl_keep isl_map *map) +isl_bool isl_map_is_bijective(__isl_keep isl_map *map) { - int sv; + isl_bool sv; sv = isl_map_is_single_valued(map); if (sv < 0 || !sv) @@ -10081,7 +10445,7 @@ return isl_map_is_injective(map); } -int isl_set_is_singleton(__isl_keep isl_set *set) +isl_bool isl_set_is_singleton(__isl_keep isl_set *set) { return isl_map_is_single_valued((isl_map *)set); } @@ -10159,22 +10523,42 @@ return isl_basic_set_is_box(set->p[0]); } -int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset) +isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset) { if (!bset) - return -1; + return isl_bool_error; return isl_space_is_wrapping(bset->dim); } -int isl_set_is_wrapping(__isl_keep isl_set *set) +isl_bool isl_set_is_wrapping(__isl_keep isl_set *set) { if (!set) - return -1; + return isl_bool_error; return isl_space_is_wrapping(set->dim); } +/* Is the domain of "map" a wrapped relation? + */ +isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_domain_is_wrapping(map->dim); +} + +/* Is the range of "map" a wrapped relation? + */ +isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map) +{ + if (!map) + return isl_bool_error; + + return isl_space_range_is_wrapping(map->dim); +} + __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap) { bmap = isl_basic_map_cow(bmap); @@ -10836,18 +11220,18 @@ c1, c2, c3, c4, isl_dim_in); } -int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap) +isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap) { if (!bmap) - return -1; + return isl_bool_error; return isl_space_can_zip(bmap->dim); } -int isl_map_can_zip(__isl_keep isl_map *map) +isl_bool isl_map_can_zip(__isl_keep isl_map *map) { if (!map) - return -1; + return isl_bool_error; return isl_space_can_zip(map->dim); } @@ -10921,10 +11305,10 @@ /* Can we apply isl_basic_map_curry to "bmap"? * That is, does it have a nested relation in its domain? */ -int isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap) +isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap) { if (!bmap) - return -1; + return isl_bool_error; return isl_space_can_curry(bmap->dim); } @@ -10932,10 +11316,10 @@ /* Can we apply isl_map_curry to "map"? * That is, does it have a nested relation in its domain? */ -int isl_map_can_curry(__isl_keep isl_map *map) +isl_bool isl_map_can_curry(__isl_keep isl_map *map) { if (!map) - return -1; + return isl_bool_error; return isl_space_can_curry(map->dim); } @@ -11001,10 +11385,10 @@ /* Can we apply isl_basic_map_uncurry to "bmap"? * That is, does it have a nested relation in its domain? */ -int isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap) +isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap) { if (!bmap) - return -1; + return isl_bool_error; return isl_space_can_uncurry(bmap->dim); } @@ -11012,10 +11396,10 @@ /* Can we apply isl_map_uncurry to "map"? * That is, does it have a nested relation in its domain? */ -int isl_map_can_uncurry(__isl_keep isl_map *map) +isl_bool isl_map_can_uncurry(__isl_keep isl_map *map) { if (!map) - return -1; + return isl_bool_error; return isl_space_can_uncurry(map->dim); } @@ -11135,7 +11519,7 @@ if (isl_space_dim(maff->space, isl_dim_out) != maff->n) isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal, - "invalid space", return isl_multi_aff_free(maff)); + "invalid space", goto error); space = isl_space_domain(isl_multi_aff_get_space(maff)); bmap = isl_basic_map_universe(isl_space_from_domain(space)); @@ -11154,6 +11538,9 @@ isl_multi_aff_free(maff); return bmap; +error: + isl_multi_aff_free(maff); + return NULL; } /* Construct a map mapping the domain the multi-affine expression @@ -11313,37 +11700,81 @@ return NULL; } -/* Add a constraint imposing that the value of the first dimension is +/* Construct a constraint imposing that the value of the first dimension is * greater than or equal to that of the second. */ -__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap, - enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +static __isl_give isl_constraint *constraint_order_ge( + __isl_take isl_space *space, enum isl_dim_type type1, int pos1, + enum isl_dim_type type2, int pos2) { isl_constraint *c; - isl_local_space *ls; - if (!bmap) + if (!space) return NULL; - if (pos1 >= isl_basic_map_dim(bmap, type1)) - isl_die(bmap->ctx, isl_error_invalid, - "index out of bounds", return isl_basic_map_free(bmap)); - if (pos2 >= isl_basic_map_dim(bmap, type2)) - isl_die(bmap->ctx, isl_error_invalid, - "index out of bounds", return isl_basic_map_free(bmap)); + c = isl_constraint_alloc_inequality(isl_local_space_from_space(space)); + + if (pos1 >= isl_constraint_dim(c, type1)) + isl_die(isl_constraint_get_ctx(c), isl_error_invalid, + "index out of bounds", return isl_constraint_free(c)); + if (pos2 >= isl_constraint_dim(c, type2)) + isl_die(isl_constraint_get_ctx(c), isl_error_invalid, + "index out of bounds", return isl_constraint_free(c)); if (type1 == type2 && pos1 == pos2) - return bmap; + return c; - ls = isl_local_space_from_space(isl_basic_map_get_space(bmap)); - c = isl_inequality_alloc(ls); c = isl_constraint_set_coefficient_si(c, type1, pos1, 1); c = isl_constraint_set_coefficient_si(c, type2, pos2, -1); + + return c; +} + +/* Add a constraint imposing that the value of the first dimension is + * greater than or equal to that of the second. + */ +__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_constraint *c; + isl_space *space; + + if (type1 == type2 && pos1 == pos2) + return bmap; + space = isl_basic_map_get_space(bmap); + c = constraint_order_ge(space, type1, pos1, type2, pos2); bmap = isl_basic_map_add_constraint(bmap, c); return bmap; } +/* Add a constraint imposing that the value of the first dimension is + * greater than or equal to that of the second. + */ +__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + isl_constraint *c; + isl_space *space; + + if (type1 == type2 && pos1 == pos2) + return map; + space = isl_map_get_space(map); + c = constraint_order_ge(space, type1, pos1, type2, pos2); + map = isl_map_add_constraint(map, c); + + return map; +} + +/* Add a constraint imposing that the value of the first dimension is + * less than or equal to that of the second. + */ +__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map, + enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2) +{ + return isl_map_order_ge(map, type2, pos2, type1, pos1); +} + /* Construct a basic map where the value of the first dimension is * greater than that of the second. */ @@ -11369,7 +11800,7 @@ bmap = isl_basic_map_alloc_space(space, 0, 0, 1); i = isl_basic_map_alloc_inequality(bmap); if (i < 0) - goto error; + return isl_basic_map_free(bmap); isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap)); pos1 += isl_basic_map_offset(bmap, type1); pos2 += isl_basic_map_offset(bmap, type2); @@ -11582,12 +12013,25 @@ isl_space *ma_space; ma_space = isl_multi_aff_get_space(ma); - m = isl_space_tuple_match(bmap->dim, type, ma_space, isl_dim_out); - isl_space_free(ma_space); - if (m >= 0 && !m) + + m = isl_space_match(bmap->dim, isl_dim_param, ma_space, isl_dim_param); + if (m < 0) + goto error; + if (!m) isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, - "spaces don't match", return -1); + "parameters don't match", goto error); + m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out); + if (m < 0) + goto error; + if (!m) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "spaces don't match", goto error); + + isl_space_free(ma_space); return m; +error: + isl_space_free(ma_space); + return -1; } /* Copy the divs from "ma" to "bmap", adding zeros for the "n_before" @@ -11889,6 +12333,30 @@ return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma); } +/* Compute the preimage of the domain of "bmap" under the function + * represented by "ma". + * In other words, plug in "ma" in the domain of "bmap". + * The result is a basic map that lives in the same space as "bmap" + * except that the domain has been replaced by the domain space of "ma". + */ +__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma) +{ + return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma); +} + +/* Compute the preimage of the range of "bmap" under the function + * represented by "ma". + * In other words, plug in "ma" in the range of "bmap". + * The result is a basic map that lives in the same space as "bmap" + * except that the range has been replaced by the domain space of "ma". + */ +__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff( + __isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma) +{ + return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma); +} + /* Check if the range of "ma" is compatible with the domain or range * (depending on "type") of "map". * Return -1 if anything is wrong. @@ -11901,7 +12369,7 @@ isl_space *ma_space; ma_space = isl_multi_aff_get_space(ma); - m = isl_space_tuple_match(map->dim, type, ma_space, isl_dim_out); + m = isl_space_tuple_is_equal(map->dim, type, ma_space, isl_dim_out); isl_space_free(ma_space); if (m >= 0 && !m) isl_die(isl_map_get_ctx(map), isl_error_invalid, @@ -11987,7 +12455,7 @@ } /* Compute the preimage of "set" under the function represented by "ma". - * In other words, plug in "ma" "set". The result is a set + * In other words, plug in "ma" in "set". The result is a set * that lives in the domain space of "ma". */ __isl_give isl_set *isl_set_preimage_multi_aff(__isl_take isl_set *set, @@ -12008,66 +12476,194 @@ return isl_map_preimage_multi_aff(map, isl_dim_in, ma); } -/* Compute the preimage of "set" under the function represented by "pma". - * In other words, plug in "pma" in "set. The result is a set - * that lives in the domain space of "pma". +/* Compute the preimage of the range of "map" under the function + * represented by "ma". + * In other words, plug in "ma" in the range of "map". + * The result is a map that lives in the same space as "map" + * except that the range has been replaced by the domain space of "ma". + */ +__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map, + __isl_take isl_multi_aff *ma) +{ + return isl_map_preimage_multi_aff(map, isl_dim_out, ma); +} + +/* Compute the preimage of "map" under the function represented by "pma". + * In other words, plug in "pma" in the domain or range of "map". + * The result is a map that lives in the same space as "map", + * except that the space of type "type" has been replaced by + * the domain space of "pma". + * + * The parameters of "map" and "pma" are assumed to have been aligned. */ -static __isl_give isl_set *set_preimage_pw_multi_aff(__isl_take isl_set *set, +static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned( + __isl_take isl_map *map, enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma) { int i; - isl_set *res; + isl_map *res; if (!pma) goto error; if (pma->n == 0) { isl_pw_multi_aff_free(pma); - res = isl_set_empty(isl_set_get_space(set)); - isl_set_free(set); + res = isl_map_empty(isl_map_get_space(map)); + isl_map_free(map); return res; } - res = isl_set_preimage_multi_aff(isl_set_copy(set), + res = isl_map_preimage_multi_aff(isl_map_copy(map), type, isl_multi_aff_copy(pma->p[0].maff)); - res = isl_set_intersect(res, isl_set_copy(pma->p[0].set)); + if (type == isl_dim_in) + res = isl_map_intersect_domain(res, + isl_map_copy(pma->p[0].set)); + else + res = isl_map_intersect_range(res, + isl_map_copy(pma->p[0].set)); for (i = 1; i < pma->n; ++i) { - isl_set *res_i; + isl_map *res_i; - res_i = isl_set_preimage_multi_aff(isl_set_copy(set), + res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type, isl_multi_aff_copy(pma->p[i].maff)); - res_i = isl_set_intersect(res_i, isl_set_copy(pma->p[i].set)); - res = isl_set_union(res, res_i); + if (type == isl_dim_in) + res_i = isl_map_intersect_domain(res_i, + isl_map_copy(pma->p[i].set)); + else + res_i = isl_map_intersect_range(res_i, + isl_map_copy(pma->p[i].set)); + res = isl_map_union(res, res_i); } isl_pw_multi_aff_free(pma); - isl_set_free(set); + isl_map_free(map); return res; error: isl_pw_multi_aff_free(pma); - isl_set_free(set); + isl_map_free(map); return NULL; } -__isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set, - __isl_take isl_pw_multi_aff *pma) +/* Compute the preimage of "map" under the function represented by "pma". + * In other words, plug in "pma" in the domain or range of "map". + * The result is a map that lives in the same space as "map", + * except that the space of type "type" has been replaced by + * the domain space of "pma". + */ +__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma) { - if (!set || !pma) + if (!map || !pma) goto error; - if (isl_space_match(set->dim, isl_dim_param, pma->dim, isl_dim_param)) - return set_preimage_pw_multi_aff(set, pma); + if (isl_space_match(map->dim, isl_dim_param, pma->dim, isl_dim_param)) + return isl_map_preimage_pw_multi_aff_aligned(map, type, pma); - if (!isl_space_has_named_params(set->dim) || + if (!isl_space_has_named_params(map->dim) || !isl_space_has_named_params(pma->dim)) - isl_die(set->ctx, isl_error_invalid, + isl_die(map->ctx, isl_error_invalid, "unaligned unnamed parameters", goto error); - set = isl_set_align_params(set, isl_pw_multi_aff_get_space(pma)); - pma = isl_pw_multi_aff_align_params(pma, isl_set_get_space(set)); + map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map)); - return set_preimage_pw_multi_aff(set, pma); + return isl_map_preimage_pw_multi_aff_aligned(map, type, pma); error: isl_pw_multi_aff_free(pma); - return isl_set_free(set); + return isl_map_free(map); +} + +/* Compute the preimage of "set" under the function represented by "pma". + * In other words, plug in "pma" in "set". The result is a set + * that lives in the domain space of "pma". + */ +__isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set, + __isl_take isl_pw_multi_aff *pma) +{ + return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma); +} + +/* Compute the preimage of the domain of "map" under the function + * represented by "pma". + * In other words, plug in "pma" in the domain of "map". + * The result is a map that lives in the same space as "map", + * except that domain space has been replaced by the domain space of "pma". + */ +__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma) +{ + return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma); +} + +/* Compute the preimage of the range of "map" under the function + * represented by "pma". + * In other words, plug in "pma" in the range of "map". + * The result is a map that lives in the same space as "map", + * except that range space has been replaced by the domain space of "pma". + */ +__isl_give isl_map *isl_map_preimage_range_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma) +{ + return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma); +} + +/* Compute the preimage of "map" under the function represented by "mpa". + * In other words, plug in "mpa" in the domain or range of "map". + * The result is a map that lives in the same space as "map", + * except that the space of type "type" has been replaced by + * the domain space of "mpa". + * + * If the map does not involve any constraints that refer to the + * dimensions of the substituted space, then the only possible + * effect of "mpa" on the map is to map the space to a different space. + * We create a separate isl_multi_aff to effectuate this change + * in order to avoid spurious splitting of the map along the pieces + * of "mpa". + */ +__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map, + enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa) +{ + int n; + isl_pw_multi_aff *pma; + + if (!map || !mpa) + goto error; + + n = isl_map_dim(map, type); + if (!isl_map_involves_dims(map, type, 0, n)) { + isl_space *space; + isl_multi_aff *ma; + + space = isl_multi_pw_aff_get_space(mpa); + isl_multi_pw_aff_free(mpa); + ma = isl_multi_aff_zero(space); + return isl_map_preimage_multi_aff(map, type, ma); + } + + pma = isl_pw_multi_aff_from_multi_pw_aff(mpa); + return isl_map_preimage_pw_multi_aff(map, type, pma); +error: + isl_map_free(map); + isl_multi_pw_aff_free(mpa); + return NULL; +} + +/* Compute the preimage of "map" under the function represented by "mpa". + * In other words, plug in "mpa" in the domain "map". + * The result is a map that lives in the same space as "map", + * except that domain space has been replaced by the domain space of "mpa". + */ +__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff( + __isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa); +} + +/* Compute the preimage of "set" by the function represented by "mpa". + * In other words, plug in "mpa" in "set". + */ +__isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set, + __isl_take isl_multi_pw_aff *mpa) +{ + return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa); } diff -Nru isl-0.12.2/isl_map_list.c isl-0.15/isl_map_list.c --- isl-0.12.2/isl_map_list.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_map_list.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,32 @@ +#include +#include + +#undef EL +#define EL isl_basic_map + +#include + +#undef BASE +#define BASE basic_map + +#include + +#undef EL +#define EL isl_map + +#include + +#undef BASE +#define BASE map + +#include + +#undef EL +#define EL isl_union_map + +#include + +#undef BASE +#define BASE union_map + +#include diff -Nru isl-0.12.2/isl_map_no_piplib.c isl-0.15/isl_map_no_piplib.c --- isl-0.12.2/isl_map_no_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_map_no_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -/* - * 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 - */ - -#include "isl_map_piplib.h" -#include - -struct isl_map *isl_pip_basic_map_lexopt( - struct isl_basic_map *bmap, struct isl_basic_set *dom, - struct isl_set **empty, int max) -{ - isl_basic_map_free(bmap); - isl_basic_set_free(dom); - return NULL; -} diff -Nru isl-0.12.2/isl_map_piplib.c isl-0.15/isl_map_piplib.c --- isl-0.12.2/isl_map_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_map_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,476 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include "isl_piplib.h" -#include "isl_map_piplib.h" - -static void copy_values_from(isl_int *dst, Entier *src, unsigned n) -{ - int i; - - for (i = 0; i < n; ++i) - entier_assign(dst[i], src[i]); -} - -static void add_value(isl_int *dst, Entier *src) -{ - mpz_add(*dst, *dst, *src); -} - -static void copy_constraint_from(isl_int *dst, PipVector *src, - unsigned nparam, unsigned n_in, unsigned n_out, - unsigned extra, int *pos) -{ - int i; - - copy_values_from(dst, src->the_vector+src->nb_elements-1, 1); - copy_values_from(dst+1, src->the_vector, nparam+n_in); - isl_seq_clr(dst+1+nparam+n_in, n_out); - isl_seq_clr(dst+1+nparam+n_in+n_out, extra); - for (i = 0; i + n_in + nparam < src->nb_elements-1; ++i) { - int p = pos[i]; - add_value(&dst[1+nparam+n_in+n_out+p], - &src->the_vector[n_in+nparam+i]); - } -} - -static int add_inequality(struct isl_ctx *ctx, - struct isl_basic_map *bmap, int *pos, PipVector *vec) -{ - unsigned nparam = isl_basic_map_n_param(bmap); - unsigned n_in = isl_basic_map_n_in(bmap); - unsigned n_out = isl_basic_map_n_out(bmap); - unsigned n_div = isl_basic_map_n_div(bmap); - int i = isl_basic_map_alloc_inequality(bmap); - if (i < 0) - return -1; - copy_constraint_from(bmap->ineq[i], vec, - nparam, n_in, n_out, n_div, pos); - - return i; -} - -/* For a div d = floor(f/m), add the constraints - * - * f - m d >= 0 - * -(f-(n-1)) + m d >= 0 - * - * Note that the second constraint is the negation of - * - * f - m d >= n - */ -static int add_div_constraints(struct isl_ctx *ctx, - struct isl_basic_map *bmap, int *pos, PipNewparm *p, unsigned div) -{ - int i, j; - unsigned total = isl_basic_map_total_dim(bmap); - unsigned div_pos = 1 + total - bmap->n_div + div; - - i = add_inequality(ctx, bmap, pos, p->vector); - if (i < 0) - return -1; - copy_values_from(&bmap->ineq[i][div_pos], &p->deno, 1); - isl_int_neg(bmap->ineq[i][div_pos], bmap->ineq[i][div_pos]); - - j = isl_basic_map_alloc_inequality(bmap); - if (j < 0) - return -1; - isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total); - isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][div_pos]); - isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1); - return j; -} - -static int add_equality(struct isl_ctx *ctx, - struct isl_basic_map *bmap, int *pos, - unsigned var, PipVector *vec) -{ - int i; - unsigned nparam = isl_basic_map_n_param(bmap); - unsigned n_in = isl_basic_map_n_in(bmap); - unsigned n_out = isl_basic_map_n_out(bmap); - - isl_assert(ctx, var < n_out, return -1); - - i = isl_basic_map_alloc_equality(bmap); - if (i < 0) - return -1; - copy_constraint_from(bmap->eq[i], vec, - nparam, n_in, n_out, bmap->extra, pos); - isl_int_set_si(bmap->eq[i][1+nparam+n_in+var], -1); - - return i; -} - -static int find_div(struct isl_ctx *ctx, - struct isl_basic_map *bmap, int *pos, PipNewparm *p) -{ - int i, j; - unsigned nparam = isl_basic_map_n_param(bmap); - unsigned n_in = isl_basic_map_n_in(bmap); - unsigned n_out = isl_basic_map_n_out(bmap); - - i = isl_basic_map_alloc_div(bmap); - if (i < 0) - return -1; - - copy_constraint_from(bmap->div[i]+1, p->vector, - nparam, n_in, n_out, bmap->extra, pos); - - copy_values_from(bmap->div[i], &p->deno, 1); - for (j = 0; j < i; ++j) - if (isl_seq_eq(bmap->div[i], bmap->div[j], - 1+1+isl_basic_map_total_dim(bmap)+j)) { - isl_basic_map_free_div(bmap, 1); - return j; - } - - if (add_div_constraints(ctx, bmap, pos, p, i) < 0) - return -1; - - return i; -} - -/* Count some properties of a quast - * - maximal number of new parameters - * - maximal depth - * - total number of solutions - * - total number of empty branches - */ -static void quast_count(PipQuast *q, int *maxnew, int depth, int *maxdepth, - int *sol, int *nosol) -{ - PipNewparm *p; - - for (p = q->newparm; p; p = p->next) - if (p->rank > *maxnew) - *maxnew = p->rank; - if (q->condition) { - if (++depth > *maxdepth) - *maxdepth = depth; - quast_count(q->next_else, maxnew, depth, maxdepth, sol, nosol); - quast_count(q->next_then, maxnew, depth, maxdepth, sol, nosol); - } else { - if (q->list) - ++(*sol); - else - ++(*nosol); - } -} - -/* - * pos: array of length bmap->set.extra, mapping each of the existential - * variables PIP proposes to an existential variable in bmap - * bmap: collects the currently active constraints - * rest: collects the empty leaves of the quast (if not NULL) - */ -struct scan_data { - struct isl_ctx *ctx; - struct isl_basic_map *bmap; - struct isl_set **rest; - int *pos; -}; - -/* - * New existentially quantified variables are places after the existing ones. - */ -static struct isl_map *scan_quast_r(struct scan_data *data, PipQuast *q, - struct isl_map *map) -{ - PipNewparm *p; - struct isl_basic_map *bmap = data->bmap; - unsigned old_n_div = bmap->n_div; - unsigned nparam = isl_basic_map_n_param(bmap); - unsigned n_in = isl_basic_map_n_in(bmap); - unsigned n_out = isl_basic_map_n_out(bmap); - - if (!map) - goto error; - - for (p = q->newparm; p; p = p->next) { - int pos; - unsigned pip_param = nparam + n_in; - - pos = find_div(data->ctx, bmap, data->pos, p); - if (pos < 0) - goto error; - data->pos[p->rank - pip_param] = pos; - } - - if (q->condition) { - int pos = add_inequality(data->ctx, bmap, data->pos, - q->condition); - if (pos < 0) - goto error; - map = scan_quast_r(data, q->next_then, map); - - if (isl_inequality_negate(bmap, pos)) - goto error; - map = scan_quast_r(data, q->next_else, map); - - if (isl_basic_map_free_inequality(bmap, 1)) - goto error; - } else if (q->list) { - PipList *l; - int j; - /* if bmap->n_out is zero, we are only interested in the domains - * where a solution exists and not in the actual solution - */ - for (j = 0, l = q->list; j < n_out && l; ++j, l = l->next) - if (add_equality(data->ctx, bmap, data->pos, j, - l->vector) < 0) - goto error; - map = isl_map_add_basic_map(map, isl_basic_map_copy(bmap)); - if (isl_basic_map_free_equality(bmap, n_out)) - goto error; - } else if (data->rest) { - struct isl_basic_set *bset; - bset = isl_basic_set_from_basic_map(isl_basic_map_copy(bmap)); - bset = isl_basic_set_drop_dims(bset, n_in, n_out); - if (!bset) - goto error; - *data->rest = isl_set_add_basic_set(*data->rest, bset); - } - - if (isl_basic_map_free_inequality(bmap, 2*(bmap->n_div - old_n_div))) - goto error; - if (isl_basic_map_free_div(bmap, bmap->n_div - old_n_div)) - goto error; - return map; -error: - isl_map_free(map); - return NULL; -} - -/* - * Returns a map of dimension "keep_dim" with "context" as domain and - * as range the first "isl_space_dim(keep_dim, isl_dim_out)" variables - * in the quast lists. - */ -static struct isl_map *isl_map_from_quast(struct isl_ctx *ctx, PipQuast *q, - isl_space *keep_dim, - struct isl_basic_set *context, - struct isl_set **rest) -{ - int pip_param; - int nexist; - int max_depth; - int n_sol, n_nosol; - struct scan_data data; - struct isl_map *map = NULL; - isl_space *dims; - unsigned nparam; - unsigned dim; - unsigned keep; - - data.ctx = ctx; - data.rest = rest; - data.bmap = NULL; - data.pos = NULL; - - if (!context || !keep_dim) - goto error; - - dim = isl_basic_set_n_dim(context); - nparam = isl_basic_set_n_param(context); - keep = isl_space_dim(keep_dim, isl_dim_out); - pip_param = nparam + dim; - - max_depth = 0; - n_sol = 0; - n_nosol = 0; - nexist = pip_param-1; - quast_count(q, &nexist, 0, &max_depth, &n_sol, &n_nosol); - nexist -= pip_param-1; - - if (rest) { - *rest = isl_set_alloc_space(isl_space_copy(context->dim), n_nosol, - ISL_MAP_DISJOINT); - if (!*rest) - goto error; - } - map = isl_map_alloc_space(isl_space_copy(keep_dim), n_sol, - ISL_MAP_DISJOINT); - if (!map) - goto error; - - dims = isl_space_reverse(isl_space_copy(context->dim)); - data.bmap = isl_basic_map_from_basic_set(context, dims); - data.bmap = isl_basic_map_extend_space(data.bmap, - keep_dim, nexist, keep, max_depth+2*nexist); - if (!data.bmap) - goto error2; - - if (data.bmap->extra) { - int i; - data.pos = isl_alloc_array(ctx, int, data.bmap->extra); - if (!data.pos) - goto error; - for (i = 0; i < data.bmap->n_div; ++i) - data.pos[i] = i; - } - - map = scan_quast_r(&data, q, map); - map = isl_map_finalize(map); - if (!map) - goto error2; - if (rest) { - *rest = isl_set_finalize(*rest); - if (!*rest) - goto error2; - } - isl_basic_map_free(data.bmap); - if (data.pos) - free(data.pos); - return map; -error: - isl_basic_set_free(context); - isl_space_free(keep_dim); -error2: - if (data.pos) - free(data.pos); - isl_basic_map_free(data.bmap); - isl_map_free(map); - if (rest) { - isl_set_free(*rest); - *rest = NULL; - } - return NULL; -} - -static void copy_values_to(Entier *dst, isl_int *src, unsigned n) -{ - int i; - - for (i = 0; i < n; ++i) - entier_assign(dst[i], src[i]); -} - -static void copy_constraint_to(Entier *dst, isl_int *src, - unsigned pip_param, unsigned pip_var, - unsigned extra_front, unsigned extra_back) -{ - copy_values_to(dst+1+extra_front+pip_var+pip_param+extra_back, src, 1); - copy_values_to(dst+1+extra_front+pip_var, src+1, pip_param); - copy_values_to(dst+1+extra_front, src+1+pip_param, pip_var); -} - -PipMatrix *isl_basic_map_to_pip(struct isl_basic_map *bmap, unsigned pip_param, - unsigned extra_front, unsigned extra_back) -{ - int i; - unsigned nrow; - unsigned ncol; - PipMatrix *M; - unsigned off; - unsigned pip_var = isl_basic_map_total_dim(bmap) - pip_param; - - nrow = extra_front + bmap->n_eq + bmap->n_ineq; - ncol = 1 + extra_front + pip_var + pip_param + extra_back + 1; - M = pip_matrix_alloc(nrow, ncol); - if (!M) - return NULL; - - off = extra_front; - for (i = 0; i < bmap->n_eq; ++i) { - entier_set_si(M->p[off+i][0], 0); - copy_constraint_to(M->p[off+i], bmap->eq[i], - pip_param, pip_var, extra_front, extra_back); - } - off += bmap->n_eq; - for (i = 0; i < bmap->n_ineq; ++i) { - entier_set_si(M->p[off+i][0], 1); - copy_constraint_to(M->p[off+i], bmap->ineq[i], - pip_param, pip_var, extra_front, extra_back); - } - return M; -} - -PipMatrix *isl_basic_set_to_pip(struct isl_basic_set *bset, unsigned pip_param, - unsigned extra_front, unsigned extra_back) -{ - return isl_basic_map_to_pip((struct isl_basic_map *)bset, - pip_param, extra_front, extra_back); -} - -struct isl_map *isl_pip_basic_map_lexopt( - struct isl_basic_map *bmap, struct isl_basic_set *dom, - struct isl_set **empty, int max) -{ - PipOptions *options; - PipQuast *sol; - struct isl_map *map; - struct isl_ctx *ctx; - PipMatrix *domain = NULL, *context = NULL; - unsigned nparam, n_in, n_out; - - bmap = isl_basic_map_detect_equalities(bmap); - if (!bmap || !dom) - goto error; - - ctx = bmap->ctx; - isl_assert(ctx, isl_basic_map_compatible_domain(bmap, dom), goto error); - nparam = isl_basic_map_n_param(bmap); - n_in = isl_basic_map_n_in(bmap); - n_out = isl_basic_map_n_out(bmap); - - domain = isl_basic_map_to_pip(bmap, nparam + n_in, 0, dom->n_div); - if (!domain) - goto error; - context = isl_basic_map_to_pip((struct isl_basic_map *)dom, 0, 0, 0); - if (!context) - goto error; - - options = pip_options_init(); - options->Simplify = 1; - options->Maximize = max; - options->Urs_unknowns = -1; - options->Urs_parms = -1; - sol = pip_solve(domain, context, -1, options); - - if (sol) { - struct isl_basic_set *copy; - copy = isl_basic_set_copy(dom); - map = isl_map_from_quast(ctx, sol, - isl_space_copy(bmap->dim), copy, empty); - } else { - map = isl_map_empty_like_basic_map(bmap); - if (empty) - *empty = NULL; - } - if (!map) - goto error; - if (map->n == 0 && empty) { - isl_set_free(*empty); - *empty = isl_set_from_basic_set(dom); - } else - isl_basic_set_free(dom); - isl_basic_map_free(bmap); - - pip_quast_free(sol); - pip_options_free(options); - pip_matrix_free(domain); - pip_matrix_free(context); - - return map; -error: - if (domain) - pip_matrix_free(domain); - if (context) - pip_matrix_free(context); - isl_basic_map_free(bmap); - isl_basic_set_free(dom); - return NULL; -} diff -Nru isl-0.12.2/isl_map_piplib.h isl-0.15/isl_map_piplib.h --- isl-0.12.2/isl_map_piplib.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_map_piplib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -/* - * 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_MAP_PIPLIB_H -#define ISL_MAP_PIPLIB_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -struct isl_map *isl_pip_basic_map_lexopt( - struct isl_basic_map *bmap, struct isl_basic_set *dom, - struct isl_set **empty, int max); - -#if defined(__cplusplus) -} -#endif - -#endif diff -Nru isl-0.12.2/isl_map_private.h isl-0.15/isl_map_private.h --- isl-0.12.2/isl_map_private.h 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_map_private.h 2015-06-11 07:55:31.000000000 +0000 @@ -15,12 +15,12 @@ #define isl_basic_set_list isl_basic_map_list #define isl_set_list isl_map_list #include -ISL_DECLARE_LIST(basic_map) -ISL_DECLARE_LIST(map) #include #include #include #include +#include +#include /* A "basic map" is a relation between two sets of variables, * called the "in" and "out" variables. @@ -42,6 +42,7 @@ #define ISL_BASIC_MAP_NORMALIZED (1 << 5) #define ISL_BASIC_MAP_NORMALIZED_DIVS (1 << 6) #define ISL_BASIC_MAP_ALL_EQUALITIES (1 << 7) +#define ISL_BASIC_MAP_REDUCED_COEFFICIENTS (1 << 8) #define ISL_BASIC_SET_FINAL (1 << 0) #define ISL_BASIC_SET_EMPTY (1 << 1) #define ISL_BASIC_SET_NO_IMPLICIT (1 << 2) @@ -50,6 +51,7 @@ #define ISL_BASIC_SET_NORMALIZED (1 << 5) #define ISL_BASIC_SET_NORMALIZED_DIVS (1 << 6) #define ISL_BASIC_SET_ALL_EQUALITIES (1 << 7) +#define ISL_BASIC_SET_REDUCED_COEFFICIENTS (1 << 8) unsigned flags; struct isl_ctx *ctx; @@ -109,6 +111,53 @@ #include +__isl_give isl_basic_set *isl_basic_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim, unsigned extra, + unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_set *isl_basic_set_extend(__isl_take isl_basic_set *base, + unsigned nparam, unsigned dim, unsigned extra, + unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_set *isl_basic_set_extend_constraints( + __isl_take isl_basic_set *base, unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_set *isl_basic_set_finalize( + __isl_take isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_dup(__isl_keep isl_basic_set *bset); +__isl_give isl_basic_set *isl_basic_set_simplify( + __isl_take isl_basic_set *bset); + +__isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx, + unsigned nparam, unsigned in, unsigned out, unsigned extra, + unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_map *isl_basic_map_finalize( + __isl_take isl_basic_map *bmap); +__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base, + unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra, + unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_map *isl_basic_map_extend_constraints( + __isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq); +__isl_give isl_basic_map *isl_basic_map_simplify( + __isl_take isl_basic_map *bmap); + +__isl_give isl_set *isl_set_alloc(isl_ctx *ctx, + unsigned nparam, unsigned dim, int n, unsigned flags); +__isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set, + __isl_take isl_basic_set *bset); +__isl_give isl_set *isl_set_finalize(__isl_take isl_set *set); +__isl_give isl_set *isl_set_dup(__isl_keep isl_set *set); + +__isl_give isl_map *isl_map_alloc(isl_ctx *ctx, + unsigned nparam, unsigned in, unsigned out, int n, unsigned flags); +__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map, + __isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_dup(__isl_keep isl_map *map); +__isl_give isl_map *isl_map_finalize(__isl_take isl_map *map); + +__isl_give isl_basic_set *isl_basic_set_from_underlying_set( + __isl_take isl_basic_set *bset, __isl_take isl_basic_set *like); +__isl_give isl_set *isl_set_from_underlying_set( + __isl_take isl_set *set, __isl_take isl_basic_set *like); +__isl_give isl_set *isl_set_to_underlying_set(__isl_take isl_set *set); + __isl_give isl_map *isl_map_realign(__isl_take isl_map *map, __isl_take isl_reordering *r); __isl_give isl_set *isl_set_realign(__isl_take isl_set *set, @@ -149,8 +198,10 @@ struct isl_map *isl_map_grow(struct isl_map *map, int n); struct isl_set *isl_set_grow(struct isl_set *set, int n); -int isl_basic_set_contains(struct isl_basic_set *bset, struct isl_vec *vec); -int isl_basic_map_contains(struct isl_basic_map *bmap, struct isl_vec *vec); +isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset, + __isl_keep isl_vec *vec); +isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap, + __isl_keep isl_vec *vec); __isl_give isl_basic_set *isl_basic_set_alloc_space(__isl_take isl_space *dim, unsigned extra, unsigned n_eq, unsigned n_ineq); @@ -197,6 +248,8 @@ struct isl_set *isl_set_cow(struct isl_set *set); struct isl_map *isl_map_cow(struct isl_map *map); +uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap); + struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap); struct isl_basic_set *isl_basic_set_set_to_empty(struct isl_basic_set *bset); struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset); @@ -207,6 +260,10 @@ struct isl_basic_map *dst, struct isl_basic_map *src); struct isl_basic_set *isl_basic_set_align_divs( struct isl_basic_set *dst, struct isl_basic_set *src); +__isl_give isl_map *isl_map_align_divs_to_basic_map_list( + __isl_take isl_map *map, __isl_keep isl_basic_map_list *list); +__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map( + __isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap); __isl_give isl_basic_map *isl_basic_map_sort_divs( __isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_sort_divs(__isl_take isl_map *map); @@ -218,9 +275,7 @@ __isl_take isl_basic_set *bset); int isl_basic_map_plain_cmp(const __isl_keep isl_basic_map *bmap1, const __isl_keep isl_basic_map *bmap2); -int isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1, - __isl_keep isl_basic_set *bset2); -int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, +isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2); struct isl_basic_map *isl_basic_map_normalize_constraints( struct isl_basic_map *bmap); @@ -231,6 +286,8 @@ struct isl_basic_set *isl_basic_map_underlying_set(struct isl_basic_map *bmap); __isl_give isl_basic_set *isl_basic_set_underlying_set( __isl_take isl_basic_set *bset); +__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set( + __isl_take isl_basic_map_list *list); struct isl_set *isl_map_underlying_set(struct isl_map *map); struct isl_basic_map *isl_basic_map_overlying_set(struct isl_basic_set *bset, struct isl_basic_map *like); @@ -251,8 +308,14 @@ struct isl_map *isl_map_drop(struct isl_map *map, enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints( + __isl_take isl_basic_map *bmap, int *progress, int detect_divs); +__isl_give isl_basic_map *isl_basic_map_detect_inequality_pairs( + __isl_take isl_basic_map *bmap, int *progress); + struct isl_map *isl_map_remove_empty_parts(struct isl_map *map); struct isl_set *isl_set_remove_empty_parts(struct isl_set *set); +__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map); struct isl_set *isl_set_normalize(struct isl_set *set); @@ -275,6 +338,8 @@ int isl_basic_map_add_div_constraint(__isl_keep isl_basic_map *bmap, unsigned div, int sign); int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div); +__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints( + __isl_take isl_basic_map *bmap); struct isl_basic_map *isl_basic_map_drop_redundant_divs( struct isl_basic_map *bmap); struct isl_basic_set *isl_basic_set_drop_redundant_divs( @@ -305,9 +370,10 @@ isl_int *isl_set_wrap_facet(__isl_keep isl_set *set, isl_int *facet, isl_int *ridge); -int isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, + __isl_keep isl_point *point); +isl_bool isl_set_contains_point(__isl_keep isl_set *set, __isl_keep isl_point *point); -int isl_set_contains_point(__isl_keep isl_set *set, __isl_keep isl_point *point); int isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset, unsigned first, unsigned n, int *signs); @@ -342,9 +408,9 @@ __isl_take isl_map *map1, __isl_take isl_map *map2, __isl_give isl_map *(*fn)(__isl_take isl_map *map1, __isl_take isl_map *map2)); -int isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1, +isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1, __isl_keep isl_map *map2, - int (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2)); + isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2)); int isl_basic_map_foreach_lexopt(__isl_keep isl_basic_map *bmap, int max, int (*fn)(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list, @@ -363,8 +429,44 @@ int isl_map_compatible_range(__isl_keep isl_map *map, __isl_keep isl_set *set); -int isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap); +isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap); int isl_map_is_set(__isl_keep isl_map *map); +int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset, + unsigned dim, isl_int *val); + +__isl_give isl_basic_map *isl_basic_map_plain_affine_hull( + __isl_take isl_basic_map *bmap); + +int isl_basic_set_dim_residue_class(struct isl_basic_set *bset, + int pos, isl_int *modulo, isl_int *residue); +int isl_set_dim_residue_class(struct isl_set *set, + int pos, isl_int *modulo, isl_int *residue); + +__isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, isl_int value); +__isl_give isl_set *isl_set_fix(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int value); +int isl_map_plain_is_fixed(__isl_keep isl_map *map, + enum isl_dim_type type, unsigned pos, isl_int *val); + +int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap, + int pos); + +__isl_give isl_basic_map *isl_basic_map_reduce_coefficients( + __isl_take isl_basic_map *bmap); + +__isl_give isl_basic_map *isl_basic_map_shift_div( + __isl_take isl_basic_map *bmap, int div, isl_int shift); + +__isl_give isl_basic_map_list *isl_map_get_basic_map_list( + __isl_keep isl_map *map); + +__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp); + +int isl_basic_set_count_upto(__isl_keep isl_basic_set *bset, + isl_int max, isl_int *count); +int isl_set_count_upto(__isl_keep isl_set *set, isl_int max, isl_int *count); + #endif diff -Nru isl-0.12.2/isl_map_simplify.c isl-0.15/isl_map_simplify.c --- isl-0.12.2/isl_map_simplify.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_map_simplify.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,12 +1,15 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * 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 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include @@ -14,10 +17,11 @@ #include #include "isl_equalities.h" #include -#include +#include #include "isl_tab.h" #include #include +#include static void swap_equality(struct isl_basic_map *bmap, int a, int b) { @@ -493,14 +497,16 @@ /* Assumes divs have been ordered if keep_divs is set. */ -static void eliminate_div(struct isl_basic_map *bmap, isl_int *eq, - unsigned div, int keep_divs) +static __isl_give isl_basic_map *eliminate_div(__isl_take isl_basic_map *bmap, + isl_int *eq, unsigned div, int keep_divs) { unsigned pos = isl_space_dim(bmap->dim, isl_dim_all) + div; eliminate_var_using_equality(bmap, pos, eq, keep_divs, NULL); - isl_basic_map_drop_div(bmap, div); + bmap = isl_basic_map_drop_div(bmap, div); + + return bmap; } /* Check if elimination of div "div" using equality "eq" would not @@ -554,8 +560,9 @@ continue; modified = 1; *progress = 1; - eliminate_div(bmap, bmap->eq[i], d, 1); - isl_basic_map_drop_equality(bmap, i); + bmap = eliminate_div(bmap, bmap->eq[i], d, 1); + if (isl_basic_map_drop_equality(bmap, i) < 0) + return isl_basic_map_free(bmap); break; } } @@ -731,12 +738,14 @@ if (k <= 0) return bmap; - elim_for = isl_calloc_array(ctx, int, bmap->n_div); size = round_up(4 * bmap->n_div / 3 - 1); + if (size == 0) + return bmap; + elim_for = isl_calloc_array(ctx, int, bmap->n_div); bits = ffs(size) - 1; index = isl_calloc_array(ctx, int, size); - if (!index) - return bmap; + if (!elim_for || !index) + goto out; eq = isl_blk_alloc(ctx, 1+total); if (isl_blk_is_error(eq)) goto out; @@ -767,7 +776,9 @@ k = elim_for[l] - 1; isl_int_set_si(eq.data[1+total_var+k], -1); isl_int_set_si(eq.data[1+total_var+l], 1); - eliminate_div(bmap, eq.data, l, 1); + bmap = eliminate_div(bmap, eq.data, l, 1); + if (!bmap) + break; isl_int_set_si(eq.data[1+total_var+k], 0); isl_int_set_si(eq.data[1+total_var+l], 0); } @@ -1109,8 +1120,8 @@ return bmap; } -static struct isl_basic_map *remove_duplicate_constraints( - struct isl_basic_map *bmap, int *progress, int detect_divs) +__isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints( + __isl_take isl_basic_map *bmap, int *progress, int detect_divs) { unsigned int size; isl_int ***index; @@ -1124,6 +1135,8 @@ return bmap; size = round_up(4 * (bmap->n_ineq+1) / 3 - 1); + if (size == 0) + return bmap; bits = ffs(size) - 1; ctx = isl_basic_map_get_ctx(bmap); index = isl_calloc_array(ctx, isl_int **, size); @@ -1180,6 +1193,26 @@ return bmap; } +/* Detect all pairs of inequalities that form an equality. + * + * isl_basic_map_remove_duplicate_constraints detects at most one such pair. + * Call it repeatedly while it is making progress. + */ +__isl_give isl_basic_map *isl_basic_map_detect_inequality_pairs( + __isl_take isl_basic_map *bmap, int *progress) +{ + int duplicate; + + do { + duplicate = 0; + bmap = isl_basic_map_remove_duplicate_constraints(bmap, + &duplicate, 0); + if (progress && duplicate) + *progress = 1; + } while (duplicate); + + return bmap; +} /* Eliminate knowns divs from constraints where they appear with * a (positive or negative) unit coefficient. @@ -1294,7 +1327,10 @@ bmap = isl_basic_map_gauss(bmap, &progress); /* requires equalities in normal form */ bmap = normalize_divs(bmap, &progress); - bmap = remove_duplicate_constraints(bmap, &progress, 1); + bmap = isl_basic_map_remove_duplicate_constraints(bmap, + &progress, 1); + if (bmap && progress) + ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS); } return bmap; } @@ -1385,8 +1421,9 @@ /* * Remove divs that don't occur in any of the constraints or other divs. - * These can arise when dropping some of the variables in a quast - * returned by piplib. + * These can arise when dropping constraints from a basic map or + * when the divs of a basic map have been temporarily aligned + * with the divs of another basic map. */ static struct isl_basic_map *remove_redundant_divs(struct isl_basic_map *bmap) { @@ -1553,7 +1590,8 @@ } if (n_lower > 0 && n_upper > 0) { bmap = isl_basic_map_normalize_constraints(bmap); - bmap = remove_duplicate_constraints(bmap, NULL, 0); + bmap = isl_basic_map_remove_duplicate_constraints(bmap, + NULL, 0); bmap = isl_basic_map_gauss(bmap, NULL); bmap = isl_basic_map_remove_redundancies(bmap); need_gauss = 0; @@ -1725,10 +1763,12 @@ int k, h, l; isl_ctx *ctx; - if (!bset) - return NULL; + if (!bset || !context) + return bset; size = round_up(4 * (context->n_ineq+1) / 3 - 1); + if (size == 0) + return bset; bits = ffs(size) - 1; ctx = isl_basic_set_get_ctx(bset); index = isl_calloc_array(ctx, isl_int **, size); @@ -1759,6 +1799,42 @@ return bset; } +/* Remove constraints from "bmap" that are identical to constraints + * in "context" or that are more relaxed (greater constant term). + * + * We perform the test for shifted copies on the pure constraints + * in remove_shifted_constraints. + */ +static __isl_give isl_basic_map *isl_basic_map_remove_shifted_constraints( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_map *context) +{ + isl_basic_set *bset, *bset_context; + + if (!bmap || !context) + goto error; + + if (bmap->n_ineq == 0 || context->n_ineq == 0) { + isl_basic_map_free(context); + return bmap; + } + + context = isl_basic_map_align_divs(context, bmap); + bmap = isl_basic_map_align_divs(bmap, context); + + bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap)); + bset_context = isl_basic_map_underlying_set(context); + bset = remove_shifted_constraints(bset, bset_context); + isl_basic_set_free(bset_context); + + bmap = isl_basic_map_overlying_set(bset, bmap); + + return bmap; +error: + isl_basic_map_free(bmap); + isl_basic_map_free(context); + return NULL; +} + /* Does the (linear part of a) constraint "c" involve any of the "len" * "relevant" dimensions? */ @@ -1989,7 +2065,8 @@ for (i = 0; i < context_ineq; ++i) if (isl_tab_freeze_constraint(tab, i) < 0) goto error; - tab = isl_tab_extend(tab, bset->n_ineq); + if (isl_tab_extend_cons(tab, bset->n_ineq) < 0) + goto error; for (i = 0; i < bset->n_ineq; ++i) if (isl_tab_add_ineq(tab, bset->ineq[i]) < 0) goto error; @@ -2078,20 +2155,17 @@ context = drop_irrelevant_constraints(context, bset); - bset = isl_basic_set_intersect(bset, isl_basic_set_copy(context)); - if (isl_basic_set_plain_is_empty(bset)) { - isl_basic_set_free(context); - return bset; - } - bset = isl_basic_set_sort_constraints(bset); - aff = isl_basic_set_affine_hull(isl_basic_set_copy(bset)); + aff = isl_basic_set_copy(bset); + aff = isl_basic_set_intersect(aff, isl_basic_set_copy(context)); + aff = isl_basic_set_affine_hull(aff); if (!aff) goto error; if (isl_basic_set_plain_is_empty(aff)) { - isl_basic_set_free(aff); + isl_basic_set_free(bset); isl_basic_set_free(context); - return bset; + return aff; } + bset = isl_basic_set_sort_constraints(bset); if (aff->n_eq == 0) { isl_basic_set_free(aff); return uset_gist_full(bset, context); @@ -2149,6 +2223,7 @@ if (div_eq == 0) return bmap; + bmap = isl_basic_map_cow(bmap); if (context->n_div > 0) bmap = isl_basic_map_align_divs(bmap, context); @@ -2169,10 +2244,28 @@ return bmap; } +/* Return a basic map that has the same intersection with "context" as "bmap" + * and that is as "simple" as possible. + * + * The core computation is performed on the pure constraints. + * When we add back the meaning of the integer divisions, we need + * to (re)introduce the div constraints. If we happen to have + * discovered that some of these integer divisions are equal to + * some affine combination of other variables, then these div + * constraints may end up getting simplified in terms of the equalities, + * resulting in extra inequalities on the other variables that + * may have been removed already or that may not even have been + * part of the input. We try and remove those constraints of + * this form that are most obviously redundant with respect to + * the context. We also remove those div constraints that are + * redundant with respect to the other constraints in the result. + */ struct isl_basic_map *isl_basic_map_gist(struct isl_basic_map *bmap, struct isl_basic_map *context) { - struct isl_basic_set *bset; + isl_basic_set *bset, *eq; + isl_basic_map *eq_bmap; + unsigned n_div, n_eq, n_ineq; if (!bmap || !context) goto error; @@ -2182,8 +2275,10 @@ return bmap; } if (isl_basic_map_plain_is_empty(context)) { + isl_space *space = isl_basic_map_get_space(bmap); isl_basic_map_free(bmap); - return context; + isl_basic_map_free(context); + return isl_basic_map_universe(space); } if (isl_basic_map_plain_is_empty(bmap)) { isl_basic_map_free(context); @@ -2200,11 +2295,33 @@ context = isl_basic_map_align_divs(context, bmap); bmap = isl_basic_map_align_divs(bmap, context); + n_div = isl_basic_map_dim(bmap, isl_dim_div); bset = uset_gist(isl_basic_map_underlying_set(isl_basic_map_copy(bmap)), - isl_basic_map_underlying_set(context)); + isl_basic_map_underlying_set(isl_basic_map_copy(context))); + + if (!bset || bset->n_eq == 0 || n_div == 0 || + isl_basic_set_plain_is_empty(bset)) { + isl_basic_map_free(context); + return isl_basic_map_overlying_set(bset, bmap); + } + + n_eq = bset->n_eq; + n_ineq = bset->n_ineq; + eq = isl_basic_set_copy(bset); + eq = isl_basic_set_cow(eq); + if (isl_basic_set_free_inequality(eq, n_ineq) < 0) + eq = isl_basic_set_free(eq); + if (isl_basic_set_free_equality(bset, n_eq) < 0) + bset = isl_basic_set_free(bset); + + eq_bmap = isl_basic_map_overlying_set(eq, isl_basic_map_copy(bmap)); + eq_bmap = isl_basic_map_remove_shifted_constraints(eq_bmap, context); + bmap = isl_basic_map_overlying_set(bset, bmap); + bmap = isl_basic_map_intersect(bmap, eq_bmap); + bmap = isl_basic_map_remove_redundancies(bmap); - return isl_basic_map_overlying_set(bset, bmap); + return bmap; error: isl_basic_map_free(bmap); isl_basic_map_free(context); @@ -2220,17 +2337,19 @@ int i; if (!map || !context) - goto error;; + goto error; if (isl_basic_map_plain_is_empty(context)) { + isl_space *space = isl_map_get_space(map); isl_map_free(map); - return isl_map_from_basic_map(context); + isl_basic_map_free(context); + return isl_map_universe(space); } context = isl_basic_map_remove_redundancies(context); map = isl_map_cow(map); if (!map || !context) - goto error;; + goto error; isl_assert(map->ctx, isl_space_is_equal(map->dim, context->dim), goto error); map = isl_map_compute_divs(map); if (!map) @@ -2257,7 +2376,7 @@ } /* Return a map that has the same intersection with "context" as "map" - * and that as "simple" as possible. + * and that is as "simple" as possible. * * If "map" is already the universe, then we cannot make it any simpler. * Similarly, if "context" is the universe, then we cannot exploit it @@ -2266,12 +2385,21 @@ * return the corresponding universe. * * If none of these cases apply, we have to work a bit harder. + * During this computation, we make use of a single disjunct context, + * so if the original context consists of more than one disjunct + * then we need to approximate the context by a single disjunct set. + * Simply taking the simple hull may drop constraints that are + * only implicitly available in each disjunct. We therefore also + * look for constraints among those defining "map" that are valid + * for the context. These can then be used to simplify away + * the corresponding constraints in "map". */ static __isl_give isl_map *map_gist(__isl_take isl_map *map, __isl_take isl_map *context) { int equal; int is_universe; + isl_basic_map *hull; is_universe = isl_map_plain_is_universe(map); if (is_universe >= 0 && !is_universe) @@ -2294,7 +2422,22 @@ } context = isl_map_compute_divs(context); - return isl_map_gist_basic_map(map, isl_map_simple_hull(context)); + if (!context) + goto error; + if (isl_map_n_basic_map(context) == 1) { + hull = isl_map_simple_hull(context); + } else { + isl_ctx *ctx; + isl_map_list *list; + + ctx = isl_map_get_ctx(map); + list = isl_map_list_alloc(ctx, 2); + list = isl_map_list_add(list, isl_map_copy(context)); + list = isl_map_list_add(list, isl_map_copy(map)); + hull = isl_map_unshifted_simple_hull_from_map_list(context, + list); + } + return isl_map_gist_basic_map(map, hull); error: isl_map_free(map); isl_map_free(context); @@ -2337,6 +2480,19 @@ (struct isl_map *)context); } +/* Compute the gist of "bmap" with respect to the constraints "context" + * on the domain. + */ +__isl_give isl_basic_map *isl_basic_map_gist_domain( + __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *context) +{ + isl_space *space = isl_basic_map_get_space(bmap); + isl_basic_map *bmap_context = isl_basic_map_universe(space); + + bmap_context = isl_basic_map_intersect_domain(bmap_context, context); + return isl_basic_map_gist(bmap, bmap_context); +} + __isl_give isl_map *isl_map_gist_domain(__isl_take isl_map *map, __isl_take isl_set *context) { @@ -2372,7 +2528,7 @@ * one basic map in the context of the equalities of the other * basic map and check if we get a contradiction. */ -int isl_basic_map_plain_is_disjoint(__isl_keep isl_basic_map *bmap1, +isl_bool isl_basic_map_plain_is_disjoint(__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) { struct isl_vec *v = NULL; @@ -2381,17 +2537,17 @@ int i; if (!bmap1 || !bmap2) - return -1; + return isl_bool_error; isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim), - return -1); + return isl_bool_error); if (bmap1->n_div || bmap2->n_div) - return 0; + return isl_bool_false; if (!bmap1->n_eq && !bmap2->n_eq) - return 0; + return isl_bool_false; total = isl_space_dim(bmap1->dim, isl_dim_all); if (total == 0) - return 0; + return isl_bool_false; v = isl_vec_alloc(bmap1->ctx, 1 + total); if (!v) goto error; @@ -2426,15 +2582,15 @@ } isl_vec_free(v); free(elim); - return 0; + return isl_bool_false; disjoint: isl_vec_free(v); free(elim); - return 1; + return isl_bool_true; error: isl_vec_free(v); free(elim); - return -1; + return isl_bool_error; } int isl_basic_set_plain_is_disjoint(__isl_keep isl_basic_set *bset1, @@ -2446,13 +2602,10 @@ /* Are "map1" and "map2" obviously disjoint? * - * If they have different parameters, then we skip any further tests. - * In particular, the outcome of the subsequent calls to - * isl_space_tuple_match may be affected by the different parameters - * in nested spaces. + * If one of them is empty or if they live in different spaces (ignoring + * parameters), then they are clearly disjoint. * - * If one of them is empty or if they live in different spaces (assuming - * they have the same parameters), then they are clearly disjoint. + * If they have different parameters, then we skip any further tests. * * If they are obviously equal, but not obviously empty, then we will * not be able to detect if they are disjoint. @@ -2460,16 +2613,16 @@ * Otherwise we check if each basic map in "map1" is obviously disjoint * from each basic map in "map2". */ -int isl_map_plain_is_disjoint(__isl_keep isl_map *map1, +isl_bool isl_map_plain_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2) { int i, j; - int disjoint; - int intersect; - int match; + isl_bool disjoint; + isl_bool intersect; + isl_bool match; if (!map1 || !map2) - return -1; + return isl_bool_error; disjoint = isl_map_plain_is_empty(map1); if (disjoint < 0 || disjoint) @@ -2479,34 +2632,34 @@ if (disjoint < 0 || disjoint) return disjoint; - match = isl_space_match(map1->dim, isl_dim_param, - map2->dim, isl_dim_param); - if (match < 0 || !match) - return match < 0 ? -1 : 0; - - match = isl_space_tuple_match(map1->dim, isl_dim_in, + match = isl_space_tuple_is_equal(map1->dim, isl_dim_in, map2->dim, isl_dim_in); if (match < 0 || !match) - return match < 0 ? -1 : 1; + return match < 0 ? isl_bool_error : isl_bool_true; - match = isl_space_tuple_match(map1->dim, isl_dim_out, + match = isl_space_tuple_is_equal(map1->dim, isl_dim_out, map2->dim, isl_dim_out); if (match < 0 || !match) - return match < 0 ? -1 : 1; + return match < 0 ? isl_bool_error : isl_bool_true; + + match = isl_space_match(map1->dim, isl_dim_param, + map2->dim, isl_dim_param); + if (match < 0 || !match) + return match < 0 ? isl_bool_error : isl_bool_false; intersect = isl_map_plain_is_equal(map1, map2); if (intersect < 0 || intersect) - return intersect < 0 ? -1 : 0; + return intersect < 0 ? isl_bool_error : isl_bool_false; for (i = 0; i < map1->n; ++i) { for (j = 0; j < map2->n; ++j) { - int d = isl_basic_map_plain_is_disjoint(map1->p[i], - map2->p[j]); - if (d != 1) + isl_bool d = isl_basic_map_plain_is_disjoint(map1->p[i], + map2->p[j]); + if (d != isl_bool_true) return d; } } - return 1; + return isl_bool_true; } /* Are "map1" and "map2" disjoint? @@ -2516,10 +2669,10 @@ * If none of these cases apply, we compute the intersection and see if * the result is empty. */ -int isl_map_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2) { - int disjoint; - int intersect; + isl_bool disjoint; + isl_bool intersect; isl_map *test; disjoint = isl_map_plain_is_disjoint(map1, map2); @@ -2536,11 +2689,11 @@ intersect = isl_map_plain_is_universe(map1); if (intersect < 0 || intersect) - return intersect < 0 ? -1 : 0; + return intersect < 0 ? isl_bool_error : isl_bool_false; intersect = isl_map_plain_is_universe(map2); if (intersect < 0 || intersect) - return intersect < 0 ? -1 : 0; + return intersect < 0 ? isl_bool_error : isl_bool_false; test = isl_map_intersect(isl_map_copy(map1), isl_map_copy(map2)); disjoint = isl_map_is_empty(test); @@ -2549,7 +2702,57 @@ return disjoint; } -int isl_set_plain_is_disjoint(__isl_keep isl_set *set1, +/* Are "bmap1" and "bmap2" disjoint? + * + * They are disjoint if they are "obviously disjoint" or if one of them + * is empty. Otherwise, they are not disjoint if one of them is universal. + * If none of these cases apply, we compute the intersection and see if + * the result is empty. + */ +isl_bool isl_basic_map_is_disjoint(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) +{ + isl_bool disjoint; + isl_bool intersect; + isl_basic_map *test; + + disjoint = isl_basic_map_plain_is_disjoint(bmap1, bmap2); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_basic_map_is_empty(bmap1); + if (disjoint < 0 || disjoint) + return disjoint; + + disjoint = isl_basic_map_is_empty(bmap2); + if (disjoint < 0 || disjoint) + return disjoint; + + intersect = isl_basic_map_is_universe(bmap1); + if (intersect < 0 || intersect) + return intersect < 0 ? isl_bool_error : isl_bool_false; + + intersect = isl_basic_map_is_universe(bmap2); + if (intersect < 0 || intersect) + return intersect < 0 ? isl_bool_error : isl_bool_false; + + test = isl_basic_map_intersect(isl_basic_map_copy(bmap1), + isl_basic_map_copy(bmap2)); + disjoint = isl_basic_map_is_empty(test); + isl_basic_map_free(test); + + return disjoint; +} + +/* Are "bset1" and "bset2" disjoint? + */ +isl_bool isl_basic_set_is_disjoint(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_is_disjoint(bset1, bset2); +} + +isl_bool isl_set_plain_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2) { return isl_map_plain_is_disjoint((struct isl_map *)set1, @@ -2558,16 +2761,11 @@ /* Are "set1" and "set2" disjoint? */ -int isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2) +isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2) { return isl_map_is_disjoint(set1, set2); } -int isl_set_fast_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2) -{ - return isl_set_plain_is_disjoint(set1, set2); -} - /* Check if we can combine a given div with lower bound l and upper * bound u with some other div and if so return that other div. * Otherwise return -1. @@ -3122,3 +3320,209 @@ return (struct isl_set *) isl_map_drop_redundant_divs((struct isl_map *)set); } + +/* Does "bmap" satisfy any equality that involves more than 2 variables + * and/or has coefficients different from -1 and 1? + */ +static int has_multiple_var_equality(__isl_keep isl_basic_map *bmap) +{ + int i; + unsigned total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + + for (i = 0; i < bmap->n_eq; ++i) { + int j, k; + + j = isl_seq_first_non_zero(bmap->eq[i] + 1, total); + if (j < 0) + continue; + if (!isl_int_is_one(bmap->eq[i][1 + j]) && + !isl_int_is_negone(bmap->eq[i][1 + j])) + return 1; + + j += 1; + k = isl_seq_first_non_zero(bmap->eq[i] + 1 + j, total - j); + if (k < 0) + continue; + j += k; + if (!isl_int_is_one(bmap->eq[i][1 + j]) && + !isl_int_is_negone(bmap->eq[i][1 + j])) + return 1; + + j += 1; + k = isl_seq_first_non_zero(bmap->eq[i] + 1 + j, total - j); + if (k >= 0) + return 1; + } + + return 0; +} + +/* Remove any common factor g from the constraint coefficients in "v". + * The constant term is stored in the first position and is replaced + * by floor(c/g). If any common factor is removed and if this results + * in a tightening of the constraint, then set *tightened. + */ +static __isl_give isl_vec *normalize_constraint(__isl_take isl_vec *v, + int *tightened) +{ + isl_ctx *ctx; + + if (!v) + return NULL; + ctx = isl_vec_get_ctx(v); + isl_seq_gcd(v->el + 1, v->size - 1, &ctx->normalize_gcd); + if (isl_int_is_zero(ctx->normalize_gcd)) + return v; + if (isl_int_is_one(ctx->normalize_gcd)) + return v; + v = isl_vec_cow(v); + if (!v) + return NULL; + if (tightened && !isl_int_is_divisible_by(v->el[0], ctx->normalize_gcd)) + *tightened = 1; + isl_int_fdiv_q(v->el[0], v->el[0], ctx->normalize_gcd); + isl_seq_scale_down(v->el + 1, v->el + 1, ctx->normalize_gcd, + v->size - 1); + return v; +} + +/* If "bmap" is an integer set that satisfies any equality involving + * more than 2 variables and/or has coefficients different from -1 and 1, + * then use variable compression to reduce the coefficients by removing + * any (hidden) common factor. + * In particular, apply the variable compression to each constraint, + * factor out any common factor in the non-constant coefficients and + * then apply the inverse of the compression. + * At the end, we mark the basic map as having reduced constants. + * If this flag is still set on the next invocation of this function, + * then we skip the computation. + * + * Removing a common factor may result in a tightening of some of + * the constraints. If this happens, then we may end up with two + * opposite inequalities that can be replaced by an equality. + * We therefore call isl_basic_map_detect_inequality_pairs, + * which checks for such pairs of inequalities as well as eliminate_divs_eq + * and isl_basic_map_gauss if such a pair was found. + */ +__isl_give isl_basic_map *isl_basic_map_reduce_coefficients( + __isl_take isl_basic_map *bmap) +{ + unsigned total; + isl_ctx *ctx; + isl_vec *v; + isl_mat *eq, *T, *T2; + int i; + int tightened; + + if (!bmap) + return NULL; + if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS)) + return bmap; + if (isl_basic_map_is_rational(bmap)) + return bmap; + if (bmap->n_eq == 0) + return bmap; + if (!has_multiple_var_equality(bmap)) + return bmap; + + total = isl_basic_map_dim(bmap, isl_dim_all); + ctx = isl_basic_map_get_ctx(bmap); + v = isl_vec_alloc(ctx, 1 + total); + if (!v) + return isl_basic_map_free(bmap); + + eq = isl_mat_sub_alloc6(ctx, bmap->eq, 0, bmap->n_eq, 0, 1 + total); + T = isl_mat_variable_compression(eq, &T2); + if (!T || !T2) + goto error; + if (T->n_col == 0) { + isl_mat_free(T); + isl_mat_free(T2); + isl_vec_free(v); + return isl_basic_map_set_to_empty(bmap); + } + + tightened = 0; + for (i = 0; i < bmap->n_ineq; ++i) { + isl_seq_cpy(v->el, bmap->ineq[i], 1 + total); + v = isl_vec_mat_product(v, isl_mat_copy(T)); + v = normalize_constraint(v, &tightened); + v = isl_vec_mat_product(v, isl_mat_copy(T2)); + if (!v) + goto error; + isl_seq_cpy(bmap->ineq[i], v->el, 1 + total); + } + + isl_mat_free(T); + isl_mat_free(T2); + isl_vec_free(v); + + ISL_F_SET(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS); + + if (tightened) { + int progress = 0; + + bmap = isl_basic_map_detect_inequality_pairs(bmap, &progress); + if (progress) { + bmap = eliminate_divs_eq(bmap, &progress); + bmap = isl_basic_map_gauss(bmap, NULL); + } + } + + return bmap; +error: + isl_mat_free(T); + isl_mat_free(T2); + isl_vec_free(v); + return isl_basic_map_free(bmap); +} + +/* Shift the integer division at position "div" of "bmap" by "shift". + * + * That is, if the integer division has the form + * + * floor(f(x)/d) + * + * then replace it by + * + * floor((f(x) + shift * d)/d) - shift + */ +__isl_give isl_basic_map *isl_basic_map_shift_div( + __isl_take isl_basic_map *bmap, int div, isl_int shift) +{ + int i; + unsigned total; + + if (!bmap) + return NULL; + + total = isl_basic_map_dim(bmap, isl_dim_all); + total -= isl_basic_map_dim(bmap, isl_dim_div); + + isl_int_addmul(bmap->div[div][1], shift, bmap->div[div][0]); + + for (i = 0; i < bmap->n_eq; ++i) { + if (isl_int_is_zero(bmap->eq[i][1 + total + div])) + continue; + isl_int_submul(bmap->eq[i][0], + shift, bmap->eq[i][1 + total + div]); + } + for (i = 0; i < bmap->n_ineq; ++i) { + if (isl_int_is_zero(bmap->ineq[i][1 + total + div])) + continue; + isl_int_submul(bmap->ineq[i][0], + shift, bmap->ineq[i][1 + total + div]); + } + for (i = 0; i < bmap->n_div; ++i) { + if (isl_int_is_zero(bmap->div[i][0])) + continue; + if (isl_int_is_zero(bmap->div[i][1 + 1 + total + div])) + continue; + isl_int_submul(bmap->div[i][1], + shift, bmap->div[i][1 + 1 + total + div]); + } + + return bmap; +} diff -Nru isl-0.12.2/isl_map_subtract.c isl-0.15/isl_map_subtract.c --- isl-0.12.2/isl_map_subtract.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_map_subtract.c 2015-06-02 09:28:10.000000000 +0000 @@ -8,11 +8,12 @@ */ #include -#include +#include #include #include #include "isl_tab.h" #include +#include /* Expand the constraint "c" into "v". The initial "dim" dimensions * are the same, but "v" may have more divs than "c" and the divs of "c" @@ -286,14 +287,14 @@ * has been removed when we end up in a leaf, we simply pass along * the original basic map. */ -static int basic_map_collect_diff(__isl_take isl_basic_map *bmap, +static isl_stat basic_map_collect_diff(__isl_take isl_basic_map *bmap, __isl_take isl_map *map, struct isl_diff_collector *dc) { int i; int modified; int level; int init; - int empty; + isl_bool empty; isl_ctx *ctx; struct isl_tab *tab = NULL; struct isl_tab_undo **snap = NULL; @@ -306,7 +307,7 @@ if (empty) { isl_basic_map_free(bmap); isl_map_free(map); - return empty < 0 ? -1 : 0; + return empty < 0 ? isl_stat_error : isl_stat_ok; } bmap = isl_basic_map_cow(bmap); @@ -436,7 +437,7 @@ isl_basic_map_free(bmap); isl_map_free(map); - return 0; + return isl_stat_ok; error: isl_tab_free(tab); free(snap); @@ -450,7 +451,7 @@ free(div_map); isl_basic_map_free(bmap); isl_map_free(map); - return -1; + return isl_stat_error; } /* A diff collector that actually collects all parts of the @@ -482,7 +483,7 @@ { struct isl_subtract_diff_collector sdc; sdc.dc.add = &basic_map_subtract_add; - sdc.diff = isl_map_empty_like_basic_map(bmap); + sdc.diff = isl_map_empty(isl_basic_map_get_space(bmap)); if (basic_map_collect_diff(bmap, map, &sdc.dc) < 0) { isl_map_free(sdc.diff); sdc.diff = NULL; @@ -490,13 +491,32 @@ return sdc.diff; } +/* Return an empty map living in the same space as "map1" and "map2". + */ +static __isl_give isl_map *replace_pair_by_empty( __isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + isl_space *space; + + space = isl_map_get_space(map1); + isl_map_free(map1); + isl_map_free(map2); + return isl_map_empty(space); +} + /* Return the set difference between map1 and map2. * (U_i A_i) \ (U_j B_j) is computed as U_i (A_i \ (U_j B_j)) + * + * If "map1" and "map2" are obviously equal to each other, + * then return an empty map in the same space. + * + * If "map1" and "map2" are disjoint, then simply return "map1". */ static __isl_give isl_map *map_subtract( __isl_take isl_map *map1, __isl_take isl_map *map2) { int i; + int equal, disjoint; struct isl_map *diff; if (!map1 || !map2) @@ -504,7 +524,16 @@ isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error); - if (isl_map_is_empty(map2)) { + equal = isl_map_plain_is_equal(map1, map2); + if (equal < 0) + goto error; + if (equal) + return replace_pair_by_empty(map1, map2); + + disjoint = isl_map_is_disjoint(map1, map2); + if (disjoint < 0) + goto error; + if (disjoint) { isl_map_free(map2); return map1; } @@ -517,7 +546,7 @@ map1 = isl_map_remove_empty_parts(map1); map2 = isl_map_remove_empty_parts(map2); - diff = isl_map_empty_like(map1); + diff = isl_map_empty(isl_map_get_space(map1)); for (i = 0; i < map1->n; ++i) { struct isl_map *d; d = basic_map_subtract(isl_basic_map_copy(map1->p[i]), @@ -608,7 +637,7 @@ */ struct isl_is_empty_diff_collector { struct isl_diff_collector dc; - int empty; + isl_bool empty; }; /* isl_is_empty_diff_collector callback. @@ -628,36 +657,38 @@ /* Check if bmap \ map is empty by computing this set difference * and breaking off as soon as the difference is known to be non-empty. */ -static int basic_map_diff_is_empty(__isl_keep isl_basic_map *bmap, +static isl_bool basic_map_diff_is_empty(__isl_keep isl_basic_map *bmap, __isl_keep isl_map *map) { - int r; + isl_bool empty; + isl_stat r; struct isl_is_empty_diff_collector edc; - r = isl_basic_map_plain_is_empty(bmap); - if (r) - return r; + empty = isl_basic_map_plain_is_empty(bmap); + if (empty) + return empty; edc.dc.add = &basic_map_is_empty_add; - edc.empty = 1; + edc.empty = isl_bool_true; r = basic_map_collect_diff(isl_basic_map_copy(bmap), isl_map_copy(map), &edc.dc); if (!edc.empty) - return 0; + return isl_bool_false; - return r < 0 ? -1 : 1; + return r < 0 ? isl_bool_error : isl_bool_true; } /* Check if map1 \ map2 is empty by checking if the set difference is empty * for each of the basic maps in map1. */ -static int map_diff_is_empty(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +static isl_bool map_diff_is_empty(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) { int i; - int is_empty = 1; + isl_bool is_empty = isl_bool_true; if (!map1 || !map2) - return -1; + return isl_bool_error; for (i = 0; i < map1->n; ++i) { is_empty = basic_map_diff_is_empty(map1->p[i], map2); @@ -746,25 +777,27 @@ return NULL; } -/* Return 1 is the singleton map "map1" is a subset of "map2", +/* Return isl_bool_true if the singleton map "map1" is a subset of "map2", * i.e., if the single element of "map1" is also an element of "map2". * Assumes "map2" has known divs. */ -static int map_is_singleton_subset(__isl_keep isl_map *map1, +static isl_bool map_is_singleton_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2) { int i; - int is_subset = 0; + isl_bool is_subset = isl_bool_false; struct isl_point *point; if (!map1 || !map2) - return -1; + return isl_bool_error; if (map1->n != 1) - return -1; + isl_die(isl_map_get_ctx(map1), isl_error_invalid, + "expecting single-disjunct input", + return isl_bool_error); point = singleton_extract_point(map1->p[0]); if (!point) - return -1; + return isl_bool_error; for (i = 0; i < map2->n; ++i) { is_subset = isl_basic_map_contains_point(map2->p[i], point); @@ -776,39 +809,40 @@ return is_subset; } -static int map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +static isl_bool map_is_subset(__isl_keep isl_map *map1, + __isl_keep isl_map *map2) { - int is_subset = 0; - int empty; + isl_bool is_subset = isl_bool_false; + isl_bool empty; int rat1, rat2; if (!map1 || !map2) - return -1; + return isl_bool_error; if (!isl_map_has_equal_space(map1, map2)) - return 0; + return isl_bool_false; empty = isl_map_is_empty(map1); if (empty < 0) - return -1; + return isl_bool_error; if (empty) - return 1; + return isl_bool_true; empty = isl_map_is_empty(map2); if (empty < 0) - return -1; + return isl_bool_error; if (empty) - return 0; + return isl_bool_false; rat1 = isl_map_has_rational(map1); rat2 = isl_map_has_rational(map2); if (rat1 < 0 || rat2 < 0) - return -1; + return isl_bool_error; if (rat1 && !rat2) - return 0; + return isl_bool_false; if (isl_map_plain_is_universe(map2)) - return 1; + return isl_bool_true; map2 = isl_map_compute_divs(isl_map_copy(map2)); if (isl_map_plain_is_singleton(map1)) { @@ -822,13 +856,13 @@ return is_subset; } -int isl_map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2) +isl_bool isl_map_is_subset(__isl_keep isl_map *map1, __isl_keep isl_map *map2) { return isl_map_align_params_map_map_and_test(map1, map2, &map_is_subset); } -int isl_set_is_subset(struct isl_set *set1, struct isl_set *set2) +isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2) { return isl_map_is_subset( (struct isl_map *)set1, (struct isl_map *)set2); diff -Nru isl-0.12.2/isl_map_to_basic_set.c isl-0.15/isl_map_to_basic_set.c --- isl-0.12.2/isl_map_to_basic_set.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_map_to_basic_set.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,10 @@ +#include +#include +#include + +#define KEY_BASE map +#define KEY_EQUAL isl_map_plain_is_equal +#define VAL_BASE basic_set +#define VAL_EQUAL isl_basic_set_plain_is_equal + +#include diff -Nru isl-0.12.2/isl_mat.c isl-0.15/isl_mat.c --- isl-0.12.2/isl_mat.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_mat.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,19 +1,23 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2014 Ecole Normale Superieure * * 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 + * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France */ #include #include #include -#include +#include #include +#include #include #include +#include isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat) { @@ -205,7 +209,7 @@ return mat2; } -void *isl_mat_free(struct isl_mat *mat) +__isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat) { if (!mat) return NULL; @@ -345,6 +349,30 @@ return isl_mat_diag(ctx, n_row, ctx->one); } +/* Is "mat" a (possibly scaled) identity matrix? + */ +int isl_mat_is_scaled_identity(__isl_keep isl_mat *mat) +{ + int i; + + if (!mat) + return -1; + if (mat->n_row != mat->n_col) + return 0; + + for (i = 0; i < mat->n_row; ++i) { + if (isl_seq_first_non_zero(mat->row[i], i) != -1) + return 0; + if (isl_int_ne(mat->row[0][0], mat->row[i][i])) + return 0; + if (isl_seq_first_non_zero(mat->row[i] + i + 1, + mat->n_col - (i + 1)) != -1) + return 0; + } + + return 1; +} + struct isl_vec *isl_mat_vec_product(struct isl_mat *mat, struct isl_vec *vec) { int i; @@ -530,7 +558,7 @@ * with U and Q unimodular matrices and H a matrix in column echelon form * such that on each echelon row the entries in the non-echelon column * are non-negative (if neg == 0) or non-positive (if neg == 1) - * and stricly smaller (in absolute value) than the entries in the echelon + * and strictly smaller (in absolute value) than the entries in the echelon * column. * If U or Q are NULL, then these matrices are not computed. */ @@ -1007,6 +1035,11 @@ return mat; } +/* Calculate the product of two matrices. + * + * This function is optimized for operand matrices that contain many zeros and + * skips multiplications where we know one of the operands is zero. + */ __isl_give isl_mat *isl_mat_product(__isl_take isl_mat *left, __isl_take isl_mat *right) { @@ -1027,10 +1060,13 @@ return prod; } for (i = 0; i < prod->n_row; ++i) { - for (j = 0; j < prod->n_col; ++j) { + for (j = 0; j < prod->n_col; ++j) isl_int_mul(prod->row[i][j], left->row[i][0], right->row[0][j]); - for (k = 1; k < left->n_col; ++k) + for (k = 1; k < left->n_col; ++k) { + if (isl_int_is_zero(left->row[i][k])) + continue; + for (j = 0; j < prod->n_col; ++j) isl_int_addmul(prod->row[i][j], left->row[i][k], right->row[k][j]); } @@ -1151,14 +1187,12 @@ struct isl_set *isl_set_preimage(struct isl_set *set, struct isl_mat *mat) { - struct isl_ctx *ctx; int i; set = isl_set_cow(set); if (!set) return NULL; - ctx = set->ctx; for (i = 0; i < set->n; ++i) { set->p[i] = isl_basic_set_preimage(set->p[i], isl_mat_copy(mat)); @@ -1553,6 +1587,26 @@ return NULL; } +/* Return a copy of row "row" of "mat" as an isl_vec. + */ +__isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row) +{ + isl_vec *v; + + if (!mat) + return NULL; + if (row >= mat->n_row) + isl_die(mat->ctx, isl_error_invalid, "row out of range", + return NULL); + + v = isl_vec_alloc(isl_mat_get_ctx(mat), mat->n_col); + if (!v) + return NULL; + isl_seq_cpy(v->el, mat->row[row], mat->n_col); + + return v; +} + __isl_give isl_mat *isl_mat_vec_concat(__isl_take isl_mat *top, __isl_take isl_vec *bot) { diff -Nru isl-0.12.2/isl_mat_private.h isl-0.15/isl_mat_private.h --- isl-0.12.2/isl_mat_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_mat_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,5 @@ #include +#include struct isl_mat { int ref; @@ -28,3 +29,18 @@ void isl_mat_sub_neg(struct isl_ctx *ctx, isl_int **dst, isl_int **src, unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col); __isl_give isl_mat *isl_mat_diag(isl_ctx *ctx, unsigned n_row, isl_int d); + +__isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row, + isl_int m); + +__isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row); + +int isl_mat_is_scaled_identity(__isl_keep isl_mat *mat); + +void isl_mat_col_mul(struct isl_mat *mat, int dst_col, isl_int f, int src_col); +void isl_mat_col_submul(struct isl_mat *mat, + int dst_col, isl_int f, int src_col); + +int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v); +__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat, + int row, int col, isl_int v); diff -Nru isl-0.12.2/isl_morph.c isl-0.15/isl_morph.c --- isl-0.12.2/isl_morph.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_morph.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,20 +1,30 @@ /* - * Copyright 2010 INRIA Saclay + * Copyright 2010-2011 INRIA Saclay + * Copyright 2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France */ #include +#include #include -#include +#include #include #include #include +isl_ctx *isl_morph_get_ctx(__isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + return isl_basic_set_get_ctx(morph->dom); +} + __isl_give isl_morph *isl_morph_alloc( __isl_take isl_basic_set *dom, __isl_take isl_basic_set *ran, __isl_take isl_mat *map, __isl_take isl_mat *inv) @@ -88,6 +98,87 @@ free(morph); } +/* Is "morph" an identity on the parameters? + */ +static int identity_on_parameters(__isl_keep isl_morph *morph) +{ + int is_identity; + unsigned nparam; + isl_mat *sub; + + nparam = isl_morph_dom_dim(morph, isl_dim_param); + if (nparam != isl_morph_ran_dim(morph, isl_dim_param)) + return 0; + if (nparam == 0) + return 1; + sub = isl_mat_sub_alloc(morph->map, 0, 1 + nparam, 0, 1 + nparam); + is_identity = isl_mat_is_scaled_identity(sub); + isl_mat_free(sub); + + return is_identity; +} + +/* Return an affine expression of the variables of the range of "morph" + * in terms of the parameters and the variables of the domain on "morph". + * + * In order for the space manipulations to make sense, we require + * that the parameters are not modified by "morph". + */ +__isl_give isl_multi_aff *isl_morph_get_var_multi_aff( + __isl_keep isl_morph *morph) +{ + isl_space *dom, *ran, *space; + isl_local_space *ls; + isl_multi_aff *ma; + unsigned nparam, nvar; + int i; + int is_identity; + + if (!morph) + return NULL; + + is_identity = identity_on_parameters(morph); + if (is_identity < 0) + return NULL; + if (!is_identity) + isl_die(isl_morph_get_ctx(morph), isl_error_invalid, + "cannot handle parameter compression", return NULL); + + dom = isl_morph_get_dom_space(morph); + ls = isl_local_space_from_space(isl_space_copy(dom)); + ran = isl_morph_get_ran_space(morph); + space = isl_space_map_from_domain_and_range(dom, ran); + ma = isl_multi_aff_zero(space); + + nparam = isl_multi_aff_dim(ma, isl_dim_param); + nvar = isl_multi_aff_dim(ma, isl_dim_out); + for (i = 0; i < nvar; ++i) { + isl_val *val; + isl_vec *v; + isl_aff *aff; + + v = isl_mat_get_row(morph->map, 1 + nparam + i); + v = isl_vec_insert_els(v, 0, 1); + val = isl_mat_get_element_val(morph->map, 0, 0); + v = isl_vec_set_element_val(v, 0, val); + aff = isl_aff_alloc_vec(isl_local_space_copy(ls), v); + ma = isl_multi_aff_set_aff(ma, i, aff); + } + + isl_local_space_free(ls); + return ma; +} + +/* Return the domain space of "morph". + */ +__isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph) +{ + if (!morph) + return NULL; + + return isl_basic_set_get_space(morph->dom); +} + __isl_give isl_space *isl_morph_get_ran_space(__isl_keep isl_morph *morph) { if (!morph) @@ -213,8 +304,8 @@ if (!morph) return; - isl_basic_set_print(morph->dom, out, 0, "", "", ISL_FORMAT_ISL); - isl_basic_set_print(morph->ran, out, 0, "", "", ISL_FORMAT_ISL); + isl_basic_set_dump(morph->dom); + isl_basic_set_dump(morph->ran); isl_mat_print_internal(morph->map, out, 4); isl_mat_print_internal(morph->inv, out, 4); } diff -Nru isl-0.12.2/isl_morph.h isl-0.15/isl_morph.h --- isl-0.12.2/isl_morph.h 2013-12-23 11:34:14.000000000 +0000 +++ isl-0.15/isl_morph.h 2015-04-19 12:02:52.000000000 +0000 @@ -35,6 +35,8 @@ }; typedef struct isl_morph isl_morph; +isl_ctx *isl_morph_get_ctx(__isl_keep isl_morph *morph); + __isl_give isl_morph *isl_morph_alloc( __isl_take isl_basic_set *dom, __isl_take isl_basic_set *ran, __isl_take isl_mat *map, __isl_take isl_mat *inv); @@ -42,7 +44,10 @@ __isl_give isl_morph *isl_morph_identity(__isl_keep isl_basic_set *bset); void isl_morph_free(__isl_take isl_morph *morph); +__isl_give isl_space *isl_morph_get_dom_space(__isl_keep isl_morph *morph); __isl_give isl_space *isl_morph_get_ran_space(__isl_keep isl_morph *morph); +__isl_give isl_multi_aff *isl_morph_get_var_multi_aff( + __isl_keep isl_morph *morph); unsigned isl_morph_dom_dim(__isl_keep isl_morph *morph, enum isl_dim_type type); unsigned isl_morph_ran_dim(__isl_keep isl_morph *morph, enum isl_dim_type type); diff -Nru isl-0.12.2/isl_multi_apply_set.c isl-0.15/isl_multi_apply_set.c --- isl-0.12.2/isl_multi_apply_set.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_apply_set.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +#define APPLY_DOMBASE set +#define APPLY_DOM isl_set + +#include + +#undef APPLY_DOMBASE +#undef APPLY_DOM diff -Nru isl-0.12.2/isl_multi_apply_templ.c isl-0.15/isl_multi_apply_templ.c --- isl-0.12.2/isl_multi_apply_templ.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_apply_templ.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,81 @@ +/* + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2013 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + +#include + +/* Transform the elements of "multi" by applying "fn" to them + * with extra argument "set". + * + * The parameters of "multi" and "set" are assumed to have been aligned. + */ +__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)( + __isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set, + __isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set)) +{ + int i; + + if (!multi || !set) + goto error; + + if (multi->n == 0) { + FN(APPLY_DOM,free)(set); + return multi; + } + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + goto error; + + for (i = 0; i < multi->n; ++i) { + multi->p[i] = fn(multi->p[i], FN(APPLY_DOM,copy)(set)); + if (!multi->p[i]) + goto error; + } + + FN(APPLY_DOM,free)(set); + return multi; +error: + FN(APPLY_DOM,free)(set); + FN(MULTI(BASE),free)(multi); + return NULL; +} + +/* Transform the elements of "multi" by applying "fn" to them + * with extra argument "set". + * + * Align the parameters if needed and call apply_set_aligned. + */ +static __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply),APPLY_DOMBASE)( + __isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set, + __isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set)) +{ + isl_ctx *ctx; + + if (!multi || !set) + goto error; + + if (isl_space_match(multi->space, isl_dim_param, + set->dim, isl_dim_param)) + return FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(multi, + set, fn); + ctx = FN(MULTI(BASE),get_ctx)(multi); + if (!isl_space_has_named_params(multi->space) || + !isl_space_has_named_params(set->dim)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + multi = FN(MULTI(BASE),align_params)(multi, + FN(APPLY_DOM,get_space)(set)); + set = FN(APPLY_DOM,align_params)(set, FN(MULTI(BASE),get_space)(multi)); + return FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(multi, set, fn); +error: + FN(MULTI(BASE),free)(multi); + FN(APPLY_DOM,free)(set); + return NULL; +} diff -Nru isl-0.12.2/isl_multi_apply_union_set.c isl-0.15/isl_multi_apply_union_set.c --- isl-0.12.2/isl_multi_apply_union_set.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_apply_union_set.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +#define APPLY_DOMBASE union_set +#define APPLY_DOM isl_union_set + +#include + +#undef APPLY_DOMBASE +#undef APPLY_DOM diff -Nru isl-0.12.2/isl_multi_floor.c isl-0.15/isl_multi_floor.c --- isl-0.12.2/isl_multi_floor.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_floor.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright 2014 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + */ + +#include + +/* Given f, return floor(f). + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),floor)(__isl_take MULTI(BASE) *multi) +{ + int i; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + for (i = 0; i < multi->n; ++i) { + multi->p[i] = FN(EL,floor)(multi->p[i]); + if (!multi->p[i]) + return FN(MULTI(BASE),free)(multi); + } + + return multi; +} diff -Nru isl-0.12.2/isl_multi_gist.c isl-0.15/isl_multi_gist.c --- isl-0.12.2/isl_multi_gist.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_gist.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2013 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + +#include + +/* Compute the gist of "multi" with respect to the domain constraints + * of "context". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),gist)(__isl_take MULTI(BASE) *multi, + __isl_take DOM *context) +{ + return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, context, &FN(EL,gist)); +} + +/* Compute the gist of "multi" with respect to the parameter constraints + * of "context". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_set *context) +{ + return FN(MULTI(BASE),apply_set)(multi, context, &FN(EL,gist_params)); +} diff -Nru isl-0.12.2/isl_multi_intersect.c isl-0.15/isl_multi_intersect.c --- isl-0.12.2/isl_multi_intersect.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_intersect.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2013 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + +#include + +/* Intersect the domain of "multi" with "domain". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_domain)( + __isl_take MULTI(BASE) *multi, __isl_take DOM *domain) +{ + return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, domain, + &FN(EL,intersect_domain)); +} + +/* Intersect the parameter domain of "multi" with "domain". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_params)( + __isl_take MULTI(BASE) *multi, __isl_take isl_set *domain) +{ + return FN(MULTI(BASE),apply_set)(multi, domain, + &FN(EL,intersect_params)); +} diff -Nru isl-0.12.2/isl_multi_macro.h isl-0.15/isl_multi_macro.h --- isl-0.12.2/isl_multi_macro.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_multi_macro.h 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +#define xCAT(A,B) A ## B +#define CAT(A,B) xCAT(A,B) +#undef EL +#define EL CAT(isl_,BASE) +#define xFN(TYPE,NAME) TYPE ## _ ## NAME +#define FN(TYPE,NAME) xFN(TYPE,NAME) +#define xMULTI(BASE) isl_multi_ ## BASE +#define MULTI(BASE) xMULTI(BASE) +#undef DOM +#define DOM CAT(isl_,DOMBASE) diff -Nru isl-0.12.2/isl_multi_templ.c isl-0.15/isl_multi_templ.c --- isl-0.12.2/isl_multi_templ.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_multi_templ.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2011 Sven Verdoolaege - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2013 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -12,14 +12,8 @@ #include #include -#define xCAT(A,B) A ## B -#define CAT(A,B) xCAT(A,B) -#undef EL -#define EL CAT(isl_,BASE) -#define xFN(TYPE,NAME) TYPE ## _ ## NAME -#define FN(TYPE,NAME) xFN(TYPE,NAME) -#define xMULTI(BASE) isl_multi_ ## BASE -#define MULTI(BASE) xMULTI(BASE) +#include + #define MULTI_NAME(BASE) "isl_multi_" #BASE #define xLIST(EL) EL ## _list #define LIST(EL) xLIST(EL) @@ -34,6 +28,18 @@ return multi ? isl_space_copy(multi->space) : NULL; } +/* Return the position of the dimension of the given type and name + * in "multi". + * Return -1 if no such dimension can be found. + */ +int FN(MULTI(BASE),find_dim_by_name)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, const char *name) +{ + if (!multi) + return -1; + return isl_space_find_dim_by_name(multi->space, type, name); +} + __isl_give isl_space *FN(MULTI(BASE),get_domain_space)( __isl_keep MULTI(BASE) *multi) { @@ -105,7 +111,7 @@ return multi; } -void *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi) +__isl_null MULTI(BASE) *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi) { int i; @@ -123,6 +129,32 @@ return NULL; } +#ifndef NO_DIMS +/* Check whether "multi" has non-zero coefficients for any dimension + * in the given range or if any of these dimensions appear + * with non-zero coefficients in any of the integer divisions involved. + */ +isl_bool FN(MULTI(BASE),involves_dims)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (!multi) + return isl_bool_error; + if (multi->n == 0 || n == 0) + return isl_bool_false; + + for (i = 0; i < multi->n; ++i) { + isl_bool involves; + + involves = FN(EL,involves_dims)(multi->p[i], type, first, n); + if (involves < 0 || involves) + return involves; + } + + return isl_bool_false; +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),insert_dims)( __isl_take MULTI(BASE) *multi, enum isl_dim_type type, unsigned first, unsigned n) @@ -164,6 +196,7 @@ return FN(MULTI(BASE),insert_dims)(multi, type, pos, n); } +#endif unsigned FN(MULTI(BASE),dim)(__isl_keep MULTI(BASE) *multi, enum isl_dim_type type) @@ -171,6 +204,25 @@ return multi ? isl_space_dim(multi->space, type) : 0; } +/* Return the position of the first dimension of "type" with id "id". + * Return -1 if there is no such dimension. + */ +int FN(MULTI(BASE),find_dim_by_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, __isl_keep isl_id *id) +{ + if (!multi) + return -1; + return isl_space_find_dim_by_id(multi->space, type, id); +} + +/* Return the id of the given dimension. + */ +__isl_give isl_id *FN(MULTI(BASE),get_dim_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos) +{ + return multi ? isl_space_get_dim_id(multi->space, type, pos) : NULL; +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),set_dim_name)( __isl_take MULTI(BASE) *multi, enum isl_dim_type type, unsigned pos, const char *s) @@ -202,6 +254,24 @@ return multi ? isl_space_get_tuple_name(multi->space, type) : NULL; } +/* Does the specified tuple have an id? + */ +isl_bool FN(MULTI(BASE),has_tuple_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + if (!multi) + return isl_bool_error; + return isl_space_has_tuple_id(multi->space, type); +} + +/* Return the id of the specified tuple. + */ +__isl_give isl_id *FN(MULTI(BASE),get_tuple_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + return multi ? isl_space_get_tuple_id(multi->space, type) : NULL; +} + __isl_give EL *FN(FN(MULTI(BASE),get),BASE)(__isl_keep MULTI(BASE) *multi, int pos) { @@ -221,12 +291,23 @@ { isl_space *multi_space = NULL; isl_space *el_space = NULL; + int match; multi = FN(MULTI(BASE),cow)(multi); if (!multi || !el) goto error; multi_space = FN(MULTI(BASE),get_space)(multi); + match = FN(EL,matching_params)(el, multi_space); + if (match < 0) + goto error; + if (!match) { + multi = FN(MULTI(BASE),align_params)(multi, + FN(EL,get_space)(el)); + isl_space_free(multi_space); + multi_space = FN(MULTI(BASE),get_space)(multi); + el = FN(EL,align_params)(el, isl_space_copy(multi_space)); + } if (FN(EL,check_match_domain_space)(el, multi_space) < 0) goto error; @@ -302,6 +383,28 @@ return FN(MULTI(BASE),reset_space_and_domain)(multi, space, domain); } +/* Set the id of the given dimension of "multi" to "id". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_dim_id)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + isl_space *space; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi || !id) + goto error; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_set_dim_id(space, type, pos, id); + + return FN(MULTI(BASE),reset_space)(multi, space); +error: + isl_id_free(id); + FN(MULTI(BASE),free)(multi); + return NULL; +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_name)( __isl_keep MULTI(BASE) *multi, enum isl_dim_type type, const char *s) @@ -319,19 +422,58 @@ } __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_id)( - __isl_keep MULTI(BASE) *multi, enum isl_dim_type type, + __isl_take MULTI(BASE) *multi, enum isl_dim_type type, __isl_take isl_id *id) { isl_space *space; multi = FN(MULTI(BASE),cow)(multi); if (!multi) - return isl_id_free(id); + goto error; space = FN(MULTI(BASE),get_space)(multi); space = isl_space_set_tuple_id(space, type, id); return FN(MULTI(BASE),reset_space)(multi, space); +error: + isl_id_free(id); + return NULL; +} + +/* Drop the id on the specified tuple. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_tuple_id)( + __isl_take MULTI(BASE) *multi, enum isl_dim_type type) +{ + isl_space *space; + + if (!multi) + return NULL; + if (!FN(MULTI(BASE),has_tuple_id)(multi, type)) + return multi; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_reset_tuple_id(space, type); + + return FN(MULTI(BASE),reset_space)(multi, space); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_user)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_reset_user(space); + + return FN(MULTI(BASE),reset_space)(multi, space); } __isl_give MULTI(BASE) *FN(MULTI(BASE),realign_domain)( @@ -367,10 +509,17 @@ __isl_take MULTI(BASE) *multi, __isl_take isl_space *model) { isl_ctx *ctx; + isl_reordering *exp; if (!multi || !model) goto error; + if (isl_space_match(multi->space, isl_dim_param, + model, isl_dim_param)) { + isl_space_free(model); + return multi; + } + ctx = isl_space_get_ctx(model); if (!isl_space_has_named_params(model)) isl_die(ctx, isl_error_invalid, @@ -378,16 +527,12 @@ if (!isl_space_has_named_params(multi->space)) isl_die(ctx, isl_error_invalid, "input has unnamed parameters", goto error); - if (!isl_space_match(multi->space, isl_dim_param, - model, isl_dim_param)) { - isl_reordering *exp; - model = isl_space_params(model); - exp = isl_parameter_alignment_reordering(multi->space, model); - exp = isl_reordering_extend_space(exp, + model = isl_space_params(model); + exp = isl_parameter_alignment_reordering(multi->space, model); + exp = isl_reordering_extend_space(exp, FN(MULTI(BASE),get_domain_space)(multi)); - multi = FN(MULTI(BASE),realign_domain)(multi, exp); - } + multi = FN(MULTI(BASE),realign_domain)(multi, exp); isl_space_free(model); return multi; @@ -397,73 +542,6 @@ return NULL; } -#ifndef NO_GIST -static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_params_multi_set_and)( - __isl_take MULTI(BASE) *multi, __isl_take isl_set *set, - __isl_give MULTI(BASE) *(*fn)(__isl_take MULTI(BASE) *multi, - __isl_take isl_set *set)) -{ - isl_ctx *ctx; - - if (!multi || !set) - goto error; - if (isl_space_match(multi->space, isl_dim_param, - set->dim, isl_dim_param)) - return fn(multi, set); - ctx = FN(MULTI(BASE),get_ctx)(multi); - if (!isl_space_has_named_params(multi->space) || - !isl_space_has_named_params(set->dim)) - isl_die(ctx, isl_error_invalid, - "unaligned unnamed parameters", goto error); - multi = FN(MULTI(BASE),align_params)(multi, isl_set_get_space(set)); - set = isl_set_align_params(set, FN(MULTI(BASE),get_space)(multi)); - return fn(multi, set); -error: - FN(MULTI(BASE),free)(multi); - isl_set_free(set); - return NULL; -} - -__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_aligned)( - __isl_take MULTI(BASE) *multi, __isl_take isl_set *context) -{ - int i; - - multi = FN(MULTI(BASE),cow)(multi); - if (!multi || !context) - goto error; - - for (i = 0; i < multi->n; ++i) { - multi->p[i] = FN(EL,gist)(multi->p[i], isl_set_copy(context)); - if (!multi->p[i]) - goto error; - } - - isl_set_free(context); - return multi; -error: - isl_set_free(context); - FN(MULTI(BASE),free)(multi); - return NULL; -} - -__isl_give MULTI(BASE) *FN(MULTI(BASE),gist)(__isl_take MULTI(BASE) *multi, - __isl_take isl_set *context) -{ - return FN(MULTI(BASE),align_params_multi_set_and)(multi, context, - &FN(MULTI(BASE),gist_aligned)); -} - -__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_params)( - __isl_take MULTI(BASE) *multi, __isl_take isl_set *context) -{ - isl_space *space = FN(MULTI(BASE),get_domain_space)(multi); - isl_set *dom_context = isl_set_universe(space); - dom_context = isl_set_intersect_params(dom_context, context); - return FN(MULTI(BASE),gist)(multi, dom_context); -} -#endif - __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),LIST(BASE))( __isl_take isl_space *space, __isl_take LIST(EL) *list) { @@ -545,6 +623,7 @@ } #endif +#ifndef NO_ZERO /* Construct a multi expression in the given space with value zero in * each of the output dimensions. */ @@ -579,13 +658,29 @@ return multi; } +#endif #ifndef NO_FROM_BASE +/* Create a multiple expression with a single output/set dimension + * equal to "el". + * For most multiple expression types, the base type has a single + * output/set dimension and the space of the result is therefore + * the same as the space of the input. + * In the case of isl_multi_union_pw_aff, however, the base type + * lives in a parameter space and we therefore need to add + * a single set dimension. + */ __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),BASE)(__isl_take EL *el) { + isl_space *space; MULTI(BASE) *multi; - multi = FN(MULTI(BASE),alloc)(FN(EL,get_space)(el)); + space = FN(EL,get_space(el)); + if (isl_space_is_params(space)) { + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + } + multi = FN(MULTI(BASE),alloc)(space); multi = FN(FN(MULTI(BASE),set),BASE)(multi, 0, el); return multi; @@ -632,10 +727,42 @@ return multi; } +/* Align the parameters of "multi1" and "multi2" (if needed) and call "fn". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_params_multi_multi_and)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2, + __isl_give MULTI(BASE) *(*fn)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2)) +{ + isl_ctx *ctx; + + if (!multi1 || !multi2) + goto error; + if (isl_space_match(multi1->space, isl_dim_param, + multi2->space, isl_dim_param)) + return fn(multi1, multi2); + ctx = FN(MULTI(BASE),get_ctx)(multi1); + if (!isl_space_has_named_params(multi1->space) || + !isl_space_has_named_params(multi2->space)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + multi1 = FN(MULTI(BASE),align_params)(multi1, + FN(MULTI(BASE),get_space)(multi2)); + multi2 = FN(MULTI(BASE),align_params)(multi2, + FN(MULTI(BASE),get_space)(multi1)); + return fn(multi1, multi2); +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} + /* Given two MULTI(BASE)s A -> B and C -> D, - * construct a MULTI(BASE) (A * C) -> (B, D). + * construct a MULTI(BASE) (A * C) -> [B -> D]. + * + * The parameters are assumed to have been aligned. */ -__isl_give MULTI(BASE) *FN(MULTI(BASE),range_product)( +static __isl_give MULTI(BASE) *FN(MULTI(BASE),range_product_aligned)( __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) { int i, n1, n2; @@ -672,6 +799,131 @@ return NULL; } +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) (A * C) -> [B -> D]. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2, + &FN(MULTI(BASE),range_product_aligned)); +} + +/* Is the range of "multi" a wrapped relation? + */ +isl_bool FN(MULTI(BASE),range_is_wrapping)(__isl_keep MULTI(BASE) *multi) +{ + if (!multi) + return isl_bool_error; + return isl_space_range_is_wrapping(multi->space); +} + +/* Given a function A -> [B -> C], extract the function A -> B. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_domain)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + int total, keep; + + if (!multi) + return NULL; + if (!isl_space_range_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range is not a product", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + total = isl_space_dim(space, isl_dim_out); + space = isl_space_range_factor_domain(space); + keep = isl_space_dim(space, isl_dim_out); + multi = FN(MULTI(BASE),drop_dims)(multi, + isl_dim_out, keep, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Given a function A -> [B -> C], extract the function A -> C. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + int total, keep; + + if (!multi) + return NULL; + if (!isl_space_range_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range is not a product", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + total = isl_space_dim(space, isl_dim_out); + space = isl_space_range_factor_range(space); + keep = isl_space_dim(space, isl_dim_out); + multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_out, 0, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +#ifndef NO_PRODUCT +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) [A -> C] -> [B -> D]. + * + * The parameters are assumed to have been aligned. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),product_aligned)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + int i; + EL *el; + isl_space *space; + MULTI(BASE) *res; + int in1, in2, out1, out2; + + in1 = FN(MULTI(BASE),dim)(multi1, isl_dim_in); + in2 = FN(MULTI(BASE),dim)(multi2, isl_dim_in); + out1 = FN(MULTI(BASE),dim)(multi1, isl_dim_out); + out2 = FN(MULTI(BASE),dim)(multi2, isl_dim_out); + space = isl_space_product(FN(MULTI(BASE),get_space)(multi1), + FN(MULTI(BASE),get_space)(multi2)); + res = FN(MULTI(BASE),alloc)(isl_space_copy(space)); + space = isl_space_domain(space); + + for (i = 0; i < out1; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi1, i); + el = FN(EL,insert_dims)(el, isl_dim_in, in1, in2); + el = FN(EL,reset_domain_space)(el, isl_space_copy(space)); + res = FN(FN(MULTI(BASE),set),BASE)(res, i, el); + } + + for (i = 0; i < out2; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi2, i); + el = FN(EL,insert_dims)(el, isl_dim_in, 0, in1); + el = FN(EL,reset_domain_space)(el, isl_space_copy(space)); + res = FN(FN(MULTI(BASE),set),BASE)(res, out1 + i, el); + } + + isl_space_free(space); + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return res; +} + +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) [A -> C] -> [B -> D]. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2, + &FN(MULTI(BASE),product_aligned)); +} +#endif + __isl_give MULTI(BASE) *FN(MULTI(BASE),flatten_range)( __isl_take MULTI(BASE) *multi) { @@ -693,7 +945,7 @@ } /* Given two MULTI(BASE)s A -> B and C -> D, - * construct a MULTI(BASE) (A * C) -> [B -> D]. + * construct a MULTI(BASE) (A * C) -> (B, D). */ __isl_give MULTI(BASE) *FN(MULTI(BASE),flat_range_product)( __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) @@ -746,6 +998,7 @@ return NULL; } +#ifndef NO_SPLICE /* Given two multi expressions, "multi1" * * [A1 A2] -> [B1 B2] @@ -797,6 +1050,7 @@ FN(MULTI(BASE),free)(multi2); return NULL; } +#endif /* This function is currently only used from isl_aff.c */ @@ -838,6 +1092,25 @@ return NULL; } +/* Subtract "multi2" from "multi1" and return the result. + * + * The parameters of "multi1" and "multi2" are assumed to have been aligned. + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),sub_aligned)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,sub)); +} + +/* Subtract "multi2" from "multi1" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),sub)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2, + &FN(MULTI(BASE),sub_aligned)); +} + /* Multiply the elements of "multi" by "v" and return the result. */ __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi, @@ -874,6 +1147,46 @@ return FN(MULTI(BASE),free)(multi); } +/* Divide the elements of "multi" by "v" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_val *v) +{ + int i; + + if (!multi || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return multi; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + for (i = 0; i < multi->n; ++i) { + multi->p[i] = FN(EL,scale_down_val)(multi->p[i], + isl_val_copy(v)); + if (!multi->p[i]) + goto error; + } + + isl_val_free(v); + return multi; +error: + isl_val_free(v); + return FN(MULTI(BASE),free)(multi); +} + /* Multiply the elements of "multi" by the corresponding element of "mv" * and return the result. */ @@ -885,7 +1198,7 @@ if (!multi || !mv) goto error; - if (!isl_space_tuple_match(multi->space, isl_dim_out, + if (!isl_space_tuple_is_equal(multi->space, isl_dim_out, mv->space, isl_dim_set)) isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid, "spaces don't match", goto error); @@ -909,3 +1222,224 @@ isl_multi_val_free(mv); return FN(MULTI(BASE),free)(multi); } + +/* Divide the elements of "multi" by the corresponding element of "mv" + * and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + int i; + + if (!multi || !mv) + goto error; + + if (!isl_space_tuple_is_equal(multi->space, isl_dim_out, + mv->space, isl_dim_set)) + isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid, + "spaces don't match", goto error); + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + for (i = 0; i < multi->n; ++i) { + isl_val *v; + + v = isl_multi_val_get_val(mv, i); + multi->p[i] = FN(EL,scale_down_val)(multi->p[i], v); + if (!multi->p[i]) + goto error; + } + + isl_multi_val_free(mv); + return multi; +error: + isl_multi_val_free(mv); + return FN(MULTI(BASE),free)(multi); +} + +/* Compute the residues of the elements of "multi" modulo + * the corresponding element of "mv" and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + int i; + + if (!multi || !mv) + goto error; + + if (!isl_space_tuple_is_equal(multi->space, isl_dim_out, + mv->space, isl_dim_set)) + isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid, + "spaces don't match", goto error); + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + for (i = 0; i < multi->n; ++i) { + isl_val *v; + + v = isl_multi_val_get_val(mv, i); + multi->p[i] = FN(EL,mod_val)(multi->p[i], v); + if (!multi->p[i]) + goto error; + } + + isl_multi_val_free(mv); + return multi; +error: + isl_multi_val_free(mv); + return FN(MULTI(BASE),free)(multi); +} + +#ifndef NO_MOVE_DIMS +/* Move the "n" dimensions of "src_type" starting at "src_pos" of "multi" + * to dimensions of "dst_type" at "dst_pos". + * + * We only support moving input dimensions to parameters and vice versa. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),move_dims)(__isl_take MULTI(BASE) *multi, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + int i; + + if (!multi) + return NULL; + + if (n == 0 && + !isl_space_is_named_or_nested(multi->space, src_type) && + !isl_space_is_named_or_nested(multi->space, dst_type)) + return multi; + + if (dst_type == isl_dim_out || src_type == isl_dim_out) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "cannot move output/set dimension", + return FN(MULTI(BASE),free)(multi)); + if (dst_type == isl_dim_div || src_type == isl_dim_div) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "cannot move divs", + return FN(MULTI(BASE),free)(multi)); + if (src_pos + n > isl_space_dim(multi->space, src_type)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range out of bounds", + return FN(MULTI(BASE),free)(multi)); + if (dst_type == src_type) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_unsupported, + "moving dims within the same type not supported", + return FN(MULTI(BASE),free)(multi)); + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + multi->space = isl_space_move_dims(multi->space, dst_type, dst_pos, + src_type, src_pos, n); + if (!multi->space) + return FN(MULTI(BASE),free)(multi); + + for (i = 0; i < multi->n; ++i) { + multi->p[i] = FN(EL,move_dims)(multi->p[i], dst_type, dst_pos, + src_type, src_pos, n); + if (!multi->p[i]) + return FN(MULTI(BASE),free)(multi); + } + + return multi; +} +#endif + +/* Convert a multiple expression defined over a parameter domain + * into one that is defined over a zero-dimensional set. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),from_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + if (!multi) + return NULL; + if (!isl_space_is_set(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "not living in a set space", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_from_range(space); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Are "multi1" and "multi2" obviously equal? + */ +isl_bool FN(MULTI(BASE),plain_is_equal)(__isl_keep MULTI(BASE) *multi1, + __isl_keep MULTI(BASE) *multi2) +{ + int i; + isl_bool equal; + + if (!multi1 || !multi2) + return isl_bool_error; + if (multi1->n != multi2->n) + return isl_bool_false; + equal = isl_space_is_equal(multi1->space, multi2->space); + if (equal < 0 || !equal) + return equal; + + for (i = 0; i < multi1->n; ++i) { + equal = FN(EL,plain_is_equal)(multi1->p[i], multi2->p[i]); + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} + +#ifndef NO_DOMAIN +/* Return the shared domain of the elements of "multi". + */ +__isl_give isl_set *FN(MULTI(BASE),domain)(__isl_take MULTI(BASE) *multi) +{ + int i; + isl_set *dom; + + if (!multi) + return NULL; + + dom = isl_set_universe(FN(MULTI(BASE),get_domain_space)(multi)); + for (i = 0; i < multi->n; ++i) { + isl_set *dom_i; + + dom_i = FN(EL,domain)(FN(FN(MULTI(BASE),get),BASE)(multi, i)); + dom = isl_set_intersect(dom, dom_i); + } + + FN(MULTI(BASE),free)(multi); + return dom; +} +#endif + +#ifndef NO_NEG +/* Return the opposite of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi) +{ + int i; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + for (i = 0; i < multi->n; ++i) { + multi->p[i] = FN(EL,neg)(multi->p[i]); + if (!multi->p[i]) + return FN(MULTI(BASE),free)(multi); + } + + return multi; +} +#endif diff -Nru isl-0.12.2/isl_multi_templ.h isl-0.15/isl_multi_templ.h --- isl-0.12.2/isl_multi_templ.h 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/isl_multi_templ.h 2015-06-02 09:28:10.000000000 +0000 @@ -1,11 +1,6 @@ #include -#define xCAT(A,B) A ## B -#define CAT(A,B) xCAT(A,B) -#undef EL -#define EL CAT(isl_,BASE) -#define xMULTI(BASE) isl_multi_ ## BASE -#define MULTI(BASE) xMULTI(BASE) +#include struct MULTI(BASE) { int ref; diff -Nru isl-0.12.2/isl_obj.c isl-0.15/isl_obj.c --- isl-0.12.2/isl_obj.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_obj.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,169 +1,27 @@ /* * Copyright 2010 INRIA Saclay + * Copyright 2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ +#include #include #include +#include +#include #include +#include #include -struct isl_int_obj { - int ref; - isl_ctx *ctx; - isl_int v; -}; - -__isl_give isl_int_obj *isl_int_obj_alloc(isl_ctx *ctx, isl_int v) -{ - isl_int_obj *i; - - i = isl_alloc_type(ctx, isl_int_obj); - if (!i) - return NULL; - - i->ctx = ctx; - isl_ctx_ref(ctx); - i->ref = 1; - isl_int_init(i->v); - isl_int_set(i->v, v); - - return i; -} - -__isl_give isl_int_obj *isl_int_obj_copy(__isl_keep isl_int_obj *i) -{ - if (!i) - return NULL; - - i->ref++; - return i; -} - -__isl_give isl_int_obj *isl_int_obj_dup(__isl_keep isl_int_obj *i) -{ - if (!i) - return NULL; - - return isl_int_obj_alloc(i->ctx, i->v); -} - -__isl_give isl_int_obj *isl_int_obj_cow(__isl_take isl_int_obj *i) -{ - if (!i) - return NULL; - - if (i->ref == 1) - return i; - i->ref--; - return isl_int_obj_dup(i); -} - -void isl_int_obj_free(__isl_take isl_int_obj *i) -{ - if (!i) - return; - - if (--i->ref > 0) - return; - - isl_ctx_deref(i->ctx); - isl_int_clear(i->v); - free(i); -} - -__isl_give isl_int_obj *isl_int_obj_add(__isl_take isl_int_obj *i1, - __isl_take isl_int_obj *i2) -{ - i1 = isl_int_obj_cow(i1); - if (!i1 || !i2) - goto error; - - isl_int_add(i1->v, i1->v, i2->v); - - isl_int_obj_free(i2); - return i1; -error: - isl_int_obj_free(i1); - isl_int_obj_free(i2); - return NULL; -} - -__isl_give isl_int_obj *isl_int_obj_sub(__isl_take isl_int_obj *i1, - __isl_take isl_int_obj *i2) -{ - i1 = isl_int_obj_cow(i1); - if (!i1 || !i2) - goto error; - - isl_int_sub(i1->v, i1->v, i2->v); - - isl_int_obj_free(i2); - return i1; -error: - isl_int_obj_free(i1); - isl_int_obj_free(i2); - return NULL; -} - -__isl_give isl_int_obj *isl_int_obj_mul(__isl_take isl_int_obj *i1, - __isl_take isl_int_obj *i2) -{ - i1 = isl_int_obj_cow(i1); - if (!i1 || !i2) - goto error; - - isl_int_mul(i1->v, i1->v, i2->v); - - isl_int_obj_free(i2); - return i1; -error: - isl_int_obj_free(i1); - isl_int_obj_free(i2); - return NULL; -} - -void isl_int_obj_get_int(__isl_keep isl_int_obj *i, isl_int *v) -{ - if (!i) - return; - isl_int_set(*v, i->v); -} - -static void *isl_obj_int_copy(void *v) -{ - return isl_int_obj_copy((isl_int_obj *)v); -} - -static void isl_obj_int_free(void *v) -{ - isl_int_obj_free((isl_int_obj *)v); -} - -static __isl_give isl_printer *isl_obj_int_print(__isl_take isl_printer *p, - void *v) -{ - isl_int_obj *i = v; - return isl_printer_print_isl_int(p, i->v); -} - -static void *isl_obj_int_add(void *v1, void *v2) -{ - return isl_int_obj_add((isl_int_obj *)v1, (isl_int_obj *)v2); -} - -struct isl_obj_vtable isl_obj_int_vtable = { - isl_obj_int_copy, - isl_obj_int_add, - isl_obj_int_print, - isl_obj_int_free -}; - static void *isl_obj_val_copy(void *v) { return isl_val_copy((isl_val *)v); @@ -304,6 +162,35 @@ isl_obj_union_set_free }; +static void *isl_obj_pw_multi_aff_copy(void *v) +{ + return isl_pw_multi_aff_copy((isl_pw_multi_aff *) v); +} + +static void isl_obj_pw_multi_aff_free(void *v) +{ + isl_pw_multi_aff_free((isl_pw_multi_aff *) v); +} + +static __isl_give isl_printer *isl_obj_pw_multi_aff_print( + __isl_take isl_printer *p, void *v) +{ + return isl_printer_print_pw_multi_aff(p, (isl_pw_multi_aff *) v); +} + +static void *isl_obj_pw_multi_aff_add(void *v1, void *v2) +{ + return isl_pw_multi_aff_add((isl_pw_multi_aff *) v1, + (isl_pw_multi_aff *) v2); +} + +struct isl_obj_vtable isl_obj_pw_multi_aff_vtable = { + isl_obj_pw_multi_aff_copy, + isl_obj_pw_multi_aff_add, + isl_obj_pw_multi_aff_print, + isl_obj_pw_multi_aff_free +}; + static void *isl_obj_none_copy(void *v) { return v; @@ -452,3 +339,26 @@ isl_obj_union_pw_qpf_print, isl_obj_union_pw_qpf_free }; + +static void *isl_obj_schedule_copy(void *v) +{ + return isl_schedule_copy((isl_schedule *) v); +} + +static void isl_obj_schedule_free(void *v) +{ + isl_schedule_free((isl_schedule *) v); +} + +static __isl_give isl_printer *isl_obj_schedule_print( + __isl_take isl_printer *p, void *v) +{ + return isl_printer_print_schedule(p, (isl_schedule *) v); +} + +struct isl_obj_vtable isl_obj_schedule_vtable = { + isl_obj_schedule_copy, + NULL, + isl_obj_schedule_print, + isl_obj_schedule_free +}; diff -Nru isl-0.12.2/isl_options.c isl-0.15/isl_options.c --- isl-0.12.2/isl_options.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_options.c 2015-06-10 18:25:33.000000000 +0000 @@ -17,30 +17,6 @@ #include #include -struct isl_arg_choice isl_lp_solver_choice[] = { - {"tab", ISL_LP_TAB}, -#ifdef ISL_PIPLIB - {"pip", ISL_LP_PIP}, -#endif - {0} -}; - -struct isl_arg_choice isl_ilp_solver_choice[] = { - {"gbr", ISL_ILP_GBR}, -#ifdef ISL_PIPLIB - {"pip", ISL_ILP_PIP}, -#endif - {0} -}; - -struct isl_arg_choice isl_pip_solver_choice[] = { - {"tab", ISL_PIP_TAB}, -#ifdef ISL_PIPLIB - {"pip", ISL_PIP_PIP}, -#endif - {0} -}; - struct isl_arg_choice isl_pip_context_choice[] = { {"gbr", ISL_CONTEXT_GBR}, {"lexmin", ISL_CONTEXT_LEXMIN}, @@ -96,12 +72,30 @@ {0} }; +#define ISL_SCHEDULE_FUSE_MAX 0 +#define ISL_SCHEDULE_FUSE_MIN 1 + static struct isl_arg_choice fuse[] = { {"max", ISL_SCHEDULE_FUSE_MAX}, {"min", ISL_SCHEDULE_FUSE_MIN}, {0} }; +/* Callback for setting the "schedule-fuse" option. + * This (now hidden) option tries to mimic an option that was + * replaced by the schedule-serialize-sccs option. + * Setting the old option to ISL_SCHEDULE_FUSE_MIN is now + * expressed by turning on the schedule-serialize-sccs option. + */ +static int set_fuse(void *opt, unsigned val) +{ + struct isl_options *options = opt; + + options->schedule_serialize_sccs = (val == ISL_SCHEDULE_FUSE_MIN); + + return 0; +} + static struct isl_arg_choice separation_bounds[] = { {"explicit", ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT}, {"implicit", ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT}, @@ -114,12 +108,6 @@ } ISL_ARGS_START(struct isl_options, isl_options_args) -ISL_ARG_CHOICE(struct isl_options, lp_solver, 0, "lp-solver", \ - isl_lp_solver_choice, ISL_LP_TAB, "lp solver to use") -ISL_ARG_CHOICE(struct isl_options, ilp_solver, 0, "ilp-solver", \ - isl_ilp_solver_choice, ISL_ILP_GBR, "ilp solver to use") -ISL_ARG_CHOICE(struct isl_options, pip, 0, "pip", \ - isl_pip_solver_choice, ISL_PIP_TAB, "pip solver to use") ISL_ARG_CHOICE(struct isl_options, context, 0, "context", \ isl_pip_context_choice, ISL_CONTEXT_GBR, "how to handle the pip context tableau") @@ -156,10 +144,10 @@ ". A value of -1 allows arbitrary coefficients.") ISL_ARG_BOOL(struct isl_options, schedule_parametric, 0, "schedule-parametric", 1, "construct possibly parametric schedules") -ISL_ARG_BOOL(struct isl_options, schedule_outer_zero_distance, 0, - "schedule-outer-zero-distance", 0, - "try to construct schedules with outer zero distances over " - "proximity dependences") +ISL_ARG_BOOL(struct isl_options, schedule_outer_coincidence, 0, + "schedule-outer-coincidence", 0, + "try to construct schedules where the outer member of each band " + "satisfies the coincidence constraints") ISL_ARG_BOOL(struct isl_options, schedule_maximize_band_depth, 0, "schedule-maximize-band-depth", 0, "maximize the number of scheduling dimensions in a band") @@ -172,8 +160,12 @@ ISL_ARG_CHOICE(struct isl_options, schedule_algorithm, 0, "schedule-algorithm", isl_schedule_algorithm_choice, ISL_SCHEDULE_ALGORITHM_ISL, "scheduling algorithm to use") -ISL_ARG_CHOICE(struct isl_options, schedule_fuse, 0, "schedule-fuse", fuse, - ISL_SCHEDULE_FUSE_MAX, "level of fusion during scheduling") +ISL_ARG_BOOL(struct isl_options, schedule_serialize_sccs, 0, + "schedule-serialize-sccs", 0, + "serialize strongly connected components in dependence graph") +ISL_ARG_PHANTOM_USER_CHOICE_F(0, "schedule-fuse", fuse, &set_fuse, + ISL_SCHEDULE_FUSE_MAX, "level of fusion during scheduling", + ISL_ARG_HIDDEN) ISL_ARG_BOOL(struct isl_options, tile_scale_tile_loops, 0, "tile-scale-tile-loops", 1, "scale tile loops") ISL_ARG_BOOL(struct isl_options, tile_shift_point_loops, 0, @@ -181,6 +173,9 @@ ISL_ARG_STR(struct isl_options, ast_iterator_type, 0, "ast-iterator-type", "type", "int", "type used for iterators during printing of AST") +ISL_ARG_BOOL(struct isl_options, ast_always_print_block, 0, + "ast-always-print-block", 0, "print for and if bodies as a block " + "regardless of the number of statements in the body") ISL_ARG_BOOL(struct isl_options, ast_build_atomic_upper_bound, 0, "ast-build-atomic-upper-bound", 1, "generate atomic upper bounds") ISL_ARG_BOOL(struct isl_options, ast_build_prefer_pdiv, 0, @@ -202,6 +197,10 @@ "ast-build-allow-else", 1, "generate if statements with else branches") ISL_ARG_BOOL(struct isl_options, ast_build_allow_or, 0, "ast-build-allow-or", 1, "generate if conditions with disjunctions") +ISL_ARG_BOOL(struct isl_options, print_stats, 0, "print-stats", 0, + "print statistics for every isl_ctx") +ISL_ARG_ULONG(struct isl_options, max_operations, 0, + "max-operations", 0, "default number of maximal operations per isl_ctx") ISL_ARG_VERSION(print_version) ISL_ARGS_END @@ -253,19 +252,19 @@ schedule_separate_components) ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, - schedule_outer_zero_distance) + schedule_outer_coincidence) ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, - schedule_outer_zero_distance) + schedule_outer_coincidence) ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, schedule_algorithm) ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, schedule_algorithm) -ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, - schedule_fuse) -ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, - schedule_fuse) +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_serialize_sccs) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_serialize_sccs) ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, tile_scale_tile_loops) @@ -302,6 +301,11 @@ ISL_CTX_GET_STR_DEF(isl_options, struct isl_options, isl_options_args, ast_iterator_type) +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_always_print_block) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + ast_always_print_block) + ISL_CTX_SET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, ast_build_separation_bounds) ISL_CTX_GET_CHOICE_DEF(isl_options, struct isl_options, isl_options_args, diff -Nru isl-0.12.2/isl_options_private.h isl-0.15/isl_options_private.h --- isl-0.12.2/isl_options_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_options_private.h 2015-06-10 18:25:33.000000000 +0000 @@ -4,18 +4,6 @@ #include struct isl_options { - #define ISL_LP_TAB 0 - #define ISL_LP_PIP 1 - unsigned lp_solver; - - #define ISL_ILP_GBR 0 - #define ISL_ILP_PIP 1 - unsigned ilp_solver; - - #define ISL_PIP_TAB 0 - #define ISL_PIP_PIP 1 - unsigned pip; - #define ISL_CONTEXT_GBR 0 #define ISL_CONTEXT_LEXMIN 1 unsigned context; @@ -50,17 +38,18 @@ int schedule_max_coefficient; int schedule_max_constant_term; int schedule_parametric; - int schedule_outer_zero_distance; + int schedule_outer_coincidence; int schedule_maximize_band_depth; int schedule_split_scaled; int schedule_separate_components; unsigned schedule_algorithm; - int schedule_fuse; + int schedule_serialize_sccs; int tile_scale_tile_loops; int tile_shift_point_loops; char *ast_iterator_type; + int ast_always_print_block; int ast_build_atomic_upper_bound; int ast_build_prefer_pdiv; @@ -70,6 +59,9 @@ int ast_build_scale_strides; int ast_build_allow_else; int ast_build_allow_or; + + int print_stats; + unsigned long max_operations; }; #endif diff -Nru isl-0.12.2/isl_output.c isl-0.15/isl_output.c --- isl-0.12.2/isl_output.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_output.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,7 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -8,6 +9,7 @@ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France */ #include @@ -15,16 +17,18 @@ #include #include #include -#include +#include #include #include #include #include +#include #include #include #include #include -#include +#include +#include #include static const char *s_to[2] = { " -> ", " \\to " }; @@ -294,152 +298,129 @@ return print_affine_of_len(dim, NULL, p, c, len); } -static int defining_equality(__isl_keep isl_basic_map *eq, - __isl_keep isl_space *dim, enum isl_dim_type type, int pos) -{ - int i; - unsigned total; - - if (!eq) - return -1; - - pos += isl_space_offset(dim, type); - total = isl_basic_map_total_dim(eq); - - for (i = 0; i < eq->n_eq; ++i) { - if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos) - continue; - if (isl_int_is_one(eq->eq[i][1 + pos])) - isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total); - return i; - } - - return -1; -} +/* Internal data structure for print_space. + * + * latex is set if that is the output format. + * print_dim (if not NULL) is called on each dimension. + * user is set by the caller of print_space and may be used inside print_dim. + * + * space is the global space that is being printed. This field is set by + * print_space. + * type is the tuple of the global space that is currently being printed. + * This field is set by print_space. + */ +struct isl_print_space_data { + int latex; + __isl_give isl_printer *(*print_dim)(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos); + void *user; -static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p, - __isl_keep isl_aff *aff); + isl_space *space; + enum isl_dim_type type; +}; -/* offset is the offset of local_dim inside global_type of global_dim. +/* offset is the offset of local_dim inside data->type of data->space. */ static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p, - __isl_keep isl_space *global_dim, enum isl_dim_type global_type, __isl_keep isl_space *local_dim, enum isl_dim_type local_type, - int latex, __isl_keep isl_basic_map *eq, - __isl_keep isl_multi_aff *maff, int offset) + struct isl_print_space_data *data, int offset) { - int i, j; + int i; - if (global_dim != local_dim && local_type == isl_dim_out) + if (data->space != local_dim && local_type == isl_dim_out) offset += local_dim->n_in; for (i = 0; i < isl_space_dim(local_dim, local_type); ++i) { if (i) p = isl_printer_print_str(p, ", "); - if (maff && global_type == isl_dim_out) { - p = print_aff_body(p, maff->p[offset + i]); - continue; - } - j = defining_equality(eq, global_dim, global_type, offset + i); - if (j >= 0) { - int pos = 1 + isl_space_offset(global_dim, global_type) - + offset + i; - p = print_affine_of_len(eq->dim, NULL, - p, eq->eq[j], pos); - } else { - p = print_name(global_dim, p, global_type, offset + i, - latex); - } + if (data->print_dim) + p = data->print_dim(p, data, offset + i); + else + p = print_name(data->space, p, data->type, offset + i, + data->latex); } return p; } -static __isl_give isl_printer *print_var_list(__isl_keep isl_space *dim, - __isl_take isl_printer *p, enum isl_dim_type type, - int latex, __isl_keep isl_basic_map *eq, __isl_keep isl_multi_aff *maff) +static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p, + __isl_keep isl_space *space, enum isl_dim_type type) { - return print_nested_var_list(p, dim, type, dim, type, latex, - eq, maff, 0); + struct isl_print_space_data data = { .space = space, .type = type }; + + return print_nested_var_list(p, space, type, &data, 0); } static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p, - __isl_keep isl_space *global_dim, enum isl_dim_type global_type, __isl_keep isl_space *local_dim, - int latex, __isl_keep isl_basic_map *eq, - __isl_keep isl_multi_aff *maff, int offset); + struct isl_print_space_data *data, int offset); static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p, - __isl_keep isl_space *global_dim, enum isl_dim_type global_type, __isl_keep isl_space *local_dim, enum isl_dim_type local_type, - int latex, __isl_keep isl_basic_map *eq, - __isl_keep isl_multi_aff *maff, int offset) + struct isl_print_space_data *data, int offset) { const char *name = NULL; unsigned n = isl_space_dim(local_dim, local_type); if ((local_type == isl_dim_in || local_type == isl_dim_out)) { name = isl_space_get_tuple_name(local_dim, local_type); if (name) { - if (latex) + if (data->latex) p = isl_printer_print_str(p, "\\mathrm{"); p = isl_printer_print_str(p, name); - if (latex) + if (data->latex) p = isl_printer_print_str(p, "}"); } } - if (!latex || n != 1 || name) - p = isl_printer_print_str(p, s_open_list[latex]); + if (!data->latex || n != 1 || name) + p = isl_printer_print_str(p, s_open_list[data->latex]); if ((local_type == isl_dim_in || local_type == isl_dim_out) && local_dim->nested[local_type - isl_dim_in]) { - if (global_dim != local_dim && local_type == isl_dim_out) + if (data->space != local_dim && local_type == isl_dim_out) offset += local_dim->n_in; - p = print_nested_map_dim(p, global_dim, global_type, + p = print_nested_map_dim(p, local_dim->nested[local_type - isl_dim_in], - latex, eq, maff, offset); + data, offset); } else - p = print_nested_var_list(p, global_dim, global_type, - local_dim, local_type, latex, - eq, maff, offset); - if (!latex || n != 1 || name) - p = isl_printer_print_str(p, s_close_list[latex]); + p = print_nested_var_list(p, local_dim, local_type, data, + offset); + if (!data->latex || n != 1 || name) + p = isl_printer_print_str(p, s_close_list[data->latex]); return p; } static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim, __isl_take isl_printer *p, enum isl_dim_type type, - int latex, __isl_keep isl_basic_map *eq, __isl_keep isl_multi_aff *maff) + struct isl_print_space_data *data) { - return print_nested_tuple(p, dim, type, dim, type, latex, eq, maff, 0); + data->space = dim; + data->type = type; + return print_nested_tuple(p, dim, type, data, 0); } static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p, - __isl_keep isl_space *global_dim, enum isl_dim_type global_type, __isl_keep isl_space *local_dim, - int latex, __isl_keep isl_basic_map *eq, - __isl_keep isl_multi_aff *maff, int offset) + struct isl_print_space_data *data, int offset) { - p = print_nested_tuple(p, global_dim, global_type, - local_dim, isl_dim_in, latex, eq, maff, offset); - p = isl_printer_print_str(p, s_to[latex]); - p = print_nested_tuple(p, global_dim, global_type, - local_dim, isl_dim_out, latex, eq, maff, offset); + p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset); + p = isl_printer_print_str(p, s_to[data->latex]); + p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset); return p; } static __isl_give isl_printer *print_space(__isl_keep isl_space *dim, - __isl_take isl_printer *p, int latex, int rational, - __isl_keep isl_basic_map *eq, __isl_keep isl_multi_aff *maff) + __isl_take isl_printer *p, int rational, + struct isl_print_space_data *data) { - if (rational && !latex) + if (rational && !data->latex) p = isl_printer_print_str(p, "rat: "); if (isl_space_is_params(dim)) ; else if (isl_space_is_set(dim)) - p = print_tuple(dim, p, isl_dim_set, latex, eq, maff); + p = print_tuple(dim, p, isl_dim_set, data); else { - p = print_tuple(dim, p, isl_dim_in, latex, eq, maff); - p = isl_printer_print_str(p, s_to[latex]); - p = print_tuple(dim, p, isl_dim_out, latex, eq, maff); + p = print_tuple(dim, p, isl_dim_in, data); + p = isl_printer_print_str(p, s_to[data->latex]); + p = print_tuple(dim, p, isl_dim_out, data); } return p; @@ -453,7 +434,7 @@ p = isl_printer_start_line(p); p = isl_printer_print_str(p, "symbolic "); - p = print_var_list(dim, p, isl_dim_param, 0, NULL, NULL); + p = print_var_list(p, dim, isl_dim_param); p = isl_printer_print_str(p, ";"); p = isl_printer_end_line(p); return p; @@ -531,26 +512,85 @@ return NULL; } -static __isl_give isl_printer *print_omega_constraints( - __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p) +static __isl_give isl_printer *print_div(__isl_keep isl_space *dim, + __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p) { - if (bmap->n_eq + bmap->n_ineq == 0) - return p; + int c = p->output_format == ISL_FORMAT_C; + p = isl_printer_print_str(p, c ? "floord(" : "floor(("); + p = print_affine_of_len(dim, div, p, + div->row[pos] + 1, div->n_col - 1); + p = isl_printer_print_str(p, c ? ", " : ")/"); + p = isl_printer_print_isl_int(p, div->row[pos][0]); + p = isl_printer_print_str(p, ")"); + return p; +} - p = isl_printer_print_str(p, ": "); +/* Print a comma separated list of div names, with their definitions + * (provided that they have a definition and we are printing in isl format). + */ +static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex) +{ + int i; + unsigned n_div; + + if (!p || !space || !div) + return isl_printer_free(p); + + n_div = isl_mat_rows(div); + + for (i = 0; i < n_div; ++i) { + if (i) + p = isl_printer_print_str(p, ", "); + p = print_name(space, p, isl_dim_div, i, latex); + if (p->output_format != ISL_FORMAT_ISL || + isl_int_is_zero(div->row[i][0])) + continue; + p = isl_printer_print_str(p, " = "); + p = print_div(space, div, i, p); + } + + return p; +} + +static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap, + __isl_keep isl_space *dim, __isl_take isl_printer *p, int latex) +{ if (bmap->n_div > 0) { - int i; - p = isl_printer_print_str(p, "exists ("); - for (i = 0; i < bmap->n_div; ++i) { - if (i) - p = isl_printer_print_str(p, ", "); - p = print_name(bmap->dim, p, isl_dim_div, i, 0); - } + isl_space *space; + isl_mat *div; + + space = isl_basic_map_get_space(bmap); + div = isl_basic_map_get_divs(bmap); + p = isl_printer_print_str(p, s_open_exists[latex]); + p = print_div_list(p, space, div, latex); + isl_space_free(space); + isl_mat_free(div); p = isl_printer_print_str(p, ": "); } - p = print_constraints(bmap, bmap->dim, p, 0); + + p = print_constraints(bmap, dim, p, latex); + if (bmap->n_div > 0) - p = isl_printer_print_str(p, ")"); + p = isl_printer_print_str(p, s_close_exists[latex]); + return p; +} + +/* Print a colon followed by the constraints of "bmap" + * to "p", provided there are any constraints. + * The names of the variables are taken from "space". + * "latex" is set if the constraints should be printed in LaTeX format. + */ +static __isl_give isl_printer *print_optional_disjunct( + __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space, + __isl_take isl_printer *p, int latex) +{ + if (isl_basic_map_is_universe(bmap)) + return p; + + p = isl_printer_print_str(p, ": "); + p = print_disjunct(bmap, space, p, latex); + return p; } @@ -558,11 +598,11 @@ __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p) { p = isl_printer_print_str(p, "{ ["); - p = print_var_list(bmap->dim, p, isl_dim_in, 0, NULL, NULL); + p = print_var_list(p, bmap->dim, isl_dim_in); p = isl_printer_print_str(p, "] -> ["); - p = print_var_list(bmap->dim, p, isl_dim_out, 0, NULL, NULL); + p = print_var_list(p, bmap->dim, isl_dim_out); p = isl_printer_print_str(p, "] "); - p = print_omega_constraints(bmap, p); + p = print_optional_disjunct(bmap, bmap->dim, p, 0); p = isl_printer_print_str(p, " }"); return p; } @@ -571,9 +611,9 @@ __isl_keep isl_basic_set *bset, __isl_take isl_printer *p) { p = isl_printer_print_str(p, "{ ["); - p = print_var_list(bset->dim, p, isl_dim_set, 0, NULL, NULL); + p = print_var_list(p, bset->dim, isl_dim_set); p = isl_printer_print_str(p, "] "); - p = print_omega_constraints((isl_basic_map *)bset, p); + p = print_optional_disjunct(bset, bset->dim, p, 0); p = isl_printer_print_str(p, " }"); return p; } @@ -604,45 +644,19 @@ return p; } -static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap, - __isl_keep isl_space *dim, __isl_take isl_printer *p, int latex) -{ - if (bmap->n_div > 0) { - int i; - p = isl_printer_print_str(p, s_open_exists[latex]); - for (i = 0; i < bmap->n_div; ++i) { - if (i) - p = isl_printer_print_str(p, ", "); - p = print_name(dim, p, isl_dim_div, i, latex); - if (latex || isl_int_is_zero(bmap->div[i][0])) - continue; - p = isl_printer_print_str(p, " = [("); - p = print_affine(bmap, dim, p, bmap->div[i] + 1); - p = isl_printer_print_str(p, ")/"); - p = isl_printer_print_isl_int(p, bmap->div[i][0]); - p = isl_printer_print_str(p, "]"); - } - p = isl_printer_print_str(p, ": "); - } - - p = print_constraints(bmap, dim, p, latex); - - if (bmap->n_div > 0) - p = isl_printer_print_str(p, s_close_exists[latex]); - return p; -} - static __isl_give isl_printer *isl_basic_map_print_isl( __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int latex) { + struct isl_print_space_data data = { .latex = latex }; int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); + if (isl_basic_map_dim(bmap, isl_dim_param) > 0) { - p = print_tuple(bmap->dim, p, isl_dim_param, latex, NULL, NULL); + p = print_tuple(bmap->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); - p = print_space(bmap->dim, p, latex, rational, NULL, NULL); + p = print_space(bmap->dim, p, rational, &data); p = isl_printer_print_str(p, " : "); p = print_disjunct(bmap, bmap->dim, p, latex); p = isl_printer_print_str(p, " }"); @@ -826,12 +840,61 @@ return NULL; } +static int defining_equality(__isl_keep isl_basic_map *eq, + __isl_keep isl_space *dim, enum isl_dim_type type, int pos) +{ + int i; + unsigned total; + + if (!eq) + return -1; + + pos += isl_space_offset(dim, type); + total = isl_basic_map_total_dim(eq); + + for (i = 0; i < eq->n_eq; ++i) { + if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos) + continue; + if (isl_int_is_one(eq->eq[i][1 + pos])) + isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total); + return i; + } + + return -1; +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_basic_map keeping track of equalities. + * + * If the current dimension is defined by these equalities, then print + * the corresponding expression. Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_basic_map *eq = data->user; + int j; + + j = defining_equality(eq, data->space, data->type, pos); + if (j >= 0) { + pos += 1 + isl_space_offset(data->space, data->type); + p = print_affine_of_len(eq->dim, NULL, p, eq->eq[j], pos); + } else { + p = print_name(data->space, p, data->type, pos, data->latex); + } + + return p; +} + static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p, struct isl_aff_split *split, int n) { + struct isl_print_space_data data = { 0 }; int i; int rational; + data.print_dim = &print_dim_eq; for (i = 0; i < n; ++i) { isl_space *dim; @@ -842,7 +905,8 @@ ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL); if (i) p = isl_printer_print_str(p, "; "); - p = print_space(dim, p, 0, rational, split[i].aff, NULL); + data.user = split[i].aff; + p = print_space(dim, p, rational, &data); p = print_disjuncts_map(split[i].map, p, 0); } @@ -852,6 +916,7 @@ static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map, __isl_take isl_printer *p) { + struct isl_print_space_data data = { 0 }; struct isl_aff_split *split = NULL; int rational; @@ -862,7 +927,7 @@ } else { rational = map->n > 0 && ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL); - p = print_space(map->dim, p, 0, rational, NULL, NULL); + p = print_space(map->dim, p, rational, &data); p = print_disjuncts_map(map, p, 0); } free_split(split, map->n); @@ -872,8 +937,10 @@ static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map, __isl_take isl_printer *p) { + struct isl_print_space_data data = { 0 }; + if (isl_map_dim(map, isl_dim_param) > 0) { - p = print_tuple(map->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(map->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, s_to[0]); } p = isl_printer_print_str(p, s_open_set[0]); @@ -885,12 +952,17 @@ static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map, __isl_take isl_printer *p, __isl_keep isl_basic_map *aff) { + struct isl_print_space_data data = { 0 }; + + data.latex = 1; if (isl_map_dim(map, isl_dim_param) > 0) { - p = print_tuple(map->dim, p, isl_dim_param, 1, NULL, NULL); + p = print_tuple(map->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, s_to[1]); } p = isl_printer_print_str(p, s_open_set[1]); - p = print_space(map->dim, p, 1, 0, aff, NULL); + data.print_dim = &print_dim_eq; + data.user = aff; + p = print_space(map->dim, p, 0, &data); p = print_disjuncts_map(map, p, 1); p = isl_printer_print_str(p, s_close_set[1]); @@ -936,24 +1008,6 @@ return NULL; } -void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent, - const char *prefix, const char *suffix, unsigned output_format) -{ - isl_printer *printer; - - if (!bmap) - return; - - printer = isl_printer_to_file(bmap->ctx, out); - printer = isl_printer_set_indent(printer, indent); - printer = isl_printer_set_prefix(printer, prefix); - printer = isl_printer_set_suffix(printer, suffix); - printer = isl_printer_set_output_format(printer, output_format); - isl_printer_print_basic_map(printer, bmap); - - isl_printer_free(printer); -} - __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p, __isl_keep isl_basic_set *bset) { @@ -976,24 +1030,6 @@ return NULL; } -void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent, - const char *prefix, const char *suffix, unsigned output_format) -{ - isl_printer *printer; - - if (!bset) - return; - - printer = isl_printer_to_file(bset->ctx, out); - printer = isl_printer_set_indent(printer, indent); - printer = isl_printer_set_prefix(printer, prefix); - printer = isl_printer_set_suffix(printer, suffix); - printer = isl_printer_set_output_format(printer, output_format); - isl_printer_print_basic_set(printer, bset); - - isl_printer_free(printer); -} - __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p, __isl_keep isl_set *set) { @@ -1015,22 +1051,6 @@ return NULL; } -void isl_set_print(struct isl_set *set, FILE *out, int indent, - unsigned output_format) -{ - isl_printer *printer; - - if (!set) - return; - - printer = isl_printer_to_file(set->ctx, out); - printer = isl_printer_set_indent(printer, indent); - printer = isl_printer_set_output_format(printer, output_format); - printer = isl_printer_print_set(printer, set); - - isl_printer_free(printer); -} - __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p, __isl_keep isl_map *map) { @@ -1058,7 +1078,7 @@ int first; }; -static int print_map_body(__isl_take isl_map *map, void *user) +static isl_stat print_map_body(__isl_take isl_map *map, void *user) { struct isl_union_print_data *data; data = (struct isl_union_print_data *)user; @@ -1070,28 +1090,32 @@ data->p = isl_map_print_isl_body(map, data->p); isl_map_free(map); - return 0; + return isl_stat_ok; } static __isl_give isl_printer *isl_union_map_print_isl( __isl_keep isl_union_map *umap, __isl_take isl_printer *p) { - struct isl_union_print_data data = { p, 1 }; + struct isl_union_print_data data; + struct isl_print_space_data space_data = { 0 }; isl_space *dim; + dim = isl_union_map_get_space(umap); if (isl_space_dim(dim, isl_dim_param) > 0) { - p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(dim, p, isl_dim_param, &space_data); p = isl_printer_print_str(p, s_to[0]); } isl_space_free(dim); p = isl_printer_print_str(p, s_open_set[0]); + data.p = p; + data.first = 1; isl_union_map_foreach_map(umap, &print_map_body, &data); p = data.p; p = isl_printer_print_str(p, s_close_set[0]); return p; } -static int print_latex_map_body(__isl_take isl_map *map, void *user) +static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user) { struct isl_union_print_data *data; data = (struct isl_union_print_data *)user; @@ -1103,7 +1127,7 @@ data->p = isl_map_print_latex(map, data->p); isl_map_free(map); - return 0; + return isl_stat_ok; } static __isl_give isl_printer *isl_union_map_print_latex( @@ -1151,22 +1175,6 @@ return NULL; } -void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent, - unsigned output_format) -{ - isl_printer *printer; - - if (!map) - return; - - printer = isl_printer_to_file(map->ctx, out); - printer = isl_printer_set_indent(printer, indent); - printer = isl_printer_set_output_format(printer, output_format); - printer = isl_printer_print_map(printer, map); - - isl_printer_free(printer); -} - static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec) { int i; @@ -1179,19 +1187,6 @@ return n; } -static __isl_give isl_printer *print_div(__isl_keep isl_space *dim, - __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p) -{ - int c = p->output_format == ISL_FORMAT_C; - p = isl_printer_print_str(p, c ? "floord(" : "[("); - p = print_affine_of_len(dim, div, p, - div->row[pos] + 1, div->n_col - 1); - p = isl_printer_print_str(p, c ? ", " : ")/"); - p = isl_printer_print_isl_int(p, div->row[pos][0]); - p = isl_printer_print_str(p, c ? ")" : "]"); - return p; -} - static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up, __isl_take isl_printer *p, int first) { @@ -1327,16 +1322,18 @@ static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp) { + struct isl_print_space_data data = { 0 }; + if (!p || !qp) goto error; if (isl_space_dim(qp->dim, isl_dim_param) > 0) { - p = print_tuple(qp->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(qp->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); if (!isl_space_is_params(qp->dim)) { - p = print_space(qp->dim, p, 0, 0, NULL, NULL); + p = print_space(qp->dim, p, 0, &data); p = isl_printer_print_str(p, " -> "); } p = print_qpolynomial(p, qp); @@ -1446,13 +1443,14 @@ static __isl_give isl_printer *isl_pwqp_print_isl_body( __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) { + struct isl_print_space_data data = { 0 }; int i = 0; for (i = 0; i < pwqp->n; ++i) { if (i) p = isl_printer_print_str(p, "; "); if (!isl_space_is_params(pwqp->p[i].set->dim)) { - p = print_space(pwqp->p[i].set->dim, p, 0, 0, NULL, NULL); + p = print_space(pwqp->p[i].set->dim, p, 0, &data); p = isl_printer_print_str(p, " -> "); } p = print_qpolynomial(p, pwqp->p[i].qp); @@ -1465,17 +1463,19 @@ static __isl_give isl_printer *print_pw_qpolynomial_isl( __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) { + struct isl_print_space_data data = { 0 }; + if (!p || !pwqp) goto error; if (isl_space_dim(pwqp->dim, isl_dim_param) > 0) { - p = print_tuple(pwqp->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(pwqp->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); if (pwqp->n == 0) { if (!isl_space_is_set(pwqp->dim)) { - p = print_tuple(pwqp->dim, p, isl_dim_in, 0, NULL, NULL); + p = print_tuple(pwqp->dim, p, isl_dim_in, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "0"); @@ -1506,13 +1506,14 @@ static __isl_give isl_printer *isl_pwf_print_isl_body( __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) { + struct isl_print_space_data data = { 0 }; int i = 0; for (i = 0; i < pwf->n; ++i) { if (i) p = isl_printer_print_str(p, "; "); if (!isl_space_is_params(pwf->p[i].set->dim)) { - p = print_space(pwf->p[i].set->dim, p, 0, 0, NULL, NULL); + p = print_space(pwf->p[i].set->dim, p, 0, &data); p = isl_printer_print_str(p, " -> "); } p = qpolynomial_fold_print(pwf->p[i].fold, p); @@ -1525,14 +1526,16 @@ static __isl_give isl_printer *print_pw_qpolynomial_fold_isl( __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) { + struct isl_print_space_data data = { 0 }; + if (isl_space_dim(pwf->dim, isl_dim_param) > 0) { - p = print_tuple(pwf->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(pwf->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); if (pwf->n == 0) { if (!isl_space_is_set(pwf->dim)) { - p = print_tuple(pwf->dim, p, isl_dim_in, 0, NULL, NULL); + p = print_tuple(pwf->dim, p, isl_dim_in, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "0"); @@ -1625,10 +1628,13 @@ } /* We skip the constraint if it is implied by the div expression. + * + * *first indicates whether this is the first constraint in the conjunction and + * is updated if the constraint is actually printed. */ static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p, __isl_keep isl_space *dim, - __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first) + __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int *first) { unsigned o_div; unsigned n_div; @@ -1640,13 +1646,16 @@ if (div >= 0 && isl_basic_set_is_div_constraint(bset, c, div)) return p; - if (!first) + if (!*first) p = isl_printer_print_str(p, " && "); p = print_affine_c(p, dim, bset, c); p = isl_printer_print_str(p, " "); p = isl_printer_print_str(p, op); p = isl_printer_print_str(p, " 0"); + + *first = 0; + return p; } @@ -1654,6 +1663,7 @@ __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset) { int i, j; + int first = 1; unsigned n_div = isl_basic_set_dim(bset, isl_dim_div); unsigned total = isl_basic_set_total_dim(bset) - n_div; @@ -1661,7 +1671,7 @@ j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div); if (j < 0) p = print_constraint_c(p, dim, bset, - bset->eq[i], "==", !i); + bset->eq[i], "==", &first); else { if (i) p = isl_printer_print_str(p, " && "); @@ -1672,11 +1682,12 @@ p = isl_printer_print_isl_int(p, bset->eq[i][1 + total + j]); p = isl_printer_print_str(p, " == 0"); + first = 0; } } for (i = 0; i < bset->n_ineq; ++i) p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=", - !bset->n_eq && !i); + &first); return p; } @@ -1739,7 +1750,7 @@ return NULL; } -static int print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user) +static isl_stat print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user) { struct isl_union_print_data *data; data = (struct isl_union_print_data *)user; @@ -1751,21 +1762,25 @@ data->p = isl_pwqp_print_isl_body(data->p, pwqp); isl_pw_qpolynomial_free(pwqp); - return 0; + return isl_stat_ok; } static __isl_give isl_printer *print_union_pw_qpolynomial_isl( __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp) { - struct isl_union_print_data data = { p, 1 }; + struct isl_union_print_data data; + struct isl_print_space_data space_data = { 0 }; isl_space *dim; + dim = isl_union_pw_qpolynomial_get_space(upwqp); if (isl_space_dim(dim, isl_dim_param) > 0) { - p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(dim, p, isl_dim_param, &space_data); p = isl_printer_print_str(p, " -> "); } isl_space_free(dim); p = isl_printer_print_str(p, "{ "); + data.p = p; + data.first = 1; isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body, &data); p = data.p; @@ -1878,7 +1893,8 @@ isl_printer_free(p); } -static int print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, void *user) +static isl_stat print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, + void *user) { struct isl_union_print_data *data; data = (struct isl_union_print_data *)user; @@ -1890,22 +1906,26 @@ data->p = isl_pwf_print_isl_body(data->p, pwf); isl_pw_qpolynomial_fold_free(pwf); - return 0; + return isl_stat_ok; } static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl( __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial_fold *upwf) { - struct isl_union_print_data data = { p, 1 }; + struct isl_union_print_data data; + struct isl_print_space_data space_data = { 0 }; isl_space *dim; + dim = isl_union_pw_qpolynomial_fold_get_space(upwf); if (isl_space_dim(dim, isl_dim_param) > 0) { - p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(dim, p, isl_dim_param, &space_data); p = isl_printer_print_str(p, " -> "); } isl_space_free(dim); p = isl_printer_print_str(p, "{ "); + data.p = p; + data.first = 1; isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf, &print_pwf_body, &data); p = data.p; @@ -1950,11 +1970,13 @@ static __isl_give isl_printer *isl_printer_print_space_isl( __isl_take isl_printer *p, __isl_keep isl_space *dim) { + struct isl_print_space_data data = { 0 }; + if (!dim) goto error; if (isl_space_dim(dim, isl_dim_param) > 0) { - p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } @@ -1962,7 +1984,7 @@ if (isl_space_is_params(dim)) p = isl_printer_print_str(p, s_such_that[0]); else - p = print_space(dim, p, 0, 0, NULL, NULL); + p = print_space(dim, p, 0, &data); p = isl_printer_print_str(p, " }"); return p; @@ -1989,37 +2011,23 @@ __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p, __isl_keep isl_local_space *ls) { - unsigned total; + struct isl_print_space_data data = { 0 }; unsigned n_div; if (!ls) goto error; - total = isl_local_space_dim(ls, isl_dim_all); if (isl_local_space_dim(ls, isl_dim_param) > 0) { - p = print_tuple(ls->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(ls->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); - p = print_space(ls->dim, p, 0, 0, NULL, NULL); + p = print_space(ls->dim, p, 0, &data); n_div = isl_local_space_dim(ls, isl_dim_div); if (n_div > 0) { - int i; p = isl_printer_print_str(p, " : "); p = isl_printer_print_str(p, s_open_exists[0]); - for (i = 0; i < n_div; ++i) { - if (i) - p = isl_printer_print_str(p, ", "); - p = print_name(ls->dim, p, isl_dim_div, i, 0); - if (isl_int_is_zero(ls->div->row[i][0])) - continue; - p = isl_printer_print_str(p, " = [("); - p = print_affine_of_len(ls->dim, ls->div, p, - ls->div->row[i] + 1, 1 + total); - p = isl_printer_print_str(p, ")/"); - p = isl_printer_print_isl_int(p, ls->div->row[i][0]); - p = isl_printer_print_str(p, "]"); - } + p = print_div_list(p, ls->dim, ls->div, 0); } else if (isl_space_is_params(ls->dim)) p = isl_printer_print_str(p, s_such_that[0]); p = isl_printer_print_str(p, " }"); @@ -2034,6 +2042,9 @@ { unsigned total; + if (isl_aff_is_nan(aff)) + return isl_printer_print_str(p, "NaN"); + total = isl_local_space_dim(aff->ls, isl_dim_all); p = isl_printer_print_str(p, "("); p = print_affine_of_len(aff->ls->dim, aff->ls->div, p, @@ -2051,10 +2062,12 @@ static __isl_give isl_printer *print_aff(__isl_take isl_printer *p, __isl_keep isl_aff *aff) { + struct isl_print_space_data data = { 0 }; + if (isl_space_is_params(aff->ls->dim)) ; else { - p = print_tuple(aff->ls->dim, p, isl_dim_set, 0, NULL, NULL); + p = print_tuple(aff->ls->dim, p, isl_dim_set, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "["); @@ -2067,11 +2080,13 @@ static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p, __isl_keep isl_aff *aff) { + struct isl_print_space_data data = { 0 }; + if (!aff) goto error; if (isl_local_space_dim(aff->ls, isl_dim_param) > 0) { - p = print_tuple(aff->ls->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(aff->ls->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); @@ -2083,25 +2098,41 @@ return NULL; } +/* Print the body of an isl_pw_aff, i.e., a semicolon delimited + * sequence of affine expressions, each followed by constraints. + */ +static __isl_give isl_printer *print_pw_aff_body( + __isl_take isl_printer *p, __isl_keep isl_pw_aff *pa) +{ + int i; + + if (!pa) + return isl_printer_free(p); + + for (i = 0; i < pa->n; ++i) { + if (i) + p = isl_printer_print_str(p, "; "); + p = print_aff(p, pa->p[i].aff); + p = print_disjuncts((isl_map *)pa->p[i].set, p, 0); + } + + return p; +} + static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p, __isl_keep isl_pw_aff *pwaff) { - int i; + struct isl_print_space_data data = { 0 }; if (!pwaff) goto error; if (isl_space_dim(pwaff->dim, isl_dim_param) > 0) { - p = print_tuple(pwaff->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(pwaff->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); - for (i = 0; i < pwaff->n; ++i) { - if (i) - p = isl_printer_print_str(p, "; "); - p = print_aff(p, pwaff->p[i].aff); - p = print_disjuncts((isl_map *)pwaff->p[i].set, p, 0); - } + p = print_pw_aff_body(p, pwaff); p = isl_printer_print_str(p, " }"); return p; error: @@ -2205,29 +2236,6 @@ return p; } -/* Print the affine expression "aff" in C format to "p". - * The dimension names are taken from "space" - * "set" represents the domain of the affine expression. - */ -static __isl_give isl_printer *print_aff_on_domain_c(__isl_take isl_printer *p, - __isl_keep isl_space *space, __isl_keep isl_aff *aff, - __isl_keep isl_set *set) -{ - isl_set *u; - isl_ast_build *build; - isl_ast_expr *expr; - - u = isl_set_universe(isl_space_copy(space)); - build = isl_ast_build_from_context(u); - build = isl_ast_build_restrict(build, isl_set_copy(set)); - expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build); - p = isl_printer_print_ast_expr(p, expr); - isl_ast_expr_free(expr); - isl_ast_build_free(build); - - return p; -} - /* In the C format, we cannot express that "pwaff" may be undefined * on parts of the domain space. We therefore assume that the expression * will only be evaluated on its definition domain and compute the gist @@ -2236,44 +2244,23 @@ static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p, __isl_keep isl_pw_aff *pwaff) { - int i; isl_set *domain; - isl_space *space; + isl_ast_build *build; + isl_ast_expr *expr; if (pwaff->n < 1) isl_die(p->ctx, isl_error_unsupported, - "cannot print empty isl_pw_aff in C format", goto error); - space = isl_pw_aff_get_domain_space(pwaff); - if (!space) - goto error; + "cannot print empty isl_pw_aff in C format", + return isl_printer_free(p)); domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff)); + build = isl_ast_build_from_context(domain); + expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff)); + p = isl_printer_print_ast_expr(p, expr); + isl_ast_expr_free(expr); + isl_ast_build_free(build); - for (i = 0; i < pwaff->n - 1; ++i) { - isl_set *set_i; - - p = isl_printer_print_str(p, "("); - - set_i = isl_set_copy(pwaff->p[i].set); - set_i = isl_set_gist(set_i, isl_set_copy(domain)); - p = print_set_c(p, space, set_i); - isl_set_free(set_i); - - p = isl_printer_print_str(p, ") ? ("); - p = print_aff_on_domain_c(p, space, - pwaff->p[i].aff, pwaff->p[i].set); - p = isl_printer_print_str(p, ") : "); - } - - isl_set_free(domain); - - p = print_aff_on_domain_c(p, space, pwaff->p[pwaff->n - 1].aff, - pwaff->p[pwaff->n - 1].set); - isl_space_free(space); return p; -error: - isl_printer_free(p); - return NULL; } __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p, @@ -2310,20 +2297,124 @@ return NULL; } +/* Print "pa" in a sequence of isl_pw_affs delimited by semicolons. + * Each isl_pw_aff itself is also printed as semicolon delimited + * sequence of pieces. + * If data->first = 1, then this is the first in the sequence. + * Update data->first to tell the next element that it is not the first. + */ +static isl_stat print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa, + void *user) +{ + struct isl_union_print_data *data; + data = (struct isl_union_print_data *) user; + + if (!data->first) + data->p = isl_printer_print_str(data->p, "; "); + data->first = 0; + + data->p = print_pw_aff_body(data->p, pa); + isl_pw_aff_free(pa); + + return data->p ? isl_stat_ok : isl_stat_error; +} + +/* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited + * sequence of affine expressions, each followed by constraints, + * with the sequence enclosed in braces. + */ +static __isl_give isl_printer *print_union_pw_aff_body( + __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) +{ + struct isl_union_print_data data = { p, 1 }; + + p = isl_printer_print_str(p, s_open_set[0]); + data.p = p; + if (isl_union_pw_aff_foreach_pw_aff(upa, + &print_pw_aff_body_wrap, &data) < 0) + data.p = isl_printer_free(p); + p = data.p; + p = isl_printer_print_str(p, s_close_set[0]); + + return p; +} + +/* Print the isl_union_pw_aff "upa" to "p" in isl format. + * + * The individual isl_pw_affs are delimited by a semicolon. + */ +static __isl_give isl_printer *print_union_pw_aff_isl( + __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) +{ + struct isl_print_space_data data = { 0 }; + isl_space *space; + + space = isl_union_pw_aff_get_space(upa); + if (isl_space_dim(space, isl_dim_param) > 0) { + p = print_tuple(space, p, isl_dim_param, &data); + p = isl_printer_print_str(p, s_to[0]); + } + isl_space_free(space); + p = print_union_pw_aff_body(p, upa); + return p; +} + +/* Print the isl_union_pw_aff "upa" to "p". + * + * We currently only support an isl format. + */ +__isl_give isl_printer *isl_printer_print_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) +{ + if (!p || !upa) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_union_pw_aff_isl(p, upa); + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "unsupported output format", return isl_printer_free(p)); +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_aff. + * + * If the current dimension is an output dimension, then print + * the corresponding expression. Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_aff *ma = data->user; + + if (data->type == isl_dim_out) + p = print_aff_body(p, ma->p[pos]); + else + p = print_name(data->space, p, data->type, pos, data->latex); + + return p; +} + static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p, __isl_keep isl_multi_aff *maff) { - return print_space(maff->space, p, 0, 0, NULL, maff); + struct isl_print_space_data data = { 0 }; + + data.print_dim = &print_dim_ma; + data.user = maff; + return print_space(maff->space, p, 0, &data); } static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p, __isl_keep isl_multi_aff *maff) { + struct isl_print_space_data data = { 0 }; + if (!maff) goto error; if (isl_space_dim(maff->space, isl_dim_param) > 0) { - p = print_tuple(maff->space, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(maff->space, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); @@ -2373,11 +2464,13 @@ static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) { + struct isl_print_space_data data = { 0 }; + if (!pma) goto error; if (isl_space_dim(pma->dim, isl_dim_param) > 0) { - p = print_tuple(pma->dim, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(pma->dim, p, isl_dim_param, &data); p = isl_printer_print_str(p, " -> "); } p = isl_printer_print_str(p, "{ "); @@ -2454,7 +2547,7 @@ return NULL; } -static int print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma, +static isl_stat print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma, void *user) { struct isl_union_print_data *data; @@ -2467,22 +2560,25 @@ data->p = print_pw_multi_aff_body(data->p, pma); isl_pw_multi_aff_free(pma); - return 0; + return isl_stat_ok; } static __isl_give isl_printer *print_union_pw_multi_aff_isl( __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma) { - struct isl_union_print_data data = { p, 1 }; + struct isl_union_print_data data; + struct isl_print_space_data space_data = { 0 }; isl_space *space; space = isl_union_pw_multi_aff_get_space(upma); if (isl_space_dim(space, isl_dim_param) > 0) { - p = print_tuple(space, p, isl_dim_param, 0, NULL, NULL); + p = print_tuple(space, p, isl_dim_param, &space_data); p = isl_printer_print_str(p, s_to[0]); } isl_space_free(space); p = isl_printer_print_str(p, s_open_set[0]); + data.p = p; + data.first = 1; isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &print_pw_multi_aff_body_wrap, &data); p = data.p; @@ -2505,21 +2601,63 @@ return NULL; } +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_pw_aff. + * + * If the current dimension is an output dimension, then print + * the corresponding piecewise affine expression. + * Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + int i; + int need_parens; + isl_multi_pw_aff *mpa = data->user; + isl_pw_aff *pa; + + if (data->type != isl_dim_out) + return print_name(data->space, p, data->type, pos, data->latex); + + pa = mpa->p[pos]; + if (pa->n == 0) + return isl_printer_print_str(p, "(0 : 1 = 0)"); + + need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set); + if (need_parens) + p = isl_printer_print_str(p, "("); + for (i = 0; i < pa->n; ++i) { + if (i) + p = isl_printer_print_str(p, "; "); + p = print_aff_body(p, pa->p[i].aff); + p = print_disjuncts(pa->p[i].set, p, 0); + } + if (need_parens) + p = isl_printer_print_str(p, ")"); + + return p; +} + +/* Print "mpa" to "p" in isl format. + */ static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa) { - int i; + struct isl_print_space_data data = { 0 }; if (!mpa) return isl_printer_free(p); - p = isl_printer_print_str(p, "("); - for (i = 0; i < mpa->n; ++i) { - if (i) - p = isl_printer_print_str(p, ","); - p = isl_printer_print_pw_aff(p, mpa->p[i]); + if (isl_space_dim(mpa->space, isl_dim_param) > 0) { + p = print_tuple(mpa->space, p, isl_dim_param, &data); + p = isl_printer_print_str(p, " -> "); } - p = isl_printer_print_str(p, ")"); + p = isl_printer_print_str(p, "{ "); + data.print_dim = &print_dim_mpa; + data.user = mpa; + p = print_space(mpa->space, p, 0, &data); + p = isl_printer_print_str(p, " }"); return p; } @@ -2534,3 +2672,120 @@ isl_die(p->ctx, isl_error_unsupported, "unsupported output format", return isl_printer_free(p)); } + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_val. + * + * If the current dimension is an output dimension, then print + * the corresponding value. Otherwise, print the name of the dimension. + */ +static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_val *mv = data->user; + + if (data->type == isl_dim_out) + return isl_printer_print_val(p, mv->p[pos]); + else + return print_name(data->space, p, data->type, pos, data->latex); +} + +/* Print the isl_multi_val "mv" to "p" in isl format. + */ +static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p, + __isl_keep isl_multi_val *mv) +{ + struct isl_print_space_data data = { 0 }; + + if (!mv) + return isl_printer_free(p); + + if (isl_space_dim(mv->space, isl_dim_param) > 0) { + p = print_tuple(mv->space, p, isl_dim_param, &data); + p = isl_printer_print_str(p, " -> "); + } + p = isl_printer_print_str(p, "{ "); + data.print_dim = &print_dim_mv; + data.user = mv; + p = print_space(mv->space, p, 0, &data); + p = isl_printer_print_str(p, " }"); + return p; +} + +/* Print the isl_multi_val "mv" to "p". + * + * Currently only supported in isl format. + */ +__isl_give isl_printer *isl_printer_print_multi_val( + __isl_take isl_printer *p, __isl_keep isl_multi_val *mv) +{ + if (!p || !mv) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_val_isl(p, mv); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + return isl_printer_free(p)); +} + +/* Print dimension "pos" of data->space to "p". + * + * data->user is assumed to be an isl_multi_union_pw_aff. + * + * The current dimension is necessarily a set dimension, so + * we print the corresponding isl_union_pw_aff, including + * the braces. + */ +static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p, + struct isl_print_space_data *data, unsigned pos) +{ + isl_multi_union_pw_aff *mupa = data->user; + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos); + p = print_union_pw_aff_body(p, upa); + isl_union_pw_aff_free(upa); + + return p; +} + +/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format. + */ +static __isl_give isl_printer *print_multi_union_pw_aff_isl( + __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa) +{ + struct isl_print_space_data data = { 0 }; + isl_space *space; + + space = isl_multi_union_pw_aff_get_space(mupa); + if (isl_space_dim(space, isl_dim_param) > 0) { + struct isl_print_space_data space_data = { 0 }; + p = print_tuple(space, p, isl_dim_param, &space_data); + p = isl_printer_print_str(p, s_to[0]); + } + + data.print_dim = &print_union_pw_aff_dim; + data.user = mupa; + + p = print_space(space, p, 0, &data); + isl_space_free(space); + + return p; +} + +/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format. + * + * We currently only support an isl format. + */ +__isl_give isl_printer *isl_printer_print_multi_union_pw_aff( + __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa) +{ + if (!p || !mupa) + return isl_printer_free(p); + + if (p->output_format == ISL_FORMAT_ISL) + return print_multi_union_pw_aff_isl(p, mupa); + isl_die(isl_printer_get_ctx(p), isl_error_unsupported, + "unsupported output format", return isl_printer_free(p)); +} diff -Nru isl-0.12.2/isl_piplib.c isl-0.15/isl_piplib.c --- isl-0.12.2/isl_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -/* - * 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 - */ - -#include "isl_piplib.h" - -void isl_seq_cpy_to_pip(Entier *dst, isl_int *src, unsigned len) -{ - int i; - - for (i = 0; i < len; ++i) - entier_assign(dst[i], src[i]); -} - -void isl_seq_cpy_from_pip(isl_int *dst, Entier *src, unsigned len) -{ - int i; - - for (i = 0; i < len; ++i) - entier_assign(dst[i], src[i]); -} diff -Nru isl-0.12.2/isl_piplib.h isl-0.15/isl_piplib.h --- isl-0.12.2/isl_piplib.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_piplib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -/* - * 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_PIPLIB_H -#define ISL_PIPLIB_H - -#include -#include -#include -#ifndef ISL_PIPLIB -#error "no piplib" -#endif - -#include - -void isl_seq_cpy_to_pip(Entier *dst, isl_int *src, unsigned len); -void isl_seq_cpy_from_pip(isl_int *dst, Entier *src, unsigned len); - -PipMatrix *isl_basic_map_to_pip(struct isl_basic_map *bmap, unsigned pip_param, - unsigned extra_front, unsigned extra_back); - -#endif diff -Nru isl-0.12.2/isl_point.c isl-0.15/isl_point.c --- isl-0.12.2/isl_point.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_point.c 2015-06-02 09:28:10.000000000 +0000 @@ -3,9 +3,11 @@ #include #include #include -#include +#include #include #include +#include +#include isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt) { @@ -118,10 +120,10 @@ return isl_point_alloc(dim, isl_vec_alloc(dim->ctx, 0)); } -int isl_point_is_void(__isl_keep isl_point *pnt) +isl_bool isl_point_is_void(__isl_keep isl_point *pnt) { if (!pnt) - return -1; + return isl_bool_error; return pnt->vec->size == 0; } @@ -296,12 +298,13 @@ struct isl_foreach_point { struct isl_scan_callback callback; - int (*fn)(__isl_take isl_point *pnt, void *user); + isl_stat (*fn)(__isl_take isl_point *pnt, void *user); void *user; isl_space *dim; }; -static int foreach_point(struct isl_scan_callback *cb, __isl_take isl_vec *sample) +static isl_stat foreach_point(struct isl_scan_callback *cb, + __isl_take isl_vec *sample) { struct isl_foreach_point *fp = (struct isl_foreach_point *)cb; isl_point *pnt; @@ -311,18 +314,18 @@ return fp->fn(pnt, fp->user); } -int isl_set_foreach_point(__isl_keep isl_set *set, - int (*fn)(__isl_take isl_point *pnt, void *user), void *user) +isl_stat isl_set_foreach_point(__isl_keep isl_set *set, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user) { struct isl_foreach_point fp = { { &foreach_point }, fn, user }; int i; if (!set) - return -1; + return isl_stat_error; fp.dim = isl_set_get_space(set); if (!fp.dim) - return -1; + return isl_stat_error; set = isl_set_copy(set); set = isl_set_cow(set); @@ -339,11 +342,11 @@ isl_set_free(set); isl_space_free(fp.dim); - return 0; + return isl_stat_ok; error: isl_set_free(set); isl_space_free(fp.dim); - return -1; + return isl_stat_error; } /* Return 1 if "bmap" contains the point "point". @@ -351,24 +354,25 @@ * The point is first extended with the divs and then passed * to basic_map_contains. */ -int isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, +isl_bool isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, __isl_keep isl_point *point) { int i; struct isl_vec *vec; unsigned dim; - int contains; + isl_bool contains; if (!bmap || !point) - return -1; - isl_assert(bmap->ctx, isl_space_is_equal(bmap->dim, point->dim), return -1); + return isl_bool_error; + isl_assert(bmap->ctx, isl_space_is_equal(bmap->dim, point->dim), + return isl_bool_error); if (bmap->n_div == 0) return isl_basic_map_contains(bmap, point->vec); dim = isl_basic_map_total_dim(bmap) - bmap->n_div; vec = isl_vec_alloc(bmap->ctx, 1 + dim + bmap->n_div); if (!vec) - return -1; + return isl_bool_error; isl_seq_cpy(vec->el, point->vec->el, point->vec->size); for (i = 0; i < bmap->n_div; ++i) { @@ -412,7 +416,8 @@ return -1; } -int isl_set_contains_point(__isl_keep isl_set *set, __isl_keep isl_point *point) +isl_bool isl_set_contains_point(__isl_keep isl_set *set, + __isl_keep isl_point *point) { return isl_map_contains_point((isl_map *)set, point); } diff -Nru isl-0.12.2/isl_polynomial.c isl-0.15/isl_polynomial.c --- isl-0.12.2/isl_polynomial.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_polynomial.c 2015-06-10 18:25:33.000000000 +0000 @@ -13,19 +13,21 @@ #include #include #include -#include -#include +#include +#include #include #include #include #include #include #include +#include #include #include #include #include #include +#include static unsigned pos(__isl_keep isl_space *dim, enum isl_dim_type type) { @@ -65,24 +67,24 @@ return (struct isl_upoly_rec *)up; } -int isl_upoly_is_equal(__isl_keep struct isl_upoly *up1, +isl_bool isl_upoly_is_equal(__isl_keep struct isl_upoly *up1, __isl_keep struct isl_upoly *up2) { int i; struct isl_upoly_rec *rec1, *rec2; if (!up1 || !up2) - return -1; + return isl_bool_error; if (up1 == up2) - return 1; + return isl_bool_true; if (up1->var != up2->var) - return 0; + return isl_bool_false; if (isl_upoly_is_cst(up1)) { struct isl_upoly_cst *cst1, *cst2; cst1 = isl_upoly_as_cst(up1); cst2 = isl_upoly_as_cst(up2); if (!cst1 || !cst2) - return -1; + return isl_bool_error; return isl_int_eq(cst1->n, cst2->n) && isl_int_eq(cst1->d, cst2->d); } @@ -90,18 +92,18 @@ rec1 = isl_upoly_as_rec(up1); rec2 = isl_upoly_as_rec(up2); if (!rec1 || !rec2) - return -1; + return isl_bool_error; if (rec1->n != rec2->n) - return 0; + return isl_bool_false; for (i = 0; i < rec1->n; ++i) { - int eq = isl_upoly_is_equal(rec1->p[i], rec2->p[i]); + isl_bool eq = isl_upoly_is_equal(rec1->p[i], rec2->p[i]); if (eq < 0 || !eq) return eq; } - return 1; + return isl_bool_true; } int isl_upoly_is_zero(__isl_keep struct isl_upoly *up) @@ -410,29 +412,29 @@ return isl_space_dim(qp->dim, type); } -int isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp) +isl_bool isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp) { - return qp ? isl_upoly_is_zero(qp->upoly) : -1; + return qp ? isl_upoly_is_zero(qp->upoly) : isl_bool_error; } -int isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp) +isl_bool isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp) { - return qp ? isl_upoly_is_one(qp->upoly) : -1; + return qp ? isl_upoly_is_one(qp->upoly) : isl_bool_error; } -int isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp) +isl_bool isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp) { - return qp ? isl_upoly_is_nan(qp->upoly) : -1; + return qp ? isl_upoly_is_nan(qp->upoly) : isl_bool_error; } -int isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp) +isl_bool isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp) { - return qp ? isl_upoly_is_infty(qp->upoly) : -1; + return qp ? isl_upoly_is_infty(qp->upoly) : isl_bool_error; } -int isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp) +isl_bool isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp) { - return qp ? isl_upoly_is_neginfty(qp->upoly) : -1; + return qp ? isl_upoly_is_neginfty(qp->upoly) : isl_bool_error; } int isl_qpolynomial_sgn(__isl_keep isl_qpolynomial *qp) @@ -1110,7 +1112,8 @@ return isl_qpolynomial_dup(qp); } -void *isl_qpolynomial_free(__isl_take isl_qpolynomial *qp) +__isl_null isl_qpolynomial *isl_qpolynomial_free( + __isl_take isl_qpolynomial *qp) { if (!qp) return NULL; @@ -1563,6 +1566,28 @@ return NULL; } +/* Divide "qp" by "v". + */ +__isl_give isl_qpolynomial *isl_qpolynomial_scale_down_val( + __isl_take isl_qpolynomial *qp, __isl_take isl_val *v) +{ + if (!qp || !v) + goto error; + + if (!isl_val_is_rat(v)) + isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + return isl_qpolynomial_scale_val(qp, isl_val_inv(v)); +error: + isl_val_free(v); + isl_qpolynomial_free(qp); + return NULL; +} + __isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2) { @@ -1867,13 +1892,20 @@ return NULL; } -int isl_qpolynomial_plain_is_equal(__isl_keep isl_qpolynomial *qp1, +/* Is "qp1" obviously equal to "qp2"? + * + * NaN is not equal to anything, not even to another NaN. + */ +isl_bool isl_qpolynomial_plain_is_equal(__isl_keep isl_qpolynomial *qp1, __isl_keep isl_qpolynomial *qp2) { - int equal; + isl_bool equal; if (!qp1 || !qp2) - return -1; + return isl_bool_error; + + if (isl_qpolynomial_is_nan(qp1) || isl_qpolynomial_is_nan(qp2)) + return isl_bool_false; equal = isl_space_is_equal(qp1->dim, qp2->dim); if (equal < 0 || !equal) @@ -2352,22 +2384,23 @@ return up_set_active(qp->upoly, active, d); } -int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp, +isl_bool isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp, enum isl_dim_type type, unsigned first, unsigned n) { int i; int *active = NULL; - int involves = 0; + isl_bool involves = isl_bool_false; if (!qp) - return -1; + return isl_bool_error; if (n == 0) - return 0; + return isl_bool_false; isl_assert(qp->dim->ctx, - first + n <= isl_qpolynomial_dim(qp, type), return -1); + first + n <= isl_qpolynomial_dim(qp, type), + return isl_bool_error); isl_assert(qp->dim->ctx, type == isl_dim_param || - type == isl_dim_in, return -1); + type == isl_dim_in, return isl_bool_error); active = isl_calloc_array(qp->dim->ctx, int, isl_space_dim(qp->dim, isl_dim_all)); @@ -2378,7 +2411,7 @@ first += isl_space_dim(qp->dim, isl_dim_param); for (i = 0; i < n; ++i) if (active[first + i]) { - involves = 1; + involves = isl_bool_true; break; } @@ -2387,7 +2420,7 @@ return involves; error: free(active); - return -1; + return isl_bool_error; } /* Remove divs that do not appear in the quasi-polynomial, nor in any @@ -2783,7 +2816,6 @@ #define PART isl_pw_qpolynomial #undef PARTS #define PARTS pw_qpolynomial -#define ALIGN_DOMAIN #include @@ -2873,17 +2905,19 @@ return NULL; } -__isl_give struct isl_upoly *isl_upoly_eval( - __isl_take struct isl_upoly *up, __isl_take isl_vec *vec) +__isl_give isl_val *isl_upoly_eval(__isl_take struct isl_upoly *up, + __isl_take isl_vec *vec) { int i; struct isl_upoly_rec *rec; - struct isl_upoly *res; - struct isl_upoly *base; + isl_val *res; + isl_val *base; if (isl_upoly_is_cst(up)) { isl_vec_free(vec); - return up; + res = isl_upoly_get_constant_val(up); + isl_upoly_free(up); + return res; } rec = isl_upoly_as_rec(up); @@ -2892,19 +2926,20 @@ isl_assert(up->ctx, rec->n >= 1, goto error); - base = isl_upoly_rat_cst(up->ctx, vec->el[1 + up->var], vec->el[0]); + base = isl_val_rat_from_isl_int(up->ctx, + vec->el[1 + up->var], vec->el[0]); res = isl_upoly_eval(isl_upoly_copy(rec->p[rec->n - 1]), isl_vec_copy(vec)); for (i = rec->n - 2; i >= 0; --i) { - res = isl_upoly_mul(res, isl_upoly_copy(base)); - res = isl_upoly_sum(res, + res = isl_val_mul(res, isl_val_copy(base)); + res = isl_val_add(res, isl_upoly_eval(isl_upoly_copy(rec->p[i]), isl_vec_copy(vec))); } - isl_upoly_free(base); + isl_val_free(base); isl_upoly_free(up); isl_vec_free(vec); return res; @@ -2914,12 +2949,11 @@ return NULL; } -__isl_give isl_qpolynomial *isl_qpolynomial_eval( - __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt) +__isl_give isl_val *isl_qpolynomial_eval(__isl_take isl_qpolynomial *qp, + __isl_take isl_point *pnt) { isl_vec *ext; - struct isl_upoly *up; - isl_space *dim; + isl_val *v; if (!qp || !pnt) goto error; @@ -2943,15 +2977,12 @@ } } - up = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext); - if (!up) - goto error; + v = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext); - dim = isl_space_copy(qp->dim); isl_qpolynomial_free(qp); isl_point_free(pnt); - return isl_qpolynomial_alloc(dim, 0, up); + return v; error: isl_qpolynomial_free(qp); isl_point_free(pnt); @@ -2971,79 +3002,6 @@ return cmp; } -int isl_qpolynomial_le_cst(__isl_keep isl_qpolynomial *qp1, - __isl_keep isl_qpolynomial *qp2) -{ - struct isl_upoly_cst *cst1, *cst2; - - if (!qp1 || !qp2) - return -1; - isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), return -1); - isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), return -1); - if (isl_qpolynomial_is_nan(qp1)) - return -1; - if (isl_qpolynomial_is_nan(qp2)) - return -1; - cst1 = isl_upoly_as_cst(qp1->upoly); - cst2 = isl_upoly_as_cst(qp2->upoly); - - return isl_upoly_cmp(cst1, cst2) <= 0; -} - -__isl_give isl_qpolynomial *isl_qpolynomial_min_cst( - __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2) -{ - struct isl_upoly_cst *cst1, *cst2; - int cmp; - - if (!qp1 || !qp2) - goto error; - isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error); - isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error); - cst1 = isl_upoly_as_cst(qp1->upoly); - cst2 = isl_upoly_as_cst(qp2->upoly); - cmp = isl_upoly_cmp(cst1, cst2); - - if (cmp <= 0) { - isl_qpolynomial_free(qp2); - } else { - isl_qpolynomial_free(qp1); - qp1 = qp2; - } - return qp1; -error: - isl_qpolynomial_free(qp1); - isl_qpolynomial_free(qp2); - return NULL; -} - -__isl_give isl_qpolynomial *isl_qpolynomial_max_cst( - __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2) -{ - struct isl_upoly_cst *cst1, *cst2; - int cmp; - - if (!qp1 || !qp2) - goto error; - isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error); - isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error); - cst1 = isl_upoly_as_cst(qp1->upoly); - cst2 = isl_upoly_as_cst(qp2->upoly); - cmp = isl_upoly_cmp(cst1, cst2); - - if (cmp >= 0) { - isl_qpolynomial_free(qp2); - } else { - isl_qpolynomial_free(qp1); - qp1 = qp2; - } - return qp1; -error: - isl_qpolynomial_free(qp1); - isl_qpolynomial_free(qp2); - return NULL; -} - __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims( __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned first, unsigned n) @@ -3259,7 +3217,7 @@ return qp; error: isl_aff_free(aff); - return NULL; + return isl_qpolynomial_free(qp); } __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_pw_aff( @@ -3783,7 +3741,7 @@ } __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up, - int (*fn)(__isl_take isl_term *term, void *user), + isl_stat (*fn)(__isl_take isl_term *term, void *user), __isl_take isl_term *term, void *user) { int i; @@ -3835,23 +3793,23 @@ return NULL; } -int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp, - int (*fn)(__isl_take isl_term *term, void *user), void *user) +isl_stat isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp, + isl_stat (*fn)(__isl_take isl_term *term, void *user), void *user) { isl_term *term; if (!qp) - return -1; + return isl_stat_error; term = isl_term_alloc(isl_space_copy(qp->dim), isl_mat_copy(qp->div)); if (!term) - return -1; + return isl_stat_error; term = isl_upoly_foreach_term(qp->upoly, fn, term, user); isl_term_free(term); - return term ? 0 : -1; + return term ? isl_stat_ok : isl_stat_error; } __isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term) @@ -3996,29 +3954,29 @@ struct isl_opt_data { isl_qpolynomial *qp; int first; - isl_qpolynomial *opt; + isl_val *opt; int max; }; -static int opt_fn(__isl_take isl_point *pnt, void *user) +static isl_stat opt_fn(__isl_take isl_point *pnt, void *user) { struct isl_opt_data *data = (struct isl_opt_data *)user; - isl_qpolynomial *val; + isl_val *val; val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt); if (data->first) { data->first = 0; data->opt = val; } else if (data->max) { - data->opt = isl_qpolynomial_max_cst(data->opt, val); + data->opt = isl_val_max(data->opt, val); } else { - data->opt = isl_qpolynomial_min_cst(data->opt, val); + data->opt = isl_val_min(data->opt, val); } - return 0; + return isl_stat_ok; } -__isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain( +__isl_give isl_val *isl_qpolynomial_opt_on_domain( __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max) { struct isl_opt_data data = { NULL, 1, NULL, max }; @@ -4028,7 +3986,9 @@ if (isl_upoly_is_cst(qp->upoly)) { isl_set_free(set); - return qp; + data.opt = isl_qpolynomial_get_constant_val(qp); + isl_qpolynomial_free(qp); + return data.opt; } set = fix_inactive(set, qp); @@ -4037,10 +3997,8 @@ if (isl_set_foreach_point(set, opt_fn, &data) < 0) goto error; - if (data.first) { - isl_space *space = isl_qpolynomial_get_domain_space(qp); - data.opt = isl_qpolynomial_zero_on_domain(space); - } + if (data.first) + data.opt = isl_val_zero(isl_set_get_ctx(set)); isl_set_free(set); isl_qpolynomial_free(qp); @@ -4048,7 +4006,7 @@ error: isl_set_free(set); isl_qpolynomial_free(qp); - isl_qpolynomial_free(data.opt); + isl_val_free(data.opt); return NULL; } @@ -4109,37 +4067,12 @@ return NULL; } -static int neg_entry(void **entry, void *user) -{ - isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry; - - *pwqp = isl_pw_qpolynomial_neg(*pwqp); - - return *pwqp ? 0 : -1; -} - -__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg( - __isl_take isl_union_pw_qpolynomial *upwqp) -{ - upwqp = isl_union_pw_qpolynomial_cow(upwqp); - if (!upwqp) - return NULL; - - if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table, - &neg_entry, NULL) < 0) - goto error; - - return upwqp; -error: - isl_union_pw_qpolynomial_free(upwqp); - return NULL; -} - __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( __isl_take isl_union_pw_qpolynomial *upwqp1, __isl_take isl_union_pw_qpolynomial *upwqp2) { - return match_bin_op(upwqp1, upwqp2, &isl_pw_qpolynomial_mul); + return isl_union_pw_qpolynomial_match_bin_op(upwqp1, upwqp2, + &isl_pw_qpolynomial_mul); } /* Reorder the columns of the given div definitions according to the @@ -4285,14 +4218,14 @@ return NULL; } -static int split_periods(__isl_take isl_set *set, +static isl_stat split_periods(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, void *user); /* Create a slice of the domain "set" such that integer division "div" * has the fixed value "v" and add the results to data->res, * replacing the integer division by "v" in "qp". */ -static int set_div(__isl_take isl_set *set, +static isl_stat set_div(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, int div, isl_int v, struct isl_split_periods_data *data) { @@ -4331,7 +4264,7 @@ * has a fixed value (ranging from "min" to "max") on each slice * and add the results to data->res. */ -static int split_div(__isl_take isl_set *set, +static isl_stat split_div(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, int div, isl_int min, isl_int max, struct isl_split_periods_data *data) { @@ -4344,11 +4277,11 @@ } isl_set_free(set); isl_qpolynomial_free(qp); - return 0; + return isl_stat_ok; error: isl_set_free(set); isl_qpolynomial_free(qp); - return -1; + return isl_stat_error; } /* If "qp" refers to any integer division @@ -4357,7 +4290,7 @@ * Add the results (or the original if no splitting occurs) * to data->res. */ -static int split_periods(__isl_take isl_set *set, +static isl_stat split_periods(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp, void *user) { int i; @@ -4365,7 +4298,7 @@ struct isl_split_periods_data *data; isl_int min, max; int total; - int r = 0; + isl_stat r = isl_stat_ok; data = (struct isl_split_periods_data *)user; @@ -4375,7 +4308,7 @@ if (qp->div->n_row == 0) { pwqp = isl_pw_qpolynomial_alloc(set, qp); data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp); - return 0; + return isl_stat_ok; } isl_int_init(min); @@ -4428,7 +4361,7 @@ error: isl_set_free(set); isl_qpolynomial_free(qp); - return -1; + return isl_stat_error; } /* If any quasi-polynomial in pwqp refers to any integer division @@ -4837,14 +4770,14 @@ return NULL; } -static int poly_entry(void **entry, void *user) +static isl_stat poly_entry(void **entry, void *user) { int *sign = user; isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry; *pwqp = isl_pw_qpolynomial_to_polynomial(*pwqp, *sign); - return *pwqp ? 0 : -1; + return *pwqp ? isl_stat_ok : isl_stat_error; } __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_to_polynomial( @@ -4854,7 +4787,7 @@ if (!upwqp) return NULL; - if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table, + if (isl_hash_table_foreach(upwqp->space->ctx, &upwqp->table, &poly_entry, &sign) < 0) goto error; diff -Nru isl-0.12.2/isl_polynomial_private.h isl-0.15/isl_polynomial_private.h --- isl-0.12.2/isl_polynomial_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_polynomial_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -95,6 +96,8 @@ struct isl_pw_qpolynomial_fold_piece p[1]; }; +void isl_term_get_num(__isl_keep isl_term *term, isl_int *n); + __isl_give struct isl_upoly *isl_upoly_zero(struct isl_ctx *ctx); __isl_give struct isl_upoly *isl_upoly_copy(__isl_keep struct isl_upoly *up); __isl_give struct isl_upoly *isl_upoly_cow(__isl_take struct isl_upoly *up); @@ -122,23 +125,20 @@ __isl_give isl_qpolynomial *isl_qpolynomial_cst_on_domain(__isl_take isl_space *dim, isl_int v); +__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain( + __isl_take isl_space *space, const isl_int n, const isl_int d); __isl_give isl_qpolynomial *isl_qpolynomial_var_pow_on_domain(__isl_take isl_space *dim, int pos, int power); -int isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp); +isl_bool isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp); int isl_qpolynomial_is_affine(__isl_keep isl_qpolynomial *qp); +int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp, + isl_int *n, isl_int *d); __isl_give isl_qpolynomial *isl_qpolynomial_add_on_domain( __isl_keep isl_set *dom, __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2); -int isl_qpolynomial_le_cst(__isl_keep isl_qpolynomial *qp1, - __isl_keep isl_qpolynomial *qp2); -__isl_give isl_qpolynomial *isl_qpolynomial_max_cst( - __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2); -__isl_give isl_qpolynomial *isl_qpolynomial_min_cst( - __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2); - int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly); __isl_give isl_qpolynomial *isl_qpolynomial_coeff( __isl_keep isl_qpolynomial *poly, @@ -161,7 +161,7 @@ __isl_take isl_pw_qpolynomial *pwqp, enum isl_dim_type type, unsigned first, unsigned n); -__isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain( +__isl_give isl_val *isl_qpolynomial_opt_on_domain( __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max); enum isl_fold isl_fold_type_negate(enum isl_fold type); @@ -183,7 +183,7 @@ __isl_take isl_qpolynomial_fold *fold1, __isl_take isl_qpolynomial_fold *fold2); -__isl_give isl_qpolynomial *isl_qpolynomial_fold_opt_on_domain( +__isl_give isl_val *isl_qpolynomial_fold_opt_on_domain( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *set, int max); int isl_pw_qpolynomial_fold_covers(__isl_keep isl_pw_qpolynomial_fold *pwf1, @@ -219,6 +219,8 @@ __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_realign_domain( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_reordering *r); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_reset_space( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_space *space); __isl_give isl_qpolynomial *isl_qpolynomial_reset_domain_space( __isl_take isl_qpolynomial *qp, __isl_take isl_space *dim); __isl_give isl_qpolynomial *isl_qpolynomial_reset_space_and_domain( @@ -231,3 +233,21 @@ __isl_take isl_space *domain); __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_reset_domain_space( __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_space *dim); + +void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d); +__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int( + __isl_take isl_qpolynomial *qp, isl_int v); +__isl_give isl_qpolynomial *isl_qpolynomial_mul_isl_int( + __isl_take isl_qpolynomial *qp, isl_int v); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul_isl_int( + __isl_take isl_pw_qpolynomial *pwqp, isl_int v); + +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int( + __isl_take isl_qpolynomial_fold *fold, isl_int v); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_mul_isl_int( + __isl_take isl_pw_qpolynomial_fold *pwf, isl_int v); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul_isl_int( + __isl_take isl_union_pw_qpolynomial *upwqp, isl_int v); +__isl_give isl_union_pw_qpolynomial_fold * +isl_union_pw_qpolynomial_fold_mul_isl_int( + __isl_take isl_union_pw_qpolynomial_fold *upwf, isl_int v); diff -Nru isl-0.12.2/isl_printer.c isl-0.15/isl_printer.c --- isl-0.12.2/isl_printer.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_printer.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,9 +1,11 @@ #include +#include #include static __isl_give isl_printer *file_start_line(__isl_take isl_printer *p) { - fprintf(p->file, "%*s%s", p->indent, "", p->prefix ? p->prefix : ""); + fprintf(p->file, "%s%*s%s", p->indent_prefix ? p->indent_prefix : "", + p->indent, "", p->prefix ? p->prefix : ""); return p; } @@ -97,6 +99,8 @@ static __isl_give isl_printer *str_start_line(__isl_take isl_printer *p) { + if (p->indent_prefix) + p = str_print(p, p->indent_prefix, strlen(p->indent_prefix)); p = str_print_indent(p, p->indent); if (p->prefix) p = str_print(p, p->prefix, strlen(p->prefix)); @@ -114,6 +118,7 @@ static __isl_give isl_printer *str_flush(__isl_take isl_printer *p) { p->buf_n = 0; + p->buf[p->buf_n] = '\0'; return p; } @@ -208,7 +213,7 @@ __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file) { - struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer); + struct isl_printer *p = isl_calloc_type(ctx, struct isl_printer); if (!p) return NULL; p->ctx = ctx; @@ -220,16 +225,18 @@ p->buf_size = 0; p->indent = 0; p->output_format = ISL_FORMAT_ISL; + p->indent_prefix = NULL; p->prefix = NULL; p->suffix = NULL; p->width = 0; + p->yaml_style = ISL_YAML_STYLE_FLOW; return p; } __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx) { - struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer); + struct isl_printer *p = isl_calloc_type(ctx, struct isl_printer); if (!p) return NULL; p->ctx = ctx; @@ -244,9 +251,11 @@ p->buf_size = 256; p->indent = 0; p->output_format = ISL_FORMAT_ISL; + p->indent_prefix = NULL; p->prefix = NULL; p->suffix = NULL; p->width = 0; + p->yaml_style = ISL_YAML_STYLE_FLOW; return p; error: @@ -254,11 +263,15 @@ return NULL; } -void *isl_printer_free(__isl_take isl_printer *p) +__isl_null isl_printer *isl_printer_free(__isl_take isl_printer *p) { if (!p) return NULL; free(p->buf); + free(p->indent_prefix); + free(p->prefix); + free(p->suffix); + free(p->yaml_state); isl_ctx_deref(p->ctx); free(p); @@ -315,13 +328,28 @@ return p; } +/* Replace the indent prefix of "p" by "prefix". + */ +__isl_give isl_printer *isl_printer_set_indent_prefix(__isl_take isl_printer *p, + const char *prefix) +{ + if (!p) + return NULL; + + free(p->indent_prefix); + p->indent_prefix = prefix ? strdup(prefix) : NULL; + + return p; +} + __isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p, const char *prefix) { if (!p) return NULL; - p->prefix = prefix; + free(p->prefix); + p->prefix = prefix ? strdup(prefix) : NULL; return p; } @@ -332,7 +360,8 @@ if (!p) return NULL; - p->suffix = suffix; + free(p->suffix); + p->suffix = suffix ? strdup(suffix) : NULL; return p; } @@ -355,6 +384,161 @@ return p->output_format; } +/* Set the YAML style of "p" to "yaml_style" and return the updated printer. + */ +__isl_give isl_printer *isl_printer_set_yaml_style(__isl_take isl_printer *p, + int yaml_style) +{ + if (!p) + return NULL; + + p->yaml_style = yaml_style; + + return p; +} + +/* Return the YAML style of "p" or -1 on error. + */ +int isl_printer_get_yaml_style(__isl_keep isl_printer *p) +{ + if (!p) + return -1; + return p->yaml_style; +} + +/* Push "state" onto the stack of currently active YAML elements and + * return the updated printer. + */ +static __isl_give isl_printer *push_state(__isl_take isl_printer *p, + enum isl_yaml_state state) +{ + if (!p) + return NULL; + + if (p->yaml_size < p->yaml_depth + 1) { + enum isl_yaml_state *state; + state = isl_realloc_array(p->ctx, p->yaml_state, + enum isl_yaml_state, p->yaml_depth + 1); + if (!state) + return isl_printer_free(p); + p->yaml_state = state; + p->yaml_size = p->yaml_depth + 1; + } + + p->yaml_state[p->yaml_depth] = state; + p->yaml_depth++; + + return p; +} + +/* Remove the innermost active YAML element from the stack and + * return the updated printer. + */ +static __isl_give isl_printer *pop_state(__isl_take isl_printer *p) +{ + if (!p) + return NULL; + p->yaml_depth--; + return p; +} + +/* Set the state of the innermost active YAML element to "state" and + * return the updated printer. + */ +static __isl_give isl_printer *update_state(__isl_take isl_printer *p, + enum isl_yaml_state state) +{ + if (!p) + return NULL; + if (p->yaml_depth < 1) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "not in YAML construct", return isl_printer_free(p)); + + p->yaml_state[p->yaml_depth - 1] = state; + + return p; +} + +/* Return the state of the innermost active YAML element. + * Return isl_yaml_none if we are not inside any YAML element. + */ +static enum isl_yaml_state current_state(__isl_keep isl_printer *p) +{ + if (!p) + return isl_yaml_none; + if (p->yaml_depth < 1) + return isl_yaml_none; + return p->yaml_state[p->yaml_depth - 1]; +} + +/* If we are printing a YAML document and we are at the start of an element, + * print whatever is needed before we can print the actual element and + * keep track of the fact that we are now printing the element. + * If "eol" is set, then whatever we print is going to be the last + * thing that gets printed on this line. + * + * If we are about the print the first key of a mapping, then nothing + * extra needs to be printed. For any other key, however, we need + * to either move to the next line (in block format) or print a comma + * (in flow format). + * Before printing a value in a mapping, we need to print a colon. + * + * For sequences, in flow format, we only need to print a comma + * for each element except the first. + * In block format, before the first element in the sequence, + * we move to a new line, print a dash and increase the indentation. + * Before any other element, we print a dash on a new line, + * temporarily moving the indentation back. + */ +static __isl_give isl_printer *enter_state(__isl_take isl_printer *p, + int eol) +{ + enum isl_yaml_state state; + + if (!p) + return NULL; + + state = current_state(p); + if (state == isl_yaml_mapping_val_start) { + if (eol) + p = p->ops->print_str(p, ":"); + else + p = p->ops->print_str(p, ": "); + p = update_state(p, isl_yaml_mapping_val); + } else if (state == isl_yaml_mapping_first_key_start) { + p = update_state(p, isl_yaml_mapping_key); + } else if (state == isl_yaml_mapping_key_start) { + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, ", "); + else { + p = p->ops->end_line(p); + p = p->ops->start_line(p); + } + p = update_state(p, isl_yaml_mapping_key); + } else if (state == isl_yaml_sequence_first_start) { + if (p->yaml_style != ISL_YAML_STYLE_FLOW) { + p = p->ops->end_line(p); + p = p->ops->start_line(p); + p = p->ops->print_str(p, "- "); + p = isl_printer_indent(p, 2); + } + p = update_state(p, isl_yaml_sequence); + } else if (state == isl_yaml_sequence_start) { + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, ", "); + else { + p = p->ops->end_line(p); + p = isl_printer_indent(p, -2); + p = p->ops->start_line(p); + p = p->ops->print_str(p, "- "); + p = isl_printer_indent(p, 2); + } + p = update_state(p, isl_yaml_sequence); + } + + return p; +} + __isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p, const char *s) { @@ -362,13 +546,16 @@ return NULL; if (!s) return isl_printer_free(p); - + p = enter_state(p, 0); + if (!p) + return NULL; return p->ops->print_str(p, s); } __isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p, double d) { + p = enter_state(p, 0); if (!p) return NULL; @@ -377,6 +564,7 @@ __isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i) { + p = enter_state(p, 0); if (!p) return NULL; @@ -386,6 +574,7 @@ __isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p, isl_int i) { + p = enter_state(p, 0); if (!p) return NULL; @@ -422,3 +611,154 @@ return p->ops->flush(p); } + +/* Start a YAML mapping and push a new state to reflect that we + * are about to print the first key in a mapping. + * + * In flow style, print the opening brace. + * In block style, move to the next line with an increased indentation, + * except if this is the outer mapping or if we are inside a sequence + * (in which case we have already increased the indentation and we want + * to print the first key on the same line as the dash). + */ +__isl_give isl_printer *isl_printer_yaml_start_mapping( + __isl_take isl_printer *p) +{ + enum isl_yaml_state state; + + p = enter_state(p, p->yaml_style == ISL_YAML_STYLE_BLOCK); + if (!p) + return NULL; + state = current_state(p); + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, "{ "); + else if (state != isl_yaml_none && state != isl_yaml_sequence) { + p = p->ops->end_line(p); + p = isl_printer_indent(p, 2); + p = p->ops->start_line(p); + } + p = push_state(p, isl_yaml_mapping_first_key_start); + return p; +} + +/* Finish a YAML mapping and pop it from the state stack. + * + * In flow style, print the closing brace. + * + * In block style, first check if we are still in the + * isl_yaml_mapping_first_key_start state. If so, we have not printed + * anything yet, so print "{}" to indicate an empty mapping. + * If we increased the indentation in isl_printer_yaml_start_mapping, + * then decrease it again. + * If this is the outer mapping then print a newline. + */ +__isl_give isl_printer *isl_printer_yaml_end_mapping( + __isl_take isl_printer *p) +{ + enum isl_yaml_state state; + + state = current_state(p); + p = pop_state(p); + if (!p) + return NULL; + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + return p->ops->print_str(p, " }"); + if (state == isl_yaml_mapping_first_key_start) + p = p->ops->print_str(p, "{}"); + if (!p) + return NULL; + state = current_state(p); + if (state != isl_yaml_none && state != isl_yaml_sequence) + p = isl_printer_indent(p, -2); + if (state == isl_yaml_none) + p = p->ops->end_line(p); + return p; +} + +/* Start a YAML sequence and push a new state to reflect that we + * are about to print the first element in a sequence. + * + * In flow style, print the opening bracket. + */ +__isl_give isl_printer *isl_printer_yaml_start_sequence( + __isl_take isl_printer *p) +{ + p = enter_state(p, p->yaml_style == ISL_YAML_STYLE_BLOCK); + p = push_state(p, isl_yaml_sequence_first_start); + if (!p) + return NULL; + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + p = p->ops->print_str(p, "[ "); + return p; +} + +/* Finish a YAML sequence and pop it from the state stack. + * + * In flow style, print the closing bracket. + * + * In block style, check if we are still in the + * isl_yaml_sequence_first_start state. If so, we have not printed + * anything yet, so print "[]" or " []" to indicate an empty sequence. + * We print the extra space when we instructed enter_state not + * to print a space at the end of the line. + * Otherwise, undo the increase in indentation performed by + * enter_state when moving away from the isl_yaml_sequence_first_start + * state. + * If this is the outer sequence then print a newline. + */ +__isl_give isl_printer *isl_printer_yaml_end_sequence( + __isl_take isl_printer *p) +{ + enum isl_yaml_state state, up; + + state = current_state(p); + p = pop_state(p); + if (!p) + return NULL; + if (p->yaml_style == ISL_YAML_STYLE_FLOW) + return p->ops->print_str(p, " ]"); + up = current_state(p); + if (state == isl_yaml_sequence_first_start) { + if (up == isl_yaml_mapping_val) + p = p->ops->print_str(p, " []"); + else + p = p->ops->print_str(p, "[]"); + } else { + p = isl_printer_indent(p, -2); + } + if (!p) + return NULL; + state = current_state(p); + if (state == isl_yaml_none) + p = p->ops->end_line(p); + return p; +} + +/* Mark the fact that the current element is finished and that + * the next output belongs to the next element. + * In particular, if we are printing a key, then prepare for + * printing the subsequent value. If we are printing a value, + * prepare for printing the next key. If we are printing an + * element in a sequence, prepare for printing the next element. + */ +__isl_give isl_printer *isl_printer_yaml_next(__isl_take isl_printer *p) +{ + enum isl_yaml_state state; + + if (!p) + return NULL; + if (p->yaml_depth < 1) + isl_die(isl_printer_get_ctx(p), isl_error_invalid, + "not in YAML construct", return isl_printer_free(p)); + + state = current_state(p); + if (state == isl_yaml_mapping_key) + state = isl_yaml_mapping_val_start; + else if (state == isl_yaml_mapping_val) + state = isl_yaml_mapping_key_start; + else if (state == isl_yaml_sequence) + state = isl_yaml_sequence_start; + p = update_state(p, state); + + return p; +} diff -Nru isl-0.12.2/isl_printer_private.h isl-0.15/isl_printer_private.h --- isl-0.12.2/isl_printer_private.h 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/isl_printer_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -1,7 +1,18 @@ #include +#include struct isl_printer_ops; +/* A printer to a file or a string. + * + * yaml_style is the YAML style in which the next elements should + * be printed and may be either ISL_YAML_STYLE_BLOCK or ISL_YAML_STYLE_FLOW, + * with ISL_YAML_STYLE_FLOW being the default. + * yaml_state keeps track of the currently active YAML elements. + * yaml_size is the size of this arrays, while yaml_depth + * is the number of elements currently in use. + * yaml_state may be NULL if no YAML printing is being performed. + */ struct isl_printer { struct isl_ctx *ctx; struct isl_printer_ops *ops; @@ -11,7 +22,13 @@ char *buf; int indent; int output_format; - const char *prefix; - const char *suffix; + char *indent_prefix; + char *prefix; + char *suffix; int width; + + int yaml_style; + int yaml_depth; + int yaml_size; + enum isl_yaml_state *yaml_state; }; diff -Nru isl-0.12.2/isl_pw_templ.c isl-0.15/isl_pw_templ.c --- isl-0.12.2/isl_pw_templ.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_pw_templ.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,16 @@ +/* + * Copyright 2010-2011 INRIA Saclay + * Copyright 2011 Sven Verdoolaege + * Copyright 2012-2014 Ecole Normale Superieure + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, + * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, + * 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + #include #include @@ -157,7 +170,7 @@ return pw; } -void *FN(PW,free)(__isl_take PW *pw) +__isl_null PW *FN(PW,free)(__isl_take PW *pw) { int i; @@ -182,9 +195,10 @@ return pw ? isl_space_get_dim_name(pw->dim, type, pos) : NULL; } -int FN(PW,has_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, unsigned pos) +isl_bool FN(PW,has_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, + unsigned pos) { - return pw ? isl_space_has_dim_id(pw->dim, type, pos) : -1; + return pw ? isl_space_has_dim_id(pw->dim, type, pos) : isl_bool_error; } __isl_give isl_id *FN(PW,get_dim_id)(__isl_keep PW *pw, enum isl_dim_type type, @@ -193,9 +207,9 @@ return pw ? isl_space_get_dim_id(pw->dim, type, pos) : NULL; } -int FN(PW,has_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) +isl_bool FN(PW,has_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) { - return pw ? isl_space_has_tuple_name(pw->dim, type) : -1; + return pw ? isl_space_has_tuple_name(pw->dim, type) : isl_bool_error; } const char *FN(PW,get_tuple_name)(__isl_keep PW *pw, enum isl_dim_type type) @@ -203,9 +217,9 @@ return pw ? isl_space_get_tuple_name(pw->dim, type) : NULL; } -int FN(PW,has_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type) +isl_bool FN(PW,has_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type) { - return pw ? isl_space_has_tuple_id(pw->dim, type) : -1; + return pw ? isl_space_has_tuple_id(pw->dim, type) : isl_bool_error; } __isl_give isl_id *FN(PW,get_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type) @@ -213,10 +227,10 @@ return pw ? isl_space_get_tuple_id(pw->dim, type) : NULL; } -int FN(PW,IS_ZERO)(__isl_keep PW *pw) +isl_bool FN(PW,IS_ZERO)(__isl_keep PW *pw) { if (!pw) - return -1; + return isl_bool_error; return pw->n == 0; } @@ -631,7 +645,9 @@ return pw; } +#endif +#ifndef NO_SUB __isl_give PW *FN(PW,sub)(__isl_take PW *pw1, __isl_take PW *pw2) { return FN(PW,add)(pw1, FN(PW,neg)(pw2)); @@ -639,14 +655,13 @@ #endif #ifndef NO_EVAL -__isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw, - __isl_take isl_point *pnt) +__isl_give isl_val *FN(PW,eval)(__isl_take PW *pw, __isl_take isl_point *pnt) { int i; int found = 0; isl_ctx *ctx; isl_space *pnt_dim = NULL; - isl_qpolynomial *qp; + isl_val *v; if (!pw || !pnt) goto error; @@ -663,14 +678,14 @@ break; } if (found) - qp = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD), + v = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD), isl_point_copy(pnt)); else - qp = isl_qpolynomial_zero_on_domain(FN(PW,get_domain_space)(pw)); + v = isl_val_zero(ctx); FN(PW,free)(pw); isl_space_free(pnt_dim); isl_point_free(pnt); - return qp; + return v; error: FN(PW,free)(pw); isl_space_free(pnt_dim); @@ -679,6 +694,13 @@ } #endif +/* Return the parameter domain of "pw". + */ +__isl_give isl_set *FN(PW,params)(__isl_take PW *pw) +{ + return isl_set_params(FN(PW,domain)(pw)); +} + __isl_give isl_set *FN(PW,domain)(__isl_take PW *pw) { int i; @@ -727,11 +749,65 @@ return 0; } +/* Convert a piecewise expression defined over a parameter domain + * into one that is defined over a zero-dimensional set. + */ +__isl_give PW *FN(PW,from_range)(__isl_take PW *pw) +{ + isl_space *space; + + if (!pw) + return NULL; + if (!isl_space_is_set(pw->dim)) + isl_die(FN(PW,get_ctx)(pw), isl_error_invalid, + "not living in a set space", return FN(PW,free)(pw)); + + space = FN(PW,get_space)(pw); + space = isl_space_from_range(space); + pw = FN(PW,reset_space)(pw, space); + + return pw; +} + +/* Fix the value of the given parameter or domain dimension of "pw" + * to be equal to "value". + */ +__isl_give PW *FN(PW,fix_si)(__isl_take PW *pw, enum isl_dim_type type, + unsigned pos, int value) +{ + int i; + + if (!pw) + return NULL; + + if (type == isl_dim_out) + isl_die(FN(PW,get_ctx)(pw), isl_error_invalid, + "cannot fix output dimension", return FN(PW,free)(pw)); + + if (pw->n == 0) + return pw; + + if (type == isl_dim_in) + type = isl_dim_set; + + pw = FN(PW,cow)(pw); + if (!pw) + return FN(PW,free)(pw); + + for (i = pw->n - 1; i >= 0; --i) { + pw->p[i].set = isl_set_fix_si(pw->p[i].set, type, pos, value); + if (FN(PW,exploit_equalities_and_remove_if_empty)(pw, i) < 0) + return FN(PW,free)(pw); + } + + return pw; +} + /* Restrict the domain of "pw" by combining each cell * with "set" through a call to "fn", where "fn" may be - * isl_set_intersect or isl_set_intersect_params. + * isl_set_intersect, isl_set_intersect_params or isl_set_subtract. */ -static __isl_give PW *FN(PW,intersect_aligned)(__isl_take PW *pw, +static __isl_give PW *FN(PW,restrict_domain_aligned)(__isl_take PW *pw, __isl_take isl_set *set, __isl_give isl_set *(*fn)(__isl_take isl_set *set1, __isl_take isl_set *set2)) @@ -767,7 +843,7 @@ static __isl_give PW *FN(PW,intersect_domain_aligned)(__isl_take PW *pw, __isl_take isl_set *set) { - return FN(PW,intersect_aligned)(pw, set, &isl_set_intersect); + return FN(PW,restrict_domain_aligned)(pw, set, &isl_set_intersect); } __isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, @@ -780,7 +856,8 @@ static __isl_give PW *FN(PW,intersect_params_aligned)(__isl_take PW *pw, __isl_take isl_set *set) { - return FN(PW,intersect_aligned)(pw, set, &isl_set_intersect_params); + return FN(PW,restrict_domain_aligned)(pw, set, + &isl_set_intersect_params); } /* Intersect the domain of "pw" with the parameter domain "context". @@ -792,6 +869,65 @@ &FN(PW,intersect_params_aligned)); } +/* Subtract "domain' from the domain of "pw", assuming their + * parameters have been aligned. + */ +static __isl_give PW *FN(PW,subtract_domain_aligned)(__isl_take PW *pw, + __isl_take isl_set *domain) +{ + return FN(PW,restrict_domain_aligned)(pw, domain, &isl_set_subtract); +} + +/* Subtract "domain' from the domain of "pw". + */ +__isl_give PW *FN(PW,subtract_domain)(__isl_take PW *pw, + __isl_take isl_set *domain) +{ + return FN(PW,align_params_pw_set_and)(pw, domain, + &FN(PW,subtract_domain_aligned)); +} + +/* Compute the gist of "pw" with respect to the domain constraints + * of "context" for the case where the domain of the last element + * of "pw" is equal to "context". + * Call "fn_el" to compute the gist of this element, replace + * its domain by the universe and drop all other elements + * as their domains are necessarily disjoint from "context". + */ +static __isl_give PW *FN(PW,gist_last)(__isl_take PW *pw, + __isl_take isl_set *context, + __isl_give EL *(*fn_el)(__isl_take EL *el, __isl_take isl_set *set)) +{ + int i; + isl_space *space; + + for (i = 0; i < pw->n - 1; ++i) { + isl_set_free(pw->p[i].set); + FN(EL,free)(pw->p[i].FIELD); + } + pw->p[0].FIELD = pw->p[pw->n - 1].FIELD; + pw->p[0].set = pw->p[pw->n - 1].set; + pw->n = 1; + + space = isl_set_get_space(context); + pw->p[0].FIELD = fn_el(pw->p[0].FIELD, context); + context = isl_set_universe(space); + isl_set_free(pw->p[0].set); + pw->p[0].set = context; + + if (!pw->p[0].FIELD || !pw->p[0].set) + return FN(PW,free)(pw); + + return pw; +} + +/* Compute the gist of "pw" with respect to the domain constraints + * of "context". Call "fn_el" to compute the gist of the elements + * and "fn_dom" to compute the gist of the domains. + * + * If the piecewise expression is empty or the context is the universe, + * then nothing can be simplified. + */ static __isl_give PW *FN(PW,gist_aligned)(__isl_take PW *pw, __isl_take isl_set *context, __isl_give EL *(*fn_el)(__isl_take EL *el, @@ -800,6 +936,7 @@ __isl_take isl_basic_set *bset)) { int i; + int is_universe; isl_basic_set *hull = NULL; if (!pw || !context) @@ -810,29 +947,57 @@ return pw; } + is_universe = isl_set_plain_is_universe(context); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_set_free(context); + return pw; + } + if (!isl_space_match(pw->dim, isl_dim_param, context->dim, isl_dim_param)) { pw = FN(PW,align_params)(pw, isl_set_get_space(context)); context = isl_set_align_params(context, FN(PW,get_space)(pw)); } - context = isl_set_compute_divs(context); - hull = isl_set_simple_hull(isl_set_copy(context)); - pw = FN(PW,cow)(pw); if (!pw) goto error; + if (pw->n == 1) { + int equal; + + equal = isl_set_plain_is_equal(pw->p[0].set, context); + if (equal < 0) + goto error; + if (equal) + return FN(PW,gist_last)(pw, context, fn_el); + } + + context = isl_set_compute_divs(context); + hull = isl_set_simple_hull(isl_set_copy(context)); + for (i = pw->n - 1; i >= 0; --i) { isl_set *set_i; int empty; + if (i == pw->n - 1) { + int equal; + equal = isl_set_plain_is_equal(pw->p[i].set, context); + if (equal < 0) + goto error; + if (equal) { + isl_basic_set_free(hull); + return FN(PW,gist_last)(pw, context, fn_el); + } + } set_i = isl_set_intersect(isl_set_copy(pw->p[i].set), isl_set_copy(context)); empty = isl_set_plain_is_empty(set_i); pw->p[i].FIELD = fn_el(pw->p[i].FIELD, set_i); pw->p[i].set = fn_dom(pw->p[i].set, isl_basic_set_copy(hull)); - if (!pw->p[i].FIELD || !pw->p[i].set) + if (empty < 0 || !pw->p[i].FIELD || !pw->p[i].set) goto error; if (empty) { isl_set_free(pw->p[i].set); @@ -922,21 +1087,21 @@ } #ifndef NO_INVOLVES_DIMS -int FN(PW,involves_dims)(__isl_keep PW *pw, enum isl_dim_type type, +isl_bool FN(PW,involves_dims)(__isl_keep PW *pw, enum isl_dim_type type, unsigned first, unsigned n) { int i; enum isl_dim_type set_type; if (!pw) - return -1; + return isl_bool_error; if (pw->n == 0 || n == 0) - return 0; + return isl_bool_false; set_type = type == isl_dim_in ? isl_dim_set : type; for (i = 0; i < pw->n; ++i) { - int involves = FN(EL,involves_dims)(pw->p[i].FIELD, + isl_bool involves = FN(EL,involves_dims)(pw->p[i].FIELD, type, first, n); if (involves < 0 || involves) return involves; @@ -945,7 +1110,7 @@ if (involves < 0 || involves) return involves; } - return 0; + return isl_bool_false; } #endif @@ -1199,42 +1364,42 @@ * In the worst case, the domain is scanned completely, * so the domain is assumed to be bounded. */ -__isl_give isl_qpolynomial *FN(PW,opt)(__isl_take PW *pw, int max) +__isl_give isl_val *FN(PW,opt)(__isl_take PW *pw, int max) { int i; - isl_qpolynomial *opt; + isl_val *opt; if (!pw) return NULL; if (pw->n == 0) { - isl_space *dim = isl_space_copy(pw->dim); + opt = isl_val_zero(FN(PW,get_ctx)(pw)); FN(PW,free)(pw); - return isl_qpolynomial_zero_on_domain(isl_space_domain(dim)); + return opt; } opt = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[0].FIELD), isl_set_copy(pw->p[0].set), max); for (i = 1; i < pw->n; ++i) { - isl_qpolynomial *opt_i; + isl_val *opt_i; opt_i = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[i].FIELD), isl_set_copy(pw->p[i].set), max); if (max) - opt = isl_qpolynomial_max_cst(opt, opt_i); + opt = isl_val_max(opt, opt_i); else - opt = isl_qpolynomial_min_cst(opt, opt_i); + opt = isl_val_min(opt, opt_i); } FN(PW,free)(pw); return opt; } -__isl_give isl_qpolynomial *FN(PW,max)(__isl_take PW *pw) +__isl_give isl_val *FN(PW,max)(__isl_take PW *pw) { return FN(PW,opt)(pw, 1); } -__isl_give isl_qpolynomial *FN(PW,min)(__isl_take PW *pw) +__isl_give isl_val *FN(PW,min)(__isl_take PW *pw) { return FN(PW,opt)(pw, 0); } @@ -1250,6 +1415,18 @@ return pw ? isl_space_domain(isl_space_copy(pw->dim)) : NULL; } +/* Return the position of the dimension of the given type and name + * in "pw". + * Return -1 if no such dimension can be found. + */ +int FN(PW,find_dim_by_name)(__isl_keep PW *pw, + enum isl_dim_type type, const char *name) +{ + if (!pw) + return -1; + return isl_space_find_dim_by_name(pw->dim, type, name); +} + #ifndef NO_RESET_DIM /* Reset the space of "pw". Since we don't know if the elements * represent the spaces themselves or their domains, we pass along @@ -1306,19 +1483,43 @@ return FN(PW,reset_space_and_domain)(pw, dim, domain); } -__isl_give PW *FN(PW,set_tuple_id)(__isl_keep PW *pw, enum isl_dim_type type, +__isl_give PW *FN(PW,set_tuple_id)(__isl_take PW *pw, enum isl_dim_type type, __isl_take isl_id *id) { isl_space *space; pw = FN(PW,cow)(pw); if (!pw) - return isl_id_free(id); + goto error; space = FN(PW,get_space)(pw); space = isl_space_set_tuple_id(space, type, id); return FN(PW,reset_space)(pw, space); +error: + isl_id_free(id); + return FN(PW,free)(pw); +} + +/* Drop the id on the specified tuple. + */ +__isl_give PW *FN(PW,reset_tuple_id)(__isl_take PW *pw, enum isl_dim_type type) +{ + isl_space *space; + + if (!pw) + return NULL; + if (!FN(PW,has_tuple_id)(pw, type)) + return pw; + + pw = FN(PW,cow)(pw); + if (!pw) + return NULL; + + space = FN(PW,get_space)(pw); + space = isl_space_reset_tuple_id(space, type); + + return FN(PW,reset_space)(pw, space); } __isl_give PW *FN(PW,set_dim_id)(__isl_take PW *pw, @@ -1326,12 +1527,28 @@ { pw = FN(PW,cow)(pw); if (!pw) - return isl_id_free(id); + goto error; pw->dim = isl_space_set_dim_id(pw->dim, type, pos, id); return FN(PW,reset_space)(pw, isl_space_copy(pw->dim)); +error: + isl_id_free(id); + return FN(PW,free)(pw); } #endif +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "pw". + */ +__isl_give PW *FN(PW,reset_user)(__isl_take PW *pw) +{ + isl_space *space; + + space = FN(PW,get_space)(pw); + space = isl_space_reset_user(space); + + return FN(PW,reset_space)(pw, space); +} + int FN(PW,has_equal_space)(__isl_keep PW *pw1, __isl_keep PW *pw2) { if (!pw1 || !pw2) @@ -1387,21 +1604,21 @@ return pw ? pw->n : 0; } -int FN(PW,foreach_piece)(__isl_keep PW *pw, - int (*fn)(__isl_take isl_set *set, __isl_take EL *el, void *user), +isl_stat FN(PW,foreach_piece)(__isl_keep PW *pw, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take EL *el, void *user), void *user) { int i; if (!pw) - return -1; + return isl_stat_error; for (i = 0; i < pw->n; ++i) if (fn(isl_set_copy(pw->p[i].set), FN(EL,copy)(pw->p[i].FIELD), user) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } #ifndef NO_LIFT @@ -1419,9 +1636,10 @@ return 0; } -static int foreach_lifted_subset(__isl_take isl_set *set, __isl_take EL *el, - int (*fn)(__isl_take isl_set *set, __isl_take EL *el, - void *user), void *user) +static isl_stat foreach_lifted_subset(__isl_take isl_set *set, + __isl_take EL *el, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take EL *el, + void *user), void *user) { int i; @@ -1445,21 +1663,21 @@ isl_set_free(set); FN(EL,free)(el); - return 0; + return isl_stat_ok; error: isl_set_free(set); FN(EL,free)(el); - return -1; + return isl_stat_error; } -int FN(PW,foreach_lifted_piece)(__isl_keep PW *pw, - int (*fn)(__isl_take isl_set *set, __isl_take EL *el, +isl_stat FN(PW,foreach_lifted_piece)(__isl_keep PW *pw, + isl_stat (*fn)(__isl_take isl_set *set, __isl_take EL *el, void *user), void *user) { int i; if (!pw) - return -1; + return isl_stat_error; for (i = 0; i < pw->n; ++i) { isl_set *set; @@ -1469,14 +1687,14 @@ el = FN(EL,copy)(pw->p[i].FIELD); if (!any_divs(set)) { if (fn(set, el, user) < 0) - return -1; + return isl_stat_error; continue; } if (foreach_lifted_subset(set, el, fn, user) < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } #endif @@ -1613,6 +1831,54 @@ return NULL; } +/* Divide the pieces of "pw" by "v" and return the result. + */ +__isl_give PW *FN(PW,scale_down_val)(__isl_take PW *pw, __isl_take isl_val *v) +{ + int i; + + if (!pw || !v) + goto error; + + if (isl_val_is_one(v)) { + isl_val_free(v); + return pw; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + if (pw->n == 0) { + isl_val_free(v); + return pw; + } + pw = FN(PW,cow)(pw); + if (!pw) + goto error; + +#ifdef HAS_TYPE + if (isl_val_is_neg(v)) + pw->type = isl_fold_type_negate(pw->type); +#endif + for (i = 0; i < pw->n; ++i) { + pw->p[i].FIELD = FN(EL,scale_down_val)(pw->p[i].FIELD, + isl_val_copy(v)); + if (!pw->p[i].FIELD) + goto error; + } + + isl_val_free(v); + return pw; +error: + isl_val_free(v); + FN(PW,free)(pw); + return NULL; +} + __isl_give PW *FN(PW,scale)(__isl_take PW *pw, isl_int v) { return FN(PW,mul_isl_int)(pw, v); @@ -1670,18 +1936,18 @@ * That is, do they have obviously identical cells and obviously identical * elements on each cell? */ -int FN(PW,plain_is_equal)(__isl_keep PW *pw1, __isl_keep PW *pw2) +isl_bool FN(PW,plain_is_equal)(__isl_keep PW *pw1, __isl_keep PW *pw2) { int i; - int equal; + isl_bool equal; if (!pw1 || !pw2) - return -1; + return isl_bool_error; if (pw1 == pw2) - return 1; + return isl_bool_true; if (!isl_space_is_equal(pw1->dim, pw2->dim)) - return 0; + return isl_bool_false; pw1 = FN(PW,copy)(pw1); pw2 = FN(PW,copy)(pw2); @@ -1708,7 +1974,7 @@ error: FN(PW,free)(pw1); FN(PW,free)(pw2); - return -1; + return isl_bool_error; } #ifndef NO_PULLBACK diff -Nru isl-0.12.2/isl_range.c isl-0.15/isl_range.c --- isl-0.12.2/isl_range.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_range.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -17,7 +17,7 @@ isl_pw_qpolynomial_fold *pwf_tight; }; -static int propagate_on_domain(__isl_take isl_basic_set *bset, +static isl_stat propagate_on_domain(__isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, struct range_data *data); /* Check whether the polynomial "poly" has sign "sign" over "bset", @@ -29,15 +29,13 @@ __isl_keep isl_qpolynomial *poly, int sign, int *signs) { struct range_data data_m; - unsigned nvar; unsigned nparam; isl_space *dim; - isl_qpolynomial *opt; + isl_val *opt; int r; enum isl_fold type; nparam = isl_basic_set_dim(bset, isl_dim_param); - nvar = isl_basic_set_dim(bset, isl_dim_set); bset = isl_basic_set_copy(bset); poly = isl_qpolynomial_copy(poly); @@ -70,14 +68,14 @@ if (!opt) r = -1; - else if (isl_qpolynomial_is_nan(opt) || - isl_qpolynomial_is_infty(opt) || - isl_qpolynomial_is_neginfty(opt)) + else if (isl_val_is_nan(opt) || + isl_val_is_infty(opt) || + isl_val_is_neginfty(opt)) r = 0; else - r = sign * isl_qpolynomial_sgn(opt) >= 0; + r = sign * isl_val_sgn(opt) >= 0; - isl_qpolynomial_free(opt); + isl_val_free(opt); return r; error: @@ -179,7 +177,7 @@ * and variables in data->signs. The integer divisions, if * any, are assumed to be non-negative. */ -static int collect_fixed_sign_terms(__isl_take isl_term *term, void *user) +static isl_stat collect_fixed_sign_terms(__isl_take isl_term *term, void *user) { struct isl_fixed_sign_data *data = (struct isl_fixed_sign_data *)user; isl_int n; @@ -189,7 +187,7 @@ unsigned nvar; if (!term) - return -1; + return isl_stat_error; nparam = isl_term_dim(term, isl_dim_param); nvar = isl_term_dim(term, isl_dim_set); @@ -221,7 +219,7 @@ isl_int_clear(n); - return 0; + return isl_stat_ok; } /* Construct and return a polynomial that consists of the terms @@ -249,7 +247,7 @@ /* Helper function to add a guarded polynomial to either pwf_tight or pwf, * depending on whether the result has been determined to be tight. */ -static int add_guarded_poly(__isl_take isl_basic_set *bset, +static isl_stat add_guarded_poly(__isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, struct range_data *data) { enum isl_fold type = data->sign < 0 ? isl_fold_min : isl_fold_max; @@ -269,7 +267,7 @@ else data->pwf = isl_pw_qpolynomial_fold_fold(data->pwf, pwf); - return 0; + return isl_stat_ok; } /* Given a lower and upper bound on the final variable and constraints @@ -287,14 +285,14 @@ * If all variables have been eliminated, then record the result. * Ohterwise, recurse on the next variable. */ -static int propagate_on_bound_pair(__isl_take isl_constraint *lower, +static isl_stat propagate_on_bound_pair(__isl_take isl_constraint *lower, __isl_take isl_constraint *upper, __isl_take isl_basic_set *bset, void *user) { struct range_data *data = (struct range_data *)user; int save_tight = data->tight; isl_qpolynomial *poly; - int r; + isl_stat r; unsigned nvar; nvar = isl_basic_set_dim(bset, isl_dim_set); @@ -356,7 +354,7 @@ /* Recursively perform range propagation on the polynomial "poly" * defined over the basic set "bset" and collect the results in "data". */ -static int propagate_on_domain(__isl_take isl_basic_set *bset, +static isl_stat propagate_on_domain(__isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly, struct range_data *data) { isl_ctx *ctx; @@ -394,22 +392,23 @@ data->monotonicity = save_monotonicity; data->poly = save_poly; - return 0; + return isl_stat_ok; error: isl_basic_set_free(bset); isl_qpolynomial_free(poly); data->monotonicity = save_monotonicity; data->poly = save_poly; - return -1; + return isl_stat_error; } -static int basic_guarded_poly_bound(__isl_take isl_basic_set *bset, void *user) +static isl_stat basic_guarded_poly_bound(__isl_take isl_basic_set *bset, + void *user) { struct range_data *data = (struct range_data *)user; isl_ctx *ctx; unsigned nparam = isl_basic_set_dim(bset, isl_dim_param); unsigned dim = isl_basic_set_dim(bset, isl_dim_set); - int r; + isl_stat r; data->signs = NULL; @@ -432,7 +431,7 @@ error: free(data->signs); isl_basic_set_free(bset); - return -1; + return isl_stat_error; } static int qpolynomial_bound_on_domain_range(__isl_take isl_basic_set *bset, diff -Nru isl-0.12.2/isl_reordering.c isl-0.15/isl_reordering.c --- isl-0.12.2/isl_reordering.c 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/isl_reordering.c 2015-04-19 12:02:52.000000000 +0000 @@ -198,6 +198,7 @@ { int i; + isl_space_dump(exp->dim); for (i = 0; i < exp->len; ++i) fprintf(stderr, "%d -> %d; ", i, exp->pos[i]); fprintf(stderr, "\n"); diff -Nru isl-0.12.2/isl_sample.c isl-0.15/isl_sample.c --- isl-0.12.2/isl_sample.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_sample.c 2015-06-02 09:28:10.000000000 +0000 @@ -10,16 +10,16 @@ #include #include #include "isl_sample.h" -#include "isl_sample_piplib.h" #include #include -#include +#include #include "isl_equalities.h" #include "isl_tab.h" #include "isl_basis_reduction.h" #include #include #include +#include static struct isl_vec *empty_sample(struct isl_basic_set *bset) { @@ -109,146 +109,6 @@ return NULL; } -static struct isl_mat *independent_bounds(struct isl_basic_set *bset) -{ - int i, j, n; - struct isl_mat *dirs = NULL; - struct isl_mat *bounds = NULL; - unsigned dim; - - if (!bset) - return NULL; - - dim = isl_basic_set_n_dim(bset); - bounds = isl_mat_alloc(bset->ctx, 1+dim, 1+dim); - if (!bounds) - return NULL; - - isl_int_set_si(bounds->row[0][0], 1); - isl_seq_clr(bounds->row[0]+1, dim); - bounds->n_row = 1; - - if (bset->n_ineq == 0) - return bounds; - - dirs = isl_mat_alloc(bset->ctx, dim, dim); - if (!dirs) { - isl_mat_free(bounds); - return NULL; - } - isl_seq_cpy(dirs->row[0], bset->ineq[0]+1, dirs->n_col); - isl_seq_cpy(bounds->row[1], bset->ineq[0], bounds->n_col); - for (j = 1, n = 1; n < dim && j < bset->n_ineq; ++j) { - int pos; - - isl_seq_cpy(dirs->row[n], bset->ineq[j]+1, dirs->n_col); - - pos = isl_seq_first_non_zero(dirs->row[n], dirs->n_col); - if (pos < 0) - continue; - for (i = 0; i < n; ++i) { - int pos_i; - pos_i = isl_seq_first_non_zero(dirs->row[i], dirs->n_col); - if (pos_i < pos) - continue; - if (pos_i > pos) - break; - isl_seq_elim(dirs->row[n], dirs->row[i], pos, - dirs->n_col, NULL); - pos = isl_seq_first_non_zero(dirs->row[n], dirs->n_col); - if (pos < 0) - break; - } - if (pos < 0) - continue; - if (i < n) { - int k; - isl_int *t = dirs->row[n]; - for (k = n; k > i; --k) - dirs->row[k] = dirs->row[k-1]; - dirs->row[i] = t; - } - ++n; - isl_seq_cpy(bounds->row[n], bset->ineq[j], bounds->n_col); - } - isl_mat_free(dirs); - bounds->n_row = 1+n; - return bounds; -} - -static void swap_inequality(struct isl_basic_set *bset, int a, int b) -{ - isl_int *t = bset->ineq[a]; - bset->ineq[a] = bset->ineq[b]; - bset->ineq[b] = t; -} - -/* Skew into positive orthant and project out lineality space. - * - * We perform a unimodular transformation that turns a selected - * maximal set of linearly independent bounds into constraints - * on the first dimensions that impose that these first dimensions - * are non-negative. In particular, the constraint matrix is lower - * triangular with positive entries on the diagonal and negative - * entries below. - * If "bset" has a lineality space then these constraints (and therefore - * all constraints in bset) only involve the first dimensions. - * The remaining dimensions then do not appear in any constraints and - * we can select any value for them, say zero. We therefore project - * out this final dimensions and plug in the value zero later. This - * is accomplished by simply dropping the final columns of - * the unimodular transformation. - */ -static struct isl_basic_set *isl_basic_set_skew_to_positive_orthant( - struct isl_basic_set *bset, struct isl_mat **T) -{ - struct isl_mat *U = NULL; - struct isl_mat *bounds = NULL; - int i, j; - unsigned old_dim, new_dim; - - *T = NULL; - if (!bset) - return NULL; - - isl_assert(bset->ctx, isl_basic_set_n_param(bset) == 0, goto error); - isl_assert(bset->ctx, bset->n_div == 0, goto error); - isl_assert(bset->ctx, bset->n_eq == 0, goto error); - - old_dim = isl_basic_set_n_dim(bset); - /* Try to move (multiples of) unit rows up. */ - for (i = 0, j = 0; i < bset->n_ineq; ++i) { - int pos = isl_seq_first_non_zero(bset->ineq[i]+1, old_dim); - if (pos < 0) - continue; - if (isl_seq_first_non_zero(bset->ineq[i]+1+pos+1, - old_dim-pos-1) >= 0) - continue; - if (i != j) - swap_inequality(bset, i, j); - ++j; - } - bounds = independent_bounds(bset); - if (!bounds) - goto error; - new_dim = bounds->n_row - 1; - bounds = isl_mat_left_hermite(bounds, 1, &U, NULL); - if (!bounds) - goto error; - U = isl_mat_drop_cols(U, 1 + new_dim, old_dim - new_dim); - bset = isl_basic_set_preimage(bset, isl_mat_copy(U)); - if (!bset) - goto error; - *T = U; - isl_mat_free(bounds); - return bset; -error: - isl_mat_free(bounds); - isl_mat_free(U); - isl_basic_set_free(bset); - return NULL; -} - /* Find a sample integer point, if any, in bset, which is known * to have equalities. If bset contains no integer points, then * return a zero-length vector. @@ -735,7 +595,6 @@ static struct isl_vec *sample_bounded(struct isl_basic_set *bset) { unsigned dim; - struct isl_ctx *ctx; struct isl_vec *sample; struct isl_tab *tab = NULL; isl_factorizer *f; @@ -760,14 +619,12 @@ if (f->n_group != 0) return factored_sample(bset, f); isl_factorizer_free(f); - - ctx = bset->ctx; tab = isl_tab_from_basic_set(bset, 1); if (tab && tab->empty) { isl_tab_free(tab); ISL_F_SET(bset, ISL_BASIC_SET_EMPTY); - sample = isl_vec_alloc(bset->ctx, 0); + sample = isl_vec_alloc(isl_basic_set_get_ctx(bset), 0); isl_basic_set_free(bset); return sample; } @@ -1064,11 +921,11 @@ if (!bset || !cone) goto error; - ctx = bset->ctx; + ctx = isl_basic_set_get_ctx(bset); total = isl_basic_set_total_dim(cone); cone_dim = total - cone->n_eq; - M = isl_mat_sub_alloc6(bset->ctx, cone->eq, 0, cone->n_eq, 1, total); + M = isl_mat_sub_alloc6(ctx, cone->eq, 0, cone->n_eq, 1, total); M = isl_mat_left_hermite(M, 0, &U, NULL); if (!M) goto error; @@ -1160,7 +1017,8 @@ isl_vec_free(row); if (isl_int_is_zero(v)) continue; - tab = isl_tab_extend(tab, 1); + if (isl_tab_extend_cons(tab, 1) < 0) + goto error; isl_int_add(bset->ineq[i][0], bset->ineq[i][0], v); ok = isl_tab_add_ineq(tab, bset->ineq[i]) >= 0; isl_int_sub(bset->ineq[i][0], bset->ineq[i][0], v); @@ -1254,27 +1112,6 @@ return NULL; } -static struct isl_vec *pip_sample(struct isl_basic_set *bset) -{ - struct isl_mat *T; - struct isl_ctx *ctx; - struct isl_vec *sample; - - bset = isl_basic_set_skew_to_positive_orthant(bset, &T); - if (!bset) - return NULL; - - ctx = bset->ctx; - sample = isl_pip_basic_set_sample(bset); - - if (sample && sample->size != 0) - sample = isl_mat_vec_product(T, sample); - else - isl_mat_free(T); - - return sample; -} - static struct isl_vec *basic_set_sample(struct isl_basic_set *bset, int bounded) { struct isl_ctx *ctx; @@ -1311,13 +1148,7 @@ if (dim == 1) return interval_sample(bset); - switch (bset->ctx->opt->ilp_solver) { - case ISL_ILP_PIP: - return pip_sample(bset); - case ISL_ILP_GBR: - return bounded ? sample_bounded(bset) : gbr_sample(bset); - } - isl_assert(bset->ctx, 0, ); + return bounded ? sample_bounded(bset) : gbr_sample(bset); error: isl_basic_set_free(bset); return NULL; @@ -1380,11 +1211,8 @@ if (!sample_vec) goto error; if (sample_vec->size == 0) { - struct isl_basic_map *sample; - sample = isl_basic_map_empty_like(bmap); isl_vec_free(sample_vec); - isl_basic_map_free(bmap); - return sample; + return isl_basic_map_set_to_empty(bmap); } bset = isl_basic_set_from_vec(sample_vec); return isl_basic_map_overlying_set(bset, bmap); @@ -1415,7 +1243,7 @@ isl_basic_map_free(sample); } if (i == map->n) - sample = isl_basic_map_empty_like_map(map); + sample = isl_basic_map_empty(isl_map_get_space(map)); isl_map_free(map); return sample; error: diff -Nru isl-0.12.2/isl_sample.h isl-0.15/isl_sample.h --- isl-0.12.2/isl_sample.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_sample.h 2015-04-19 12:02:52.000000000 +0000 @@ -8,7 +8,7 @@ */ #ifndef ISL_SAMPLE_H -#define ISL_SAMPLE +#define ISL_SAMPLE_H #include #include diff -Nru isl-0.12.2/isl_sample_no_piplib.c isl-0.15/isl_sample_no_piplib.c --- isl-0.12.2/isl_sample_no_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_sample_no_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -/* - * 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 - */ - -#include "isl_sample_piplib.h" - -struct isl_vec *isl_pip_basic_set_sample(struct isl_basic_set *bset) -{ - isl_basic_set_free(bset); - return NULL; -} diff -Nru isl-0.12.2/isl_sample_piplib.c isl-0.15/isl_sample_piplib.c --- isl-0.12.2/isl_sample_piplib.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_sample_piplib.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include "isl_piplib.h" -#include "isl_sample_piplib.h" - -struct isl_vec *isl_pip_basic_set_sample(struct isl_basic_set *bset) -{ - PipOptions *options = NULL; - PipMatrix *domain = NULL; - PipQuast *sol = NULL; - struct isl_vec *vec = NULL; - unsigned dim; - struct isl_ctx *ctx; - - if (!bset) - goto error; - ctx = isl_basic_set_get_ctx(bset); - isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error); - isl_assert(ctx, isl_basic_set_dim(bset, isl_dim_div) == 0, goto error); - dim = isl_basic_set_n_dim(bset); - domain = isl_basic_map_to_pip((struct isl_basic_map *)bset, 0, 0, 0); - if (!domain) - goto error; - - options = pip_options_init(); - if (!options) - goto error; - sol = pip_solve(domain, NULL, -1, options); - if (!sol) - goto error; - if (!sol->list) - vec = isl_vec_alloc(ctx, 0); - else { - PipList *l; - int i; - vec = isl_vec_alloc(ctx, 1 + dim); - if (!vec) - goto error; - isl_int_set_si(vec->block.data[0], 1); - for (i = 0, l = sol->list; l && i < dim; ++i, l = l->next) { - isl_seq_cpy_from_pip(&vec->block.data[1+i], - &l->vector->the_vector[0], 1); - isl_assert(ctx, !entier_zero_p(l->vector->the_deno[0]), - goto error); - } - isl_assert(ctx, i == dim, goto error); - } - - pip_quast_free(sol); - pip_options_free(options); - pip_matrix_free(domain); - - isl_basic_set_free(bset); - return vec; -error: - isl_vec_free(vec); - isl_basic_set_free(bset); - if (sol) - pip_quast_free(sol); - if (domain) - pip_matrix_free(domain); - return NULL; -} diff -Nru isl-0.12.2/isl_sample_piplib.h isl-0.15/isl_sample_piplib.h --- isl-0.12.2/isl_sample_piplib.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_sample_piplib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -/* - * 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_SAMPLE_PIP_H -#define ISL_SAMPLE_PIP - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -struct isl_vec *isl_pip_basic_set_sample(struct isl_basic_set *bset); - -#if defined(__cplusplus) -} -#endif - -#endif diff -Nru isl-0.12.2/isl_scan.c isl-0.15/isl_scan.c --- isl-0.12.2/isl_scan.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_scan.c 2015-06-02 09:28:10.000000000 +0000 @@ -11,9 +11,10 @@ #include #include "isl_basis_reduction.h" #include "isl_scan.h" -#include +#include #include "isl_tab.h" #include +#include struct isl_counter { struct isl_scan_callback callback; @@ -21,7 +22,7 @@ isl_int max; }; -static int increment_counter(struct isl_scan_callback *cb, +static isl_stat increment_counter(struct isl_scan_callback *cb, __isl_take isl_vec *sample) { struct isl_counter *cnt = (struct isl_counter *)cb; @@ -31,8 +32,8 @@ isl_vec_free(sample); if (isl_int_is_zero(cnt->max) || isl_int_lt(cnt->count, cnt->max)) - return 0; - return -1; + return isl_stat_ok; + return isl_stat_error; } static int increment_range(struct isl_scan_callback *cb, isl_int min, isl_int max) diff -Nru isl-0.12.2/isl_scan.h isl-0.15/isl_scan.h --- isl-0.12.2/isl_scan.h 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/isl_scan.h 2015-06-02 09:28:10.000000000 +0000 @@ -14,7 +14,8 @@ #include struct isl_scan_callback { - int (*add)(struct isl_scan_callback *cb, __isl_take isl_vec *sample); + isl_stat (*add)(struct isl_scan_callback *cb, + __isl_take isl_vec *sample); }; int isl_basic_set_scan(struct isl_basic_set *bset, diff -Nru isl-0.12.2/isl_schedule_band.c isl-0.15/isl_schedule_band.c --- isl-0.12.2/isl_schedule_band.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_band.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,1189 @@ +/* + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include +#include + +isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band) +{ + return band ? isl_multi_union_pw_aff_get_ctx(band->mupa) : NULL; +} + +/* Return a new uninitialized isl_schedule_band. + */ +static __isl_give isl_schedule_band *isl_schedule_band_alloc(isl_ctx *ctx) +{ + isl_schedule_band *band; + + band = isl_calloc_type(ctx, isl_schedule_band); + if (!band) + return NULL; + + band->ref = 1; + + return band; +} + +/* Return a new isl_schedule_band with partial schedule "mupa". + * First replace "mupa" by its greatest integer part to ensure + * that the schedule is always integral. + * The band is not marked permutable, the dimensions are not + * marked coincident and the AST build options are empty. + * Since there are no build options, the node is not anchored. + */ +__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa) +{ + isl_ctx *ctx; + isl_schedule_band *band; + isl_space *space; + + mupa = isl_multi_union_pw_aff_floor(mupa); + if (!mupa) + return NULL; + ctx = isl_multi_union_pw_aff_get_ctx(mupa); + band = isl_schedule_band_alloc(ctx); + if (!band) + goto error; + + band->n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); + band->coincident = isl_calloc_array(ctx, int, band->n); + band->mupa = mupa; + space = isl_space_params_alloc(ctx, 0); + band->ast_build_options = isl_union_set_empty(space); + band->anchored = 0; + + if ((band->n && !band->coincident) || !band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +error: + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Create a duplicate of the given isl_schedule_band. + */ +__isl_give isl_schedule_band *isl_schedule_band_dup( + __isl_keep isl_schedule_band *band) +{ + int i; + isl_ctx *ctx; + isl_schedule_band *dup; + + if (!band) + return NULL; + + ctx = isl_schedule_band_get_ctx(band); + dup = isl_schedule_band_alloc(ctx); + if (!dup) + return NULL; + + dup->n = band->n; + dup->coincident = isl_alloc_array(ctx, int, band->n); + if (band->n && !dup->coincident) + return isl_schedule_band_free(dup); + + for (i = 0; i < band->n; ++i) + dup->coincident[i] = band->coincident[i]; + dup->permutable = band->permutable; + + dup->mupa = isl_multi_union_pw_aff_copy(band->mupa); + dup->ast_build_options = isl_union_set_copy(band->ast_build_options); + if (!dup->mupa || !dup->ast_build_options) + return isl_schedule_band_free(dup); + + if (band->loop_type) { + dup->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !dup->loop_type) + return isl_schedule_band_free(dup); + for (i = 0; i < band->n; ++i) + dup->loop_type[i] = band->loop_type[i]; + } + if (band->isolate_loop_type) { + dup->isolate_loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !dup->isolate_loop_type) + return isl_schedule_band_free(dup); + for (i = 0; i < band->n; ++i) + dup->isolate_loop_type[i] = band->isolate_loop_type[i]; + } + + return dup; +} + +/* Return an isl_schedule_band that is equal to "band" and that has only + * a single reference. + */ +__isl_give isl_schedule_band *isl_schedule_band_cow( + __isl_take isl_schedule_band *band) +{ + if (!band) + return NULL; + + if (band->ref == 1) + return band; + band->ref--; + return isl_schedule_band_dup(band); +} + +/* Return a new reference to "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_copy( + __isl_keep isl_schedule_band *band) +{ + if (!band) + return NULL; + + band->ref++; + return band; +} + +/* Free a reference to "band" and return NULL. + */ +__isl_null isl_schedule_band *isl_schedule_band_free( + __isl_take isl_schedule_band *band) +{ + if (!band) + return NULL; + + if (--band->ref > 0) + return NULL; + + isl_multi_union_pw_aff_free(band->mupa); + isl_union_set_free(band->ast_build_options); + free(band->loop_type); + free(band->isolate_loop_type); + free(band->coincident); + free(band); + + return NULL; +} + +/* Are "band1" and "band2" obviously equal? + */ +isl_bool isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1, + __isl_keep isl_schedule_band *band2) +{ + int i; + isl_bool equal; + + if (!band1 || !band2) + return isl_bool_error; + if (band1 == band2) + return isl_bool_true; + + if (band1->n != band2->n) + return isl_bool_false; + for (i = 0; i < band1->n; ++i) + if (band1->coincident[i] != band2->coincident[i]) + return isl_bool_false; + if (band1->permutable != band2->permutable) + return isl_bool_false; + + equal = isl_multi_union_pw_aff_plain_is_equal(band1->mupa, band2->mupa); + if (equal < 0 || !equal) + return equal; + + if (!band1->loop_type != !band2->loop_type) + return isl_bool_false; + if (band1->loop_type) + for (i = 0; i < band1->n; ++i) + if (band1->loop_type[i] != band2->loop_type[i]) + return isl_bool_false; + + if (!band1->isolate_loop_type != !band2->isolate_loop_type) + return isl_bool_false; + if (band1->isolate_loop_type) + for (i = 0; i < band1->n; ++i) + if (band1->isolate_loop_type[i] != + band2->isolate_loop_type[i]) + return isl_bool_false; + + return isl_union_set_is_equal(band1->ast_build_options, + band2->ast_build_options); +} + +/* Return the number of scheduling dimensions in the band. + */ +int isl_schedule_band_n_member(__isl_keep isl_schedule_band *band) +{ + return band ? band->n : 0; +} + +/* Is the given scheduling dimension coincident within the band and + * with respect to the coincidence constraints? + */ +isl_bool isl_schedule_band_member_get_coincident( + __isl_keep isl_schedule_band *band, int pos) +{ + if (!band) + return isl_bool_error; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", return isl_bool_error); + + return band->coincident[pos]; +} + +/* Mark the given scheduling dimension as being coincident or not + * according to "coincident". + */ +__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident( + __isl_take isl_schedule_band *band, int pos, int coincident) +{ + if (!band) + return NULL; + if (isl_schedule_band_member_get_coincident(band, pos) == coincident) + return band; + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", + isl_schedule_band_free(band)); + + band->coincident[pos] = coincident; + + return band; +} + +/* Is the schedule band mark permutable? + */ +isl_bool isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band) +{ + if (!band) + return isl_bool_error; + return band->permutable; +} + +/* Mark the schedule band permutable or not according to "permutable"? + */ +__isl_give isl_schedule_band *isl_schedule_band_set_permutable( + __isl_take isl_schedule_band *band, int permutable) +{ + if (!band) + return NULL; + if (band->permutable == permutable) + return band; + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + band->permutable = permutable; + + return band; +} + +/* Is the band node "node" anchored? That is, does it reference + * the outer band nodes? + */ +int isl_schedule_band_is_anchored(__isl_keep isl_schedule_band *band) +{ + return band ? band->anchored : -1; +} + +/* Return the schedule space of the band. + */ +__isl_give isl_space *isl_schedule_band_get_space( + __isl_keep isl_schedule_band *band) +{ + if (!band) + return NULL; + return isl_multi_union_pw_aff_get_space(band->mupa); +} + +/* Intersect the domain of the band schedule of "band" with "domain". + */ +__isl_give isl_schedule_band *isl_schedule_band_intersect_domain( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *domain) +{ + band = isl_schedule_band_cow(band); + if (!band || !domain) + goto error; + + band->mupa = isl_multi_union_pw_aff_intersect_domain(band->mupa, + domain); + if (!band->mupa) + return isl_schedule_band_free(band); + + return band; +error: + isl_schedule_band_free(band); + isl_union_set_free(domain); + return NULL; +} + +/* Return the schedule of the band in isolation. + */ +__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule( + __isl_keep isl_schedule_band *band) +{ + return band ? isl_multi_union_pw_aff_copy(band->mupa) : NULL; +} + +/* Replace the schedule of "band" by "schedule". + */ +__isl_give isl_schedule_band *isl_schedule_band_set_partial_schedule( + __isl_take isl_schedule_band *band, + __isl_take isl_multi_union_pw_aff *schedule) +{ + band = isl_schedule_band_cow(band); + if (!band || !schedule) + goto error; + + isl_multi_union_pw_aff_free(band->mupa); + band->mupa = schedule; + + return band; +error: + isl_schedule_band_free(band); + isl_multi_union_pw_aff_free(schedule); + return NULL; +} + +/* Return the loop AST generation type for the band member of "band" + * at position "pos". + */ +enum isl_ast_loop_type isl_schedule_band_member_get_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos) +{ + if (!band) + return isl_ast_loop_error; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", return -1); + + if (!band->loop_type) + return isl_ast_loop_default; + + return band->loop_type[pos]; +} + +/* Set the loop AST generation type for the band member of "band" + * at position "pos" to "type". + */ +__isl_give isl_schedule_band *isl_schedule_band_member_set_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type) +{ + if (!band) + return NULL; + if (isl_schedule_band_member_get_ast_loop_type(band, pos) == type) + return band; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", + isl_schedule_band_free(band)); + + band = isl_schedule_band_cow(band); + if (!band) + return isl_schedule_band_free(band); + + if (!band->loop_type) { + isl_ctx *ctx; + + ctx = isl_schedule_band_get_ctx(band); + band->loop_type = isl_calloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->loop_type) + return isl_schedule_band_free(band); + } + + band->loop_type[pos] = type; + + return band; +} + +/* Return the loop AST generation type for the band member of "band" + * at position "pos" for the part that has been isolated by the isolate option. + */ +enum isl_ast_loop_type isl_schedule_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos) +{ + if (!band) + return isl_ast_loop_error; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", return -1); + + if (!band->isolate_loop_type) + return isl_ast_loop_default; + + return band->isolate_loop_type[pos]; +} + +/* Set the loop AST generation type for the band member of "band" + * at position "pos" to "type" for the part that has been isolated + * by the isolate option. + */ +__isl_give isl_schedule_band * +isl_schedule_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type) +{ + if (!band) + return NULL; + if (isl_schedule_band_member_get_isolate_ast_loop_type(band, pos) == + type) + return band; + + if (pos < 0 || pos >= band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid, + "invalid member position", + isl_schedule_band_free(band)); + + band = isl_schedule_band_cow(band); + if (!band) + return isl_schedule_band_free(band); + + if (!band->isolate_loop_type) { + isl_ctx *ctx; + + ctx = isl_schedule_band_get_ctx(band); + band->isolate_loop_type = isl_calloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->isolate_loop_type) + return isl_schedule_band_free(band); + } + + band->isolate_loop_type[pos] = type; + + return band; +} + +static const char *option_str[] = { + [isl_ast_loop_atomic] = "atomic", + [isl_ast_loop_unroll] = "unroll", + [isl_ast_loop_separate] = "separate" +}; + +/* Given a parameter space "space", extend it to a set space + * + * { type[x] } + * + * or + * + * { [isolate[] -> type[x]] } + * + * depending on whether "isolate" is set. + * These can be used to encode loop AST generation options of the given type. + */ +static __isl_give isl_space *loop_type_space(__isl_take isl_space *space, + enum isl_ast_loop_type type, int isolate) +{ + const char *name; + + name = option_str[type]; + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); + space = isl_space_set_tuple_name(space, isl_dim_set, name); + if (!isolate) + return space; + space = isl_space_from_range(space); + space = isl_space_set_tuple_name(space, isl_dim_in, "isolate"); + space = isl_space_wrap(space); + + return space; +} + +/* Add encodings of the "n" loop AST generation options "type" to "options". + * If "isolate" is set, then these options refer to the isolated part. + * + * In particular, for each sequence of consecutive identical types "t", + * different from the default, add an option + * + * { t[x] : first <= x <= last } + * + * or + * + * { [isolate[] -> t[x]] : first <= x <= last } + */ +static __isl_give isl_union_set *add_loop_types( + __isl_take isl_union_set *options, int n, enum isl_ast_loop_type *type, + int isolate) +{ + int i; + isl_ctx *ctx; + + if (!type) + return options; + if (!options) + return NULL; + + ctx = isl_union_set_get_ctx(options); + for (i = 0; i < n; ++i) { + int first; + isl_space *space; + isl_set *option; + + if (type[i] == isl_ast_loop_default) + continue; + + first = i; + while (i + 1 < n && type[i + 1] == type[i]) + ++i; + + space = isl_union_set_get_space(options); + space = loop_type_space(space, type[i], isolate); + option = isl_set_universe(space); + option = isl_set_lower_bound_si(option, isl_dim_set, 0, first); + option = isl_set_upper_bound_si(option, isl_dim_set, 0, i); + options = isl_union_set_add_set(options, option); + } + + return options; +} + +/* Return the AST build options associated to "band". + */ +__isl_give isl_union_set *isl_schedule_band_get_ast_build_options( + __isl_keep isl_schedule_band *band) +{ + isl_union_set *options; + + if (!band) + return NULL; + + options = isl_union_set_copy(band->ast_build_options); + options = add_loop_types(options, band->n, band->loop_type, 0); + options = add_loop_types(options, band->n, band->isolate_loop_type, 1); + + return options; +} + +/* Does "uset" contain any set that satisfies "is"? + * "is" is assumed to set its integer argument to 1 if it is satisfied. + */ +static int has_any(__isl_keep isl_union_set *uset, + isl_stat (*is)(__isl_take isl_set *set, void *user)) +{ + int found = 0; + + if (isl_union_set_foreach_set(uset, is, &found) < 0 && !found) + return -1; + + return found; +} + +/* Does "set" live in a space of the form + * + * isolate[[...] -> [...]] + * + * ? + * + * If so, set *found and abort the search. + */ +static isl_stat is_isolate(__isl_take isl_set *set, void *user) +{ + int *found = user; + + if (isl_set_has_tuple_name(set)) { + const char *name; + name = isl_set_get_tuple_name(set); + if (isl_set_is_wrapping(set) && !strcmp(name, "isolate")) + *found = 1; + } + isl_set_free(set); + + return *found ? isl_stat_error : isl_stat_ok; +} + +/* Does "options" include an option of the ofrm + * + * isolate[[...] -> [...]] + * + * ? + */ +static int has_isolate_option(__isl_keep isl_union_set *options) +{ + return has_any(options, &is_isolate); +} + +/* Does "set" encode a loop AST generation option? + */ +static isl_stat is_loop_type_option(__isl_take isl_set *set, void *user) +{ + int *found = user; + + if (isl_set_dim(set, isl_dim_set) == 1 && + isl_set_has_tuple_name(set)) { + const char *name; + enum isl_ast_loop_type type; + name = isl_set_get_tuple_name(set); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + if (strcmp(name, option_str[type])) + continue; + *found = 1; + break; + } + } + isl_set_free(set); + + return *found ? isl_stat_error : isl_stat_ok; +} + +/* Does "set" encode a loop AST generation option for the isolated part? + * That is, is of the form + * + * { [isolate[] -> t[x]] } + * + * with t equal to "atomic", "unroll" or "separate"? + */ +static isl_stat is_isolate_loop_type_option(__isl_take isl_set *set, void *user) +{ + int *found = user; + const char *name; + enum isl_ast_loop_type type; + isl_map *map; + + if (!isl_set_is_wrapping(set)) { + isl_set_free(set); + return isl_stat_ok; + } + map = isl_set_unwrap(set); + if (!isl_map_has_tuple_name(map, isl_dim_in) || + !isl_map_has_tuple_name(map, isl_dim_out)) { + isl_map_free(map); + return isl_stat_ok; + } + name = isl_map_get_tuple_name(map, isl_dim_in); + if (!strcmp(name, "isolate")) { + name = isl_map_get_tuple_name(map, isl_dim_out); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + if (strcmp(name, option_str[type])) + continue; + *found = 1; + break; + } + } + isl_map_free(map); + + return *found ? isl_stat_error : isl_stat_ok; +} + +/* Does "options" encode any loop AST generation options + * for the isolated part? + */ +static int has_isolate_loop_type_options(__isl_keep isl_union_set *options) +{ + return has_any(options, &is_isolate_loop_type_option); +} + +/* Does "options" encode any loop AST generation options? + */ +static int has_loop_type_options(__isl_keep isl_union_set *options) +{ + return has_any(options, &is_loop_type_option); +} + +/* Extract the loop AST generation type for the band member + * at position "pos" from "options". + * If "isolate" is set, then extract the loop types for the isolated part. + */ +static enum isl_ast_loop_type extract_loop_type( + __isl_keep isl_union_set *options, int pos, int isolate) +{ + isl_ctx *ctx; + enum isl_ast_loop_type type, res = isl_ast_loop_default; + + ctx = isl_union_set_get_ctx(options); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + isl_space *space; + isl_set *option; + int empty; + + space = isl_union_set_get_space(options); + space = loop_type_space(space, type, isolate); + option = isl_union_set_extract_set(options, space); + option = isl_set_fix_si(option, isl_dim_set, 0, pos); + empty = isl_set_is_empty(option); + isl_set_free(option); + + if (empty < 0) + return isl_ast_loop_error; + if (empty) + continue; + if (res != isl_ast_loop_default) + isl_die(ctx, isl_error_invalid, + "conflicting loop type options", + return isl_ast_loop_error); + res = type; + } + + return res; +} + +/* Extract the loop AST generation types for the members of "band" + * from "options" and store them in band->loop_type. + * Return -1 on error. + */ +static int extract_loop_types(__isl_keep isl_schedule_band *band, + __isl_keep isl_union_set *options) +{ + int i; + + if (!band->loop_type) { + isl_ctx *ctx = isl_schedule_band_get_ctx(band); + band->loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->loop_type) + return -1; + } + for (i = 0; i < band->n; ++i) { + band->loop_type[i] = extract_loop_type(options, i, 0); + if (band->loop_type[i] == isl_ast_loop_error) + return -1; + } + + return 0; +} + +/* Extract the loop AST generation types for the members of "band" + * from "options" for the isolated part and + * store them in band->isolate_loop_type. + * Return -1 on error. + */ +static int extract_isolate_loop_types(__isl_keep isl_schedule_band *band, + __isl_keep isl_union_set *options) +{ + int i; + + if (!band->isolate_loop_type) { + isl_ctx *ctx = isl_schedule_band_get_ctx(band); + band->isolate_loop_type = isl_alloc_array(ctx, + enum isl_ast_loop_type, band->n); + if (band->n && !band->isolate_loop_type) + return -1; + } + for (i = 0; i < band->n; ++i) { + band->isolate_loop_type[i] = extract_loop_type(options, i, 1); + if (band->isolate_loop_type[i] == isl_ast_loop_error) + return -1; + } + + return 0; +} + +/* Construct universe sets of the spaces that encode loop AST generation + * types (for the isolated part if "isolate" is set). That is, construct + * + * { atomic[x]; separate[x]; unroll[x] } + * + * or + * + * { [isolate[] -> atomic[x]]; [isolate[] -> separate[x]]; + * [isolate[] -> unroll[x]] } + */ +static __isl_give isl_union_set *loop_types(__isl_take isl_space *space, + int isolate) +{ + enum isl_ast_loop_type type; + isl_union_set *types; + + types = isl_union_set_empty(space); + for (type = isl_ast_loop_atomic; + type <= isl_ast_loop_separate; ++type) { + isl_set *set; + + space = isl_union_set_get_space(types); + space = loop_type_space(space, type, isolate); + set = isl_set_universe(space); + types = isl_union_set_add_set(types, set); + } + + return types; +} + +/* Remove all elements from spaces that encode loop AST generation types + * from "options". + */ +static __isl_give isl_union_set *clear_loop_types( + __isl_take isl_union_set *options) +{ + isl_union_set *types; + + types = loop_types(isl_union_set_get_space(options), 0); + options = isl_union_set_subtract(options, types); + + return options; +} + +/* Remove all elements from spaces that encode loop AST generation types + * for the isolated part from "options". + */ +static __isl_give isl_union_set *clear_isolate_loop_types( + __isl_take isl_union_set *options) +{ + isl_union_set *types; + + types = loop_types(isl_union_set_get_space(options), 1); + options = isl_union_set_subtract(options, types); + + return options; +} + +/* Replace the AST build options associated to "band" by "options". + * If there are any loop AST generation type options, then they + * are extracted and stored in band->loop_type. Otherwise, + * band->loop_type is removed to indicate that the default applies + * to all members. Similarly for the loop AST generation type options + * for the isolated part, which are stored in band->isolate_loop_type. + * The remaining options are stored in band->ast_build_options. + * + * Set anchored if the options include an isolate option since the + * domain of the wrapped map references the outer band node schedules. + */ +__isl_give isl_schedule_band *isl_schedule_band_set_ast_build_options( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *options) +{ + int has_isolate, has_loop_type, has_isolate_loop_type; + + band = isl_schedule_band_cow(band); + if (!band || !options) + goto error; + has_isolate = has_isolate_option(options); + if (has_isolate < 0) + goto error; + has_loop_type = has_loop_type_options(options); + if (has_loop_type < 0) + goto error; + has_isolate_loop_type = has_isolate_loop_type_options(options); + if (has_isolate_loop_type < 0) + goto error; + + if (!has_loop_type) { + free(band->loop_type); + band->loop_type = NULL; + } else { + if (extract_loop_types(band, options) < 0) + goto error; + options = clear_loop_types(options); + if (!options) + goto error; + } + + if (!has_isolate_loop_type) { + free(band->isolate_loop_type); + band->isolate_loop_type = NULL; + } else { + if (extract_isolate_loop_types(band, options) < 0) + goto error; + options = clear_isolate_loop_types(options); + if (!options) + goto error; + } + + isl_union_set_free(band->ast_build_options); + band->ast_build_options = options; + band->anchored = has_isolate; + + return band; +error: + isl_schedule_band_free(band); + isl_union_set_free(options); + return NULL; +} + +/* Multiply the partial schedule of "band" with the factors in "mv". + * Replace the result by its greatest integer part to ensure + * that the schedule is always integral. + */ +__isl_give isl_schedule_band *isl_schedule_band_scale( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) +{ + band = isl_schedule_band_cow(band); + if (!band || !mv) + goto error; + band->mupa = isl_multi_union_pw_aff_scale_multi_val(band->mupa, mv); + band->mupa = isl_multi_union_pw_aff_floor(band->mupa); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(mv); + return NULL; +} + +/* Divide the partial schedule of "band" by the factors in "mv". + * Replace the result by its greatest integer part to ensure + * that the schedule is always integral. + */ +__isl_give isl_schedule_band *isl_schedule_band_scale_down( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) +{ + band = isl_schedule_band_cow(band); + if (!band || !mv) + goto error; + band->mupa = isl_multi_union_pw_aff_scale_down_multi_val(band->mupa, + mv); + band->mupa = isl_multi_union_pw_aff_floor(band->mupa); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(mv); + return NULL; +} + +/* Given the schedule of a band, construct the corresponding + * schedule for the tile loops based on the given tile sizes + * and return the result. + * + * If the scale tile loops options is set, then the tile loops + * are scaled by the tile sizes. + * + * That is replace each schedule dimension "i" by either + * "floor(i/s)" or "s * floor(i/s)". + */ +static isl_multi_union_pw_aff *isl_multi_union_pw_aff_tile( + __isl_take isl_multi_union_pw_aff *sched, + __isl_take isl_multi_val *sizes) +{ + isl_ctx *ctx; + int i, n; + isl_val *v; + int scale; + + ctx = isl_multi_val_get_ctx(sizes); + scale = isl_options_get_tile_scale_tile_loops(ctx); + + n = isl_multi_union_pw_aff_dim(sched, isl_dim_set); + for (i = 0; i < n; ++i) { + isl_union_pw_aff *upa; + + upa = isl_multi_union_pw_aff_get_union_pw_aff(sched, i); + v = isl_multi_val_get_val(sizes, i); + + upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(v)); + upa = isl_union_pw_aff_floor(upa); + if (scale) + upa = isl_union_pw_aff_scale_val(upa, isl_val_copy(v)); + isl_val_free(v); + + sched = isl_multi_union_pw_aff_set_union_pw_aff(sched, i, upa); + } + + isl_multi_val_free(sizes); + return sched; +} + +/* Replace "band" by a band corresponding to the tile loops of a tiling + * with the given tile sizes. + */ +__isl_give isl_schedule_band *isl_schedule_band_tile( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes) +{ + band = isl_schedule_band_cow(band); + if (!band || !sizes) + goto error; + band->mupa = isl_multi_union_pw_aff_tile(band->mupa, sizes); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(sizes); + return NULL; +} + +/* Replace "band" by a band corresponding to the point loops of a tiling + * with the given tile sizes. + * "tile" is the corresponding tile loop band. + * + * If the shift point loops option is set, then the point loops + * are shifted to start at zero. That is, each schedule dimension "i" + * is replaced by "i - s * floor(i/s)". + * The expression "floor(i/s)" (or "s * floor(i/s)") is extracted from + * the tile band. + * + * Otherwise, the band is left untouched. + */ +__isl_give isl_schedule_band *isl_schedule_band_point( + __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile, + __isl_take isl_multi_val *sizes) +{ + isl_ctx *ctx; + isl_multi_union_pw_aff *scaled; + + if (!band || !sizes) + goto error; + + ctx = isl_schedule_band_get_ctx(band); + if (!isl_options_get_tile_shift_point_loops(ctx)) { + isl_multi_val_free(sizes); + return band; + } + band = isl_schedule_band_cow(band); + if (!band) + goto error; + + scaled = isl_schedule_band_get_partial_schedule(tile); + if (!isl_options_get_tile_scale_tile_loops(ctx)) + scaled = isl_multi_union_pw_aff_scale_multi_val(scaled, sizes); + else + isl_multi_val_free(sizes); + band->mupa = isl_multi_union_pw_aff_sub(band->mupa, scaled); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_schedule_band_free(band); + isl_multi_val_free(sizes); + return NULL; +} + +/* Drop the "n" dimensions starting at "pos" from "band". + * + * We apply the transformation even if "n" is zero to ensure consistent + * behavior with respect to changes in the schedule space. + * + * The loop AST generation types for the isolated part become + * meaningless after dropping dimensions, so we remove them. + */ +__isl_give isl_schedule_band *isl_schedule_band_drop( + __isl_take isl_schedule_band *band, int pos, int n) +{ + int i; + + if (pos < 0 || n < 0 || pos + n > band->n) + isl_die(isl_schedule_band_get_ctx(band), isl_error_internal, + "range out of bounds", + return isl_schedule_band_free(band)); + + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + band->mupa = isl_multi_union_pw_aff_drop_dims(band->mupa, + isl_dim_set, pos, n); + if (!band->mupa) + return isl_schedule_band_free(band); + + for (i = pos + n; i < band->n; ++i) + band->coincident[i - n] = band->coincident[i]; + if (band->loop_type) + for (i = pos + n; i < band->n; ++i) + band->loop_type[i - n] = band->loop_type[i]; + free(band->isolate_loop_type); + band->isolate_loop_type = NULL; + + band->n -= n; + + return band; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_reset_user( + __isl_take isl_schedule_band *band) +{ + band = isl_schedule_band_cow(band); + if (!band) + return NULL; + + band->mupa = isl_multi_union_pw_aff_reset_user(band->mupa); + band->ast_build_options = + isl_union_set_reset_user(band->ast_build_options); + if (!band->mupa || !band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +} + +/* Align the parameters of "band" to those of "space". + */ +__isl_give isl_schedule_band *isl_schedule_band_align_params( + __isl_take isl_schedule_band *band, __isl_take isl_space *space) +{ + band = isl_schedule_band_cow(band); + if (!band || !space) + goto error; + + band->mupa = isl_multi_union_pw_aff_align_params(band->mupa, + isl_space_copy(space)); + band->ast_build_options = + isl_union_set_align_params(band->ast_build_options, space); + if (!band->mupa || !band->ast_build_options) + return isl_schedule_band_free(band); + + return band; +error: + isl_space_free(space); + isl_schedule_band_free(band); + return NULL; +} + +/* Compute the pullback of "band" by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains of "band". + */ +__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( + __isl_take isl_schedule_band *band, + __isl_take isl_union_pw_multi_aff *upma) +{ + band = isl_schedule_band_cow(band); + if (!band || !upma) + goto error; + + band->mupa = + isl_multi_union_pw_aff_pullback_union_pw_multi_aff(band->mupa, + upma); + if (!band->mupa) + return isl_schedule_band_free(band); + + return band; +error: + isl_union_pw_multi_aff_free(upma); + isl_schedule_band_free(band); + return NULL; +} + +/* Compute the gist of "band" with respect to "context". + * In particular, compute the gist of the associated partial schedule. + */ +__isl_give isl_schedule_band *isl_schedule_band_gist( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *context) +{ + if (!band || !context) + goto error; + if (band->n == 0) { + isl_union_set_free(context); + return band; + } + band = isl_schedule_band_cow(band); + if (!band) + goto error; + band->mupa = isl_multi_union_pw_aff_gist(band->mupa, context); + if (!band->mupa) + return isl_schedule_band_free(band); + return band; +error: + isl_union_set_free(context); + isl_schedule_band_free(band); + return NULL; +} diff -Nru isl-0.12.2/isl_schedule_band.h isl-0.15/isl_schedule_band.h --- isl-0.12.2/isl_schedule_band.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_band.h 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,115 @@ +#ifndef ISL_SCHEDULE_BAND_H +#define ISL_SCHEDULE_BAND_H + +#include +#include +#include + +/* Information about a band within a schedule. + * + * n is the number of scheduling dimensions within the band. + * coincident is an array of length n, indicating whether a scheduling dimension + * satisfies the coincidence constraints in the sense that + * the corresponding dependence distances are zero. + * permutable is set if the band is permutable. + * mupa is the partial schedule corresponding to this band. The dimension + * of mupa is equal to n. + * loop_type contains the loop AST generation types for the members + * in the band. It may be NULL, if all members are + * of type isl_ast_loop_default. + * isolate_loop_type contains the loop AST generation types for the members + * in the band for the isolated part. It may be NULL, if all members are + * of type isl_ast_loop_default. + * ast_build_options are the remaining AST build options associated + * to the band. + * anchored is set if the node depends on its position in the schedule tree. + * In particular, it is set if the AST build options include + * an isolate option. + */ +struct isl_schedule_band { + int ref; + + int n; + int *coincident; + int permutable; + + isl_multi_union_pw_aff *mupa; + + int anchored; + isl_union_set *ast_build_options; + enum isl_ast_loop_type *loop_type; + enum isl_ast_loop_type *isolate_loop_type; +}; +typedef struct isl_schedule_band isl_schedule_band; + +__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff( + __isl_take isl_multi_union_pw_aff *mupa); +__isl_give isl_schedule_band *isl_schedule_band_copy( + __isl_keep isl_schedule_band *band); +__isl_null isl_schedule_band *isl_schedule_band_free( + __isl_take isl_schedule_band *band); + +isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band); + +isl_bool isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1, + __isl_keep isl_schedule_band *band2); + +int isl_schedule_band_is_anchored(__isl_keep isl_schedule_band *band); + +__isl_give isl_space *isl_schedule_band_get_space( + __isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_intersect_domain( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *domain); +__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule( + __isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_set_partial_schedule( + __isl_take isl_schedule_band *band, + __isl_take isl_multi_union_pw_aff *schedule); +enum isl_ast_loop_type isl_schedule_band_member_get_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos); +__isl_give isl_schedule_band *isl_schedule_band_member_set_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type); +enum isl_ast_loop_type isl_schedule_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_band *band, int pos); +__isl_give isl_schedule_band * +isl_schedule_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_band *band, int pos, + enum isl_ast_loop_type type); +__isl_give isl_union_set *isl_schedule_band_get_ast_build_options( + __isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_set_ast_build_options( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *options); + +int isl_schedule_band_n_member(__isl_keep isl_schedule_band *band); +isl_bool isl_schedule_band_member_get_coincident( + __isl_keep isl_schedule_band *band, int pos); +__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident( + __isl_take isl_schedule_band *band, int pos, int coincident); +isl_bool isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_set_permutable( + __isl_take isl_schedule_band *band, int permutable); + +__isl_give isl_schedule_band *isl_schedule_band_scale( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_band *isl_schedule_band_scale_down( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_band *isl_schedule_band_tile( + __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_band *isl_schedule_band_point( + __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile, + __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_band *isl_schedule_band_drop( + __isl_take isl_schedule_band *band, int pos, int n); +__isl_give isl_schedule_band *isl_schedule_band_gist( + __isl_take isl_schedule_band *band, __isl_take isl_union_set *context); + +__isl_give isl_schedule_band *isl_schedule_band_reset_user( + __isl_take isl_schedule_band *band); +__isl_give isl_schedule_band *isl_schedule_band_align_params( + __isl_take isl_schedule_band *band, __isl_take isl_space *space); +__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( + __isl_take isl_schedule_band *band, + __isl_take isl_union_pw_multi_aff *upma); + +#endif diff -Nru isl-0.12.2/isl_schedule.c isl-0.15/isl_schedule.c --- isl-0.12.2/isl_schedule.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_schedule.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2011 INRIA Saclay - * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2012-2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -10,3013 +10,245 @@ * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include -#include -#include +#include +#include #include #include +#include +#include #include -#include -#include - -/* - * The scheduling algorithm implemented in this file was inspired by - * Bondhugula et al., "Automatic Transformations for Communication-Minimized - * Parallelization and Locality Optimization in the Polyhedral Model". - */ - - -/* Internal information about a node that is used during the construction - * of a schedule. - * dim represents the space in which the domain lives - * sched is a matrix representation of the schedule being constructed - * for this node - * sched_map is an isl_map representation of the same (partial) schedule - * sched_map may be NULL - * rank is the number of linearly independent rows in the linear part - * of sched - * the columns of cmap represent a change of basis for the schedule - * coefficients; the first rank columns span the linear part of - * the schedule rows - * cinv is the inverse of cmap. - * start is the first variable in the LP problem in the sequences that - * represents the schedule coefficients of this node - * nvar is the dimension of the domain - * nparam is the number of parameters or 0 if we are not constructing - * a parametric schedule - * - * scc is the index of SCC (or WCC) this node belongs to - * - * band contains the band index for each of the rows of the schedule. - * band_id is used to differentiate between separate bands at the same - * level within the same parent band, i.e., bands that are separated - * by the parent band or bands that are independent of each other. - * zero contains a boolean for each of the rows of the schedule, - * indicating whether the corresponding scheduling dimension results - * in zero dependence distances within its band and with respect - * to the proximity edges. - */ -struct isl_sched_node { - isl_space *dim; - isl_mat *sched; - isl_map *sched_map; - int rank; - isl_mat *cmap; - isl_mat *cinv; - int start; - int nvar; - int nparam; - - int scc; - - int *band; - int *band_id; - int *zero; -}; - -static int node_has_dim(const void *entry, const void *val) -{ - struct isl_sched_node *node = (struct isl_sched_node *)entry; - isl_space *dim = (isl_space *)val; - - return isl_space_is_equal(node->dim, dim); -} - -/* An edge in the dependence graph. An edge may be used to - * ensure validity of the generated schedule, to minimize the dependence - * distance or both - * - * map is the dependence relation - * src is the source node - * dst is the sink node - * validity is set if the edge is used to ensure correctness - * proximity is set if the edge is used to minimize dependence distances - * - * For validity edges, start and end mark the sequence of inequality - * constraints in the LP problem that encode the validity constraint - * corresponding to this edge. - */ -struct isl_sched_edge { - isl_map *map; - - struct isl_sched_node *src; - struct isl_sched_node *dst; - - int validity; - int proximity; - - int start; - int end; -}; - -enum isl_edge_type { - isl_edge_validity = 0, - isl_edge_first = isl_edge_validity, - isl_edge_proximity, - isl_edge_last = isl_edge_proximity -}; -/* Internal information about the dependence graph used during - * the construction of the schedule. +/* Return a schedule encapsulating the given schedule tree. * - * intra_hmap is a cache, mapping dependence relations to their dual, - * for dependences from a node to itself - * inter_hmap is a cache, mapping dependence relations to their dual, - * for dependences between distinct nodes + * We currently only allow schedule trees with a domain or extension as root. * - * n is the number of nodes - * node is the list of nodes - * maxvar is the maximal number of variables over all nodes - * max_row is the allocated number of rows in the schedule - * n_row is the current (maximal) number of linearly independent - * rows in the node schedules - * n_total_row is the current number of rows in the node schedules - * n_band is the current number of completed bands - * band_start is the starting row in the node schedules of the current band - * root is set if this graph is the original dependence graph, - * without any splitting - * - * sorted contains a list of node indices sorted according to the - * SCC to which a node belongs - * - * n_edge is the number of edges - * edge is the list of edges - * max_edge contains the maximal number of edges of each type; - * in particular, it contains the number of edges in the inital graph. - * edge_table contains pointers into the edge array, hashed on the source - * and sink spaces; there is one such table for each type; - * a given edge may be referenced from more than one table - * if the corresponding relation appears in more than of the - * sets of dependences - * - * node_table contains pointers into the node array, hashed on the space - * - * region contains a list of variable sequences that should be non-trivial - * - * lp contains the (I)LP problem used to obtain new schedule rows - * - * src_scc and dst_scc are the source and sink SCCs of an edge with - * conflicting constraints - * - * scc represents the number of components - */ -struct isl_sched_graph { - isl_hmap_map_basic_set *intra_hmap; - isl_hmap_map_basic_set *inter_hmap; - - struct isl_sched_node *node; - int n; - int maxvar; - int max_row; - int n_row; - - int *sorted; - - int n_band; - int n_total_row; - int band_start; - - int root; - - struct isl_sched_edge *edge; - int n_edge; - int max_edge[isl_edge_last + 1]; - struct isl_hash_table *edge_table[isl_edge_last + 1]; - - struct isl_hash_table *node_table; - struct isl_region *region; - - isl_basic_set *lp; - - int src_scc; - int dst_scc; - - int scc; -}; - -/* Initialize node_table based on the list of nodes. - */ -static int graph_init_table(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i; - - graph->node_table = isl_hash_table_alloc(ctx, graph->n); - if (!graph->node_table) - return -1; - - for (i = 0; i < graph->n; ++i) { - struct isl_hash_table_entry *entry; - uint32_t hash; - - hash = isl_space_get_hash(graph->node[i].dim); - entry = isl_hash_table_find(ctx, graph->node_table, hash, - &node_has_dim, - graph->node[i].dim, 1); - if (!entry) - return -1; - entry->data = &graph->node[i]; - } - - return 0; -} - -/* Return a pointer to the node that lives within the given space, - * or NULL if there is no such node. - */ -static struct isl_sched_node *graph_find_node(isl_ctx *ctx, - struct isl_sched_graph *graph, __isl_keep isl_space *dim) -{ - struct isl_hash_table_entry *entry; - uint32_t hash; - - hash = isl_space_get_hash(dim); - entry = isl_hash_table_find(ctx, graph->node_table, hash, - &node_has_dim, dim, 0); - - return entry ? entry->data : NULL; -} - -static int edge_has_src_and_dst(const void *entry, const void *val) -{ - const struct isl_sched_edge *edge = entry; - const struct isl_sched_edge *temp = val; - - return edge->src == temp->src && edge->dst == temp->dst; -} - -/* Add the given edge to graph->edge_table[type]. - */ -static int graph_edge_table_add(isl_ctx *ctx, struct isl_sched_graph *graph, - enum isl_edge_type type, struct isl_sched_edge *edge) -{ - struct isl_hash_table_entry *entry; - uint32_t hash; - - hash = isl_hash_init(); - hash = isl_hash_builtin(hash, edge->src); - hash = isl_hash_builtin(hash, edge->dst); - entry = isl_hash_table_find(ctx, graph->edge_table[type], hash, - &edge_has_src_and_dst, edge, 1); - if (!entry) - return -1; - entry->data = edge; - - return 0; -} - -/* Allocate the edge_tables based on the maximal number of edges of - * each type. - */ -static int graph_init_edge_tables(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i; - - for (i = 0; i <= isl_edge_last; ++i) { - graph->edge_table[i] = isl_hash_table_alloc(ctx, - graph->max_edge[i]); - if (!graph->edge_table[i]) - return -1; - } - - return 0; -} - -/* If graph->edge_table[type] contains an edge from the given source - * to the given destination, then return the hash table entry of this edge. - * Otherwise, return NULL. - */ -static struct isl_hash_table_entry *graph_find_edge_entry( - struct isl_sched_graph *graph, - enum isl_edge_type type, - struct isl_sched_node *src, struct isl_sched_node *dst) -{ - isl_ctx *ctx = isl_space_get_ctx(src->dim); - uint32_t hash; - struct isl_sched_edge temp = { .src = src, .dst = dst }; - - hash = isl_hash_init(); - hash = isl_hash_builtin(hash, temp.src); - hash = isl_hash_builtin(hash, temp.dst); - return isl_hash_table_find(ctx, graph->edge_table[type], hash, - &edge_has_src_and_dst, &temp, 0); -} - - -/* If graph->edge_table[type] contains an edge from the given source - * to the given destination, then return this edge. - * Otherwise, return NULL. + * The leaf field is initialized as a leaf node so that it can be + * used to represent leaves in the constructed schedule. + * The reference count is set to -1 since the isl_schedule_tree + * should never be freed. It is up to the (internal) users of + * these leaves to ensure that they are only used while the schedule + * is still alive. */ -static struct isl_sched_edge *graph_find_edge(struct isl_sched_graph *graph, - enum isl_edge_type type, - struct isl_sched_node *src, struct isl_sched_node *dst) +__isl_give isl_schedule *isl_schedule_from_schedule_tree(isl_ctx *ctx, + __isl_take isl_schedule_tree *tree) { - struct isl_hash_table_entry *entry; + enum isl_schedule_node_type type; + isl_schedule *schedule; - entry = graph_find_edge_entry(graph, type, src, dst); - if (!entry) + if (!tree) return NULL; + type = isl_schedule_tree_get_type(tree); + if (type != isl_schedule_node_domain && + type != isl_schedule_node_extension) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported, + "root of schedule tree should be a domain or extension", + goto error); - return entry->data; -} - -/* Check whether the dependence graph has an edge of the given type - * between the given two nodes. - */ -static int graph_has_edge(struct isl_sched_graph *graph, - enum isl_edge_type type, - struct isl_sched_node *src, struct isl_sched_node *dst) -{ - struct isl_sched_edge *edge; - int empty; - - edge = graph_find_edge(graph, type, src, dst); - if (!edge) - return 0; - - empty = isl_map_plain_is_empty(edge->map); - if (empty < 0) - return -1; - - return !empty; -} - -/* If there is an edge from the given source to the given destination - * of any type then return this edge. - * Otherwise, return NULL. - */ -static struct isl_sched_edge *graph_find_any_edge(struct isl_sched_graph *graph, - struct isl_sched_node *src, struct isl_sched_node *dst) -{ - enum isl_edge_type i; - struct isl_sched_edge *edge; + schedule = isl_calloc_type(ctx, isl_schedule); + if (!schedule) + goto error; - for (i = isl_edge_first; i <= isl_edge_last; ++i) { - edge = graph_find_edge(graph, i, src, dst); - if (edge) - return edge; - } + schedule->leaf.ctx = ctx; + isl_ctx_ref(ctx); + schedule->ref = 1; + schedule->root = tree; + schedule->leaf.ref = -1; + schedule->leaf.type = isl_schedule_node_leaf; + return schedule; +error: + isl_schedule_tree_free(tree); return NULL; } -/* Remove the given edge from all the edge_tables that refer to it. - */ -static void graph_remove_edge(struct isl_sched_graph *graph, - struct isl_sched_edge *edge) -{ - isl_ctx *ctx = isl_map_get_ctx(edge->map); - enum isl_edge_type i; - - for (i = isl_edge_first; i <= isl_edge_last; ++i) { - struct isl_hash_table_entry *entry; - - entry = graph_find_edge_entry(graph, i, edge->src, edge->dst); - if (!entry) - continue; - if (entry->data != edge) - continue; - isl_hash_table_remove(ctx, graph->edge_table[i], entry); - } -} - -/* Check whether the dependence graph has any edge - * between the given two nodes. - */ -static int graph_has_any_edge(struct isl_sched_graph *graph, - struct isl_sched_node *src, struct isl_sched_node *dst) -{ - enum isl_edge_type i; - int r; - - for (i = isl_edge_first; i <= isl_edge_last; ++i) { - r = graph_has_edge(graph, i, src, dst); - if (r < 0 || r) - return r; - } - - return r; -} - -/* Check whether the dependence graph has a validity edge - * between the given two nodes. +/* Return a pointer to a schedule with as single node + * a domain node with the given domain. */ -static int graph_has_validity_edge(struct isl_sched_graph *graph, - struct isl_sched_node *src, struct isl_sched_node *dst) -{ - return graph_has_edge(graph, isl_edge_validity, src, dst); -} - -static int graph_alloc(isl_ctx *ctx, struct isl_sched_graph *graph, - int n_node, int n_edge) -{ - int i; - - graph->n = n_node; - graph->n_edge = n_edge; - graph->node = isl_calloc_array(ctx, struct isl_sched_node, graph->n); - graph->sorted = isl_calloc_array(ctx, int, graph->n); - graph->region = isl_alloc_array(ctx, struct isl_region, graph->n); - graph->edge = isl_calloc_array(ctx, - struct isl_sched_edge, graph->n_edge); - - graph->intra_hmap = isl_hmap_map_basic_set_alloc(ctx, 2 * n_edge); - graph->inter_hmap = isl_hmap_map_basic_set_alloc(ctx, 2 * n_edge); - - if (!graph->node || !graph->region || (graph->n_edge && !graph->edge) || - !graph->sorted) - return -1; - - for(i = 0; i < graph->n; ++i) - graph->sorted[i] = i; - - return 0; -} - -static void graph_free(isl_ctx *ctx, struct isl_sched_graph *graph) +__isl_give isl_schedule *isl_schedule_from_domain( + __isl_take isl_union_set *domain) { - int i; - - isl_hmap_map_basic_set_free(ctx, graph->intra_hmap); - isl_hmap_map_basic_set_free(ctx, graph->inter_hmap); + isl_ctx *ctx; + isl_schedule_tree *tree; - for (i = 0; i < graph->n; ++i) { - isl_space_free(graph->node[i].dim); - isl_mat_free(graph->node[i].sched); - isl_map_free(graph->node[i].sched_map); - isl_mat_free(graph->node[i].cmap); - isl_mat_free(graph->node[i].cinv); - if (graph->root) { - free(graph->node[i].band); - free(graph->node[i].band_id); - free(graph->node[i].zero); - } - } - free(graph->node); - free(graph->sorted); - for (i = 0; i < graph->n_edge; ++i) - isl_map_free(graph->edge[i].map); - free(graph->edge); - free(graph->region); - for (i = 0; i <= isl_edge_last; ++i) - isl_hash_table_free(ctx, graph->edge_table[i]); - isl_hash_table_free(ctx, graph->node_table); - isl_basic_set_free(graph->lp); + ctx = isl_union_set_get_ctx(domain); + tree = isl_schedule_tree_from_domain(domain); + return isl_schedule_from_schedule_tree(ctx, tree); } -/* For each "set" on which this function is called, increment - * graph->n by one and update graph->maxvar. +/* Return a pointer to a schedule with as single node + * a domain node with an empty domain. */ -static int init_n_maxvar(__isl_take isl_set *set, void *user) +__isl_give isl_schedule *isl_schedule_empty(__isl_take isl_space *space) { - struct isl_sched_graph *graph = user; - int nvar = isl_set_dim(set, isl_dim_set); - - graph->n++; - if (nvar > graph->maxvar) - graph->maxvar = nvar; - - isl_set_free(set); - - return 0; + return isl_schedule_from_domain(isl_union_set_empty(space)); } -/* Compute the number of rows that should be allocated for the schedule. - * The graph can be split at most "n - 1" times, there can be at most - * two rows for each dimension in the iteration domains (in particular, - * we usually have one row, but it may be split by split_scaled), - * and there can be one extra row for ordering the statements. - * Note that if we have actually split "n - 1" times, then no ordering - * is needed, so in principle we could use "graph->n + 2 * graph->maxvar - 1". +/* Return a new reference to "sched". */ -static int compute_max_row(struct isl_sched_graph *graph, - __isl_keep isl_union_set *domain) +__isl_give isl_schedule *isl_schedule_copy(__isl_keep isl_schedule *sched) { - graph->n = 0; - graph->maxvar = 0; - if (isl_union_set_foreach_set(domain, &init_n_maxvar, graph) < 0) - return -1; - graph->max_row = graph->n + 2 * graph->maxvar; + if (!sched) + return NULL; - return 0; + sched->ref++; + return sched; } -/* Add a new node to the graph representing the given set. +/* Return an isl_schedule that is equal to "schedule" and that has only + * a single reference. + * + * We only need and support this function when the schedule is represented + * as a schedule tree. */ -static int extract_node(__isl_take isl_set *set, void *user) +__isl_give isl_schedule *isl_schedule_cow(__isl_take isl_schedule *schedule) { - int nvar, nparam; isl_ctx *ctx; - isl_space *dim; - isl_mat *sched; - struct isl_sched_graph *graph = user; - int *band, *band_id, *zero; - - ctx = isl_set_get_ctx(set); - dim = isl_set_get_space(set); - isl_set_free(set); - nvar = isl_space_dim(dim, isl_dim_set); - nparam = isl_space_dim(dim, isl_dim_param); - if (!ctx->opt->schedule_parametric) - nparam = 0; - sched = isl_mat_alloc(ctx, 0, 1 + nparam + nvar); - graph->node[graph->n].dim = dim; - graph->node[graph->n].nvar = nvar; - graph->node[graph->n].nparam = nparam; - graph->node[graph->n].sched = sched; - graph->node[graph->n].sched_map = NULL; - band = isl_alloc_array(ctx, int, graph->max_row); - graph->node[graph->n].band = band; - band_id = isl_calloc_array(ctx, int, graph->max_row); - graph->node[graph->n].band_id = band_id; - zero = isl_calloc_array(ctx, int, graph->max_row); - graph->node[graph->n].zero = zero; - graph->n++; - - if (!sched || (graph->max_row && (!band || !band_id || !zero))) - return -1; - - return 0; -} + isl_schedule_tree *tree; -struct isl_extract_edge_data { - enum isl_edge_type type; - struct isl_sched_graph *graph; -}; - -/* Add a new edge to the graph based on the given map - * and add it to data->graph->edge_table[data->type]. - * If a dependence relation of a given type happens to be identical - * to one of the dependence relations of a type that was added before, - * then we don't create a new edge, but instead mark the original edge - * as also representing a dependence of the current type. - */ -static int extract_edge(__isl_take isl_map *map, void *user) -{ - isl_ctx *ctx = isl_map_get_ctx(map); - struct isl_extract_edge_data *data = user; - struct isl_sched_graph *graph = data->graph; - struct isl_sched_node *src, *dst; - isl_space *dim; - struct isl_sched_edge *edge; - int is_equal; - - dim = isl_space_domain(isl_map_get_space(map)); - src = graph_find_node(ctx, graph, dim); - isl_space_free(dim); - dim = isl_space_range(isl_map_get_space(map)); - dst = graph_find_node(ctx, graph, dim); - isl_space_free(dim); - - if (!src || !dst) { - isl_map_free(map); - return 0; - } - - graph->edge[graph->n_edge].src = src; - graph->edge[graph->n_edge].dst = dst; - graph->edge[graph->n_edge].map = map; - if (data->type == isl_edge_validity) { - graph->edge[graph->n_edge].validity = 1; - graph->edge[graph->n_edge].proximity = 0; - } - if (data->type == isl_edge_proximity) { - graph->edge[graph->n_edge].validity = 0; - graph->edge[graph->n_edge].proximity = 1; - } - graph->n_edge++; - - edge = graph_find_any_edge(graph, src, dst); - if (!edge) - return graph_edge_table_add(ctx, graph, data->type, - &graph->edge[graph->n_edge - 1]); - is_equal = isl_map_plain_is_equal(map, edge->map); - if (is_equal < 0) - return -1; - if (!is_equal) - return graph_edge_table_add(ctx, graph, data->type, - &graph->edge[graph->n_edge - 1]); - - graph->n_edge--; - edge->validity |= graph->edge[graph->n_edge].validity; - edge->proximity |= graph->edge[graph->n_edge].proximity; - isl_map_free(map); + if (!schedule) + return NULL; + if (schedule->ref == 1) + return schedule; - return graph_edge_table_add(ctx, graph, data->type, edge); + ctx = isl_schedule_get_ctx(schedule); + if (!schedule->root) + isl_die(ctx, isl_error_internal, + "only for schedule tree based schedules", + return isl_schedule_free(schedule)); + schedule->ref--; + tree = isl_schedule_tree_copy(schedule->root); + return isl_schedule_from_schedule_tree(ctx, tree); } -/* Check whether there is any dependence from node[j] to node[i] - * or from node[i] to node[j]. - */ -static int node_follows_weak(int i, int j, void *user) +__isl_null isl_schedule *isl_schedule_free(__isl_take isl_schedule *sched) { - int f; - struct isl_sched_graph *graph = user; - - f = graph_has_any_edge(graph, &graph->node[j], &graph->node[i]); - if (f < 0 || f) - return f; - return graph_has_any_edge(graph, &graph->node[i], &graph->node[j]); -} + if (!sched) + return NULL; -/* Check whether there is a validity dependence from node[j] to node[i], - * forcing node[i] to follow node[j]. - */ -static int node_follows_strong(int i, int j, void *user) -{ - struct isl_sched_graph *graph = user; + if (--sched->ref > 0) + return NULL; - return graph_has_validity_edge(graph, &graph->node[j], &graph->node[i]); + isl_band_list_free(sched->band_forest); + isl_schedule_tree_free(sched->root); + isl_ctx_deref(sched->leaf.ctx); + free(sched); + return NULL; } -/* Use Tarjan's algorithm for computing the strongly connected components - * in the dependence graph (only validity edges). - * If weak is set, we consider the graph to be undirected and - * we effectively compute the (weakly) connected components. - * Additionally, we also consider other edges when weak is set. +/* Replace the root of "schedule" by "tree". */ -static int detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph, int weak) +__isl_give isl_schedule *isl_schedule_set_root( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree) { - int i, n; - struct isl_tarjan_graph *g = NULL; - - g = isl_tarjan_graph_init(ctx, graph->n, - weak ? &node_follows_weak : &node_follows_strong, graph); - if (!g) - return -1; - - graph->scc = 0; - i = 0; - n = graph->n; - while (n) { - while (g->order[i] != -1) { - graph->node[g->order[i]].scc = graph->scc; - --n; - ++i; - } - ++i; - graph->scc++; + if (!schedule || !tree) + goto error; + if (schedule->root == tree) { + isl_schedule_tree_free(tree); + return schedule; } - isl_tarjan_graph_free(g); - - return 0; -} - -/* Apply Tarjan's algorithm to detect the strongly connected components - * in the dependence graph. - */ -static int detect_sccs(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - return detect_ccs(ctx, graph, 0); -} - -/* Apply Tarjan's algorithm to detect the (weakly) connected components - * in the dependence graph. - */ -static int detect_wccs(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - return detect_ccs(ctx, graph, 1); -} - -static int cmp_scc(const void *a, const void *b, void *data) -{ - struct isl_sched_graph *graph = data; - const int *i1 = a; - const int *i2 = b; + schedule = isl_schedule_cow(schedule); + if (!schedule) + goto error; + isl_schedule_tree_free(schedule->root); + schedule->root = tree; - return graph->node[*i1].scc - graph->node[*i2].scc; + return schedule; +error: + isl_schedule_free(schedule); + isl_schedule_tree_free(tree); + return NULL; } -/* Sort the elements of graph->sorted according to the corresponding SCCs. - */ -static int sort_sccs(struct isl_sched_graph *graph) +isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *schedule) { - return isl_sort(graph->sorted, graph->n, sizeof(int), &cmp_scc, graph); + return schedule ? schedule->leaf.ctx : NULL; } -/* Given a dependence relation R from a node to itself, - * construct the set of coefficients of valid constraints for elements - * in that dependence relation. - * In particular, the result contains tuples of coefficients - * c_0, c_n, c_x such that - * - * c_0 + c_n n + c_x y - c_x x >= 0 for each (x,y) in R +/* Return a pointer to the leaf of "schedule". * - * or, equivalently, - * - * c_0 + c_n n + c_x d >= 0 for each d in delta R = { y - x | (x,y) in R } - * - * We choose here to compute the dual of delta R. - * Alternatively, we could have computed the dual of R, resulting - * in a set of tuples c_0, c_n, c_x, c_y, and then - * plugged in (c_0, c_n, c_x, -c_x). + * Even though these leaves are not reference counted, we still + * indicate that this function does not return a copy. */ -static __isl_give isl_basic_set *intra_coefficients( - struct isl_sched_graph *graph, __isl_take isl_map *map) +__isl_keep isl_schedule_tree *isl_schedule_peek_leaf( + __isl_keep isl_schedule *schedule) { - isl_ctx *ctx = isl_map_get_ctx(map); - isl_set *delta; - isl_basic_set *coef; - - if (isl_hmap_map_basic_set_has(ctx, graph->intra_hmap, map)) - return isl_hmap_map_basic_set_get(ctx, graph->intra_hmap, map); - - delta = isl_set_remove_divs(isl_map_deltas(isl_map_copy(map))); - coef = isl_set_coefficients(delta); - isl_hmap_map_basic_set_set(ctx, graph->intra_hmap, map, - isl_basic_set_copy(coef)); - - return coef; + return schedule ? &schedule->leaf : NULL; } -/* Given a dependence relation R, * construct the set of coefficients - * of valid constraints for elements in that dependence relation. - * In particular, the result contains tuples of coefficients - * c_0, c_n, c_x, c_y such that - * - * c_0 + c_n n + c_x x + c_y y >= 0 for each (x,y) in R - * +/* Are "schedule1" and "schedule2" obviously equal to each other? */ -static __isl_give isl_basic_set *inter_coefficients( - struct isl_sched_graph *graph, __isl_take isl_map *map) +isl_bool isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1, + __isl_keep isl_schedule *schedule2) { - isl_ctx *ctx = isl_map_get_ctx(map); - isl_set *set; - isl_basic_set *coef; - - if (isl_hmap_map_basic_set_has(ctx, graph->inter_hmap, map)) - return isl_hmap_map_basic_set_get(ctx, graph->inter_hmap, map); - - set = isl_map_wrap(isl_map_remove_divs(isl_map_copy(map))); - coef = isl_set_coefficients(set); - isl_hmap_map_basic_set_set(ctx, graph->inter_hmap, map, - isl_basic_set_copy(coef)); - - return coef; -} - -/* Add constraints to graph->lp that force validity for the given - * dependence from a node i to itself. - * That is, add constraints that enforce - * - * (c_i_0 + c_i_n n + c_i_x y) - (c_i_0 + c_i_n n + c_i_x x) - * = c_i_x (y - x) >= 0 - * - * for each (x,y) in R. - * We obtain general constraints on coefficients (c_0, c_n, c_x) - * of valid constraints for (y - x) and then plug in (0, 0, c_i_x^+ - c_i_x^-), - * where c_i_x = c_i_x^+ - c_i_x^-, with c_i_x^+ and c_i_x^- non-negative. - * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart. - * - * Actually, we do not construct constraints for the c_i_x themselves, - * but for the coefficients of c_i_x written as a linear combination - * of the columns in node->cmap. - */ -static int add_intra_validity_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge) -{ - unsigned total; - isl_map *map = isl_map_copy(edge->map); - isl_ctx *ctx = isl_map_get_ctx(map); - isl_space *dim; - isl_dim_map *dim_map; - isl_basic_set *coef; - struct isl_sched_node *node = edge->src; - - coef = intra_coefficients(graph, map); - - dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); - - coef = isl_basic_set_transform_dims(coef, isl_dim_set, - isl_space_dim(dim, isl_dim_set), isl_mat_copy(node->cmap)); - if (!coef) - goto error; - - total = isl_basic_set_total_dim(graph->lp); - dim_map = isl_dim_map_alloc(ctx, total); - isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set), 1, - node->nvar, -1); - isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set), 1, - node->nvar, 1); - graph->lp = isl_basic_set_extend_constraints(graph->lp, - coef->n_eq, coef->n_ineq); - graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, - coef, dim_map); - isl_space_free(dim); - - return 0; -error: - isl_space_free(dim); - return -1; -} - -/* Add constraints to graph->lp that force validity for the given - * dependence from node i to node j. - * That is, add constraints that enforce - * - * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) >= 0 - * - * for each (x,y) in R. - * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y) - * of valid constraints for R and then plug in - * (c_j_0 - c_i_0, c_j_n^+ - c_j_n^- - (c_i_n^+ - c_i_n^-), - * c_j_x^+ - c_j_x^- - (c_i_x^+ - c_i_x^-)), - * where c_* = c_*^+ - c_*^-, with c_*^+ and c_*^- non-negative. - * In graph->lp, the c_*^- appear before their c_*^+ counterpart. - * - * Actually, we do not construct constraints for the c_*_x themselves, - * but for the coefficients of c_*_x written as a linear combination - * of the columns in node->cmap. - */ -static int add_inter_validity_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge) -{ - unsigned total; - isl_map *map = isl_map_copy(edge->map); - isl_ctx *ctx = isl_map_get_ctx(map); - isl_space *dim; - isl_dim_map *dim_map; - isl_basic_set *coef; - struct isl_sched_node *src = edge->src; - struct isl_sched_node *dst = edge->dst; - - coef = inter_coefficients(graph, map); - - dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); - - coef = isl_basic_set_transform_dims(coef, isl_dim_set, - isl_space_dim(dim, isl_dim_set), isl_mat_copy(src->cmap)); - coef = isl_basic_set_transform_dims(coef, isl_dim_set, - isl_space_dim(dim, isl_dim_set) + src->nvar, - isl_mat_copy(dst->cmap)); - if (!coef) - goto error; - - total = isl_basic_set_total_dim(graph->lp); - dim_map = isl_dim_map_alloc(ctx, total); - - isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, 1); - isl_dim_map_range(dim_map, dst->start + 1, 2, 1, 1, dst->nparam, -1); - isl_dim_map_range(dim_map, dst->start + 2, 2, 1, 1, dst->nparam, 1); - isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set) + src->nvar, 1, - dst->nvar, -1); - isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set) + src->nvar, 1, - dst->nvar, 1); - - isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, -1); - isl_dim_map_range(dim_map, src->start + 1, 2, 1, 1, src->nparam, 1); - isl_dim_map_range(dim_map, src->start + 2, 2, 1, 1, src->nparam, -1); - isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set), 1, - src->nvar, 1); - isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set), 1, - src->nvar, -1); - - edge->start = graph->lp->n_ineq; - graph->lp = isl_basic_set_extend_constraints(graph->lp, - coef->n_eq, coef->n_ineq); - graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, - coef, dim_map); - if (!graph->lp) - goto error; - isl_space_free(dim); - edge->end = graph->lp->n_ineq; - - return 0; -error: - isl_space_free(dim); - return -1; -} - -/* Add constraints to graph->lp that bound the dependence distance for the given - * dependence from a node i to itself. - * If s = 1, we add the constraint - * - * c_i_x (y - x) <= m_0 + m_n n - * - * or - * - * -c_i_x (y - x) + m_0 + m_n n >= 0 - * - * for each (x,y) in R. - * If s = -1, we add the constraint - * - * -c_i_x (y - x) <= m_0 + m_n n - * - * or - * - * c_i_x (y - x) + m_0 + m_n n >= 0 - * - * for each (x,y) in R. - * We obtain general constraints on coefficients (c_0, c_n, c_x) - * of valid constraints for (y - x) and then plug in (m_0, m_n, -s * c_i_x), - * with each coefficient (except m_0) represented as a pair of non-negative - * coefficients. - * - * Actually, we do not construct constraints for the c_i_x themselves, - * but for the coefficients of c_i_x written as a linear combination - * of the columns in node->cmap. - */ -static int add_intra_proximity_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge, int s) -{ - unsigned total; - unsigned nparam; - isl_map *map = isl_map_copy(edge->map); - isl_ctx *ctx = isl_map_get_ctx(map); - isl_space *dim; - isl_dim_map *dim_map; - isl_basic_set *coef; - struct isl_sched_node *node = edge->src; - - coef = intra_coefficients(graph, map); - - dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); - - coef = isl_basic_set_transform_dims(coef, isl_dim_set, - isl_space_dim(dim, isl_dim_set), isl_mat_copy(node->cmap)); - if (!coef) - goto error; - - nparam = isl_space_dim(node->dim, isl_dim_param); - total = isl_basic_set_total_dim(graph->lp); - dim_map = isl_dim_map_alloc(ctx, total); - isl_dim_map_range(dim_map, 1, 0, 0, 0, 1, 1); - isl_dim_map_range(dim_map, 4, 2, 1, 1, nparam, -1); - isl_dim_map_range(dim_map, 5, 2, 1, 1, nparam, 1); - isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set), 1, - node->nvar, s); - isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set), 1, - node->nvar, -s); - graph->lp = isl_basic_set_extend_constraints(graph->lp, - coef->n_eq, coef->n_ineq); - graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, - coef, dim_map); - isl_space_free(dim); - - return 0; -error: - isl_space_free(dim); - return -1; -} - -/* Add constraints to graph->lp that bound the dependence distance for the given - * dependence from node i to node j. - * If s = 1, we add the constraint - * - * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) - * <= m_0 + m_n n - * - * or - * - * -(c_j_0 + c_j_n n + c_j_x y) + (c_i_0 + c_i_n n + c_i_x x) + - * m_0 + m_n n >= 0 - * - * for each (x,y) in R. - * If s = -1, we add the constraint - * - * -((c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x)) - * <= m_0 + m_n n - * - * or - * - * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) + - * m_0 + m_n n >= 0 - * - * for each (x,y) in R. - * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y) - * of valid constraints for R and then plug in - * (m_0 - s*c_j_0 + s*c_i_0, m_n - s*c_j_n + s*c_i_n, - * -s*c_j_x+s*c_i_x) - * with each coefficient (except m_0, c_j_0 and c_i_0) - * represented as a pair of non-negative coefficients. - * - * Actually, we do not construct constraints for the c_*_x themselves, - * but for the coefficients of c_*_x written as a linear combination - * of the columns in node->cmap. - */ -static int add_inter_proximity_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge, int s) -{ - unsigned total; - unsigned nparam; - isl_map *map = isl_map_copy(edge->map); - isl_ctx *ctx = isl_map_get_ctx(map); - isl_space *dim; - isl_dim_map *dim_map; - isl_basic_set *coef; - struct isl_sched_node *src = edge->src; - struct isl_sched_node *dst = edge->dst; - - coef = inter_coefficients(graph, map); - - dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); - - coef = isl_basic_set_transform_dims(coef, isl_dim_set, - isl_space_dim(dim, isl_dim_set), isl_mat_copy(src->cmap)); - coef = isl_basic_set_transform_dims(coef, isl_dim_set, - isl_space_dim(dim, isl_dim_set) + src->nvar, - isl_mat_copy(dst->cmap)); - if (!coef) - goto error; - - nparam = isl_space_dim(src->dim, isl_dim_param); - total = isl_basic_set_total_dim(graph->lp); - dim_map = isl_dim_map_alloc(ctx, total); - - isl_dim_map_range(dim_map, 1, 0, 0, 0, 1, 1); - isl_dim_map_range(dim_map, 4, 2, 1, 1, nparam, -1); - isl_dim_map_range(dim_map, 5, 2, 1, 1, nparam, 1); - - isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, -s); - isl_dim_map_range(dim_map, dst->start + 1, 2, 1, 1, dst->nparam, s); - isl_dim_map_range(dim_map, dst->start + 2, 2, 1, 1, dst->nparam, -s); - isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set) + src->nvar, 1, - dst->nvar, s); - isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set) + src->nvar, 1, - dst->nvar, -s); - - isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, s); - isl_dim_map_range(dim_map, src->start + 1, 2, 1, 1, src->nparam, -s); - isl_dim_map_range(dim_map, src->start + 2, 2, 1, 1, src->nparam, s); - isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set), 1, - src->nvar, -s); - isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set), 1, - src->nvar, s); - - graph->lp = isl_basic_set_extend_constraints(graph->lp, - coef->n_eq, coef->n_ineq); - graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, - coef, dim_map); - isl_space_free(dim); - - return 0; -error: - isl_space_free(dim); - return -1; + if (!schedule1 || !schedule2) + return isl_bool_error; + if (schedule1 == schedule2) + return isl_bool_true; + return isl_schedule_tree_plain_is_equal(schedule1->root, + schedule2->root); } -static int add_all_validity_constraints(struct isl_sched_graph *graph) +/* Return the (parameter) space of the schedule, i.e., the space + * of the root domain. + */ +__isl_give isl_space *isl_schedule_get_space( + __isl_keep isl_schedule *schedule) { - int i; - - for (i = 0; i < graph->n_edge; ++i) { - struct isl_sched_edge *edge= &graph->edge[i]; - if (!edge->validity) - continue; - if (edge->src != edge->dst) - continue; - if (add_intra_validity_constraints(graph, edge) < 0) - return -1; - } - - for (i = 0; i < graph->n_edge; ++i) { - struct isl_sched_edge *edge = &graph->edge[i]; - if (!edge->validity) - continue; - if (edge->src == edge->dst) - continue; - if (add_inter_validity_constraints(graph, edge) < 0) - return -1; - } - - return 0; -} - -/* Add constraints to graph->lp that bound the dependence distance - * for all dependence relations. - * If a given proximity dependence is identical to a validity - * dependence, then the dependence distance is already bounded - * from below (by zero), so we only need to bound the distance - * from above. - * Otherwise, we need to bound the distance both from above and from below. - */ -static int add_all_proximity_constraints(struct isl_sched_graph *graph) -{ - int i; - - for (i = 0; i < graph->n_edge; ++i) { - struct isl_sched_edge *edge= &graph->edge[i]; - if (!edge->proximity) - continue; - if (edge->src == edge->dst && - add_intra_proximity_constraints(graph, edge, 1) < 0) - return -1; - if (edge->src != edge->dst && - add_inter_proximity_constraints(graph, edge, 1) < 0) - return -1; - if (edge->validity) - continue; - if (edge->src == edge->dst && - add_intra_proximity_constraints(graph, edge, -1) < 0) - return -1; - if (edge->src != edge->dst && - add_inter_proximity_constraints(graph, edge, -1) < 0) - return -1; - } - - return 0; -} - -/* Compute a basis for the rows in the linear part of the schedule - * and extend this basis to a full basis. The remaining rows - * can then be used to force linear independence from the rows - * in the schedule. - * - * In particular, given the schedule rows S, we compute - * - * S = H Q - * S U = H - * - * with H the Hermite normal form of S. That is, all but the - * first rank columns of Q are zero and so each row in S is - * a linear combination of the first rank rows of Q. - * The matrix Q is then transposed because we will write the - * coefficients of the next schedule row as a column vector s - * and express this s as a linear combination s = Q c of the - * computed basis. - * Similarly, the matrix U is transposed such that we can - * compute the coefficients c = U s from a schedule row s. - */ -static int node_update_cmap(struct isl_sched_node *node) -{ - isl_mat *H, *U, *Q; - int n_row = isl_mat_rows(node->sched); - - H = isl_mat_sub_alloc(node->sched, 0, n_row, - 1 + node->nparam, node->nvar); - - H = isl_mat_left_hermite(H, 0, &U, &Q); - isl_mat_free(node->cmap); - isl_mat_free(node->cinv); - node->cmap = isl_mat_transpose(Q); - node->cinv = isl_mat_transpose(U); - node->rank = isl_mat_initial_non_zero_cols(H); - isl_mat_free(H); - - if (!node->cmap || !node->cinv || node->rank < 0) - return -1; - return 0; -} - -/* Count the number of equality and inequality constraints - * that will be added for the given map. - * If carry is set, then we are counting the number of (validity) - * constraints that will be added in setup_carry_lp and we count - * each edge exactly once. Otherwise, we count as follows - * validity -> 1 (>= 0) - * validity+proximity -> 2 (>= 0 and upper bound) - * proximity -> 2 (lower and upper bound) - */ -static int count_map_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge, __isl_take isl_map *map, - int *n_eq, int *n_ineq, int carry) -{ - isl_basic_set *coef; - int f = carry ? 1 : edge->proximity ? 2 : 1; - - if (carry && !edge->validity) { - isl_map_free(map); - return 0; - } - - if (edge->src == edge->dst) - coef = intra_coefficients(graph, map); - else - coef = inter_coefficients(graph, map); - if (!coef) - return -1; - *n_eq += f * coef->n_eq; - *n_ineq += f * coef->n_ineq; - isl_basic_set_free(coef); - - return 0; -} - -/* Count the number of equality and inequality constraints - * that will be added to the main lp problem. - * We count as follows - * validity -> 1 (>= 0) - * validity+proximity -> 2 (>= 0 and upper bound) - * proximity -> 2 (lower and upper bound) - */ -static int count_constraints(struct isl_sched_graph *graph, - int *n_eq, int *n_ineq) -{ - int i; - - *n_eq = *n_ineq = 0; - for (i = 0; i < graph->n_edge; ++i) { - struct isl_sched_edge *edge= &graph->edge[i]; - isl_map *map = isl_map_copy(edge->map); - - if (count_map_constraints(graph, edge, map, - n_eq, n_ineq, 0) < 0) - return -1; - } - - return 0; -} - -/* Add constraints that bound the values of the variable and parameter - * coefficients of the schedule. - * - * The maximal value of the coefficients is defined by the option - * 'schedule_max_coefficient'. - */ -static int add_bound_coefficient_constraints(isl_ctx *ctx, - struct isl_sched_graph *graph) -{ - int i, j, k; - int max_coefficient; - int total; - - max_coefficient = ctx->opt->schedule_max_coefficient; - - if (max_coefficient == -1) - return 0; - - total = isl_basic_set_total_dim(graph->lp); - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - for (j = 0; j < 2 * node->nparam + 2 * node->nvar; ++j) { - int dim; - k = isl_basic_set_alloc_inequality(graph->lp); - if (k < 0) - return -1; - dim = 1 + node->start + 1 + j; - isl_seq_clr(graph->lp->ineq[k], 1 + total); - isl_int_set_si(graph->lp->ineq[k][dim], -1); - isl_int_set_si(graph->lp->ineq[k][0], max_coefficient); - } - } - - return 0; -} - -/* Construct an ILP problem for finding schedule coefficients - * that result in non-negative, but small dependence distances - * over all dependences. - * In particular, the dependence distances over proximity edges - * are bounded by m_0 + m_n n and we compute schedule coefficients - * with small values (preferably zero) of m_n and m_0. - * - * All variables of the ILP are non-negative. The actual coefficients - * may be negative, so each coefficient is represented as the difference - * of two non-negative variables. The negative part always appears - * immediately before the positive part. - * Other than that, the variables have the following order - * - * - sum of positive and negative parts of m_n coefficients - * - m_0 - * - sum of positive and negative parts of all c_n coefficients - * (unconstrained when computing non-parametric schedules) - * - sum of positive and negative parts of all c_x coefficients - * - positive and negative parts of m_n coefficients - * - for each node - * - c_i_0 - * - positive and negative parts of c_i_n (if parametric) - * - positive and negative parts of c_i_x - * - * The c_i_x are not represented directly, but through the columns of - * node->cmap. That is, the computed values are for variable t_i_x - * such that c_i_x = Q t_i_x with Q equal to node->cmap. - * - * The constraints are those from the edges plus two or three equalities - * to express the sums. - * - * If force_zero is set, then we add equalities to ensure that - * the sum of the m_n coefficients and m_0 are both zero. - */ -static int setup_lp(isl_ctx *ctx, struct isl_sched_graph *graph, - int force_zero) -{ - int i, j; - int k; - unsigned nparam; - unsigned total; - isl_space *dim; - int parametric; - int param_pos; - int n_eq, n_ineq; - int max_constant_term; - int max_coefficient; - - max_constant_term = ctx->opt->schedule_max_constant_term; - max_coefficient = ctx->opt->schedule_max_coefficient; - - parametric = ctx->opt->schedule_parametric; - nparam = isl_space_dim(graph->node[0].dim, isl_dim_param); - param_pos = 4; - total = param_pos + 2 * nparam; - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[graph->sorted[i]]; - if (node_update_cmap(node) < 0) - return -1; - node->start = total; - total += 1 + 2 * (node->nparam + node->nvar); - } - - if (count_constraints(graph, &n_eq, &n_ineq) < 0) - return -1; - - dim = isl_space_set_alloc(ctx, 0, total); - isl_basic_set_free(graph->lp); - n_eq += 2 + parametric + force_zero; - if (max_constant_term != -1) - n_ineq += graph->n; - if (max_coefficient != -1) - for (i = 0; i < graph->n; ++i) - n_ineq += 2 * graph->node[i].nparam + - 2 * graph->node[i].nvar; - - graph->lp = isl_basic_set_alloc_space(dim, 0, n_eq, n_ineq); - - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - if (!force_zero) - isl_int_set_si(graph->lp->eq[k][1], -1); - for (i = 0; i < 2 * nparam; ++i) - isl_int_set_si(graph->lp->eq[k][1 + param_pos + i], 1); - - if (force_zero) { - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - isl_int_set_si(graph->lp->eq[k][2], -1); - } - - if (parametric) { - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - isl_int_set_si(graph->lp->eq[k][3], -1); - for (i = 0; i < graph->n; ++i) { - int pos = 1 + graph->node[i].start + 1; - - for (j = 0; j < 2 * graph->node[i].nparam; ++j) - isl_int_set_si(graph->lp->eq[k][pos + j], 1); - } - } - - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - isl_int_set_si(graph->lp->eq[k][4], -1); - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int pos = 1 + node->start + 1 + 2 * node->nparam; - - for (j = 0; j < 2 * node->nvar; ++j) - isl_int_set_si(graph->lp->eq[k][pos + j], 1); - } - - if (max_constant_term != -1) - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - k = isl_basic_set_alloc_inequality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->ineq[k], 1 + total); - isl_int_set_si(graph->lp->ineq[k][1 + node->start], -1); - isl_int_set_si(graph->lp->ineq[k][0], max_constant_term); - } - - if (add_bound_coefficient_constraints(ctx, graph) < 0) - return -1; - if (add_all_validity_constraints(graph) < 0) - return -1; - if (add_all_proximity_constraints(graph) < 0) - return -1; - - return 0; -} - -/* Analyze the conflicting constraint found by - * isl_tab_basic_set_non_trivial_lexmin. If it corresponds to the validity - * constraint of one of the edges between distinct nodes, living, moreover - * in distinct SCCs, then record the source and sink SCC as this may - * be a good place to cut between SCCs. - */ -static int check_conflict(int con, void *user) -{ - int i; - struct isl_sched_graph *graph = user; - - if (graph->src_scc >= 0) - return 0; - - con -= graph->lp->n_eq; - - if (con >= graph->lp->n_ineq) - return 0; - - for (i = 0; i < graph->n_edge; ++i) { - if (!graph->edge[i].validity) - continue; - if (graph->edge[i].src == graph->edge[i].dst) - continue; - if (graph->edge[i].src->scc == graph->edge[i].dst->scc) - continue; - if (graph->edge[i].start > con) - continue; - if (graph->edge[i].end <= con) - continue; - graph->src_scc = graph->edge[i].src->scc; - graph->dst_scc = graph->edge[i].dst->scc; - } - - return 0; -} - -/* Check whether the next schedule row of the given node needs to be - * non-trivial. Lower-dimensional domains may have some trivial rows, - * but as soon as the number of remaining required non-trivial rows - * is as large as the number or remaining rows to be computed, - * all remaining rows need to be non-trivial. - */ -static int needs_row(struct isl_sched_graph *graph, struct isl_sched_node *node) -{ - return node->nvar - node->rank >= graph->maxvar - graph->n_row; -} - -/* Solve the ILP problem constructed in setup_lp. - * For each node such that all the remaining rows of its schedule - * need to be non-trivial, we construct a non-triviality region. - * This region imposes that the next row is independent of previous rows. - * In particular the coefficients c_i_x are represented by t_i_x - * variables with c_i_x = Q t_i_x and Q a unimodular matrix such that - * its first columns span the rows of the previously computed part - * of the schedule. The non-triviality region enforces that at least - * one of the remaining components of t_i_x is non-zero, i.e., - * that the new schedule row depends on at least one of the remaining - * columns of Q. - */ -static __isl_give isl_vec *solve_lp(struct isl_sched_graph *graph) -{ - int i; - isl_vec *sol; - isl_basic_set *lp; - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int skip = node->rank; - graph->region[i].pos = node->start + 1 + 2*(node->nparam+skip); - if (needs_row(graph, node)) - graph->region[i].len = 2 * (node->nvar - skip); - else - graph->region[i].len = 0; - } - lp = isl_basic_set_copy(graph->lp); - sol = isl_tab_basic_set_non_trivial_lexmin(lp, 2, graph->n, - graph->region, &check_conflict, graph); - return sol; -} - -/* Update the schedules of all nodes based on the given solution - * of the LP problem. - * The new row is added to the current band. - * All possibly negative coefficients are encoded as a difference - * of two non-negative variables, so we need to perform the subtraction - * here. Moreover, if use_cmap is set, then the solution does - * not refer to the actual coefficients c_i_x, but instead to variables - * t_i_x such that c_i_x = Q t_i_x and Q is equal to node->cmap. - * In this case, we then also need to perform this multiplication - * to obtain the values of c_i_x. - * - * If check_zero is set, then the first two coordinates of sol are - * assumed to correspond to the dependence distance. If these two - * coordinates are zero, then the corresponding scheduling dimension - * is marked as being zero distance. - */ -static int update_schedule(struct isl_sched_graph *graph, - __isl_take isl_vec *sol, int use_cmap, int check_zero) -{ - int i, j; - int zero = 0; - isl_vec *csol = NULL; - - if (!sol) - goto error; - if (sol->size == 0) - isl_die(sol->ctx, isl_error_internal, - "no solution found", goto error); - if (graph->n_total_row >= graph->max_row) - isl_die(sol->ctx, isl_error_internal, - "too many schedule rows", goto error); - - if (check_zero) - zero = isl_int_is_zero(sol->el[1]) && - isl_int_is_zero(sol->el[2]); - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int pos = node->start; - int row = isl_mat_rows(node->sched); - - isl_vec_free(csol); - csol = isl_vec_alloc(sol->ctx, node->nvar); - if (!csol) - goto error; - - isl_map_free(node->sched_map); - node->sched_map = NULL; - node->sched = isl_mat_add_rows(node->sched, 1); - if (!node->sched) - goto error; - node->sched = isl_mat_set_element(node->sched, row, 0, - sol->el[1 + pos]); - for (j = 0; j < node->nparam + node->nvar; ++j) - isl_int_sub(sol->el[1 + pos + 1 + 2 * j + 1], - sol->el[1 + pos + 1 + 2 * j + 1], - sol->el[1 + pos + 1 + 2 * j]); - for (j = 0; j < node->nparam; ++j) - node->sched = isl_mat_set_element(node->sched, - row, 1 + j, sol->el[1+pos+1+2*j+1]); - for (j = 0; j < node->nvar; ++j) - isl_int_set(csol->el[j], - sol->el[1+pos+1+2*(node->nparam+j)+1]); - if (use_cmap) - csol = isl_mat_vec_product(isl_mat_copy(node->cmap), - csol); - if (!csol) - goto error; - for (j = 0; j < node->nvar; ++j) - node->sched = isl_mat_set_element(node->sched, - row, 1 + node->nparam + j, csol->el[j]); - node->band[graph->n_total_row] = graph->n_band; - node->zero[graph->n_total_row] = zero; - } - isl_vec_free(sol); - isl_vec_free(csol); - - graph->n_row++; - graph->n_total_row++; - - return 0; -error: - isl_vec_free(sol); - isl_vec_free(csol); - return -1; -} - -/* Convert node->sched into a multi_aff and return this multi_aff. - */ -static __isl_give isl_multi_aff *node_extract_schedule_multi_aff( - struct isl_sched_node *node) -{ - int i, j; + enum isl_schedule_node_type type; isl_space *space; - isl_local_space *ls; - isl_aff *aff; - isl_multi_aff *ma; - int nrow, ncol; - isl_int v; - - nrow = isl_mat_rows(node->sched); - ncol = isl_mat_cols(node->sched) - 1; - space = isl_space_from_domain(isl_space_copy(node->dim)); - space = isl_space_add_dims(space, isl_dim_out, nrow); - ma = isl_multi_aff_zero(space); - ls = isl_local_space_from_space(isl_space_copy(node->dim)); - - isl_int_init(v); - - for (i = 0; i < nrow; ++i) { - aff = isl_aff_zero_on_domain(isl_local_space_copy(ls)); - isl_mat_get_element(node->sched, i, 0, &v); - aff = isl_aff_set_constant(aff, v); - for (j = 0; j < node->nparam; ++j) { - isl_mat_get_element(node->sched, i, 1 + j, &v); - aff = isl_aff_set_coefficient(aff, isl_dim_param, j, v); - } - for (j = 0; j < node->nvar; ++j) { - isl_mat_get_element(node->sched, - i, 1 + node->nparam + j, &v); - aff = isl_aff_set_coefficient(aff, isl_dim_in, j, v); - } - ma = isl_multi_aff_set_aff(ma, i, aff); - } - - isl_int_clear(v); - - isl_local_space_free(ls); - - return ma; -} - -/* Convert node->sched into a map and return this map. - * - * The result is cached in node->sched_map, which needs to be released - * whenever node->sched is updated. - */ -static __isl_give isl_map *node_extract_schedule(struct isl_sched_node *node) -{ - if (!node->sched_map) { - isl_multi_aff *ma; - - ma = node_extract_schedule_multi_aff(node); - node->sched_map = isl_map_from_multi_aff(ma); - } - - return isl_map_copy(node->sched_map); -} - -/* Update the given dependence relation based on the current schedule. - * That is, intersect the dependence relation with a map expressing - * that source and sink are executed within the same iteration of - * the current schedule. - * This is not the most efficient way, but this shouldn't be a critical - * operation. - */ -static __isl_give isl_map *specialize(__isl_take isl_map *map, - struct isl_sched_node *src, struct isl_sched_node *dst) -{ - isl_map *src_sched, *dst_sched, *id; - - src_sched = node_extract_schedule(src); - dst_sched = node_extract_schedule(dst); - id = isl_map_apply_range(src_sched, isl_map_reverse(dst_sched)); - return isl_map_intersect(map, id); -} - -/* Update the dependence relations of all edges based on the current schedule. - * If a dependence is carried completely by the current schedule, then - * it is removed from the edge_tables. It is kept in the list of edges - * as otherwise all edge_tables would have to be recomputed. - */ -static int update_edges(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i; - - for (i = graph->n_edge - 1; i >= 0; --i) { - struct isl_sched_edge *edge = &graph->edge[i]; - edge->map = specialize(edge->map, edge->src, edge->dst); - if (!edge->map) - return -1; - - if (isl_map_plain_is_empty(edge->map)) - graph_remove_edge(graph, edge); - } - - return 0; -} - -static void next_band(struct isl_sched_graph *graph) -{ - graph->band_start = graph->n_total_row; - graph->n_band++; -} - -/* Topologically sort statements mapped to the same schedule iteration - * and add a row to the schedule corresponding to this order. - */ -static int sort_statements(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i, j; - - if (graph->n <= 1) - return 0; - - if (update_edges(ctx, graph) < 0) - return -1; - - if (graph->n_edge == 0) - return 0; - - if (detect_sccs(ctx, graph) < 0) - return -1; - - if (graph->n_total_row >= graph->max_row) - isl_die(ctx, isl_error_internal, - "too many schedule rows", return -1); - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int row = isl_mat_rows(node->sched); - int cols = isl_mat_cols(node->sched); - - isl_map_free(node->sched_map); - node->sched_map = NULL; - node->sched = isl_mat_add_rows(node->sched, 1); - if (!node->sched) - return -1; - node->sched = isl_mat_set_element_si(node->sched, row, 0, - node->scc); - for (j = 1; j < cols; ++j) - node->sched = isl_mat_set_element_si(node->sched, - row, j, 0); - node->band[graph->n_total_row] = graph->n_band; - } - - graph->n_total_row++; - next_band(graph); - - return 0; -} - -/* Construct an isl_schedule based on the computed schedule stored - * in graph and with parameters specified by dim. - */ -static __isl_give isl_schedule *extract_schedule(struct isl_sched_graph *graph, - __isl_take isl_space *dim) -{ - int i; - isl_ctx *ctx; - isl_schedule *sched = NULL; - - if (!dim) - return NULL; - - ctx = isl_space_get_ctx(dim); - sched = isl_calloc(ctx, struct isl_schedule, - sizeof(struct isl_schedule) + - (graph->n - 1) * sizeof(struct isl_schedule_node)); - if (!sched) - goto error; - - sched->ref = 1; - sched->n = graph->n; - sched->n_band = graph->n_band; - sched->n_total_row = graph->n_total_row; - - for (i = 0; i < sched->n; ++i) { - int r, b; - int *band_end, *band_id, *zero; - - sched->node[i].sched = - node_extract_schedule_multi_aff(&graph->node[i]); - if (!sched->node[i].sched) - goto error; - - sched->node[i].n_band = graph->n_band; - if (graph->n_band == 0) - continue; - - band_end = isl_alloc_array(ctx, int, graph->n_band); - band_id = isl_alloc_array(ctx, int, graph->n_band); - zero = isl_alloc_array(ctx, int, graph->n_total_row); - sched->node[i].band_end = band_end; - sched->node[i].band_id = band_id; - sched->node[i].zero = zero; - if (!band_end || !band_id || !zero) - goto error; - - for (r = 0; r < graph->n_total_row; ++r) - zero[r] = graph->node[i].zero[r]; - for (r = b = 0; r < graph->n_total_row; ++r) { - if (graph->node[i].band[r] == b) - continue; - band_end[b++] = r; - if (graph->node[i].band[r] == -1) - break; - } - if (r == graph->n_total_row) - band_end[b++] = r; - sched->node[i].n_band = b; - for (--b; b >= 0; --b) - band_id[b] = graph->node[i].band_id[b]; - } - - sched->dim = dim; - - return sched; -error: - isl_space_free(dim); - isl_schedule_free(sched); - return NULL; -} - -/* Copy nodes that satisfy node_pred from the src dependence graph - * to the dst dependence graph. - */ -static int copy_nodes(struct isl_sched_graph *dst, struct isl_sched_graph *src, - int (*node_pred)(struct isl_sched_node *node, int data), int data) -{ - int i; - - dst->n = 0; - for (i = 0; i < src->n; ++i) { - if (!node_pred(&src->node[i], data)) - continue; - dst->node[dst->n].dim = isl_space_copy(src->node[i].dim); - dst->node[dst->n].nvar = src->node[i].nvar; - dst->node[dst->n].nparam = src->node[i].nparam; - dst->node[dst->n].sched = isl_mat_copy(src->node[i].sched); - dst->node[dst->n].sched_map = - isl_map_copy(src->node[i].sched_map); - dst->node[dst->n].band = src->node[i].band; - dst->node[dst->n].band_id = src->node[i].band_id; - dst->node[dst->n].zero = src->node[i].zero; - dst->n++; - } - - return 0; -} - -/* Copy non-empty edges that satisfy edge_pred from the src dependence graph - * to the dst dependence graph. - * If the source or destination node of the edge is not in the destination - * graph, then it must be a backward proximity edge and it should simply - * be ignored. - */ -static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst, - struct isl_sched_graph *src, - int (*edge_pred)(struct isl_sched_edge *edge, int data), int data) -{ - int i; - enum isl_edge_type t; - - dst->n_edge = 0; - for (i = 0; i < src->n_edge; ++i) { - struct isl_sched_edge *edge = &src->edge[i]; - isl_map *map; - struct isl_sched_node *dst_src, *dst_dst; - - if (!edge_pred(edge, data)) - continue; - - if (isl_map_plain_is_empty(edge->map)) - continue; - - dst_src = graph_find_node(ctx, dst, edge->src->dim); - dst_dst = graph_find_node(ctx, dst, edge->dst->dim); - if (!dst_src || !dst_dst) { - if (edge->validity) - isl_die(ctx, isl_error_internal, - "backward validity edge", return -1); - continue; - } - - map = isl_map_copy(edge->map); - - dst->edge[dst->n_edge].src = dst_src; - dst->edge[dst->n_edge].dst = dst_dst; - dst->edge[dst->n_edge].map = map; - dst->edge[dst->n_edge].validity = edge->validity; - dst->edge[dst->n_edge].proximity = edge->proximity; - dst->n_edge++; - - for (t = isl_edge_first; t <= isl_edge_last; ++t) { - if (edge != - graph_find_edge(src, t, edge->src, edge->dst)) - continue; - if (graph_edge_table_add(ctx, dst, t, - &dst->edge[dst->n_edge - 1]) < 0) - return -1; - } - } - - return 0; -} - -/* Given a "src" dependence graph that contains the nodes from "dst" - * that satisfy node_pred, copy the schedule computed in "src" - * for those nodes back to "dst". - */ -static int copy_schedule(struct isl_sched_graph *dst, - struct isl_sched_graph *src, - int (*node_pred)(struct isl_sched_node *node, int data), int data) -{ - int i; - - src->n = 0; - for (i = 0; i < dst->n; ++i) { - if (!node_pred(&dst->node[i], data)) - continue; - isl_mat_free(dst->node[i].sched); - isl_map_free(dst->node[i].sched_map); - dst->node[i].sched = isl_mat_copy(src->node[src->n].sched); - dst->node[i].sched_map = - isl_map_copy(src->node[src->n].sched_map); - src->n++; - } - - dst->max_row = src->max_row; - dst->n_total_row = src->n_total_row; - dst->n_band = src->n_band; - - return 0; -} - -/* Compute the maximal number of variables over all nodes. - * This is the maximal number of linearly independent schedule - * rows that we need to compute. - * Just in case we end up in a part of the dependence graph - * with only lower-dimensional domains, we make sure we will - * compute the required amount of extra linearly independent rows. - */ -static int compute_maxvar(struct isl_sched_graph *graph) -{ - int i; - - graph->maxvar = 0; - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int nvar; - - if (node_update_cmap(node) < 0) - return -1; - nvar = node->nvar + graph->n_row - node->rank; - if (nvar > graph->maxvar) - graph->maxvar = nvar; - } - - return 0; -} - -static int compute_schedule(isl_ctx *ctx, struct isl_sched_graph *graph); -static int compute_schedule_wcc(isl_ctx *ctx, struct isl_sched_graph *graph); - -/* Compute a schedule for a subgraph of "graph". In particular, for - * the graph composed of nodes that satisfy node_pred and edges that - * that satisfy edge_pred. The caller should precompute the number - * of nodes and edges that satisfy these predicates and pass them along - * as "n" and "n_edge". - * If the subgraph is known to consist of a single component, then wcc should - * be set and then we call compute_schedule_wcc on the constructed subgraph. - * Otherwise, we call compute_schedule, which will check whether the subgraph - * is connected. - */ -static int compute_sub_schedule(isl_ctx *ctx, - struct isl_sched_graph *graph, int n, int n_edge, - int (*node_pred)(struct isl_sched_node *node, int data), - int (*edge_pred)(struct isl_sched_edge *edge, int data), - int data, int wcc) -{ - struct isl_sched_graph split = { 0 }; - int t; - - if (graph_alloc(ctx, &split, n, n_edge) < 0) - goto error; - if (copy_nodes(&split, graph, node_pred, data) < 0) - goto error; - if (graph_init_table(ctx, &split) < 0) - goto error; - for (t = 0; t <= isl_edge_last; ++t) - split.max_edge[t] = graph->max_edge[t]; - if (graph_init_edge_tables(ctx, &split) < 0) - goto error; - if (copy_edges(ctx, &split, graph, edge_pred, data) < 0) - goto error; - split.n_row = graph->n_row; - split.max_row = graph->max_row; - split.n_total_row = graph->n_total_row; - split.n_band = graph->n_band; - split.band_start = graph->band_start; - - if (wcc && compute_schedule_wcc(ctx, &split) < 0) - goto error; - if (!wcc && compute_schedule(ctx, &split) < 0) - goto error; - - copy_schedule(graph, &split, node_pred, data); - - graph_free(ctx, &split); - return 0; -error: - graph_free(ctx, &split); - return -1; -} - -static int node_scc_exactly(struct isl_sched_node *node, int scc) -{ - return node->scc == scc; -} - -static int node_scc_at_most(struct isl_sched_node *node, int scc) -{ - return node->scc <= scc; -} - -static int node_scc_at_least(struct isl_sched_node *node, int scc) -{ - return node->scc >= scc; -} - -static int edge_scc_exactly(struct isl_sched_edge *edge, int scc) -{ - return edge->src->scc == scc && edge->dst->scc == scc; -} - -static int edge_dst_scc_at_most(struct isl_sched_edge *edge, int scc) -{ - return edge->dst->scc <= scc; -} - -static int edge_src_scc_at_least(struct isl_sched_edge *edge, int scc) -{ - return edge->src->scc >= scc; -} - -/* Pad the schedules of all nodes with zero rows such that in the end - * they all have graph->n_total_row rows. - * The extra rows don't belong to any band, so they get assigned band number -1. - */ -static int pad_schedule(struct isl_sched_graph *graph) -{ - int i, j; - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int row = isl_mat_rows(node->sched); - if (graph->n_total_row > row) { - isl_map_free(node->sched_map); - node->sched_map = NULL; - } - node->sched = isl_mat_add_zero_rows(node->sched, - graph->n_total_row - row); - if (!node->sched) - return -1; - for (j = row; j < graph->n_total_row; ++j) - node->band[j] = -1; - } - - return 0; -} - -/* Split the current graph into two parts and compute a schedule for each - * part individually. In particular, one part consists of all SCCs up - * to and including graph->src_scc, while the other part contains the other - * SCCS. - * - * The split is enforced in the schedule by constant rows with two different - * values (0 and 1). These constant rows replace the previously computed rows - * in the current band. - * It would be possible to reuse them as the first rows in the next - * band, but recomputing them may result in better rows as we are looking - * at a smaller part of the dependence graph. - * compute_split_schedule is only called when no zero-distance schedule row - * could be found on the entire graph, so we wark the splitting row as - * non zero-distance. - * - * The band_id of the second group is set to n, where n is the number - * of nodes in the first group. This ensures that the band_ids over - * the two groups remain disjoint, even if either or both of the two - * groups contain independent components. - */ -static int compute_split_schedule(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i, j, n, e1, e2; - int n_total_row, orig_total_row; - int n_band, orig_band; - int drop; - - if (graph->n_total_row >= graph->max_row) - isl_die(ctx, isl_error_internal, - "too many schedule rows", return -1); - - drop = graph->n_total_row - graph->band_start; - graph->n_total_row -= drop; - graph->n_row -= drop; - - n = 0; - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int row = isl_mat_rows(node->sched) - drop; - int cols = isl_mat_cols(node->sched); - int before = node->scc <= graph->src_scc; - - if (before) - n++; - - isl_map_free(node->sched_map); - node->sched_map = NULL; - node->sched = isl_mat_drop_rows(node->sched, - graph->band_start, drop); - node->sched = isl_mat_add_rows(node->sched, 1); - if (!node->sched) - return -1; - node->sched = isl_mat_set_element_si(node->sched, row, 0, - !before); - for (j = 1; j < cols; ++j) - node->sched = isl_mat_set_element_si(node->sched, - row, j, 0); - node->band[graph->n_total_row] = graph->n_band; - node->zero[graph->n_total_row] = 0; - } - - e1 = e2 = 0; - for (i = 0; i < graph->n_edge; ++i) { - if (graph->edge[i].dst->scc <= graph->src_scc) - e1++; - if (graph->edge[i].src->scc > graph->src_scc) - e2++; - } - - graph->n_total_row++; - next_band(graph); - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - if (node->scc > graph->src_scc) - node->band_id[graph->n_band] = n; - } - - orig_total_row = graph->n_total_row; - orig_band = graph->n_band; - if (compute_sub_schedule(ctx, graph, n, e1, - &node_scc_at_most, &edge_dst_scc_at_most, - graph->src_scc, 0) < 0) - return -1; - n_total_row = graph->n_total_row; - graph->n_total_row = orig_total_row; - n_band = graph->n_band; - graph->n_band = orig_band; - if (compute_sub_schedule(ctx, graph, graph->n - n, e2, - &node_scc_at_least, &edge_src_scc_at_least, - graph->src_scc + 1, 0) < 0) - return -1; - if (n_total_row > graph->n_total_row) - graph->n_total_row = n_total_row; - if (n_band > graph->n_band) - graph->n_band = n_band; - - return pad_schedule(graph); -} - -/* Compute the next band of the schedule after updating the dependence - * relations based on the the current schedule. - */ -static int compute_next_band(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - if (update_edges(ctx, graph) < 0) - return -1; - next_band(graph); - - return compute_schedule(ctx, graph); -} - -/* Add constraints to graph->lp that force the dependence "map" (which - * is part of the dependence relation of "edge") - * to be respected and attempt to carry it, where the edge is one from - * a node j to itself. "pos" is the sequence number of the given map. - * That is, add constraints that enforce - * - * (c_j_0 + c_j_n n + c_j_x y) - (c_j_0 + c_j_n n + c_j_x x) - * = c_j_x (y - x) >= e_i - * - * for each (x,y) in R. - * We obtain general constraints on coefficients (c_0, c_n, c_x) - * of valid constraints for (y - x) and then plug in (-e_i, 0, c_j_x), - * with each coefficient in c_j_x represented as a pair of non-negative - * coefficients. - */ -static int add_intra_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge, __isl_take isl_map *map, int pos) -{ - unsigned total; - isl_ctx *ctx = isl_map_get_ctx(map); - isl_space *dim; - isl_dim_map *dim_map; - isl_basic_set *coef; - struct isl_sched_node *node = edge->src; - - coef = intra_coefficients(graph, map); - if (!coef) - return -1; - - dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); - - total = isl_basic_set_total_dim(graph->lp); - dim_map = isl_dim_map_alloc(ctx, total); - isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1); - isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set), 1, - node->nvar, -1); - isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set), 1, - node->nvar, 1); - graph->lp = isl_basic_set_extend_constraints(graph->lp, - coef->n_eq, coef->n_ineq); - graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, - coef, dim_map); - isl_space_free(dim); - - return 0; -} - -/* Add constraints to graph->lp that force the dependence "map" (which - * is part of the dependence relation of "edge") - * to be respected and attempt to carry it, where the edge is one from - * node j to node k. "pos" is the sequence number of the given map. - * That is, add constraints that enforce - * - * (c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= e_i - * - * for each (x,y) in R. - * We obtain general constraints on coefficients (c_0, c_n, c_x) - * of valid constraints for R and then plug in - * (-e_i + c_k_0 - c_j_0, c_k_n - c_j_n, c_k_x - c_j_x) - * with each coefficient (except e_i, c_k_0 and c_j_0) - * represented as a pair of non-negative coefficients. - */ -static int add_inter_constraints(struct isl_sched_graph *graph, - struct isl_sched_edge *edge, __isl_take isl_map *map, int pos) -{ - unsigned total; - isl_ctx *ctx = isl_map_get_ctx(map); - isl_space *dim; - isl_dim_map *dim_map; - isl_basic_set *coef; - struct isl_sched_node *src = edge->src; - struct isl_sched_node *dst = edge->dst; - - coef = inter_coefficients(graph, map); - if (!coef) - return -1; - - dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); - - total = isl_basic_set_total_dim(graph->lp); - dim_map = isl_dim_map_alloc(ctx, total); - - isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1); - - isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, 1); - isl_dim_map_range(dim_map, dst->start + 1, 2, 1, 1, dst->nparam, -1); - isl_dim_map_range(dim_map, dst->start + 2, 2, 1, 1, dst->nparam, 1); - isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set) + src->nvar, 1, - dst->nvar, -1); - isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set) + src->nvar, 1, - dst->nvar, 1); - - isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, -1); - isl_dim_map_range(dim_map, src->start + 1, 2, 1, 1, src->nparam, 1); - isl_dim_map_range(dim_map, src->start + 2, 2, 1, 1, src->nparam, -1); - isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 1, 2, - isl_space_dim(dim, isl_dim_set), 1, - src->nvar, 1); - isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 2, 2, - isl_space_dim(dim, isl_dim_set), 1, - src->nvar, -1); - - graph->lp = isl_basic_set_extend_constraints(graph->lp, - coef->n_eq, coef->n_ineq); - graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, - coef, dim_map); - isl_space_free(dim); - - return 0; -} - -/* Add constraints to graph->lp that force all validity dependences - * to be respected and attempt to carry them. - */ -static int add_all_constraints(struct isl_sched_graph *graph) -{ - int i, j; - int pos; - - pos = 0; - for (i = 0; i < graph->n_edge; ++i) { - struct isl_sched_edge *edge= &graph->edge[i]; - - if (!edge->validity) - continue; - - for (j = 0; j < edge->map->n; ++j) { - isl_basic_map *bmap; - isl_map *map; - - bmap = isl_basic_map_copy(edge->map->p[j]); - map = isl_map_from_basic_map(bmap); - - if (edge->src == edge->dst && - add_intra_constraints(graph, edge, map, pos) < 0) - return -1; - if (edge->src != edge->dst && - add_inter_constraints(graph, edge, map, pos) < 0) - return -1; - ++pos; - } - } - - return 0; -} - -/* Count the number of equality and inequality constraints - * that will be added to the carry_lp problem. - * We count each edge exactly once. - */ -static int count_all_constraints(struct isl_sched_graph *graph, - int *n_eq, int *n_ineq) -{ - int i, j; - - *n_eq = *n_ineq = 0; - for (i = 0; i < graph->n_edge; ++i) { - struct isl_sched_edge *edge= &graph->edge[i]; - for (j = 0; j < edge->map->n; ++j) { - isl_basic_map *bmap; - isl_map *map; - - bmap = isl_basic_map_copy(edge->map->p[j]); - map = isl_map_from_basic_map(bmap); - - if (count_map_constraints(graph, edge, map, - n_eq, n_ineq, 1) < 0) - return -1; - } - } - - return 0; -} - -/* Construct an LP problem for finding schedule coefficients - * such that the schedule carries as many dependences as possible. - * In particular, for each dependence i, we bound the dependence distance - * from below by e_i, with 0 <= e_i <= 1 and then maximize the sum - * of all e_i's. Dependence with e_i = 0 in the solution are simply - * respected, while those with e_i > 0 (in practice e_i = 1) are carried. - * Note that if the dependence relation is a union of basic maps, - * then we have to consider each basic map individually as it may only - * be possible to carry the dependences expressed by some of those - * basic maps and not all off them. - * Below, we consider each of those basic maps as a separate "edge". - * - * All variables of the LP are non-negative. The actual coefficients - * may be negative, so each coefficient is represented as the difference - * of two non-negative variables. The negative part always appears - * immediately before the positive part. - * Other than that, the variables have the following order - * - * - sum of (1 - e_i) over all edges - * - sum of positive and negative parts of all c_n coefficients - * (unconstrained when computing non-parametric schedules) - * - sum of positive and negative parts of all c_x coefficients - * - for each edge - * - e_i - * - for each node - * - c_i_0 - * - positive and negative parts of c_i_n (if parametric) - * - positive and negative parts of c_i_x - * - * The constraints are those from the (validity) edges plus three equalities - * to express the sums and n_edge inequalities to express e_i <= 1. - */ -static int setup_carry_lp(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i, j; - int k; - isl_space *dim; - unsigned total; - int n_eq, n_ineq; - int n_edge; - - n_edge = 0; - for (i = 0; i < graph->n_edge; ++i) - n_edge += graph->edge[i].map->n; - - total = 3 + n_edge; - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[graph->sorted[i]]; - node->start = total; - total += 1 + 2 * (node->nparam + node->nvar); - } - - if (count_all_constraints(graph, &n_eq, &n_ineq) < 0) - return -1; - - dim = isl_space_set_alloc(ctx, 0, total); - isl_basic_set_free(graph->lp); - n_eq += 3; - n_ineq += n_edge; - graph->lp = isl_basic_set_alloc_space(dim, 0, n_eq, n_ineq); - graph->lp = isl_basic_set_set_rational(graph->lp); - - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - isl_int_set_si(graph->lp->eq[k][0], -n_edge); - isl_int_set_si(graph->lp->eq[k][1], 1); - for (i = 0; i < n_edge; ++i) - isl_int_set_si(graph->lp->eq[k][4 + i], 1); - - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - isl_int_set_si(graph->lp->eq[k][2], -1); - for (i = 0; i < graph->n; ++i) { - int pos = 1 + graph->node[i].start + 1; - - for (j = 0; j < 2 * graph->node[i].nparam; ++j) - isl_int_set_si(graph->lp->eq[k][pos + j], 1); - } - - k = isl_basic_set_alloc_equality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->eq[k], 1 + total); - isl_int_set_si(graph->lp->eq[k][3], -1); - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int pos = 1 + node->start + 1 + 2 * node->nparam; - - for (j = 0; j < 2 * node->nvar; ++j) - isl_int_set_si(graph->lp->eq[k][pos + j], 1); - } - - for (i = 0; i < n_edge; ++i) { - k = isl_basic_set_alloc_inequality(graph->lp); - if (k < 0) - return -1; - isl_seq_clr(graph->lp->ineq[k], 1 + total); - isl_int_set_si(graph->lp->ineq[k][4 + i], -1); - isl_int_set_si(graph->lp->ineq[k][0], 1); - } - - if (add_all_constraints(graph) < 0) - return -1; - - return 0; -} - -/* If the schedule_split_scaled option is set and if the linear - * parts of the scheduling rows for all nodes in the graphs have - * non-trivial common divisor, then split off the constant term - * from the linear part. - * The constant term is then placed in a separate band and - * the linear part is reduced. - */ -static int split_scaled(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i; - int row; - isl_int gcd, gcd_i; - - if (!ctx->opt->schedule_split_scaled) - return 0; - if (graph->n <= 1) - return 0; - - if (graph->n_total_row >= graph->max_row) - isl_die(ctx, isl_error_internal, - "too many schedule rows", return -1); - - isl_int_init(gcd); - isl_int_init(gcd_i); - - isl_int_set_si(gcd, 0); - - row = isl_mat_rows(graph->node[0].sched) - 1; - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int cols = isl_mat_cols(node->sched); - - isl_seq_gcd(node->sched->row[row] + 1, cols - 1, &gcd_i); - isl_int_gcd(gcd, gcd, gcd_i); - } - - isl_int_clear(gcd_i); - - if (isl_int_cmp_si(gcd, 1) <= 0) { - isl_int_clear(gcd); - return 0; - } - - next_band(graph); - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - - isl_map_free(node->sched_map); - node->sched_map = NULL; - node->sched = isl_mat_add_zero_rows(node->sched, 1); - if (!node->sched) - goto error; - isl_int_fdiv_r(node->sched->row[row + 1][0], - node->sched->row[row][0], gcd); - isl_int_fdiv_q(node->sched->row[row][0], - node->sched->row[row][0], gcd); - isl_int_mul(node->sched->row[row][0], - node->sched->row[row][0], gcd); - node->sched = isl_mat_scale_down_row(node->sched, row, gcd); - if (!node->sched) - goto error; - node->band[graph->n_total_row] = graph->n_band; - } - - graph->n_total_row++; - - isl_int_clear(gcd); - return 0; -error: - isl_int_clear(gcd); - return -1; -} - -static int compute_component_schedule(isl_ctx *ctx, - struct isl_sched_graph *graph); - -/* Is the schedule row "sol" trivial on node "node"? - * That is, is the solution zero on the dimensions orthogonal to - * the previously found solutions? - * Return 1 if the solution is trivial, 0 if it is not and -1 on error. - * - * Each coefficient is represented as the difference between - * two non-negative values in "sol". "sol" has been computed - * in terms of the original iterators (i.e., without use of cmap). - * We construct the schedule row s and write it as a linear - * combination of (linear combinations of) previously computed schedule rows. - * s = Q c or c = U s. - * If the final entries of c are all zero, then the solution is trivial. - */ -static int is_trivial(struct isl_sched_node *node, __isl_keep isl_vec *sol) -{ - int i; - int pos; - int trivial; - isl_ctx *ctx; - isl_vec *node_sol; - - if (!sol) - return -1; - if (node->nvar == node->rank) - return 0; - - ctx = isl_vec_get_ctx(sol); - node_sol = isl_vec_alloc(ctx, node->nvar); - if (!node_sol) - return -1; - - pos = 1 + node->start + 1 + 2 * node->nparam; - - for (i = 0; i < node->nvar; ++i) - isl_int_sub(node_sol->el[i], - sol->el[pos + 2 * i + 1], sol->el[pos + 2 * i]); - - node_sol = isl_mat_vec_product(isl_mat_copy(node->cinv), node_sol); - - if (!node_sol) - return -1; - - trivial = isl_seq_first_non_zero(node_sol->el + node->rank, - node->nvar - node->rank) == -1; - - isl_vec_free(node_sol); - - return trivial; -} - -/* Is the schedule row "sol" trivial on any node where it should - * not be trivial? - * "sol" has been computed in terms of the original iterators - * (i.e., without use of cmap). - * Return 1 if any solution is trivial, 0 if they are not and -1 on error. - */ -static int is_any_trivial(struct isl_sched_graph *graph, - __isl_keep isl_vec *sol) -{ - int i; - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int trivial; - - if (!needs_row(graph, node)) - continue; - trivial = is_trivial(node, sol); - if (trivial < 0 || trivial) - return trivial; - } - - return 0; -} - -/* Construct a schedule row for each node such that as many dependences - * as possible are carried and then continue with the next band. - * - * If the computed schedule row turns out to be trivial on one or - * more nodes where it should not be trivial, then we throw it away - * and try again on each component separately. - */ -static int carry_dependences(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i; - int n_edge; - int trivial; - isl_vec *sol; - isl_basic_set *lp; - - n_edge = 0; - for (i = 0; i < graph->n_edge; ++i) - n_edge += graph->edge[i].map->n; - - if (setup_carry_lp(ctx, graph) < 0) - return -1; - - lp = isl_basic_set_copy(graph->lp); - sol = isl_tab_basic_set_non_neg_lexmin(lp); - if (!sol) - return -1; - - if (sol->size == 0) { - isl_vec_free(sol); - isl_die(ctx, isl_error_internal, - "error in schedule construction", return -1); - } - - isl_int_divexact(sol->el[1], sol->el[1], sol->el[0]); - if (isl_int_cmp_si(sol->el[1], n_edge) >= 0) { - isl_vec_free(sol); - isl_die(ctx, isl_error_unknown, - "unable to carry dependences", return -1); - } - - trivial = is_any_trivial(graph, sol); - if (trivial < 0) { - sol = isl_vec_free(sol); - } else if (trivial) { - isl_vec_free(sol); - if (graph->scc > 1) - return compute_component_schedule(ctx, graph); - isl_die(ctx, isl_error_unknown, - "unable to construct non-trivial solution", return -1); - } - - if (update_schedule(graph, sol, 0, 0) < 0) - return -1; - - if (split_scaled(ctx, graph) < 0) - return -1; - - return compute_next_band(ctx, graph); -} - -/* Are there any (non-empty) validity edges in the graph? - */ -static int has_validity_edges(struct isl_sched_graph *graph) -{ - int i; - - for (i = 0; i < graph->n_edge; ++i) { - int empty; - - empty = isl_map_plain_is_empty(graph->edge[i].map); - if (empty < 0) - return -1; - if (empty) - continue; - if (graph->edge[i].validity) - return 1; - } - - return 0; -} - -/* Should we apply a Feautrier step? - * That is, did the user request the Feautrier algorithm and are - * there any validity dependences (left)? - */ -static int need_feautrier_step(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - if (ctx->opt->schedule_algorithm != ISL_SCHEDULE_ALGORITHM_FEAUTRIER) - return 0; - - return has_validity_edges(graph); -} - -/* Compute a schedule for a connected dependence graph using Feautrier's - * multi-dimensional scheduling algorithm. - * The original algorithm is described in [1]. - * The main idea is to minimize the number of scheduling dimensions, by - * trying to satisfy as many dependences as possible per scheduling dimension. - * - * [1] P. Feautrier, Some Efficient Solutions to the Affine Scheduling - * Problem, Part II: Multi-Dimensional Time. - * In Intl. Journal of Parallel Programming, 1992. - */ -static int compute_schedule_wcc_feautrier(isl_ctx *ctx, - struct isl_sched_graph *graph) -{ - return carry_dependences(ctx, graph); -} - -/* Compute a schedule for a connected dependence graph. - * We try to find a sequence of as many schedule rows as possible that result - * in non-negative dependence distances (independent of the previous rows - * in the sequence, i.e., such that the sequence is tilable). - * If we can't find any more rows we either - * - split between SCCs and start over (assuming we found an interesting - * pair of SCCs between which to split) - * - continue with the next band (assuming the current band has at least - * one row) - * - try to carry as many dependences as possible and continue with the next - * band - * - * If Feautrier's algorithm is selected, we first recursively try to satisfy - * as many validity dependences as possible. When all validity dependences - * are satisfied we extend the schedule to a full-dimensional schedule. - * - * If we manage to complete the schedule, we finish off by topologically - * sorting the statements based on the remaining dependences. - * - * If ctx->opt->schedule_outer_zero_distance is set, then we force the - * outermost dimension in the current band to be zero distance. If this - * turns out to be impossible, we fall back on the general scheme above - * and try to carry as many dependences as possible. - */ -static int compute_schedule_wcc(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int force_zero = 0; - - if (detect_sccs(ctx, graph) < 0) - return -1; - if (sort_sccs(graph) < 0) - return -1; - - if (compute_maxvar(graph) < 0) - return -1; - - if (need_feautrier_step(ctx, graph)) - return compute_schedule_wcc_feautrier(ctx, graph); - - if (ctx->opt->schedule_outer_zero_distance) - force_zero = 1; - - while (graph->n_row < graph->maxvar) { - isl_vec *sol; - - graph->src_scc = -1; - graph->dst_scc = -1; - - if (setup_lp(ctx, graph, force_zero) < 0) - return -1; - sol = solve_lp(graph); - if (!sol) - return -1; - if (sol->size == 0) { - isl_vec_free(sol); - if (!ctx->opt->schedule_maximize_band_depth && - graph->n_total_row > graph->band_start) - return compute_next_band(ctx, graph); - if (graph->src_scc >= 0) - return compute_split_schedule(ctx, graph); - if (graph->n_total_row > graph->band_start) - return compute_next_band(ctx, graph); - return carry_dependences(ctx, graph); - } - if (update_schedule(graph, sol, 1, 1) < 0) - return -1; - force_zero = 0; - } - - if (graph->n_total_row > graph->band_start) - next_band(graph); - return sort_statements(ctx, graph); -} - -/* Add a row to the schedules that separates the SCCs and move - * to the next band. - */ -static int split_on_scc(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - int i; - - if (graph->n_total_row >= graph->max_row) - isl_die(ctx, isl_error_internal, - "too many schedule rows", return -1); - - for (i = 0; i < graph->n; ++i) { - struct isl_sched_node *node = &graph->node[i]; - int row = isl_mat_rows(node->sched); - - isl_map_free(node->sched_map); - node->sched_map = NULL; - node->sched = isl_mat_add_zero_rows(node->sched, 1); - node->sched = isl_mat_set_element_si(node->sched, row, 0, - node->scc); - if (!node->sched) - return -1; - node->band[graph->n_total_row] = graph->n_band; - } - - graph->n_total_row++; - next_band(graph); - - return 0; -} - -/* Compute a schedule for each component (identified by node->scc) - * of the dependence graph separately and then combine the results. - * Depending on the setting of schedule_fuse, a component may be - * either weakly or strongly connected. - * - * The band_id is adjusted such that each component has a separate id. - * Note that the band_id may have already been set to a value different - * from zero by compute_split_schedule. - */ -static int compute_component_schedule(isl_ctx *ctx, - struct isl_sched_graph *graph) -{ - int wcc, i; - int n, n_edge; - int n_total_row, orig_total_row; - int n_band, orig_band; - - if (ctx->opt->schedule_fuse == ISL_SCHEDULE_FUSE_MIN || - ctx->opt->schedule_separate_components) - if (split_on_scc(ctx, graph) < 0) - return -1; - - n_total_row = 0; - orig_total_row = graph->n_total_row; - n_band = 0; - orig_band = graph->n_band; - for (i = 0; i < graph->n; ++i) - graph->node[i].band_id[graph->n_band] += graph->node[i].scc; - for (wcc = 0; wcc < graph->scc; ++wcc) { - n = 0; - for (i = 0; i < graph->n; ++i) - if (graph->node[i].scc == wcc) - n++; - n_edge = 0; - for (i = 0; i < graph->n_edge; ++i) - if (graph->edge[i].src->scc == wcc && - graph->edge[i].dst->scc == wcc) - n_edge++; - - if (compute_sub_schedule(ctx, graph, n, n_edge, - &node_scc_exactly, - &edge_scc_exactly, wcc, 1) < 0) - return -1; - if (graph->n_total_row > n_total_row) - n_total_row = graph->n_total_row; - graph->n_total_row = orig_total_row; - if (graph->n_band > n_band) - n_band = graph->n_band; - graph->n_band = orig_band; - } - - graph->n_total_row = n_total_row; - graph->n_band = n_band; - - return pad_schedule(graph); -} - -/* Compute a schedule for the given dependence graph. - * We first check if the graph is connected (through validity dependences) - * and, if not, compute a schedule for each component separately. - * If schedule_fuse is set to minimal fusion, then we check for strongly - * connected components instead and compute a separate schedule for - * each such strongly connected component. - */ -static int compute_schedule(isl_ctx *ctx, struct isl_sched_graph *graph) -{ - if (ctx->opt->schedule_fuse == ISL_SCHEDULE_FUSE_MIN) { - if (detect_sccs(ctx, graph) < 0) - return -1; - } else { - if (detect_wccs(ctx, graph) < 0) - return -1; - } - - if (graph->scc > 1) - return compute_component_schedule(ctx, graph); - - return compute_schedule_wcc(ctx, graph); -} - -/* Compute a schedule for the given union of domains that respects - * all the validity dependences. - * If the default isl scheduling algorithm is used, it tries to minimize - * the dependence distances over the proximity dependences. - * If Feautrier's scheduling algorithm is used, the proximity dependence - * distances are only minimized during the extension to a full-dimensional - * schedule. - */ -__isl_give isl_schedule *isl_union_set_compute_schedule( - __isl_take isl_union_set *domain, - __isl_take isl_union_map *validity, - __isl_take isl_union_map *proximity) -{ - isl_ctx *ctx = isl_union_set_get_ctx(domain); - isl_space *dim; - struct isl_sched_graph graph = { 0 }; - isl_schedule *sched; - struct isl_extract_edge_data data; - - domain = isl_union_set_align_params(domain, - isl_union_map_get_space(validity)); - domain = isl_union_set_align_params(domain, - isl_union_map_get_space(proximity)); - dim = isl_union_set_get_space(domain); - validity = isl_union_map_align_params(validity, isl_space_copy(dim)); - proximity = isl_union_map_align_params(proximity, dim); - - if (!domain) - goto error; - - graph.n = isl_union_set_n_set(domain); - if (graph.n == 0) - goto empty; - if (graph_alloc(ctx, &graph, graph.n, - isl_union_map_n_map(validity) + isl_union_map_n_map(proximity)) < 0) - goto error; - if (compute_max_row(&graph, domain) < 0) - goto error; - graph.root = 1; - graph.n = 0; - if (isl_union_set_foreach_set(domain, &extract_node, &graph) < 0) - goto error; - if (graph_init_table(ctx, &graph) < 0) - goto error; - graph.max_edge[isl_edge_validity] = isl_union_map_n_map(validity); - graph.max_edge[isl_edge_proximity] = isl_union_map_n_map(proximity); - if (graph_init_edge_tables(ctx, &graph) < 0) - goto error; - graph.n_edge = 0; - data.graph = &graph; - data.type = isl_edge_validity; - if (isl_union_map_foreach_map(validity, &extract_edge, &data) < 0) - goto error; - data.type = isl_edge_proximity; - if (isl_union_map_foreach_map(proximity, &extract_edge, &data) < 0) - goto error; - - if (compute_schedule(ctx, &graph) < 0) - goto error; + isl_union_set *domain; -empty: - sched = extract_schedule(&graph, isl_union_set_get_space(domain)); + if (!schedule) + return NULL; + if (!schedule->root) + isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid, + "schedule tree representation not available", + return NULL); + type = isl_schedule_tree_get_type(schedule->root); + if (type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule), isl_error_internal, + "root node not a domain node", return NULL); - graph_free(ctx, &graph); + domain = isl_schedule_tree_domain_get_domain(schedule->root); + space = isl_union_set_get_space(domain); isl_union_set_free(domain); - isl_union_map_free(validity); - isl_union_map_free(proximity); - return sched; -error: - graph_free(ctx, &graph); - isl_union_set_free(domain); - isl_union_map_free(validity); - isl_union_map_free(proximity); - return NULL; + return space; } -void *isl_schedule_free(__isl_take isl_schedule *sched) +/* Return a pointer to the root of "schedule". + */ +__isl_give isl_schedule_node *isl_schedule_get_root( + __isl_keep isl_schedule *schedule) { - int i; - if (!sched) - return NULL; + isl_ctx *ctx; + isl_schedule_tree *tree; + isl_schedule_tree_list *ancestors; - if (--sched->ref > 0) + if (!schedule) return NULL; - for (i = 0; i < sched->n; ++i) { - isl_multi_aff_free(sched->node[i].sched); - free(sched->node[i].band_end); - free(sched->node[i].band_id); - free(sched->node[i].zero); - } - isl_space_free(sched->dim); - isl_band_list_free(sched->band_forest); - free(sched); - return NULL; -} - -isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *schedule) -{ - return schedule ? isl_space_get_ctx(schedule->dim) : NULL; + if (!schedule->root) + isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid, + "schedule tree representation not available", + return NULL); + + ctx = isl_schedule_get_ctx(schedule); + tree = isl_schedule_tree_copy(schedule->root); + schedule = isl_schedule_copy(schedule); + ancestors = isl_schedule_tree_list_alloc(ctx, 0); + return isl_schedule_node_alloc(schedule, tree, ancestors, NULL); } /* Set max_out to the maximal number of output dimensions over * all maps. */ -static int update_max_out(__isl_take isl_map *map, void *user) +static isl_stat update_max_out(__isl_take isl_map *map, void *user) { int *max_out = user; int n_out = isl_map_dim(map, isl_dim_out); @@ -3025,7 +257,7 @@ *max_out = n_out; isl_map_free(map); - return 0; + return isl_stat_ok; } /* Internal data structure for map_pad_range. @@ -3041,7 +273,7 @@ /* Pad the range of the given map with zeros to data->max_out and * then add the result to data->res. */ -static int map_pad_range(__isl_take isl_map *map, void *user) +static isl_stat map_pad_range(__isl_take isl_map *map, void *user) { struct isl_pad_schedule_map_data *data = user; int i; @@ -3053,9 +285,9 @@ data->res = isl_union_map_add_map(data->res, map); if (!data->res) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Pad the ranges of the maps in the union map with zeros such they all have @@ -3083,473 +315,498 @@ return data.res; } -/* Return an isl_union_map of the schedule. If we have already constructed - * a band forest, then this band forest may have been modified so we need - * to extract the isl_union_map from the forest rather than from - * the originally computed schedule. This reconstructed schedule map - * then needs to be padded with zeros to unify the schedule space - * since the result of isl_band_list_get_suffix_schedule may not have - * a unified schedule space. +/* Return the domain of the root domain node of "schedule". */ -__isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched) +__isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule) { - int i; - isl_union_map *umap; - - if (!sched) + if (!schedule) return NULL; + if (!schedule->root) + isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid, + "schedule tree representation not available", + return NULL); + return isl_schedule_tree_domain_get_domain(schedule->root); +} - if (sched->band_forest) { - umap = isl_band_list_get_suffix_schedule(sched->band_forest); - return pad_schedule_map(umap); - } +/* Traverse all nodes of "sched" in depth first preorder. + * + * If "fn" returns -1 on any of the nodes, then the traversal is aborted. + * If "fn" returns 0 on any of the nodes, then the subtree rooted + * at that node is skipped. + * + * Return 0 on success and -1 on failure. + */ +isl_stat isl_schedule_foreach_schedule_node_top_down( + __isl_keep isl_schedule *sched, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user) +{ + isl_schedule_node *node; + isl_stat r; - umap = isl_union_map_empty(isl_space_copy(sched->dim)); - for (i = 0; i < sched->n; ++i) { - isl_multi_aff *ma; + if (!sched) + return isl_stat_error; - ma = isl_multi_aff_copy(sched->node[i].sched); - umap = isl_union_map_add_map(umap, isl_map_from_multi_aff(ma)); - } + node = isl_schedule_get_root(sched); + r = isl_schedule_node_foreach_descendant_top_down(node, fn, user); + isl_schedule_node_free(node); - return umap; + return r; } -static __isl_give isl_band_list *construct_band_list( - __isl_keep isl_schedule *schedule, __isl_keep isl_band *parent, - int band_nr, int *parent_active, int n_active); - -/* Construct an isl_band structure for the band in the given schedule - * with sequence number band_nr for the n_active nodes marked by active. - * If the nodes don't have a band with the given sequence number, - * then a band without members is created. - * - * Because of the way the schedule is constructed, we know that - * the position of the band inside the schedule of a node is the same - * for all active nodes. - * - * The partial schedule for the band is created before the children - * are created to that construct_band_list can refer to the partial - * schedule of the parent. - */ -static __isl_give isl_band *construct_band(__isl_keep isl_schedule *schedule, - __isl_keep isl_band *parent, - int band_nr, int *active, int n_active) +/* Traverse the node of "sched" in depth first postorder, + * allowing the user to modify the visited node. + * The traversal continues from the node returned by the callback function. + * It is the responsibility of the user to ensure that this does not + * lead to an infinite loop. It is safest to always return a pointer + * to the same position (same ancestors and child positions) as the input node. + */ +__isl_give isl_schedule *isl_schedule_map_schedule_node_bottom_up( + __isl_take isl_schedule *schedule, + __isl_give isl_schedule_node *(*fn)( + __isl_take isl_schedule_node *node, void *user), void *user) { - int i, j; - isl_ctx *ctx = isl_schedule_get_ctx(schedule); - isl_band *band; - unsigned start, end; + isl_schedule_node *node; - band = isl_band_alloc(ctx); - if (!band) - return NULL; + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); - band->schedule = schedule; - band->parent = parent; + node = isl_schedule_node_map_descendant_bottom_up(node, fn, user); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); - for (i = 0; i < schedule->n; ++i) - if (active[i]) - break; + return schedule; +} - if (i >= schedule->n) - isl_die(ctx, isl_error_internal, - "band without active statements", goto error); +/* Wrapper around isl_schedule_node_reset_user for use as + * an isl_schedule_map_schedule_node_bottom_up callback. + */ +static __isl_give isl_schedule_node *reset_user( + __isl_take isl_schedule_node *node, void *user) +{ + return isl_schedule_node_reset_user(node); +} - start = band_nr ? schedule->node[i].band_end[band_nr - 1] : 0; - end = band_nr < schedule->node[i].n_band ? - schedule->node[i].band_end[band_nr] : start; - band->n = end - start; +/* Reset the user pointer on all identifiers of parameters and tuples + * in the schedule "schedule". + */ +__isl_give isl_schedule *isl_schedule_reset_user( + __isl_take isl_schedule *schedule) +{ + return isl_schedule_map_schedule_node_bottom_up(schedule, &reset_user, + NULL); +} - band->zero = isl_alloc_array(ctx, int, band->n); - if (band->n && !band->zero) - goto error; +/* Wrapper around isl_schedule_node_align_params for use as + * an isl_schedule_map_schedule_node_bottom_up callback. + */ +static __isl_give isl_schedule_node *align_params( + __isl_take isl_schedule_node *node, void *user) +{ + isl_space *space = user; - for (j = 0; j < band->n; ++j) - band->zero[j] = schedule->node[i].zero[start + j]; + return isl_schedule_node_align_params(node, isl_space_copy(space)); +} - band->pma = isl_union_pw_multi_aff_empty(isl_space_copy(schedule->dim)); - for (i = 0; i < schedule->n; ++i) { - isl_multi_aff *ma; - isl_pw_multi_aff *pma; - unsigned n_out; - - if (!active[i]) - continue; - - ma = isl_multi_aff_copy(schedule->node[i].sched); - n_out = isl_multi_aff_dim(ma, isl_dim_out); - ma = isl_multi_aff_drop_dims(ma, isl_dim_out, end, n_out - end); - ma = isl_multi_aff_drop_dims(ma, isl_dim_out, 0, start); - pma = isl_pw_multi_aff_from_multi_aff(ma); - band->pma = isl_union_pw_multi_aff_add_pw_multi_aff(band->pma, - pma); - } - if (!band->pma) - goto error; +/* Align the parameters of all nodes in schedule "schedule" + * to those of "space". + */ +__isl_give isl_schedule *isl_schedule_align_params( + __isl_take isl_schedule *schedule, __isl_take isl_space *space) +{ + schedule = isl_schedule_map_schedule_node_bottom_up(schedule, + &align_params, space); + isl_space_free(space); + return schedule; +} - for (i = 0; i < schedule->n; ++i) - if (active[i] && schedule->node[i].n_band > band_nr + 1) - break; - - if (i < schedule->n) { - band->children = construct_band_list(schedule, band, - band_nr + 1, active, n_active); - if (!band->children) - goto error; - } +/* Wrapper around isl_schedule_node_pullback_union_pw_multi_aff for use as + * an isl_schedule_map_schedule_node_bottom_up callback. + */ +static __isl_give isl_schedule_node *pullback_upma( + __isl_take isl_schedule_node *node, void *user) +{ + isl_union_pw_multi_aff *upma = user; - return band; -error: - isl_band_free(band); - return NULL; + return isl_schedule_node_pullback_union_pw_multi_aff(node, + isl_union_pw_multi_aff_copy(upma)); } -/* Internal data structure used inside cmp_band and pw_multi_aff_extract_int. - * - * r is set to a negative value if anything goes wrong. +/* Compute the pullback of "schedule" by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains of "schedule". * - * c1 stores the result of extract_int. - * c2 is a temporary value used inside cmp_band_in_ancestor. - * t is a temporary value used inside extract_int. - * - * first and equal are used inside extract_int. - * first is set if we are looking at the first isl_multi_aff inside - * the isl_union_pw_multi_aff. - * equal is set if all the isl_multi_affs have been equal so far. + * The schedule tree is not allowed to contain any expansion nodes. */ -struct isl_cmp_band_data { - int r; +__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff( + __isl_take isl_schedule *schedule, + __isl_take isl_union_pw_multi_aff *upma) +{ + schedule = isl_schedule_map_schedule_node_bottom_up(schedule, + &pullback_upma, upma); + isl_union_pw_multi_aff_free(upma); + return schedule; +} - int first; - int equal; +/* Intersect the domain of the schedule "schedule" with "domain". + * The root of "schedule" is required to be a domain node. + */ +__isl_give isl_schedule *isl_schedule_intersect_domain( + __isl_take isl_schedule *schedule, __isl_take isl_union_set *domain) +{ + enum isl_schedule_node_type root_type; + isl_schedule_node *node; - isl_int t; - isl_int c1; - isl_int c2; -}; + if (!schedule || !domain) + goto error; -/* Check if "ma" assigns a constant value. - * Note that this function is only called on isl_multi_affs - * with a single output dimension. - * - * If "ma" assigns a constant value then we compare it to data->c1 - * or assign it to data->c1 if this is the first isl_multi_aff we consider. - * If "ma" does not assign a constant value or if it assigns a value - * that is different from data->c1, then we set data->equal to zero - * and terminate the check. - */ -static int multi_aff_extract_int(__isl_take isl_set *set, - __isl_take isl_multi_aff *ma, void *user) -{ - isl_aff *aff; - struct isl_cmp_band_data *data = user; - - aff = isl_multi_aff_get_aff(ma, 0); - data->r = isl_aff_is_cst(aff); - if (data->r >= 0 && data->r) { - isl_aff_get_constant(aff, &data->t); - if (data->first) { - isl_int_set(data->c1, data->t); - data->first = 0; - } else if (!isl_int_eq(data->c1, data->t)) - data->equal = 0; - } else if (data->r >= 0 && !data->r) - data->equal = 0; - - isl_aff_free(aff); - isl_set_free(set); - isl_multi_aff_free(ma); + root_type = isl_schedule_tree_get_type(schedule->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid, + "root node must be a domain node", goto error); - if (data->r < 0) - return -1; - if (!data->equal) - return -1; - return 0; + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_domain_intersect_domain(node, domain); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +error: + isl_schedule_free(schedule); + isl_union_set_free(domain); + return NULL; } -/* This function is called for each isl_pw_multi_aff in - * the isl_union_pw_multi_aff checked by extract_int. - * Check all the isl_multi_affs inside "pma". +/* Return an isl_union_map representation of the schedule. + * If we still have access to the schedule tree, then we return + * an isl_union_map corresponding to the subtree schedule of the child + * of the root domain node. That is, we do not intersect the domain + * of the returned isl_union_map with the domain constraints. + * Otherwise, we must have removed it because we created a band forest. + * If so, we extract the isl_union_map from the forest. + * This reconstructed schedule map + * then needs to be padded with zeros to unify the schedule space + * since the result of isl_band_list_get_suffix_schedule may not have + * a unified schedule space. */ -static int pw_multi_aff_extract_int(__isl_take isl_pw_multi_aff *pma, - void *user) +__isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched) { - int r; + enum isl_schedule_node_type type; + isl_schedule_node *node; + isl_union_map *umap; - r = isl_pw_multi_aff_foreach_piece(pma, &multi_aff_extract_int, user); - isl_pw_multi_aff_free(pma); + if (!sched) + return NULL; - return r; -} + if (sched->root) { + type = isl_schedule_tree_get_type(sched->root); + if (type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(sched), isl_error_internal, + "root node not a domain node", return NULL); + + node = isl_schedule_get_root(sched); + node = isl_schedule_node_child(node, 0); + umap = isl_schedule_node_get_subtree_schedule_union_map(node); + isl_schedule_node_free(node); -/* Check if "upma" assigns a single constant value to its domain. - * If so, return 1 and store the result in data->c1. - * If not, return 0. - * - * A negative return value from isl_union_pw_multi_aff_foreach_pw_multi_aff - * means that either an error occurred or that we have broken off the check - * because we already know the result is going to be negative. - * In the latter case, data->equal is set to zero. - */ -static int extract_int(__isl_keep isl_union_pw_multi_aff *upma, - struct isl_cmp_band_data *data) -{ - data->first = 1; - data->equal = 1; - - if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, - &pw_multi_aff_extract_int, data) < 0) { - if (!data->equal) - return 0; - return -1; + return umap; } - return !data->first && data->equal; + umap = isl_band_list_get_suffix_schedule(sched->band_forest); + return pad_schedule_map(umap); } -/* Compare "b1" and "b2" based on the parent schedule of their ancestor - * "ancestor". - * - * If the parent of "ancestor" also has a single member, then we - * first try to compare the two band based on the partial schedule - * of this parent. - * - * Otherwise, or if the result is inconclusive, we look at the partial schedule - * of "ancestor" itself. - * In particular, we specialize the parent schedule based - * on the domains of the child schedules, check if both assign - * a single constant value and, if so, compare the two constant values. - * If the specialized parent schedules do not assign a constant value, - * then they cannot be used to order the two bands and so in this case - * we return 0. - */ -static int cmp_band_in_ancestor(__isl_keep isl_band *b1, - __isl_keep isl_band *b2, struct isl_cmp_band_data *data, - __isl_keep isl_band *ancestor) -{ - isl_union_pw_multi_aff *upma; - isl_union_set *domain; - int r; +static __isl_give isl_band_list *construct_band_list( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain, + __isl_keep isl_band *parent); - if (data->r < 0) - return 0; +/* Construct an isl_band structure from the given schedule tree node, + * which may be either a band node or a leaf node. + * In the latter case, construct a zero-dimensional band. + * "domain" is the universe set of the domain elements that reach "node". + * "parent" is the parent isl_band of the isl_band constructed + * by this function. + * + * In case of a band node, we copy the properties (except tilability, + * which is implicit in an isl_band) to the isl_band. + * We assume that the band node is not zero-dimensional. + * If the child of the band node is not a leaf node, + * then we extract the children of the isl_band from this child. + */ +static __isl_give isl_band *construct_band(__isl_take isl_schedule_node *node, + __isl_take isl_union_set *domain, __isl_keep isl_band *parent) +{ + int i; + isl_ctx *ctx; + isl_band *band = NULL; + isl_multi_union_pw_aff *mupa; - if (ancestor->parent && ancestor->parent->n == 1) { - r = cmp_band_in_ancestor(b1, b2, data, ancestor->parent); - if (data->r < 0) - return 0; - if (r) - return r; - } + if (!node || !domain) + goto error; - upma = isl_union_pw_multi_aff_copy(b1->pma); - domain = isl_union_pw_multi_aff_domain(upma); - upma = isl_union_pw_multi_aff_copy(ancestor->pma); - upma = isl_union_pw_multi_aff_intersect_domain(upma, domain); - r = extract_int(upma, data); - isl_union_pw_multi_aff_free(upma); + ctx = isl_schedule_node_get_ctx(node); + band = isl_band_alloc(ctx); + if (!band) + goto error; - if (r < 0) - data->r = -1; - if (r < 0 || !r) - return 0; - - isl_int_set(data->c2, data->c1); - - upma = isl_union_pw_multi_aff_copy(b2->pma); - domain = isl_union_pw_multi_aff_domain(upma); - upma = isl_union_pw_multi_aff_copy(ancestor->pma); - upma = isl_union_pw_multi_aff_intersect_domain(upma, domain); - r = extract_int(upma, data); - isl_union_pw_multi_aff_free(upma); + band->schedule = node->schedule; + band->parent = parent; - if (r < 0) - data->r = -1; - if (r < 0 || !r) - return 0; + if (isl_schedule_node_get_type(node) == isl_schedule_node_leaf) { + band->n = 0; + band->pma = isl_union_pw_multi_aff_from_domain(domain); + isl_schedule_node_free(node); + return band; + } + + band->n = isl_schedule_node_band_n_member(node); + if (band->n == 0) + isl_die(ctx, isl_error_unsupported, + "zero-dimensional band nodes not supported", + goto error); + band->coincident = isl_alloc_array(ctx, int, band->n); + if (band->n && !band->coincident) + goto error; + for (i = 0; i < band->n; ++i) + band->coincident[i] = + isl_schedule_node_band_member_get_coincident(node, i); + mupa = isl_schedule_node_band_get_partial_schedule(node); + band->pma = isl_union_pw_multi_aff_from_multi_union_pw_aff(mupa); + if (!band->pma) + goto error; - return isl_int_cmp(data->c2, data->c1); -} + node = isl_schedule_node_child(node, 0); + if (isl_schedule_node_get_type(node) == isl_schedule_node_leaf) { + isl_schedule_node_free(node); + isl_union_set_free(domain); + return band; + } -/* Compare "a" and "b" based on the parent schedule of their parent. - */ -static int cmp_band(const void *a, const void *b, void *user) -{ - isl_band *b1 = *(isl_band * const *) a; - isl_band *b2 = *(isl_band * const *) b; - struct isl_cmp_band_data *data = user; + band->children = construct_band_list(node, domain, band); + if (!band->children) + return isl_band_free(band); - return cmp_band_in_ancestor(b1, b2, data, b1->parent); + return band; +error: + isl_union_set_free(domain); + isl_schedule_node_free(node); + isl_band_free(band); + return NULL; } -/* Sort the elements in "list" based on the partial schedules of its parent - * (and ancestors). In particular if the parent assigns constant values - * to the domains of the bands in "list", then the elements are sorted - * according to that order. - * This order should be a more "natural" order for the user, but otherwise - * shouldn't have any effect. - * If we would be constructing an isl_band forest directly in - * isl_union_set_compute_schedule then there wouldn't be any need - * for a reordering, since the children would be added to the list - * in their natural order automatically. - * - * If there is only one element in the list, then there is no need to sort - * anything. - * If the partial schedule of the parent has more than one member - * (or if there is no parent), then it's - * defnitely not assigning constant values to the different children in - * the list and so we wouldn't be able to use it to sort the list. +/* Construct a list of isl_band structures from the children of "node". + * "node" itself is a sequence or set node, so that each of the child nodes + * is a filter node and the list returned by node_construct_band_list + * consists of a single element. + * "domain" is the universe set of the domain elements that reach "node". + * "parent" is the parent isl_band of the isl_band structures constructed + * by this function. */ -static __isl_give isl_band_list *sort_band_list(__isl_take isl_band_list *list, +static __isl_give isl_band_list *construct_band_list_from_children( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain, __isl_keep isl_band *parent) { - struct isl_cmp_band_data data; + int i, n; + isl_ctx *ctx; + isl_band_list *list; - if (!list) - return NULL; - if (list->n <= 1) - return list; - if (!parent || parent->n != 1) - return list; - - data.r = 0; - isl_int_init(data.c1); - isl_int_init(data.c2); - isl_int_init(data.t); - isl_sort(list->p, list->n, sizeof(list->p[0]), &cmp_band, &data); - if (data.r < 0) - list = isl_band_list_free(list); - isl_int_clear(data.c1); - isl_int_clear(data.c2); - isl_int_clear(data.t); + n = isl_schedule_node_n_children(node); + + ctx = isl_schedule_node_get_ctx(node); + list = isl_band_list_alloc(ctx, 0); + for (i = 0; i < n; ++i) { + isl_schedule_node *child; + isl_band_list *list_i; + + child = isl_schedule_node_get_child(node, i); + list_i = construct_band_list(child, isl_union_set_copy(domain), + parent); + list = isl_band_list_concat(list, list_i); + } + + isl_union_set_free(domain); + isl_schedule_node_free(node); return list; } -/* Construct a list of bands that start at the same position (with - * sequence number band_nr) in the schedules of the nodes that - * were active in the parent band. - * - * A separate isl_band structure is created for each band_id - * and for each node that does not have a band with sequence - * number band_nr. In the latter case, a band without members - * is created. - * This ensures that if a band has any children, then each node - * that was active in the band is active in exactly one of the children. +/* Construct an isl_band structure from the given sequence node + * (or set node that is treated as a sequence node). + * A single-dimensional band is created with as schedule for each of + * filters of the children, the corresponding child position. + * "domain" is the universe set of the domain elements that reach "node". + * "parent" is the parent isl_band of the isl_band constructed + * by this function. */ -static __isl_give isl_band_list *construct_band_list( - __isl_keep isl_schedule *schedule, __isl_keep isl_band *parent, - int band_nr, int *parent_active, int n_active) +static __isl_give isl_band_list *construct_band_list_sequence( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain, + __isl_keep isl_band *parent) { - int i, j; - isl_ctx *ctx = isl_schedule_get_ctx(schedule); - int *active; - int n_band; - isl_band_list *list; - - n_band = 0; - for (i = 0; i < n_active; ++i) { - for (j = 0; j < schedule->n; ++j) { - if (!parent_active[j]) - continue; - if (schedule->node[j].n_band <= band_nr) - continue; - if (schedule->node[j].band_id[band_nr] == i) { - n_band++; - break; - } - } - } - for (j = 0; j < schedule->n; ++j) - if (schedule->node[j].n_band <= band_nr) - n_band++; - - if (n_band == 1) { - isl_band *band; - list = isl_band_list_alloc(ctx, n_band); - band = construct_band(schedule, parent, band_nr, - parent_active, n_active); - return isl_band_list_add(list, band); - } + int i, n; + isl_ctx *ctx; + isl_band *band = NULL; + isl_space *space; + isl_union_pw_multi_aff *upma; - active = isl_alloc_array(ctx, int, schedule->n); - if (schedule->n && !active) - return NULL; + if (!node || !domain) + goto error; - list = isl_band_list_alloc(ctx, n_band); + ctx = isl_schedule_node_get_ctx(node); + band = isl_band_alloc(ctx); + if (!band) + goto error; - for (i = 0; i < n_active; ++i) { - int n = 0; - isl_band *band; + band->schedule = node->schedule; + band->parent = parent; + band->n = 1; + band->coincident = isl_calloc_array(ctx, int, band->n); + if (!band->coincident) + goto error; - for (j = 0; j < schedule->n; ++j) { - active[j] = parent_active[j] && - schedule->node[j].n_band > band_nr && - schedule->node[j].band_id[band_nr] == i; - if (active[j]) - n++; - } - if (n == 0) - continue; + n = isl_schedule_node_n_children(node); + space = isl_union_set_get_space(domain); + upma = isl_union_pw_multi_aff_empty(isl_space_copy(space)); - band = construct_band(schedule, parent, band_nr, active, n); + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, 1); - list = isl_band_list_add(list, band); - } - for (i = 0; i < schedule->n; ++i) { - isl_band *band; - if (!parent_active[i]) - continue; - if (schedule->node[i].n_band > band_nr) - continue; - for (j = 0; j < schedule->n; ++j) - active[j] = j == i; - band = construct_band(schedule, parent, band_nr, active, 1); - list = isl_band_list_add(list, band); + for (i = 0; i < n; ++i) { + isl_schedule_node *child; + isl_union_set *filter; + isl_val *v; + isl_val_list *vl; + isl_multi_val *mv; + isl_union_pw_multi_aff *upma_i; + + child = isl_schedule_node_get_child(node, i); + filter = isl_schedule_node_filter_get_filter(child); + isl_schedule_node_free(child); + filter = isl_union_set_intersect(filter, + isl_union_set_copy(domain)); + v = isl_val_int_from_si(ctx, i); + vl = isl_val_list_from_val(v); + mv = isl_multi_val_from_val_list(isl_space_copy(space), vl); + upma_i = isl_union_pw_multi_aff_multi_val_on_domain(filter, mv); + upma = isl_union_pw_multi_aff_union_add(upma, upma_i); } - free(active); + isl_space_free(space); - list = sort_band_list(list, parent); + band->pma = upma; + if (!band->pma) + goto error; - return list; + band->children = construct_band_list_from_children(node, domain, band); + if (!band->children) + band = isl_band_free(band); + return isl_band_list_from_band(band); +error: + isl_union_set_free(domain); + isl_schedule_node_free(node); + isl_band_free(band); + return NULL; } -/* Construct a band forest representation of the schedule and - * return the list of roots. +/* Construct a list of isl_band structures from "node" depending + * on the type of "node". + * "domain" is the universe set of the domain elements that reach "node". + * "parent" is the parent isl_band of the isl_band structures constructed + * by this function. + * + * If schedule_separate_components is set then set nodes are treated + * as sequence nodes. Otherwise, we directly extract an (implicitly + * parallel) list of isl_band structures. + * + * If "node" is a filter, then "domain" is updated by the filter. */ -static __isl_give isl_band_list *construct_forest( - __isl_keep isl_schedule *schedule) +static __isl_give isl_band_list *construct_band_list( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain, + __isl_keep isl_band *parent) { - int i; - isl_ctx *ctx = isl_schedule_get_ctx(schedule); - isl_band_list *forest; - int *active; - - active = isl_alloc_array(ctx, int, schedule->n); - if (schedule->n && !active) - return NULL; - - for (i = 0; i < schedule->n; ++i) - active[i] = 1; + enum isl_schedule_node_type type; + isl_ctx *ctx; + isl_band *band; + isl_band_list *list; + isl_union_set *filter; - forest = construct_band_list(schedule, NULL, 0, active, schedule->n); + if (!node || !domain) + goto error; - free(active); + type = isl_schedule_node_get_type(node); + switch (type) { + case isl_schedule_node_error: + goto error; + case isl_schedule_node_context: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "context nodes not supported", goto error); + case isl_schedule_node_domain: + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "internal domain nodes not allowed", goto error); + case isl_schedule_node_expansion: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "expansion nodes not supported", goto error); + case isl_schedule_node_extension: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "extension nodes not supported", goto error); + case isl_schedule_node_filter: + filter = isl_schedule_node_filter_get_filter(node); + domain = isl_union_set_intersect(domain, filter); + node = isl_schedule_node_child(node, 0); + return construct_band_list(node, domain, parent); + case isl_schedule_node_guard: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "guard nodes not supported", goto error); + case isl_schedule_node_mark: + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "mark nodes not supported", goto error); + case isl_schedule_node_set: + ctx = isl_schedule_node_get_ctx(node); + if (isl_options_get_schedule_separate_components(ctx)) + return construct_band_list_sequence(node, domain, + parent); + else + return construct_band_list_from_children(node, domain, + parent); + case isl_schedule_node_sequence: + return construct_band_list_sequence(node, domain, parent); + case isl_schedule_node_leaf: + case isl_schedule_node_band: + band = construct_band(node, domain, parent); + list = isl_band_list_from_band(band); + break; + } - return forest; + return list; +error: + isl_union_set_free(domain); + isl_schedule_node_free(node); + return NULL; } /* Return the roots of a band forest representation of the schedule. + * The band forest is constructed from the schedule tree, + * but once such a band forest is + * constructed, we forget about the original schedule tree since + * the user may modify the schedule through the band forest. */ __isl_give isl_band_list *isl_schedule_get_band_forest( __isl_keep isl_schedule *schedule) { + isl_schedule_node *node; + isl_union_set *domain; + if (!schedule) return NULL; - if (!schedule->band_forest) - schedule->band_forest = construct_forest(schedule); + if (schedule->root) { + node = isl_schedule_get_root(schedule); + domain = isl_schedule_node_domain_get_domain(node); + domain = isl_union_set_universe(domain); + node = isl_schedule_node_child(node, 0); + + schedule->band_forest = construct_band_list(node, domain, NULL); + schedule->root = isl_schedule_tree_free(schedule->root); + } return isl_band_list_dup(schedule->band_forest); } @@ -3613,11 +870,216 @@ return p; } +/* Insert a band node with partial schedule "partial" between the domain + * root node of "schedule" and its single child. + * Return a pointer to the updated schedule. + * + * If any of the nodes in the tree depend on the set of outer band nodes + * then we refuse to insert the band node. + */ +__isl_give isl_schedule *isl_schedule_insert_partial_schedule( + __isl_take isl_schedule *schedule, + __isl_take isl_multi_union_pw_aff *partial) +{ + isl_schedule_node *node; + int anchored; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + if (!node) + goto error; + if (isl_schedule_node_get_type(node) != isl_schedule_node_domain) + isl_die(isl_schedule_node_get_ctx(node), isl_error_internal, + "root node not a domain node", goto error); + + node = isl_schedule_node_child(node, 0); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert band node in anchored subtree", + goto error); + node = isl_schedule_node_insert_partial_schedule(node, partial); + + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +error: + isl_schedule_node_free(node); + isl_multi_union_pw_aff_free(partial); + return NULL; +} + +/* Insert a context node with constraints "context" between the domain + * root node of "schedule" and its single child. + * Return a pointer to the updated schedule. + */ +__isl_give isl_schedule *isl_schedule_insert_context( + __isl_take isl_schedule *schedule, __isl_take isl_set *context) +{ + isl_schedule_node *node; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_insert_context(node, context); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +} + +/* Insert a guard node with constraints "guard" between the domain + * root node of "schedule" and its single child. + * Return a pointer to the updated schedule. + */ +__isl_give isl_schedule *isl_schedule_insert_guard( + __isl_take isl_schedule *schedule, __isl_take isl_set *guard) +{ + isl_schedule_node *node; + + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_insert_guard(node, guard); + schedule = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + + return schedule; +} + +/* Return a tree with as top-level node a filter corresponding to "filter" and + * as child, the (single) child of "tree". + * However, if this single child is of type "type", then the filter is inserted + * in the children of this single child instead. + */ +static __isl_give isl_schedule_tree *insert_filter_in_child_of_type( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter, + enum isl_schedule_node_type type) +{ + if (!isl_schedule_tree_has_children(tree)) { + isl_schedule_tree_free(tree); + return isl_schedule_tree_from_filter(filter); + } else { + tree = isl_schedule_tree_child(tree, 0); + } + + if (isl_schedule_tree_get_type(tree) == type) + tree = isl_schedule_tree_children_insert_filter(tree, filter); + else + tree = isl_schedule_tree_insert_filter(tree, filter); + + return tree; +} + +/* Construct a schedule that combines the schedules "schedule1" and "schedule2" + * with a top-level node (underneath the domain node) of type "type", + * either isl_schedule_node_sequence or isl_schedule_node_set. + * The domains of the two schedules are assumed to be disjoint. + * + * The new schedule has as domain the union of the domains of the two + * schedules. The child of the domain node is a node of type "type" + * with two filters corresponding to the domains of the input schedules. + * If one (or both) of the top-level nodes of the two schedules is itself + * of type "type", then the filter is pushed into the children of that + * node and the sequence of set is flattened. + */ +__isl_give isl_schedule *isl_schedule_pair(enum isl_schedule_node_type type, + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2) +{ + int disjoint; + isl_ctx *ctx; + enum isl_schedule_node_type root_type; + isl_schedule_tree *tree1, *tree2; + isl_union_set *filter1, *filter2, *domain; + + if (!schedule1 || !schedule2) + goto error; + + root_type = isl_schedule_tree_get_type(schedule1->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule1), isl_error_internal, + "root node not a domain node", goto error); + root_type = isl_schedule_tree_get_type(schedule2->root); + if (root_type != isl_schedule_node_domain) + isl_die(isl_schedule_get_ctx(schedule1), isl_error_internal, + "root node not a domain node", goto error); + + ctx = isl_schedule_get_ctx(schedule1); + tree1 = isl_schedule_tree_copy(schedule1->root); + filter1 = isl_schedule_tree_domain_get_domain(tree1); + tree2 = isl_schedule_tree_copy(schedule2->root); + filter2 = isl_schedule_tree_domain_get_domain(tree2); + + isl_schedule_free(schedule1); + isl_schedule_free(schedule2); + + disjoint = isl_union_set_is_disjoint(filter1, filter2); + if (disjoint < 0) + filter1 = isl_union_set_free(filter1); + if (!disjoint) + isl_die(ctx, isl_error_invalid, + "schedule domains not disjoint", + filter1 = isl_union_set_free(filter1)); + + domain = isl_union_set_union(isl_union_set_copy(filter1), + isl_union_set_copy(filter2)); + filter1 = isl_union_set_gist(filter1, isl_union_set_copy(domain)); + filter2 = isl_union_set_gist(filter2, isl_union_set_copy(domain)); + + tree1 = insert_filter_in_child_of_type(tree1, filter1, type); + tree2 = insert_filter_in_child_of_type(tree2, filter2, type); + + tree1 = isl_schedule_tree_from_pair(type, tree1, tree2); + tree1 = isl_schedule_tree_insert_domain(tree1, domain); + + return isl_schedule_from_schedule_tree(ctx, tree1); +error: + isl_schedule_free(schedule1); + isl_schedule_free(schedule2); + return NULL; +} + +/* Construct a schedule that combines the schedules "schedule1" and "schedule2" + * through a sequence node. + * The domains of the input schedules are assumed to be disjoint. + */ +__isl_give isl_schedule *isl_schedule_sequence( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2) +{ + return isl_schedule_pair(isl_schedule_node_sequence, + schedule1, schedule2); +} + +/* Construct a schedule that combines the schedules "schedule1" and "schedule2" + * through a set node. + * The domains of the input schedules are assumed to be disjoint. + */ +__isl_give isl_schedule *isl_schedule_set( + __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2) +{ + return isl_schedule_pair(isl_schedule_node_set, schedule1, schedule2); +} + +/* Print "schedule" to "p". + * + * If "schedule" was created from a schedule tree, then we print + * the schedule tree representation. Otherwise, we print + * the band forest representation. + */ __isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p, __isl_keep isl_schedule *schedule) { isl_band_list *forest; + if (!schedule) + return isl_printer_free(p); + + if (schedule->root) + return isl_printer_print_schedule_tree(p, schedule->root); + forest = isl_schedule_get_band_forest(schedule); p = print_band_list(p, forest); @@ -3635,6 +1097,7 @@ return; printer = isl_printer_to_file(isl_schedule_get_ctx(schedule), stderr); + printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK); printer = isl_printer_print_schedule(printer, schedule); isl_printer_free(printer); diff -Nru isl-0.12.2/isl_schedule_node.c isl-0.15/isl_schedule_node.c --- isl-0.12.2/isl_schedule_node.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_node.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,4320 @@ +/* + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include +#include + +/* Create a new schedule node in the given schedule, point at the given + * tree with given ancestors and child positions. + * "child_pos" may be NULL if there are no ancestors. + */ +__isl_give isl_schedule_node *isl_schedule_node_alloc( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree, + __isl_take isl_schedule_tree_list *ancestors, int *child_pos) +{ + isl_ctx *ctx; + isl_schedule_node *node; + int i, n; + + if (!schedule || !tree || !ancestors) + goto error; + n = isl_schedule_tree_list_n_schedule_tree(ancestors); + if (n > 0 && !child_pos) + goto error; + ctx = isl_schedule_get_ctx(schedule); + node = isl_calloc_type(ctx, isl_schedule_node); + if (!node) + goto error; + node->ref = 1; + node->schedule = schedule; + node->tree = tree; + node->ancestors = ancestors; + node->child_pos = isl_alloc_array(ctx, int, n); + if (n && !node->child_pos) + return isl_schedule_node_free(node); + for (i = 0; i < n; ++i) + node->child_pos[i] = child_pos[i]; + + return node; +error: + isl_schedule_free(schedule); + isl_schedule_tree_free(tree); + isl_schedule_tree_list_free(ancestors); + return NULL; +} + +/* Return a pointer to the root of a schedule tree with as single + * node a domain node with the given domain. + */ +__isl_give isl_schedule_node *isl_schedule_node_from_domain( + __isl_take isl_union_set *domain) +{ + isl_schedule *schedule; + isl_schedule_node *node; + + schedule = isl_schedule_from_domain(domain); + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + + return node; +} + +/* Return a pointer to the root of a schedule tree with as single + * node a extension node with the given extension. + */ +__isl_give isl_schedule_node *isl_schedule_node_from_extension( + __isl_take isl_union_map *extension) +{ + isl_ctx *ctx; + isl_schedule *schedule; + isl_schedule_tree *tree; + isl_schedule_node *node; + + if (!extension) + return NULL; + + ctx = isl_union_map_get_ctx(extension); + tree = isl_schedule_tree_from_extension(extension); + schedule = isl_schedule_from_schedule_tree(ctx, tree); + node = isl_schedule_get_root(schedule); + isl_schedule_free(schedule); + + return node; +} + +/* Return the isl_ctx to which "node" belongs. + */ +isl_ctx *isl_schedule_node_get_ctx(__isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_get_ctx(node->schedule) : NULL; +} + +/* Return a pointer to the leaf of the schedule into which "node" points. + * + * Even though these leaves are not reference counted, we still + * indicate that this function does not return a copy. + */ +__isl_keep isl_schedule_tree *isl_schedule_node_peek_leaf( + __isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_peek_leaf(node->schedule) : NULL; +} + +/* Return a pointer to the leaf of the schedule into which "node" points. + * + * Even though these leaves are not reference counted, we still + * return a "copy" of the leaf here such that it can still be "freed" + * by the user. + */ +__isl_give isl_schedule_tree *isl_schedule_node_get_leaf( + __isl_keep isl_schedule_node *node) +{ + return isl_schedule_tree_copy(isl_schedule_node_peek_leaf(node)); +} + +/* Return the type of the node or isl_schedule_node_error on error. + */ +enum isl_schedule_node_type isl_schedule_node_get_type( + __isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_tree_get_type(node->tree) + : isl_schedule_node_error; +} + +/* Return the type of the parent of "node" or isl_schedule_node_error on error. + */ +enum isl_schedule_node_type isl_schedule_node_get_parent_type( + __isl_keep isl_schedule_node *node) +{ + int pos; + int has_parent; + isl_schedule_tree *parent; + enum isl_schedule_node_type type; + + if (!node) + return isl_schedule_node_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0) + return isl_schedule_node_error; + if (!has_parent) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no parent", return isl_schedule_node_error); + + pos = isl_schedule_tree_list_n_schedule_tree(node->ancestors) - 1; + parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, pos); + type = isl_schedule_tree_get_type(parent); + isl_schedule_tree_free(parent); + + return type; +} + +/* Return a copy of the subtree that this node points to. + */ +__isl_give isl_schedule_tree *isl_schedule_node_get_tree( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_copy(node->tree); +} + +/* Return a copy of the schedule into which "node" points. + */ +__isl_give isl_schedule *isl_schedule_node_get_schedule( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + return isl_schedule_copy(node->schedule); +} + +/* Return a fresh copy of "node". + */ +__isl_take isl_schedule_node *isl_schedule_node_dup( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_node_alloc(isl_schedule_copy(node->schedule), + isl_schedule_tree_copy(node->tree), + isl_schedule_tree_list_copy(node->ancestors), + node->child_pos); +} + +/* Return an isl_schedule_node that is equal to "node" and that has only + * a single reference. + */ +__isl_give isl_schedule_node *isl_schedule_node_cow( + __isl_take isl_schedule_node *node) +{ + if (!node) + return NULL; + + if (node->ref == 1) + return node; + node->ref--; + return isl_schedule_node_dup(node); +} + +/* Return a new reference to "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_copy( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + node->ref++; + return node; +} + +/* Free "node" and return NULL. + * + * Since the node may point to a leaf of its schedule, which + * point to a field inside the schedule, we need to make sure + * we free the tree before freeing the schedule. + */ +__isl_null isl_schedule_node *isl_schedule_node_free( + __isl_take isl_schedule_node *node) +{ + if (!node) + return NULL; + if (--node->ref > 0) + return NULL; + + isl_schedule_tree_list_free(node->ancestors); + free(node->child_pos); + isl_schedule_tree_free(node->tree); + isl_schedule_free(node->schedule); + free(node); + + return NULL; +} + +/* Do "node1" and "node2" point to the same position in the same + * schedule? + */ +isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2) +{ + int i, n1, n2; + + if (!node1 || !node2) + return isl_bool_error; + if (node1 == node2) + return isl_bool_true; + if (node1->schedule != node2->schedule) + return isl_bool_false; + + n1 = isl_schedule_node_get_tree_depth(node1); + n2 = isl_schedule_node_get_tree_depth(node2); + if (n1 != n2) + return isl_bool_false; + for (i = 0; i < n1; ++i) + if (node1->child_pos[i] != node2->child_pos[i]) + return isl_bool_false; + + return isl_bool_true; +} + +/* Return the number of outer schedule dimensions of "node" + * in its schedule tree. + * + * Return -1 on error. + */ +int isl_schedule_node_get_schedule_depth(__isl_keep isl_schedule_node *node) +{ + int i, n; + int depth = 0; + + if (!node) + return -1; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *tree; + + tree = isl_schedule_tree_list_get_schedule_tree( + node->ancestors, i); + if (!tree) + return -1; + if (tree->type == isl_schedule_node_band) + depth += isl_schedule_tree_band_n_member(tree); + isl_schedule_tree_free(tree); + } + + return depth; +} + +/* Internal data structure for + * isl_schedule_node_get_prefix_schedule_union_pw_multi_aff + * + * "initialized" is set if the filter field has been initialized. + * If "universe_domain" is not set, then the collected filter is intersected + * with the the domain of the root domain node. + * "universe_filter" is set if we are only collecting the universes of filters + * "collect_prefix" is set if we are collecting prefixes. + * "filter" collects all outer filters and is NULL until "initialized" is set. + * "prefix" collects all outer band partial schedules (if "collect_prefix" + * is set). If it is used, then it is initialized by the caller + * of collect_filter_prefix to a zero-dimensional function. + */ +struct isl_schedule_node_get_filter_prefix_data { + int initialized; + int universe_domain; + int universe_filter; + int collect_prefix; + isl_union_set *filter; + isl_multi_union_pw_aff *prefix; +}; + +static int collect_filter_prefix(__isl_keep isl_schedule_tree_list *list, + int n, struct isl_schedule_node_get_filter_prefix_data *data); + +/* Update the filter and prefix information in "data" based on the first "n" + * elements in "list" and the expansion tree root "tree". + * + * We first collect the information from the elements in "list", + * initializing the filter based on the domain of the expansion. + * Then we map the results to the expanded space and combined them + * with the results already in "data". + */ +static int collect_filter_prefix_expansion(__isl_take isl_schedule_tree *tree, + __isl_keep isl_schedule_tree_list *list, int n, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + struct isl_schedule_node_get_filter_prefix_data contracted; + isl_union_pw_multi_aff *c; + isl_union_map *exp, *universe; + isl_union_set *filter; + + c = isl_schedule_tree_expansion_get_contraction(tree); + exp = isl_schedule_tree_expansion_get_expansion(tree); + + contracted.initialized = 1; + contracted.universe_domain = data->universe_domain; + contracted.universe_filter = data->universe_filter; + contracted.collect_prefix = data->collect_prefix; + universe = isl_union_map_universe(isl_union_map_copy(exp)); + filter = isl_union_map_domain(universe); + if (data->collect_prefix) { + isl_space *space = isl_union_set_get_space(filter); + space = isl_space_set_from_params(space); + contracted.prefix = isl_multi_union_pw_aff_zero(space); + } + contracted.filter = filter; + + if (collect_filter_prefix(list, n, &contracted) < 0) + contracted.filter = isl_union_set_free(contracted.filter); + if (data->collect_prefix) { + isl_multi_union_pw_aff *prefix; + + prefix = contracted.prefix; + prefix = + isl_multi_union_pw_aff_pullback_union_pw_multi_aff(prefix, + isl_union_pw_multi_aff_copy(c)); + data->prefix = isl_multi_union_pw_aff_flat_range_product( + prefix, data->prefix); + } + filter = contracted.filter; + if (data->universe_domain) + filter = isl_union_set_preimage_union_pw_multi_aff(filter, + isl_union_pw_multi_aff_copy(c)); + else + filter = isl_union_set_apply(filter, isl_union_map_copy(exp)); + if (!data->initialized) + data->filter = filter; + else + data->filter = isl_union_set_intersect(filter, data->filter); + data->initialized = 1; + + isl_union_pw_multi_aff_free(c); + isl_union_map_free(exp); + isl_schedule_tree_free(tree); + + return 0; +} + +/* Update the filter information in "data" based on the first "n" + * elements in "list" and the extension tree root "tree", in case + * data->universe_domain is set and data->collect_prefix is not. + * + * We collect the universe domain of the elements in "list" and + * add it to the universe range of the extension (intersected + * with the already collected filter, if any). + */ +static int collect_universe_domain_extension(__isl_take isl_schedule_tree *tree, + __isl_keep isl_schedule_tree_list *list, int n, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + struct isl_schedule_node_get_filter_prefix_data data_outer; + isl_union_map *extension; + isl_union_set *filter; + + data_outer.initialized = 0; + data_outer.universe_domain = 1; + data_outer.universe_filter = data->universe_filter; + data_outer.collect_prefix = 0; + data_outer.filter = NULL; + data_outer.prefix = NULL; + + if (collect_filter_prefix(list, n, &data_outer) < 0) + data_outer.filter = isl_union_set_free(data_outer.filter); + + extension = isl_schedule_tree_extension_get_extension(tree); + extension = isl_union_map_universe(extension); + filter = isl_union_map_range(extension); + if (data_outer.initialized) + filter = isl_union_set_union(filter, data_outer.filter); + if (data->initialized) + filter = isl_union_set_intersect(filter, data->filter); + + data->filter = filter; + + isl_schedule_tree_free(tree); + + return 0; +} + +/* Update "data" based on the tree node "tree" in case "data" has + * not been initialized yet. + * + * Return 0 on success and -1 on error. + * + * If "tree" is a filter, then we set data->filter to this filter + * (or its universe). + * If "tree" is a domain, then this means we have reached the root + * of the schedule tree without being able to extract any information. + * We therefore initialize data->filter to the universe of the domain, + * or the domain itself if data->universe_domain is not set. + * If "tree" is a band with at least one member, then we set data->filter + * to the universe of the schedule domain and replace the zero-dimensional + * data->prefix by the band schedule (if data->collect_prefix is set). + */ +static int collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + enum isl_schedule_node_type type; + isl_multi_union_pw_aff *mupa; + isl_union_set *filter; + + type = isl_schedule_tree_get_type(tree); + switch (type) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_expansion: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "should be handled by caller", return -1); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot handle extension nodes", return -1); + case isl_schedule_node_context: + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return 0; + case isl_schedule_node_domain: + filter = isl_schedule_tree_domain_get_domain(tree); + if (data->universe_domain) + filter = isl_union_set_universe(filter); + data->filter = filter; + break; + case isl_schedule_node_band: + if (isl_schedule_tree_band_n_member(tree) == 0) + return 0; + mupa = isl_schedule_tree_band_get_partial_schedule(tree); + if (data->collect_prefix) { + isl_multi_union_pw_aff_free(data->prefix); + mupa = isl_multi_union_pw_aff_reset_tuple_id(mupa, + isl_dim_set); + data->prefix = isl_multi_union_pw_aff_copy(mupa); + } + filter = isl_multi_union_pw_aff_domain(mupa); + filter = isl_union_set_universe(filter); + data->filter = filter; + break; + case isl_schedule_node_filter: + filter = isl_schedule_tree_filter_get_filter(tree); + if (data->universe_filter) + filter = isl_union_set_universe(filter); + data->filter = filter; + break; + } + + if ((data->collect_prefix && !data->prefix) || !data->filter) + return -1; + + data->initialized = 1; + + return 0; +} + +/* Update "data" based on the tree node "tree" in case "data" has + * already been initialized. + * + * Return 0 on success and -1 on error. + * + * If "tree" is a domain and data->universe_domain is not set, then + * intersect data->filter with the domain. + * If "tree" is a filter, then we intersect data->filter with this filter + * (or its universe). + * If "tree" is a band with at least one member and data->collect_prefix + * is set, then we extend data->prefix with the band schedule. + * If "tree" is an extension, then we make sure that we are not collecting + * information on any extended domain elements. + */ +static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree, + struct isl_schedule_node_get_filter_prefix_data *data) +{ + enum isl_schedule_node_type type; + isl_multi_union_pw_aff *mupa; + isl_union_set *filter; + isl_union_map *extension; + int empty; + + type = isl_schedule_tree_get_type(tree); + switch (type) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_expansion: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "should be handled by caller", return -1); + case isl_schedule_node_extension: + extension = isl_schedule_tree_extension_get_extension(tree); + extension = isl_union_map_intersect_range(extension, + isl_union_set_copy(data->filter)); + empty = isl_union_map_is_empty(extension); + isl_union_map_free(extension); + if (empty < 0) + return -1; + if (empty) + break; + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot handle extension nodes", return -1); + case isl_schedule_node_context: + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + case isl_schedule_node_domain: + if (data->universe_domain) + break; + filter = isl_schedule_tree_domain_get_domain(tree); + data->filter = isl_union_set_intersect(data->filter, filter); + break; + case isl_schedule_node_band: + if (isl_schedule_tree_band_n_member(tree) == 0) + break; + if (!data->collect_prefix) + break; + mupa = isl_schedule_tree_band_get_partial_schedule(tree); + data->prefix = isl_multi_union_pw_aff_flat_range_product(mupa, + data->prefix); + if (!data->prefix) + return -1; + break; + case isl_schedule_node_filter: + filter = isl_schedule_tree_filter_get_filter(tree); + if (data->universe_filter) + filter = isl_union_set_universe(filter); + data->filter = isl_union_set_intersect(data->filter, filter); + if (!data->filter) + return -1; + break; + } + + return 0; +} + +/* Collect filter and/or prefix information from the first "n" + * elements in "list" (which represent the ancestors of a node). + * Store the results in "data". + * + * Extension nodes are only supported if they do not affect the outcome, + * i.e., if we are collecting information on non-extended domain elements, + * or if we are collecting the universe domain (without prefix). + * + * Return 0 on success and -1 on error. + * + * We traverse the list from innermost ancestor (last element) + * to outermost ancestor (first element), calling collect_filter_prefix_init + * on each node as long as we have not been able to extract any information + * yet and collect_filter_prefix_update afterwards. + * If we come across an expansion node, then we interrupt the traversal + * and call collect_filter_prefix_expansion to restart the traversal + * over the remaining ancestors and to combine the results with those + * that have already been collected. + * If we come across an extension node and we are only computing + * the universe domain, then we interrupt the traversal and call + * collect_universe_domain_extension to restart the traversal + * over the remaining ancestors and to combine the results with those + * that have already been collected. + * On successful return, data->initialized will be set since the outermost + * ancestor is a domain node, which always results in an initialization. + */ +static int collect_filter_prefix(__isl_keep isl_schedule_tree_list *list, + int n, struct isl_schedule_node_get_filter_prefix_data *data) +{ + int i; + + if (!list) + return -1; + + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *tree; + enum isl_schedule_node_type type; + int r; + + tree = isl_schedule_tree_list_get_schedule_tree(list, i); + if (!tree) + return -1; + type = isl_schedule_tree_get_type(tree); + if (type == isl_schedule_node_expansion) + return collect_filter_prefix_expansion(tree, list, i, + data); + if (type == isl_schedule_node_extension && + data->universe_domain && !data->collect_prefix) + return collect_universe_domain_extension(tree, list, i, + data); + if (!data->initialized) + r = collect_filter_prefix_init(tree, data); + else + r = collect_filter_prefix_update(tree, data); + isl_schedule_tree_free(tree); + if (r < 0) + return -1; + } + + return 0; +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" interesected with all outer filters + * as an isl_multi_union_pw_aff. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * + * We collect all the filters and partial schedules in collect_filter_prefix + * and intersect the domain of the combined schedule with the combined filter. + */ +__isl_give isl_multi_union_pw_aff * +isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( + __isl_keep isl_schedule_node *node) +{ + int n; + isl_space *space; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + space = isl_schedule_get_space(node->schedule); + space = isl_space_set_from_params(space); + if (node->tree == node->schedule->root) + return isl_multi_union_pw_aff_zero(space); + + data.initialized = 0; + data.universe_domain = 1; + data.universe_filter = 0; + data.collect_prefix = 1; + data.filter = NULL; + data.prefix = isl_multi_union_pw_aff_zero(space); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (collect_filter_prefix(node->ancestors, n, &data) < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + + data.prefix = isl_multi_union_pw_aff_intersect_domain(data.prefix, + data.filter); + + return data.prefix; +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" interesected with all outer filters + * as an isl_union_pw_multi_aff. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * + * We collect all the filters and partial schedules in collect_filter_prefix. + * The partial schedules are collected as an isl_multi_union_pw_aff. + * If this isl_multi_union_pw_aff is zero-dimensional, then it does not + * contain any domain information, so we construct the isl_union_pw_multi_aff + * result as a zero-dimensional function on the collected filter. + * Otherwise, we convert the isl_multi_union_pw_aff to + * an isl_multi_union_pw_aff and intersect the domain with the filter. + */ +__isl_give isl_union_pw_multi_aff * +isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( + __isl_keep isl_schedule_node *node) +{ + int n; + isl_space *space; + isl_union_pw_multi_aff *prefix; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + space = isl_schedule_get_space(node->schedule); + if (node->tree == node->schedule->root) + return isl_union_pw_multi_aff_empty(space); + + space = isl_space_set_from_params(space); + data.initialized = 0; + data.universe_domain = 1; + data.universe_filter = 0; + data.collect_prefix = 1; + data.filter = NULL; + data.prefix = isl_multi_union_pw_aff_zero(space); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (collect_filter_prefix(node->ancestors, n, &data) < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + + if (data.prefix && + isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set) == 0) { + isl_multi_union_pw_aff_free(data.prefix); + prefix = isl_union_pw_multi_aff_from_domain(data.filter); + } else { + prefix = + isl_union_pw_multi_aff_from_multi_union_pw_aff(data.prefix); + prefix = isl_union_pw_multi_aff_intersect_domain(prefix, + data.filter); + } + + return prefix; +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" interesected with all outer filters + * as an isl_union_map. + */ +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map( + __isl_keep isl_schedule_node *node) +{ + isl_union_pw_multi_aff *upma; + + upma = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); + return isl_union_map_from_union_pw_multi_aff(upma); +} + +/* Return the concatenation of the partial schedules of all outer band + * nodes of "node" intersected with all outer domain constraints. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * Essentially, this functions intersected the domain of the output + * of isl_schedule_node_get_prefix_schedule_union_map with the output + * of isl_schedule_node_get_domain, except that it only traverses + * the ancestors of "node" once. + */ +__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation( + __isl_keep isl_schedule_node *node) +{ + int n; + isl_space *space; + isl_union_map *prefix; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + space = isl_schedule_get_space(node->schedule); + if (node->tree == node->schedule->root) + return isl_union_map_empty(space); + + space = isl_space_set_from_params(space); + data.initialized = 0; + data.universe_domain = 0; + data.universe_filter = 0; + data.collect_prefix = 1; + data.filter = NULL; + data.prefix = isl_multi_union_pw_aff_zero(space); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (collect_filter_prefix(node->ancestors, n, &data) < 0) + data.prefix = isl_multi_union_pw_aff_free(data.prefix); + + if (data.prefix && + isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set) == 0) { + isl_multi_union_pw_aff_free(data.prefix); + prefix = isl_union_map_from_domain(data.filter); + } else { + prefix = isl_union_map_from_multi_union_pw_aff(data.prefix); + prefix = isl_union_map_intersect_domain(prefix, data.filter); + } + + return prefix; +} + +/* Return the domain elements that reach "node". + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * None of the ancestors of "node" may be an extension node, unless + * there is also a filter ancestor that filters out all the extended + * domain elements. + * + * Otherwise, we collect all filters reaching the node, + * intersected with the root domain in collect_filter_prefix. + */ +__isl_give isl_union_set *isl_schedule_node_get_domain( + __isl_keep isl_schedule_node *node) +{ + int n; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + if (node->tree == node->schedule->root) { + isl_space *space; + + space = isl_schedule_get_space(node->schedule); + return isl_union_set_empty(space); + } + + data.initialized = 0; + data.universe_domain = 0; + data.universe_filter = 0; + data.collect_prefix = 0; + data.filter = NULL; + data.prefix = NULL; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (collect_filter_prefix(node->ancestors, n, &data) < 0) + data.filter = isl_union_set_free(data.filter); + + return data.filter; +} + +/* Return the union of universe sets of the domain elements that reach "node". + * + * If "node" is pointing at the root of the schedule tree, then + * there are no domain elements reaching the current node, so + * we return an empty result. + * + * Otherwise, we collect the universes of all filters reaching the node + * in collect_filter_prefix. + */ +__isl_give isl_union_set *isl_schedule_node_get_universe_domain( + __isl_keep isl_schedule_node *node) +{ + int n; + struct isl_schedule_node_get_filter_prefix_data data; + + if (!node) + return NULL; + + if (node->tree == node->schedule->root) { + isl_space *space; + + space = isl_schedule_get_space(node->schedule); + return isl_union_set_empty(space); + } + + data.initialized = 0; + data.universe_domain = 1; + data.universe_filter = 1; + data.collect_prefix = 0; + data.filter = NULL; + data.prefix = NULL; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (collect_filter_prefix(node->ancestors, n, &data) < 0) + data.filter = isl_union_set_free(data.filter); + + return data.filter; +} + +/* Return the subtree schedule of "node". + * + * Since isl_schedule_tree_get_subtree_schedule_union_map does not handle + * trees that do not contain any schedule information, we first + * move down to the first relevant descendant and handle leaves ourselves. + * + * If the subtree rooted at "node" contains any expansion nodes, then + * the returned subtree schedule is formulated in terms of the expanded + * domains. + * The subtree is not allowed to contain any extension nodes. + */ +__isl_give isl_union_map *isl_schedule_node_get_subtree_schedule_union_map( + __isl_keep isl_schedule_node *node) +{ + isl_schedule_tree *tree, *leaf; + isl_union_map *umap; + + tree = isl_schedule_node_get_tree(node); + leaf = isl_schedule_node_peek_leaf(node); + tree = isl_schedule_tree_first_schedule_descendant(tree, leaf); + if (!tree) + return NULL; + if (tree == leaf) { + isl_union_set *domain; + domain = isl_schedule_node_get_universe_domain(node); + isl_schedule_tree_free(tree); + return isl_union_map_from_domain(domain); + } + + umap = isl_schedule_tree_get_subtree_schedule_union_map(tree); + isl_schedule_tree_free(tree); + return umap; +} + +/* Return the number of ancestors of "node" in its schedule tree. + */ +int isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node) +{ + if (!node) + return -1; + return isl_schedule_tree_list_n_schedule_tree(node->ancestors); +} + +/* Does "node" have a parent? + * + * That is, does it point to any node of the schedule other than the root? + */ +isl_bool isl_schedule_node_has_parent(__isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + if (!node->ancestors) + return isl_bool_error; + + return isl_schedule_tree_list_n_schedule_tree(node->ancestors) != 0; +} + +/* Return the position of "node" among the children of its parent. + */ +int isl_schedule_node_get_child_position(__isl_keep isl_schedule_node *node) +{ + int n; + int has_parent; + + if (!node) + return -1; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0) + return -1; + if (!has_parent) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no parent", return -1); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + return node->child_pos[n - 1]; +} + +/* Does the parent (if any) of "node" have any children with a smaller child + * position than this one? + */ +isl_bool isl_schedule_node_has_previous_sibling( + __isl_keep isl_schedule_node *node) +{ + int n; + isl_bool has_parent; + + if (!node) + return isl_bool_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0 || !has_parent) + return has_parent; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + + return node->child_pos[n - 1] > 0; +} + +/* Does the parent (if any) of "node" have any children with a greater child + * position than this one? + */ +isl_bool isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node) +{ + int n, n_child; + isl_bool has_parent; + isl_schedule_tree *tree; + + if (!node) + return isl_bool_error; + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0 || !has_parent) + return has_parent; + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n - 1); + if (!tree) + return isl_bool_error; + n_child = isl_schedule_tree_list_n_schedule_tree(tree->children); + isl_schedule_tree_free(tree); + + return node->child_pos[n - 1] + 1 < n_child; +} + +/* Does "node" have any children? + * + * Any node other than the leaf nodes is considered to have at least + * one child, even if the corresponding isl_schedule_tree does not + * have any children. + */ +isl_bool isl_schedule_node_has_children(__isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + return !isl_schedule_tree_is_leaf(node->tree); +} + +/* Return the number of children of "node"? + * + * Any node other than the leaf nodes is considered to have at least + * one child, even if the corresponding isl_schedule_tree does not + * have any children. That is, the number of children of "node" is + * only zero if its tree is the explicit empty tree. Otherwise, + * if the isl_schedule_tree has any children, then it is equal + * to the number of children of "node". If it has zero children, + * then "node" still has a leaf node as child. + */ +int isl_schedule_node_n_children(__isl_keep isl_schedule_node *node) +{ + int n; + + if (!node) + return -1; + + if (isl_schedule_tree_is_leaf(node->tree)) + return 0; + + n = isl_schedule_tree_n_children(node->tree); + if (n == 0) + return 1; + + return n; +} + +/* Move the "node" pointer to the ancestor of the given generation + * of the node it currently points to, where generation 0 is the node + * itself and generation 1 is its parent. + */ +__isl_give isl_schedule_node *isl_schedule_node_ancestor( + __isl_take isl_schedule_node *node, int generation) +{ + int n; + isl_schedule_tree *tree; + + if (!node) + return NULL; + if (generation == 0) + return node; + n = isl_schedule_node_get_tree_depth(node); + if (n < 0) + return isl_schedule_node_free(node); + if (generation < 0 || generation > n) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "generation out of bounds", + return isl_schedule_node_free(node)); + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n - generation); + isl_schedule_tree_free(node->tree); + node->tree = tree; + node->ancestors = isl_schedule_tree_list_drop(node->ancestors, + n - generation, generation); + if (!node->ancestors || !node->tree) + return isl_schedule_node_free(node); + + return node; +} + +/* Move the "node" pointer to the parent of the node it currently points to. + */ +__isl_give isl_schedule_node *isl_schedule_node_parent( + __isl_take isl_schedule_node *node) +{ + if (!node) + return NULL; + if (!isl_schedule_node_has_parent(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no parent", + return isl_schedule_node_free(node)); + return isl_schedule_node_ancestor(node, 1); +} + +/* Move the "node" pointer to the root of its schedule tree. + */ +__isl_give isl_schedule_node *isl_schedule_node_root( + __isl_take isl_schedule_node *node) +{ + int n; + + if (!node) + return NULL; + n = isl_schedule_node_get_tree_depth(node); + if (n < 0) + return isl_schedule_node_free(node); + return isl_schedule_node_ancestor(node, n); +} + +/* Move the "node" pointer to the child at position "pos" of the node + * it currently points to. + */ +__isl_give isl_schedule_node *isl_schedule_node_child( + __isl_take isl_schedule_node *node, int pos) +{ + int n; + isl_ctx *ctx; + isl_schedule_tree *tree; + int *child_pos; + + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + if (!isl_schedule_node_has_children(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no children", + return isl_schedule_node_free(node)); + + ctx = isl_schedule_node_get_ctx(node); + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + child_pos = isl_realloc_array(ctx, node->child_pos, int, n + 1); + if (!child_pos) + return isl_schedule_node_free(node); + node->child_pos = child_pos; + node->child_pos[n] = pos; + + node->ancestors = isl_schedule_tree_list_add(node->ancestors, + isl_schedule_tree_copy(node->tree)); + tree = node->tree; + if (isl_schedule_tree_has_children(tree)) + tree = isl_schedule_tree_get_child(tree, pos); + else + tree = isl_schedule_node_get_leaf(node); + isl_schedule_tree_free(node->tree); + node->tree = tree; + + if (!node->tree || !node->ancestors) + return isl_schedule_node_free(node); + + return node; +} + +/* Move the "node" pointer to the first child of the node + * it currently points to. + */ +__isl_give isl_schedule_node *isl_schedule_node_first_child( + __isl_take isl_schedule_node *node) +{ + return isl_schedule_node_child(node, 0); +} + +/* Move the "node" pointer to the child of this node's parent in + * the previous child position. + */ +__isl_give isl_schedule_node *isl_schedule_node_previous_sibling( + __isl_take isl_schedule_node *node) +{ + int n; + isl_schedule_tree *parent, *tree; + + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + if (!isl_schedule_node_has_previous_sibling(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no previous sibling", + return isl_schedule_node_free(node)); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n - 1); + if (!parent) + return isl_schedule_node_free(node); + node->child_pos[n - 1]--; + tree = isl_schedule_tree_list_get_schedule_tree(parent->children, + node->child_pos[n - 1]); + isl_schedule_tree_free(parent); + if (!tree) + return isl_schedule_node_free(node); + isl_schedule_tree_free(node->tree); + node->tree = tree; + + return node; +} + +/* Move the "node" pointer to the child of this node's parent in + * the next child position. + */ +__isl_give isl_schedule_node *isl_schedule_node_next_sibling( + __isl_take isl_schedule_node *node) +{ + int n; + isl_schedule_tree *parent, *tree; + + node = isl_schedule_node_cow(node); + if (!node) + return NULL; + if (!isl_schedule_node_has_next_sibling(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "node has no next sibling", + return isl_schedule_node_free(node)); + + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n - 1); + if (!parent) + return isl_schedule_node_free(node); + node->child_pos[n - 1]++; + tree = isl_schedule_tree_list_get_schedule_tree(parent->children, + node->child_pos[n - 1]); + isl_schedule_tree_free(parent); + if (!tree) + return isl_schedule_node_free(node); + isl_schedule_tree_free(node->tree); + node->tree = tree; + + return node; +} + +/* Return a copy to the child at position "pos" of "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_get_child( + __isl_keep isl_schedule_node *node, int pos) +{ + return isl_schedule_node_child(isl_schedule_node_copy(node), pos); +} + +/* Traverse the descendant of "node" in depth-first order, including + * "node" itself. Call "enter" whenever a node is entered and "leave" + * whenever a node is left. The callback "enter" is responsible + * for moving to the deepest initial subtree of its argument that + * should be traversed. + */ +static __isl_give isl_schedule_node *traverse( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*enter)( + __isl_take isl_schedule_node *node, void *user), + __isl_give isl_schedule_node *(*leave)( + __isl_take isl_schedule_node *node, void *user), + void *user) +{ + int depth; + + if (!node) + return NULL; + + depth = isl_schedule_node_get_tree_depth(node); + do { + node = enter(node, user); + node = leave(node, user); + while (node && isl_schedule_node_get_tree_depth(node) > depth && + !isl_schedule_node_has_next_sibling(node)) { + node = isl_schedule_node_parent(node); + node = leave(node, user); + } + if (node && isl_schedule_node_get_tree_depth(node) > depth) + node = isl_schedule_node_next_sibling(node); + } while (node && isl_schedule_node_get_tree_depth(node) > depth); + + return node; +} + +/* Internal data structure for isl_schedule_node_foreach_descendant_top_down. + * + * "fn" is the user-specified callback function. + * "user" is the user-specified argument for the callback. + */ +struct isl_schedule_node_preorder_data { + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user); + void *user; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * for use in a preorder visit. + * + * If the user callback returns a negative value, then we abort + * the traversal. If this callback returns zero, then we skip + * the subtree rooted at the current node. Otherwise, we move + * down to the first child and repeat the process until a leaf + * is reached. + */ +static __isl_give isl_schedule_node *preorder_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_schedule_node_preorder_data *data = user; + + if (!node) + return NULL; + + do { + isl_bool r; + + r = data->fn(node, data->user); + if (r < 0) + return isl_schedule_node_free(node); + if (r == isl_bool_false) + return node; + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node + * for use in a preorder visit. + * Since we already visited the node when we entered it, + * we do not need to do anything here. + */ +static __isl_give isl_schedule_node *preorder_leave( + __isl_take isl_schedule_node *node, void *user) +{ + return node; +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth first preorder. + * + * If "fn" returns -1 on any of the nodes, then the traversal is aborted. + * If "fn" returns 0 on any of the nodes, then the subtree rooted + * at that node is skipped. + * + * Return 0 on success and -1 on failure. + */ +isl_stat isl_schedule_node_foreach_descendant_top_down( + __isl_keep isl_schedule_node *node, + isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user) +{ + struct isl_schedule_node_preorder_data data = { fn, user }; + + node = isl_schedule_node_copy(node); + node = traverse(node, &preorder_enter, &preorder_leave, &data); + isl_schedule_node_free(node); + + return node ? isl_stat_ok : isl_stat_error; +} + +/* Internal data structure for isl_schedule_node_map_descendant_bottom_up. + * + * "fn" is the user-specified callback function. + * "user" is the user-specified argument for the callback. + */ +struct isl_schedule_node_postorder_data { + __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, + void *user); + void *user; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * for use in a postorder visit. + * + * Since we are performing a postorder visit, we only need + * to move to the deepest initial leaf here. + */ +static __isl_give isl_schedule_node *postorder_enter( + __isl_take isl_schedule_node *node, void *user) +{ + while (node && isl_schedule_node_has_children(node)) + node = isl_schedule_node_first_child(node); + + return node; +} + +/* Callback for "traverse" to leave a node + * for use in a postorder visit. + * + * Since we are performing a postorder visit, we need + * to call the user callback here. + */ +static __isl_give isl_schedule_node *postorder_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_schedule_node_postorder_data *data = user; + + return data->fn(node, data->user); +} + +/* Traverse the descendants of "node" (including the node itself) + * in depth first postorder, allowing the user to modify the visited node. + * The traversal continues from the node returned by the callback function. + * It is the responsibility of the user to ensure that this does not + * lead to an infinite loop. It is safest to always return a pointer + * to the same position (same ancestors and child positions) as the input node. + */ +__isl_give isl_schedule_node *isl_schedule_node_map_descendant_bottom_up( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node, + void *user), void *user) +{ + struct isl_schedule_node_postorder_data data = { fn, user }; + + return traverse(node, &postorder_enter, &postorder_leave, &data); +} + +/* Traverse the ancestors of "node" from the root down to and including + * the parent of "node", calling "fn" on each of them. + * + * If "fn" returns -1 on any of the nodes, then the traversal is aborted. + * + * Return 0 on success and -1 on failure. + */ +isl_stat isl_schedule_node_foreach_ancestor_top_down( + __isl_keep isl_schedule_node *node, + isl_stat (*fn)(__isl_keep isl_schedule_node *node, void *user), + void *user) +{ + int i, n; + + if (!node) + return isl_stat_error; + + n = isl_schedule_node_get_tree_depth(node); + for (i = 0; i < n; ++i) { + isl_schedule_node *ancestor; + isl_stat r; + + ancestor = isl_schedule_node_copy(node); + ancestor = isl_schedule_node_ancestor(ancestor, n - i); + r = fn(ancestor, user); + isl_schedule_node_free(ancestor); + if (r < 0) + return isl_stat_error; + } + + return isl_stat_ok; +} + +/* Is any node in the subtree rooted at "node" anchored? + * That is, do any of these nodes reference the outer band nodes? + */ +isl_bool isl_schedule_node_is_subtree_anchored( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + return isl_schedule_tree_is_subtree_anchored(node->tree); +} + +/* Return the number of members in the given band node. + */ +unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node) +{ + return node ? isl_schedule_tree_band_n_member(node->tree) : 0; +} + +/* Is the band member at position "pos" of the band node "node" + * marked coincident? + */ +isl_bool isl_schedule_node_band_member_get_coincident( + __isl_keep isl_schedule_node *node, int pos) +{ + if (!node) + return isl_bool_error; + return isl_schedule_tree_band_member_get_coincident(node->tree, pos); +} + +/* Mark the band member at position "pos" the band node "node" + * as being coincident or not according to "coincident". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_coincident( + __isl_take isl_schedule_node *node, int pos, int coincident) +{ + int c; + isl_schedule_tree *tree; + + if (!node) + return NULL; + c = isl_schedule_node_band_member_get_coincident(node, pos); + if (c == coincident) + return node; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_member_set_coincident(tree, pos, + coincident); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Is the band node "node" marked permutable? + */ +isl_bool isl_schedule_node_band_get_permutable( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_bool_error; + + return isl_schedule_tree_band_get_permutable(node->tree); +} + +/* Mark the band node "node" permutable or not according to "permutable"? + */ +__isl_give isl_schedule_node *isl_schedule_node_band_set_permutable( + __isl_take isl_schedule_node *node, int permutable) +{ + isl_schedule_tree *tree; + + if (!node) + return NULL; + if (isl_schedule_node_band_get_permutable(node) == permutable) + return node; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_set_permutable(tree, permutable); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Return the schedule space of the band node. + */ +__isl_give isl_space *isl_schedule_node_band_get_space( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_band_get_space(node->tree); +} + +/* Return the schedule of the band node in isolation. + */ +__isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_band_get_partial_schedule(node->tree); +} + +/* Return the schedule of the band node in isolation in the form of + * an isl_union_map. + * + * If the band does not have any members, then we construct a universe map + * with the universe of the domain elements reaching the node as domain. + * Otherwise, we extract an isl_multi_union_pw_aff representation and + * convert that to an isl_union_map. + */ +__isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map( + __isl_keep isl_schedule_node *node) +{ + isl_multi_union_pw_aff *mupa; + + if (!node) + return NULL; + + if (isl_schedule_node_get_type(node) != isl_schedule_node_band) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a band node", return NULL); + if (isl_schedule_node_band_n_member(node) == 0) { + isl_union_set *domain; + + domain = isl_schedule_node_get_universe_domain(node); + return isl_union_map_from_domain(domain); + } + + mupa = isl_schedule_node_band_get_partial_schedule(node); + return isl_union_map_from_multi_union_pw_aff(mupa); +} + +/* Return the loop AST generation type for the band member of band node "node" + * at position "pos". + */ +enum isl_ast_loop_type isl_schedule_node_band_member_get_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos) +{ + if (!node) + return isl_ast_loop_error; + + return isl_schedule_tree_band_member_get_ast_loop_type(node->tree, pos); +} + +/* Set the loop AST generation type for the band member of band node "node" + * at position "pos" to "type". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_member_set_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type) +{ + isl_schedule_tree *tree; + + if (!node) + return NULL; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_member_set_ast_loop_type(tree, pos, type); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Return the loop AST generation type for the band member of band node "node" + * at position "pos" for the isolated part. + */ +enum isl_ast_loop_type isl_schedule_node_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_node *node, int pos) +{ + if (!node) + return isl_ast_loop_error; + + return isl_schedule_tree_band_member_get_isolate_ast_loop_type( + node->tree, pos); +} + +/* Set the loop AST generation type for the band member of band node "node" + * at position "pos" for the isolated part to "type". + */ +__isl_give isl_schedule_node * +isl_schedule_node_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_node *node, int pos, + enum isl_ast_loop_type type) +{ + isl_schedule_tree *tree; + + if (!node) + return NULL; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_member_set_isolate_ast_loop_type(tree, + pos, type); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Return the AST build options associated to band node "node". + */ +__isl_give isl_union_set *isl_schedule_node_band_get_ast_build_options( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_band_get_ast_build_options(node->tree); +} + +/* Replace the AST build options associated to band node "node" by "options". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_set_ast_build_options( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *options) +{ + isl_schedule_tree *tree; + + if (!node || !options) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_band_set_ast_build_options(tree, options); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_set_free(options); + return NULL; +} + +/* Make sure that that spaces of "node" and "mv" are the same. + * Return -1 on error, reporting the error to the user. + */ +static int check_space_multi_val(__isl_keep isl_schedule_node *node, + __isl_keep isl_multi_val *mv) +{ + isl_space *node_space, *mv_space; + int equal; + + node_space = isl_schedule_node_band_get_space(node); + mv_space = isl_multi_val_get_space(mv); + equal = isl_space_tuple_is_equal(node_space, isl_dim_set, + mv_space, isl_dim_set); + isl_space_free(mv_space); + isl_space_free(node_space); + if (equal < 0) + return -1; + if (!equal) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "spaces don't match", return -1); + + return 0; +} + +/* Multiply the partial schedule of the band node "node" + * with the factors in "mv". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_scale( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !mv) + goto error; + if (check_space_multi_val(node, mv) < 0) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot scale band node with anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_scale(tree, mv); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(mv); + isl_schedule_node_free(node); + return NULL; +} + +/* Divide the partial schedule of the band node "node" + * by the factors in "mv". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_scale_down( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !mv) + goto error; + if (check_space_multi_val(node, mv) < 0) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot scale down band node with anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_scale_down(tree, mv); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(mv); + isl_schedule_node_free(node); + return NULL; +} + +/* Tile "node" with tile sizes "sizes". + * + * The current node is replaced by two nested nodes corresponding + * to the tile dimensions and the point dimensions. + * + * Return a pointer to the outer (tile) node. + * + * If any of the descendants of "node" depend on the set of outer band nodes, + * then we refuse to tile the node. + * + * If the scale tile loops option is set, then the tile loops + * are scaled by the tile sizes. If the shift point loops option is set, + * then the point loops are shifted to start at zero. + * In particular, these options affect the tile and point loop schedules + * as follows + * + * scale shift original tile point + * + * 0 0 i floor(i/s) i + * 1 0 i s * floor(i/s) i + * 0 1 i floor(i/s) i - s * floor(i/s) + * 1 1 i s * floor(i/s) i - s * floor(i/s) + */ +__isl_give isl_schedule_node *isl_schedule_node_band_tile( + __isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes) +{ + isl_schedule_tree *tree; + int anchored; + + if (!node || !sizes) + goto error; + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot tile band node with anchored subtree", + goto error); + + if (check_space_multi_val(node, sizes) < 0) + goto error; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_tile(tree, sizes); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_multi_val_free(sizes); + isl_schedule_node_free(node); + return NULL; +} + +/* Move the band node "node" down to all the leaves in the subtree + * rooted at "node". + * Return a pointer to the node in the resulting tree that is in the same + * position as the node pointed to by "node" in the original tree. + * + * If the node only has a leaf child, then nothing needs to be done. + * Otherwise, the child of the node is removed and the result is + * appended to all the leaves in the subtree rooted at the original child. + * The original node is then replaced by the result of this operation. + * + * If any of the nodes in the subtree rooted at "node" depend on + * the set of outer band nodes then we refuse to sink the band node. + */ +__isl_give isl_schedule_node *isl_schedule_node_band_sink( + __isl_take isl_schedule_node *node) +{ + enum isl_schedule_node_type type; + isl_schedule_tree *tree, *child; + int anchored; + + if (!node) + return NULL; + + type = isl_schedule_node_get_type(node); + if (type != isl_schedule_node_band) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a band node", isl_schedule_node_free(node)); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + return isl_schedule_node_free(node); + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot sink band node in anchored subtree", + isl_schedule_node_free(node)); + if (isl_schedule_tree_n_children(node->tree) == 0) + return node; + + tree = isl_schedule_node_get_tree(node); + child = isl_schedule_tree_get_child(tree, 0); + tree = isl_schedule_tree_reset_children(tree); + tree = isl_schedule_tree_append_to_leaves(child, tree); + + return isl_schedule_node_graft_tree(node, tree); +} + +/* Split "node" into two nested band nodes, one with the first "pos" + * dimensions and one with the remaining dimensions. + * The schedules of the two band nodes live in anonymous spaces. + */ +__isl_give isl_schedule_node *isl_schedule_node_band_split( + __isl_take isl_schedule_node *node, int pos) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_split(tree, pos); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Return the context of the context node "node". + */ +__isl_give isl_set *isl_schedule_node_context_get_context( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_context_get_context(node->tree); +} + +/* Return the domain of the domain node "node". + */ +__isl_give isl_union_set *isl_schedule_node_domain_get_domain( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_domain_get_domain(node->tree); +} + +/* Return the expansion map of expansion node "node". + */ +__isl_give isl_union_map *isl_schedule_node_expansion_get_expansion( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_expansion_get_expansion(node->tree); +} + +/* Return the contraction of expansion node "node". + */ +__isl_give isl_union_pw_multi_aff *isl_schedule_node_expansion_get_contraction( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_expansion_get_contraction(node->tree); +} + +/* Replace the contraction and the expansion of the expansion node "node" + * by "contraction" and "expansion". + */ +__isl_give isl_schedule_node * +isl_schedule_node_expansion_set_contraction_and_expansion( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_schedule_tree *tree; + + if (!node || !contraction || !expansion) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_expansion_set_contraction_and_expansion(tree, + contraction, expansion); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Return the extension of the extension node "node". + */ +__isl_give isl_union_map *isl_schedule_node_extension_get_extension( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_extension_get_extension(node->tree); +} + +/* Replace the extension of extension node "node" by "extension". + */ +__isl_give isl_schedule_node *isl_schedule_node_extension_set_extension( + __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension) +{ + isl_schedule_tree *tree; + + if (!node || !extension) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_extension_set_extension(tree, extension); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_map_free(extension); + return NULL; +} + +/* Return the filter of the filter node "node". + */ +__isl_give isl_union_set *isl_schedule_node_filter_get_filter( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_filter_get_filter(node->tree); +} + +/* Replace the filter of filter node "node" by "filter". + */ +__isl_give isl_schedule_node *isl_schedule_node_filter_set_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + isl_schedule_tree *tree; + + if (!node || !filter) + goto error; + + tree = isl_schedule_tree_copy(node->tree); + tree = isl_schedule_tree_filter_set_filter(tree, filter); + return isl_schedule_node_graft_tree(node, tree); +error: + isl_schedule_node_free(node); + isl_union_set_free(filter); + return NULL; +} + +/* Return the guard of the guard node "node". + */ +__isl_give isl_set *isl_schedule_node_guard_get_guard( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_guard_get_guard(node->tree); +} + +/* Return the mark identifier of the mark node "node". + */ +__isl_give isl_id *isl_schedule_node_mark_get_id( + __isl_keep isl_schedule_node *node) +{ + if (!node) + return NULL; + + return isl_schedule_tree_mark_get_id(node->tree); +} + +/* Replace the child at position "pos" of the sequence node "node" + * by the children of sequence root node of "tree". + */ +__isl_give isl_schedule_node *isl_schedule_node_sequence_splice( + __isl_take isl_schedule_node *node, int pos, + __isl_take isl_schedule_tree *tree) +{ + isl_schedule_tree *node_tree; + + if (!node || !tree) + goto error; + if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a sequence node", goto error); + if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a sequence node", goto error); + node_tree = isl_schedule_node_get_tree(node); + node_tree = isl_schedule_tree_sequence_splice(node_tree, pos, tree); + node = isl_schedule_node_graft_tree(node, node_tree); + + return node; +error: + isl_schedule_node_free(node); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Update the ancestors of "node" to point to the tree that "node" + * now points to. + * That is, replace the child in the original parent that corresponds + * to the current tree position by node->tree and continue updating + * the ancestors in the same way until the root is reached. + * + * If "fn" is not NULL, then it is called on each ancestor as we move up + * the tree so that it can modify the ancestor before it is added + * to the list of ancestors of the modified node. + * The additional "pos" argument records the position + * of the "tree" argument in the original schedule tree. + * + * If "node" originally points to a leaf of the schedule tree, then make sure + * that in the end it points to a leaf in the updated schedule tree. + */ +static __isl_give isl_schedule_node *update_ancestors( + __isl_take isl_schedule_node *node, + __isl_give isl_schedule_tree *(*fn)(__isl_take isl_schedule_tree *tree, + __isl_keep isl_schedule_node *pos, void *user), void *user) +{ + int i, n; + int is_leaf; + isl_ctx *ctx; + isl_schedule_tree *tree; + isl_schedule_node *pos = NULL; + + if (fn) + pos = isl_schedule_node_copy(node); + + node = isl_schedule_node_cow(node); + if (!node) + return isl_schedule_node_free(pos); + + ctx = isl_schedule_node_get_ctx(node); + n = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + tree = isl_schedule_tree_copy(node->tree); + + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *parent; + + parent = isl_schedule_tree_list_get_schedule_tree( + node->ancestors, i); + parent = isl_schedule_tree_replace_child(parent, + node->child_pos[i], tree); + if (fn) { + pos = isl_schedule_node_parent(pos); + parent = fn(parent, pos, user); + } + node->ancestors = isl_schedule_tree_list_set_schedule_tree( + node->ancestors, i, isl_schedule_tree_copy(parent)); + + tree = parent; + } + + if (fn) + isl_schedule_node_free(pos); + + is_leaf = isl_schedule_tree_is_leaf(node->tree); + node->schedule = isl_schedule_set_root(node->schedule, tree); + if (is_leaf) { + isl_schedule_tree_free(node->tree); + node->tree = isl_schedule_node_get_leaf(node); + } + + if (!node->schedule || !node->ancestors) + return isl_schedule_node_free(node); + + return node; +} + +/* Replace the subtree that "pos" points to by "tree", updating + * the ancestors to maintain a consistent state. + */ +__isl_give isl_schedule_node *isl_schedule_node_graft_tree( + __isl_take isl_schedule_node *pos, __isl_take isl_schedule_tree *tree) +{ + if (!tree || !pos) + goto error; + if (pos->tree == tree) { + isl_schedule_tree_free(tree); + return pos; + } + + pos = isl_schedule_node_cow(pos); + if (!pos) + goto error; + + isl_schedule_tree_free(pos->tree); + pos->tree = tree; + + return update_ancestors(pos, NULL, NULL); +error: + isl_schedule_node_free(pos); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Make sure we can insert a node between "node" and its parent. + * Return -1 on error, reporting the reason why we cannot insert a node. + */ +static int check_insert(__isl_keep isl_schedule_node *node) +{ + int has_parent; + enum isl_schedule_node_type type; + + has_parent = isl_schedule_node_has_parent(node); + if (has_parent < 0) + return -1; + if (!has_parent) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert node outside of root", return -1); + + type = isl_schedule_node_get_parent_type(node); + if (type == isl_schedule_node_error) + return -1; + if (type == isl_schedule_node_set || type == isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert node between set or sequence node " + "and its filter children", return -1); + + return 0; +} + +/* Insert a band node with partial schedule "mupa" between "node" and + * its parent. + * Return a pointer to the new band node. + * + * If any of the nodes in the subtree rooted at "node" depend on + * the set of outer band nodes then we refuse to insert the band node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_partial_schedule( + __isl_take isl_schedule_node *node, + __isl_take isl_multi_union_pw_aff *mupa) +{ + int anchored; + isl_schedule_band *band; + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + goto error; + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot insert band node in anchored subtree", + goto error); + + tree = isl_schedule_node_get_tree(node); + band = isl_schedule_band_from_multi_union_pw_aff(mupa); + tree = isl_schedule_tree_insert_band(tree, band); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +error: + isl_schedule_node_free(node); + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Insert a context node with context "context" between "node" and its parent. + * Return a pointer to the new context node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_context( + __isl_take isl_schedule_node *node, __isl_take isl_set *context) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_context(tree, context); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert an expansion node with the given "contraction" and "expansion" + * between "node" and its parent. + * Return a pointer to the new expansion node. + * + * Typically the domain and range spaces of the expansion are different. + * This means that only one of them can refer to the current domain space + * in a consistent tree. It is up to the caller to ensure that the tree + * returns to a consistent state. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_expansion( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_expansion(tree, contraction, expansion); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert an extension node with extension "extension" between "node" and + * its parent. + * Return a pointer to the new extension node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_extension( + __isl_take isl_schedule_node *node, + __isl_take isl_union_map *extension) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_extension(tree, extension); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert a filter node with filter "filter" between "node" and its parent. + * Return a pointer to the new filter node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_filter(tree, filter); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert a guard node with guard "guard" between "node" and its parent. + * Return a pointer to the new guard node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_guard( + __isl_take isl_schedule_node *node, __isl_take isl_set *guard) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_guard(tree, guard); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Insert a mark node with mark identifier "mark" between "node" and + * its parent. + * Return a pointer to the new mark node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_mark( + __isl_take isl_schedule_node *node, __isl_take isl_id *mark) +{ + isl_schedule_tree *tree; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_insert_mark(tree, mark); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Attach the current subtree of "node" to a sequence of filter tree nodes + * with filters described by "filters", attach this sequence + * of filter tree nodes as children to a new tree of type "type" and + * replace the original subtree of "node" by this new tree. + */ +static __isl_give isl_schedule_node *isl_schedule_node_insert_children( + __isl_take isl_schedule_node *node, + enum isl_schedule_node_type type, + __isl_take isl_union_set_list *filters) +{ + int i, n; + isl_ctx *ctx; + isl_schedule_tree *tree; + isl_schedule_tree_list *list; + + if (check_insert(node) < 0) + node = isl_schedule_node_free(node); + + if (!node || !filters) + goto error; + + ctx = isl_schedule_node_get_ctx(node); + n = isl_union_set_list_n_union_set(filters); + list = isl_schedule_tree_list_alloc(ctx, n); + for (i = 0; i < n; ++i) { + isl_schedule_tree *tree; + isl_union_set *filter; + + tree = isl_schedule_node_get_tree(node); + filter = isl_union_set_list_get_union_set(filters, i); + tree = isl_schedule_tree_insert_filter(tree, filter); + list = isl_schedule_tree_list_add(list, tree); + } + tree = isl_schedule_tree_from_children(type, list); + node = isl_schedule_node_graft_tree(node, tree); + + isl_union_set_list_free(filters); + return node; +error: + isl_union_set_list_free(filters); + isl_schedule_node_free(node); + return NULL; +} + +/* Insert a sequence node with child filters "filters" between "node" and + * its parent. That is, the tree that "node" points to is attached + * to each of the child nodes of the filter nodes. + * Return a pointer to the new sequence node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_sequence( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters) +{ + return isl_schedule_node_insert_children(node, + isl_schedule_node_sequence, filters); +} + +/* Insert a set node with child filters "filters" between "node" and + * its parent. That is, the tree that "node" points to is attached + * to each of the child nodes of the filter nodes. + * Return a pointer to the new set node. + */ +__isl_give isl_schedule_node *isl_schedule_node_insert_set( + __isl_take isl_schedule_node *node, + __isl_take isl_union_set_list *filters) +{ + return isl_schedule_node_insert_children(node, + isl_schedule_node_set, filters); +} + +/* Remove "node" from its schedule tree and return a pointer + * to the leaf at the same position in the updated schedule tree. + * + * It is not allowed to remove the root of a schedule tree or + * a child of a set or sequence node. + */ +__isl_give isl_schedule_node *isl_schedule_node_cut( + __isl_take isl_schedule_node *node) +{ + isl_schedule_tree *leaf; + enum isl_schedule_node_type parent_type; + + if (!node) + return NULL; + if (!isl_schedule_node_has_parent(node)) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot cut root", return isl_schedule_node_free(node)); + + parent_type = isl_schedule_node_get_parent_type(node); + if (parent_type == isl_schedule_node_set || + parent_type == isl_schedule_node_sequence) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot cut child of set or sequence", + return isl_schedule_node_free(node)); + + leaf = isl_schedule_node_get_leaf(node); + return isl_schedule_node_graft_tree(node, leaf); +} + +/* Remove a single node from the schedule tree, attaching the child + * of "node" directly to its parent. + * Return a pointer to this former child or to the leaf the position + * of the original node if there was no child. + * It is not allowed to remove the root of a schedule tree, + * a set or sequence node, a child of a set or sequence node or + * a band node with an anchored subtree. + */ +__isl_give isl_schedule_node *isl_schedule_node_delete( + __isl_take isl_schedule_node *node) +{ + int n; + isl_schedule_tree *tree; + enum isl_schedule_node_type type; + + if (!node) + return NULL; + + if (isl_schedule_node_get_tree_depth(node) == 0) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot delete root node", + return isl_schedule_node_free(node)); + n = isl_schedule_node_n_children(node); + if (n != 1) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "can only delete node with a single child", + return isl_schedule_node_free(node)); + type = isl_schedule_node_get_parent_type(node); + if (type == isl_schedule_node_sequence || type == isl_schedule_node_set) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "cannot delete child of set or sequence", + return isl_schedule_node_free(node)); + if (isl_schedule_node_get_type(node) == isl_schedule_node_band) { + int anchored; + + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + return isl_schedule_node_free(node); + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), + isl_error_invalid, + "cannot delete band node with anchored subtree", + return isl_schedule_node_free(node)); + } + + tree = isl_schedule_node_get_tree(node); + if (!tree || isl_schedule_tree_has_children(tree)) { + tree = isl_schedule_tree_child(tree, 0); + } else { + isl_schedule_tree_free(tree); + tree = isl_schedule_node_get_leaf(node); + } + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Internal data structure for the group_ancestor callback. + * + * If "finished" is set, then we no longer need to modify + * any further ancestors. + * + * "contraction" and "expansion" represent the expansion + * that reflects the grouping. + * + * "domain" contains the domain elements that reach the position + * where the grouping is performed. That is, it is the range + * of the resulting expansion. + * "domain_universe" is the universe of "domain". + * "group" is the set of group elements, i.e., the domain + * of the resulting expansion. + * "group_universe" is the universe of "group". + * + * "sched" is the schedule for the group elements, in pratice + * an identity mapping on "group_universe". + * "dim" is the dimension of "sched". + */ +struct isl_schedule_group_data { + int finished; + + isl_union_map *expansion; + isl_union_pw_multi_aff *contraction; + + isl_union_set *domain; + isl_union_set *domain_universe; + isl_union_set *group; + isl_union_set *group_universe; + + int dim; + isl_multi_aff *sched; +}; + +/* Is domain covered by data->domain within data->domain_universe? + */ +static int locally_covered_by_domain(__isl_keep isl_union_set *domain, + struct isl_schedule_group_data *data) +{ + int is_subset; + isl_union_set *test; + + test = isl_union_set_copy(domain); + test = isl_union_set_intersect(test, + isl_union_set_copy(data->domain_universe)); + is_subset = isl_union_set_is_subset(test, data->domain); + isl_union_set_free(test); + + return is_subset; +} + +/* Update the band tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * Add the part of the identity schedule on the group instances data->sched + * that corresponds to this band node to the band schedule. + * If the domain elements that reach the node and that are part + * of data->domain_universe are all elements of data->domain (and therefore + * replaced by the group instances) then this data->domain_universe + * is removed from the domain of the band schedule. + */ +static __isl_give isl_schedule_tree *group_band( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_union_set *domain; + isl_multi_aff *ma; + isl_multi_union_pw_aff *mupa, *partial; + int is_covered; + int depth, n, has_id; + + domain = isl_schedule_node_get_domain(pos); + is_covered = locally_covered_by_domain(domain, data); + if (is_covered >= 0 && is_covered) { + domain = isl_union_set_universe(domain); + domain = isl_union_set_subtract(domain, + isl_union_set_copy(data->domain_universe)); + tree = isl_schedule_tree_band_intersect_domain(tree, domain); + } else + isl_union_set_free(domain); + if (is_covered < 0) + return isl_schedule_tree_free(tree); + depth = isl_schedule_node_get_schedule_depth(pos); + n = isl_schedule_tree_band_n_member(tree); + ma = isl_multi_aff_copy(data->sched); + ma = isl_multi_aff_drop_dims(ma, isl_dim_out, 0, depth); + ma = isl_multi_aff_drop_dims(ma, isl_dim_out, n, data->dim - depth - n); + mupa = isl_multi_union_pw_aff_from_multi_aff(ma); + partial = isl_schedule_tree_band_get_partial_schedule(tree); + has_id = isl_multi_union_pw_aff_has_tuple_id(partial, isl_dim_set); + if (has_id < 0) { + partial = isl_multi_union_pw_aff_free(partial); + } else if (has_id) { + isl_id *id; + id = isl_multi_union_pw_aff_get_tuple_id(partial, isl_dim_set); + mupa = isl_multi_union_pw_aff_set_tuple_id(mupa, + isl_dim_set, id); + } + partial = isl_multi_union_pw_aff_union_add(partial, mupa); + tree = isl_schedule_tree_band_set_partial_schedule(tree, partial); + + return tree; +} + +/* Drop the parameters in "uset" that are not also in "space". + * "n" is the number of parameters in "space". + */ +static __isl_give isl_union_set *union_set_drop_extra_params( + __isl_take isl_union_set *uset, __isl_keep isl_space *space, int n) +{ + int n2; + + uset = isl_union_set_align_params(uset, isl_space_copy(space)); + n2 = isl_union_set_dim(uset, isl_dim_param); + uset = isl_union_set_project_out(uset, isl_dim_param, n, n2 - n); + + return uset; +} + +/* Update the context tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * We do not actually need to update "tree" since a context node only + * refers to the schedule space. However, we may need to update "data" + * to not refer to any parameters introduced by the context node. + */ +static __isl_give isl_schedule_tree *group_context( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_space *space; + isl_union_set *domain; + int n1, n2; + int involves; + + if (isl_schedule_node_get_tree_depth(pos) == 1) + return tree; + + domain = isl_schedule_node_get_universe_domain(pos); + space = isl_union_set_get_space(domain); + isl_union_set_free(domain); + + n1 = isl_space_dim(space, isl_dim_param); + data->expansion = isl_union_map_align_params(data->expansion, space); + n2 = isl_union_map_dim(data->expansion, isl_dim_param); + + if (!data->expansion) + return isl_schedule_tree_free(tree); + if (n1 == n2) + return tree; + + involves = isl_union_map_involves_dims(data->expansion, + isl_dim_param, n1, n2 - n1); + if (involves < 0) + return isl_schedule_tree_free(tree); + if (involves) + isl_die(isl_schedule_node_get_ctx(pos), isl_error_invalid, + "grouping cannot only refer to global parameters", + return isl_schedule_tree_free(tree)); + + data->expansion = isl_union_map_project_out(data->expansion, + isl_dim_param, n1, n2 - n1); + space = isl_union_map_get_space(data->expansion); + + data->contraction = isl_union_pw_multi_aff_align_params( + data->contraction, isl_space_copy(space)); + n2 = isl_union_pw_multi_aff_dim(data->contraction, isl_dim_param); + data->contraction = isl_union_pw_multi_aff_drop_dims(data->contraction, + isl_dim_param, n1, n2 - n1); + + data->domain = union_set_drop_extra_params(data->domain, space, n1); + data->domain_universe = + union_set_drop_extra_params(data->domain_universe, space, n1); + data->group = union_set_drop_extra_params(data->group, space, n1); + data->group_universe = + union_set_drop_extra_params(data->group_universe, space, n1); + + data->sched = isl_multi_aff_align_params(data->sched, + isl_space_copy(space)); + n2 = isl_multi_aff_dim(data->sched, isl_dim_param); + data->sched = isl_multi_aff_drop_dims(data->sched, + isl_dim_param, n1, n2 - n1); + + isl_space_free(space); + + return tree; +} + +/* Update the domain tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * We first double-check that all grouped domain elements are actually + * part of the root domain and then replace those elements by the group + * instances. + */ +static __isl_give isl_schedule_tree *group_domain( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_union_set *domain; + int is_subset; + + domain = isl_schedule_tree_domain_get_domain(tree); + is_subset = isl_union_set_is_subset(data->domain, domain); + isl_union_set_free(domain); + if (is_subset < 0) + return isl_schedule_tree_free(tree); + if (!is_subset) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "grouped domain should be part of outer domain", + return isl_schedule_tree_free(tree)); + domain = isl_schedule_tree_domain_get_domain(tree); + domain = isl_union_set_subtract(domain, + isl_union_set_copy(data->domain)); + domain = isl_union_set_union(domain, isl_union_set_copy(data->group)); + tree = isl_schedule_tree_domain_set_domain(tree, domain); + + return tree; +} + +/* Update the expansion tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * Let G_1 -> D_1 be the expansion of "tree" and G_2 -> D_2 the newly + * introduced expansion in a descendant of "tree". + * We first double-check that D_2 is a subset of D_1. + * Then we remove D_2 from the range of G_1 -> D_1 and add the mapping + * G_1 -> D_1 . D_2 -> G_2. + * Simmilarly, we restrict the domain of the contraction to the universe + * of the range of the updated expansion and add G_2 -> D_2 . D_1 -> G_1, + * attempting to remove the domain constraints of this additional part. + */ +static __isl_give isl_schedule_tree *group_expansion( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + struct isl_schedule_group_data *data) +{ + isl_union_set *domain; + isl_union_map *expansion, *umap; + isl_union_pw_multi_aff *contraction, *upma; + int is_subset; + + expansion = isl_schedule_tree_expansion_get_expansion(tree); + domain = isl_union_map_range(expansion); + is_subset = isl_union_set_is_subset(data->domain, domain); + isl_union_set_free(domain); + if (is_subset < 0) + return isl_schedule_tree_free(tree); + if (!is_subset) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "grouped domain should be part " + "of outer expansion domain", + return isl_schedule_tree_free(tree)); + expansion = isl_schedule_tree_expansion_get_expansion(tree); + umap = isl_union_map_from_union_pw_multi_aff( + isl_union_pw_multi_aff_copy(data->contraction)); + umap = isl_union_map_apply_range(expansion, umap); + expansion = isl_schedule_tree_expansion_get_expansion(tree); + expansion = isl_union_map_subtract_range(expansion, + isl_union_set_copy(data->domain)); + expansion = isl_union_map_union(expansion, umap); + umap = isl_union_map_universe(isl_union_map_copy(expansion)); + domain = isl_union_map_range(umap); + contraction = isl_schedule_tree_expansion_get_contraction(tree); + umap = isl_union_map_from_union_pw_multi_aff(contraction); + umap = isl_union_map_apply_range(isl_union_map_copy(data->expansion), + umap); + upma = isl_union_pw_multi_aff_from_union_map(umap); + contraction = isl_schedule_tree_expansion_get_contraction(tree); + contraction = isl_union_pw_multi_aff_intersect_domain(contraction, + domain); + domain = isl_union_pw_multi_aff_domain( + isl_union_pw_multi_aff_copy(upma)); + upma = isl_union_pw_multi_aff_gist(upma, domain); + contraction = isl_union_pw_multi_aff_union_add(contraction, upma); + tree = isl_schedule_tree_expansion_set_contraction_and_expansion(tree, + contraction, expansion); + + return tree; +} + +/* Update the tree root "tree" to refer to the group instances + * in data->group rather than the original domain elements in data->domain. + * "pos" is the position in the original schedule tree where the modified + * "tree" will be attached. + * + * If we have come across a domain or expansion node before (data->finished + * is set), then we no longer need perform any modifications. + * + * If "tree" is a filter, then we add data->group_universe to the filter. + * We also remove data->domain_universe from the filter if all the domain + * elements in this universe that reach the filter node are part of + * the elements that are being grouped by data->expansion. + * If "tree" is a band, domain or expansion, then it is handled + * in a separate function. + */ +static __isl_give isl_schedule_tree *group_ancestor( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_node *pos, + void *user) +{ + struct isl_schedule_group_data *data = user; + isl_union_set *domain; + int is_covered; + + if (!tree || !pos) + return isl_schedule_tree_free(tree); + + if (data->finished) + return tree; + + switch (isl_schedule_tree_get_type(tree)) { + case isl_schedule_node_error: + return isl_schedule_tree_free(tree); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported, + "grouping not allowed in extended tree", + return isl_schedule_tree_free(tree)); + case isl_schedule_node_band: + tree = group_band(tree, pos, data); + break; + case isl_schedule_node_context: + tree = group_context(tree, pos, data); + break; + case isl_schedule_node_domain: + tree = group_domain(tree, pos, data); + data->finished = 1; + break; + case isl_schedule_node_filter: + domain = isl_schedule_node_get_domain(pos); + is_covered = locally_covered_by_domain(domain, data); + isl_union_set_free(domain); + if (is_covered < 0) + return isl_schedule_tree_free(tree); + domain = isl_schedule_tree_filter_get_filter(tree); + if (is_covered) + domain = isl_union_set_subtract(domain, + isl_union_set_copy(data->domain_universe)); + domain = isl_union_set_union(domain, + isl_union_set_copy(data->group_universe)); + tree = isl_schedule_tree_filter_set_filter(tree, domain); + break; + case isl_schedule_node_expansion: + tree = group_expansion(tree, pos, data); + data->finished = 1; + break; + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return tree; +} + +/* Group the domain elements that reach "node" into instances + * of a single statement with identifier "group_id". + * In particular, group the domain elements according to their + * prefix schedule. + * + * That is, introduce an expansion node with as contraction + * the prefix schedule (with the target space replaced by "group_id") + * and as expansion the inverse of this contraction (with its range + * intersected with the domain elements that reach "node"). + * The outer nodes are then modified to refer to the group instances + * instead of the original domain elements. + * + * No instance of "group_id" is allowed to reach "node" prior + * to the grouping. + * No ancestor of "node" is allowed to be an extension node. + * + * Return a pointer to original node in tree, i.e., the child + * of the newly introduced expansion node. + */ +__isl_give isl_schedule_node *isl_schedule_node_group( + __isl_take isl_schedule_node *node, __isl_take isl_id *group_id) +{ + struct isl_schedule_group_data data = { 0 }; + isl_space *space; + isl_union_set *domain; + isl_union_pw_multi_aff *contraction; + isl_union_map *expansion; + int disjoint; + + if (!node || !group_id) + goto error; + if (check_insert(node) < 0) + goto error; + + domain = isl_schedule_node_get_domain(node); + data.domain = isl_union_set_copy(domain); + data.domain_universe = isl_union_set_copy(domain); + data.domain_universe = isl_union_set_universe(data.domain_universe); + + data.dim = isl_schedule_node_get_schedule_depth(node); + if (data.dim == 0) { + isl_ctx *ctx; + isl_set *set; + isl_union_set *group; + isl_union_map *univ; + + ctx = isl_schedule_node_get_ctx(node); + space = isl_space_set_alloc(ctx, 0, 0); + space = isl_space_set_tuple_id(space, isl_dim_set, group_id); + set = isl_set_universe(isl_space_copy(space)); + group = isl_union_set_from_set(set); + expansion = isl_union_map_from_domain_and_range(domain, group); + univ = isl_union_map_universe(isl_union_map_copy(expansion)); + contraction = isl_union_pw_multi_aff_from_union_map(univ); + expansion = isl_union_map_reverse(expansion); + } else { + isl_multi_union_pw_aff *prefix; + isl_union_set *univ; + + prefix = + isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(node); + prefix = isl_multi_union_pw_aff_set_tuple_id(prefix, + isl_dim_set, group_id); + space = isl_multi_union_pw_aff_get_space(prefix); + contraction = isl_union_pw_multi_aff_from_multi_union_pw_aff( + prefix); + univ = isl_union_set_universe(isl_union_set_copy(domain)); + contraction = + isl_union_pw_multi_aff_intersect_domain(contraction, univ); + expansion = isl_union_map_from_union_pw_multi_aff( + isl_union_pw_multi_aff_copy(contraction)); + expansion = isl_union_map_reverse(expansion); + expansion = isl_union_map_intersect_range(expansion, domain); + } + space = isl_space_map_from_set(space); + data.sched = isl_multi_aff_identity(space); + data.group = isl_union_map_domain(isl_union_map_copy(expansion)); + data.group = isl_union_set_coalesce(data.group); + data.group_universe = isl_union_set_copy(data.group); + data.group_universe = isl_union_set_universe(data.group_universe); + data.expansion = isl_union_map_copy(expansion); + data.contraction = isl_union_pw_multi_aff_copy(contraction); + node = isl_schedule_node_insert_expansion(node, contraction, expansion); + + disjoint = isl_union_set_is_disjoint(data.domain_universe, + data.group_universe); + + node = update_ancestors(node, &group_ancestor, &data); + + isl_union_set_free(data.domain); + isl_union_set_free(data.domain_universe); + isl_union_set_free(data.group); + isl_union_set_free(data.group_universe); + isl_multi_aff_free(data.sched); + isl_union_map_free(data.expansion); + isl_union_pw_multi_aff_free(data.contraction); + + node = isl_schedule_node_child(node, 0); + + if (!node || disjoint < 0) + return isl_schedule_node_free(node); + if (!disjoint) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "group instances already reach node", + isl_schedule_node_free(node)); + + return node; +error: + isl_schedule_node_free(node); + isl_id_free(group_id); + return NULL; +} + +/* Compute the gist of the given band node with respect to "context". + */ +__isl_give isl_schedule_node *isl_schedule_node_band_gist( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *context) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_band_gist(tree, context); + return isl_schedule_node_graft_tree(node, tree); +} + +/* Internal data structure for isl_schedule_node_gist. + * "n_expansion" is the number of outer expansion nodes + * with respect to the current position + * "filters" contains an element for each outer filter, expansion or + * extension node with respect to the current position, each representing + * the intersection of the previous element and the filter on the filter node + * or the expansion/extension of the previous element. + * The first element in the original context passed to isl_schedule_node_gist. + */ +struct isl_node_gist_data { + int n_expansion; + isl_union_set_list *filters; +}; + +/* Enter the expansion node "node" during a isl_schedule_node_gist traversal. + * + * In particular, add an extra element to data->filters containing + * the expansion of the previous element and replace the expansion + * and contraction on "node" by the gist with respect to these filters. + * Also keep track of the fact that we have entered another expansion. + */ +static __isl_give isl_schedule_node *gist_enter_expansion( + __isl_take isl_schedule_node *node, struct isl_node_gist_data *data) +{ + int n; + isl_union_set *inner; + isl_union_map *expansion; + isl_union_pw_multi_aff *contraction; + + data->n_expansion++; + + n = isl_union_set_list_n_union_set(data->filters); + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + expansion = isl_schedule_node_expansion_get_expansion(node); + inner = isl_union_set_apply(inner, expansion); + + contraction = isl_schedule_node_expansion_get_contraction(node); + contraction = isl_union_pw_multi_aff_gist(contraction, + isl_union_set_copy(inner)); + + data->filters = isl_union_set_list_add(data->filters, inner); + + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + expansion = isl_schedule_node_expansion_get_expansion(node); + expansion = isl_union_map_gist_domain(expansion, inner); + node = isl_schedule_node_expansion_set_contraction_and_expansion(node, + contraction, expansion); + + return node; +} + +/* Enter the extension node "node" during a isl_schedule_node_gist traversal. + * + * In particular, add an extra element to data->filters containing + * the union of the previous element with the additional domain elements + * introduced by the extension. + */ +static __isl_give isl_schedule_node *gist_enter_extension( + __isl_take isl_schedule_node *node, struct isl_node_gist_data *data) +{ + int n; + isl_union_set *inner, *extra; + isl_union_map *extension; + + n = isl_union_set_list_n_union_set(data->filters); + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + extension = isl_schedule_node_extension_get_extension(node); + extra = isl_union_map_range(extension); + inner = isl_union_set_union(inner, extra); + + data->filters = isl_union_set_list_add(data->filters, inner); + + return node; +} + +/* Can we finish gisting at this node? + * That is, is the filter on the current filter node a subset of + * the original context passed to isl_schedule_node_gist? + * If we have gone through any expansions, then we cannot perform + * this test since the current domain elements are incomparable + * to the domain elements in the original context. + */ +static int gist_done(__isl_keep isl_schedule_node *node, + struct isl_node_gist_data *data) +{ + isl_union_set *filter, *outer; + int subset; + + if (data->n_expansion != 0) + return 0; + + filter = isl_schedule_node_filter_get_filter(node); + outer = isl_union_set_list_get_union_set(data->filters, 0); + subset = isl_union_set_is_subset(filter, outer); + isl_union_set_free(outer); + isl_union_set_free(filter); + + return subset; +} + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * by isl_schedule_node_gist. + * + * The "filters" list is extended by one element each time + * we come across a filter node by the result of intersecting + * the last element in the list with the filter on the filter node. + * + * If the filter on the current filter node is a subset of + * the original context passed to isl_schedule_node_gist, + * then there is no need to go into its subtree since it cannot + * be further simplified by the context. The "filters" list is + * still extended for consistency, but the actual value of the + * added element is immaterial since it will not be used. + * + * Otherwise, the filter on the current filter node is replaced by + * the gist of the original filter with respect to the intersection + * of the original context with the intermediate filters. + * + * If the new element in the "filters" list is empty, then no elements + * can reach the descendants of the current filter node. The subtree + * underneath the filter node is therefore removed. + * + * Each expansion node we come across is handled by + * gist_enter_expansion. + * + * Each extension node we come across is handled by + * gist_enter_extension. + */ +static __isl_give isl_schedule_node *gist_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_node_gist_data *data = user; + + do { + isl_union_set *filter, *inner; + int done, empty; + int n; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_expansion: + node = gist_enter_expansion(node, data); + continue; + case isl_schedule_node_extension: + node = gist_enter_extension(node, data); + continue; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + continue; + case isl_schedule_node_filter: + break; + } + done = gist_done(node, data); + filter = isl_schedule_node_filter_get_filter(node); + if (done < 0 || done) { + data->filters = isl_union_set_list_add(data->filters, + filter); + if (done < 0) + return isl_schedule_node_free(node); + return node; + } + n = isl_union_set_list_n_union_set(data->filters); + inner = isl_union_set_list_get_union_set(data->filters, n - 1); + filter = isl_union_set_gist(filter, isl_union_set_copy(inner)); + node = isl_schedule_node_filter_set_filter(node, + isl_union_set_copy(filter)); + filter = isl_union_set_intersect(filter, inner); + empty = isl_union_set_is_empty(filter); + data->filters = isl_union_set_list_add(data->filters, filter); + if (empty < 0) + return isl_schedule_node_free(node); + if (!empty) + continue; + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_cut(node); + node = isl_schedule_node_parent(node); + return node; + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node for isl_schedule_node_gist. + * + * In particular, if the current node is a filter node, then we remove + * the element on the "filters" list that was added when we entered + * the node. There is no need to compute any gist here, since we + * already did that when we entered the node. + * + * If the current node is an expansion, then we decrement + * the number of outer expansions and remove the element + * in data->filters that was added by gist_enter_expansion. + * + * If the current node is an extension, then remove the element + * in data->filters that was added by gist_enter_extension. + * + * If the current node is a band node, then we compute the gist of + * the band node with respect to the intersection of the original context + * and the intermediate filters. + * + * If the current node is a sequence or set node, then some of + * the filter children may have become empty and so they are removed. + * If only one child is left, then the set or sequence node along with + * the single remaining child filter is removed. The filter can be + * removed because the filters on a sequence or set node are supposed + * to partition the incoming domain instances. + * In principle, it should then be impossible for there to be zero + * remaining children, but should this happen, we replace the entire + * subtree with an empty filter. + */ +static __isl_give isl_schedule_node *gist_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_node_gist_data *data = user; + isl_schedule_tree *tree; + int i, n; + isl_union_set *filter; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_expansion: + data->n_expansion--; + case isl_schedule_node_extension: + case isl_schedule_node_filter: + n = isl_union_set_list_n_union_set(data->filters); + data->filters = isl_union_set_list_drop(data->filters, + n - 1, 1); + break; + case isl_schedule_node_band: + n = isl_union_set_list_n_union_set(data->filters); + filter = isl_union_set_list_get_union_set(data->filters, n - 1); + node = isl_schedule_node_band_gist(node, filter); + break; + case isl_schedule_node_set: + case isl_schedule_node_sequence: + tree = isl_schedule_node_get_tree(node); + n = isl_schedule_tree_n_children(tree); + for (i = n - 1; i >= 0; --i) { + isl_schedule_tree *child; + isl_union_set *filter; + int empty; + + child = isl_schedule_tree_get_child(tree, i); + filter = isl_schedule_tree_filter_get_filter(child); + empty = isl_union_set_is_empty(filter); + isl_union_set_free(filter); + isl_schedule_tree_free(child); + if (empty < 0) + tree = isl_schedule_tree_free(tree); + else if (empty) + tree = isl_schedule_tree_drop_child(tree, i); + } + n = isl_schedule_tree_n_children(tree); + node = isl_schedule_node_graft_tree(node, tree); + if (n == 1) { + node = isl_schedule_node_delete(node); + node = isl_schedule_node_delete(node); + } else if (n == 0) { + isl_space *space; + + filter = + isl_union_set_list_get_union_set(data->filters, 0); + space = isl_union_set_get_space(filter); + isl_union_set_free(filter); + filter = isl_union_set_empty(space); + node = isl_schedule_node_cut(node); + node = isl_schedule_node_insert_filter(node, filter); + } + break; + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + break; + } + + return node; +} + +/* Compute the gist of the subtree at "node" with respect to + * the reaching domain elements in "context". + * In particular, compute the gist of all band and filter nodes + * in the subtree with respect to "context". Children of set or sequence + * nodes that end up with an empty filter are removed completely. + * + * We keep track of the intersection of "context" with all outer filters + * of the current node within the subtree in the final element of "filters". + * Initially, this list contains the single element "context" and it is + * extended or shortened each time we enter or leave a filter node. + */ +__isl_give isl_schedule_node *isl_schedule_node_gist( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *context) +{ + struct isl_node_gist_data data; + + data.n_expansion = 0; + data.filters = isl_union_set_list_from_union_set(context); + node = traverse(node, &gist_enter, &gist_leave, &data); + isl_union_set_list_free(data.filters); + return node; +} + +/* Intersect the domain of domain node "node" with "domain". + * + * If the domain of "node" is already a subset of "domain", + * then nothing needs to be changed. + * + * Otherwise, we replace the domain of the domain node by the intersection + * and simplify the subtree rooted at "node" with respect to this intersection. + */ +__isl_give isl_schedule_node *isl_schedule_node_domain_intersect_domain( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain) +{ + isl_schedule_tree *tree; + isl_union_set *uset; + int is_subset; + + if (!node || !domain) + goto error; + + uset = isl_schedule_tree_domain_get_domain(node->tree); + is_subset = isl_union_set_is_subset(uset, domain); + isl_union_set_free(uset); + if (is_subset < 0) + goto error; + if (is_subset) { + isl_union_set_free(domain); + return node; + } + + tree = isl_schedule_tree_copy(node->tree); + uset = isl_schedule_tree_domain_get_domain(tree); + uset = isl_union_set_intersect(uset, domain); + tree = isl_schedule_tree_domain_set_domain(tree, + isl_union_set_copy(uset)); + node = isl_schedule_node_graft_tree(node, tree); + + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_gist(node, uset); + node = isl_schedule_node_parent(node); + + return node; +error: + isl_schedule_node_free(node); + isl_union_set_free(domain); + return NULL; +} + +/* Internal data structure for isl_schedule_node_get_subtree_expansion. + * "expansions" contains a list of accumulated expansions + * for each outer expansion, set or sequence node. The first element + * in the list is an identity mapping on the reaching domain elements. + * "res" collects the results. + */ +struct isl_subtree_expansion_data { + isl_union_map_list *expansions; + isl_union_map *res; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * by isl_schedule_node_get_subtree_expansion. + * + * Whenever we come across an expansion node, the last element + * of data->expansions is combined with the expansion + * on the expansion node. + * + * Whenever we come across a filter node that is the child + * of a set or sequence node, data->expansions is extended + * with a new element that restricts the previous element + * to the elements selected by the filter. + * The previous element can then be reused while backtracking. + */ +static __isl_give isl_schedule_node *subtree_expansion_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_expansion_data *data = user; + + do { + enum isl_schedule_node_type type; + isl_union_set *filter; + isl_union_map *inner, *expansion; + int n; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + filter = isl_schedule_node_filter_get_filter(node); + n = isl_union_map_list_n_union_map(data->expansions); + inner = + isl_union_map_list_get_union_map(data->expansions, + n - 1); + inner = isl_union_map_intersect_range(inner, filter); + data->expansions = + isl_union_map_list_add(data->expansions, inner); + break; + case isl_schedule_node_expansion: + n = isl_union_map_list_n_union_map(data->expansions); + expansion = + isl_schedule_node_expansion_get_expansion(node); + inner = + isl_union_map_list_get_union_map(data->expansions, + n - 1); + inner = isl_union_map_apply_range(inner, expansion); + data->expansions = + isl_union_map_list_set_union_map(data->expansions, + n - 1, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node for + * isl_schedule_node_get_subtree_expansion. + * + * If we come across a filter node that is the child + * of a set or sequence node, then we remove the element + * of data->expansions that was added in subtree_expansion_enter. + * + * If we reach a leaf node, then the accumulated expansion is + * added to data->res. + */ +static __isl_give isl_schedule_node *subtree_expansion_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_expansion_data *data = user; + int n; + isl_union_map *inner; + enum isl_schedule_node_type type; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + n = isl_union_map_list_n_union_map(data->expansions); + data->expansions = isl_union_map_list_drop(data->expansions, + n - 1, 1); + break; + case isl_schedule_node_leaf: + n = isl_union_map_list_n_union_map(data->expansions); + inner = isl_union_map_list_get_union_map(data->expansions, + n - 1); + data->res = isl_union_map_union(data->res, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return node; +} + +/* Return a mapping from the domain elements that reach "node" + * to the corresponding domain elements in the leaves of the subtree + * rooted at "node" obtained by composing the intermediate expansions. + * + * We start out with an identity mapping between the domain elements + * that reach "node" and compose it with all the expansions + * on a path from "node" to a leaf while traversing the subtree. + * Within the children of an a sequence or set node, the + * accumulated expansion is restricted to the elements selected + * by the filter child. + */ +__isl_give isl_union_map *isl_schedule_node_get_subtree_expansion( + __isl_keep isl_schedule_node *node) +{ + struct isl_subtree_expansion_data data; + isl_space *space; + isl_union_set *domain; + isl_union_map *expansion; + + if (!node) + return NULL; + + domain = isl_schedule_node_get_universe_domain(node); + space = isl_union_set_get_space(domain); + expansion = isl_union_set_identity(domain); + data.res = isl_union_map_empty(space); + data.expansions = isl_union_map_list_from_union_map(expansion); + + node = isl_schedule_node_copy(node); + node = traverse(node, &subtree_expansion_enter, + &subtree_expansion_leave, &data); + if (!node) + data.res = isl_union_map_free(data.res); + isl_schedule_node_free(node); + + isl_union_map_list_free(data.expansions); + + return data.res; +} + +/* Internal data structure for isl_schedule_node_get_subtree_contraction. + * "contractions" contains a list of accumulated contractions + * for each outer expansion, set or sequence node. The first element + * in the list is an identity mapping on the reaching domain elements. + * "res" collects the results. + */ +struct isl_subtree_contraction_data { + isl_union_pw_multi_aff_list *contractions; + isl_union_pw_multi_aff *res; +}; + +/* Callback for "traverse" to enter a node and to move + * to the deepest initial subtree that should be traversed + * by isl_schedule_node_get_subtree_contraction. + * + * Whenever we come across an expansion node, the last element + * of data->contractions is combined with the contraction + * on the expansion node. + * + * Whenever we come across a filter node that is the child + * of a set or sequence node, data->contractions is extended + * with a new element that restricts the previous element + * to the elements selected by the filter. + * The previous element can then be reused while backtracking. + */ +static __isl_give isl_schedule_node *subtree_contraction_enter( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_contraction_data *data = user; + + do { + enum isl_schedule_node_type type; + isl_union_set *filter; + isl_union_pw_multi_aff *inner, *contraction; + int n; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + filter = isl_schedule_node_filter_get_filter(node); + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + inner = + isl_union_pw_multi_aff_list_get_union_pw_multi_aff( + data->contractions, n - 1); + inner = isl_union_pw_multi_aff_intersect_domain(inner, + filter); + data->contractions = + isl_union_pw_multi_aff_list_add(data->contractions, + inner); + break; + case isl_schedule_node_expansion: + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + contraction = + isl_schedule_node_expansion_get_contraction(node); + inner = + isl_union_pw_multi_aff_list_get_union_pw_multi_aff( + data->contractions, n - 1); + inner = + isl_union_pw_multi_aff_pullback_union_pw_multi_aff( + inner, contraction); + data->contractions = + isl_union_pw_multi_aff_list_set_union_pw_multi_aff( + data->contractions, n - 1, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + } while (isl_schedule_node_has_children(node) && + (node = isl_schedule_node_first_child(node)) != NULL); + + return node; +} + +/* Callback for "traverse" to leave a node for + * isl_schedule_node_get_subtree_contraction. + * + * If we come across a filter node that is the child + * of a set or sequence node, then we remove the element + * of data->contractions that was added in subtree_contraction_enter. + * + * If we reach a leaf node, then the accumulated contraction is + * added to data->res. + */ +static __isl_give isl_schedule_node *subtree_contraction_leave( + __isl_take isl_schedule_node *node, void *user) +{ + struct isl_subtree_contraction_data *data = user; + int n; + isl_union_pw_multi_aff *inner; + enum isl_schedule_node_type type; + + switch (isl_schedule_node_get_type(node)) { + case isl_schedule_node_error: + return isl_schedule_node_free(node); + case isl_schedule_node_filter: + type = isl_schedule_node_get_parent_type(node); + if (type != isl_schedule_node_set && + type != isl_schedule_node_sequence) + break; + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + data->contractions = + isl_union_pw_multi_aff_list_drop(data->contractions, + n - 1, 1); + break; + case isl_schedule_node_leaf: + n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff( + data->contractions); + inner = isl_union_pw_multi_aff_list_get_union_pw_multi_aff( + data->contractions, n - 1); + data->res = isl_union_pw_multi_aff_union_add(data->res, inner); + break; + case isl_schedule_node_band: + case isl_schedule_node_context: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return node; +} + +/* Return a mapping from the domain elements in the leaves of the subtree + * rooted at "node" to the corresponding domain elements that reach "node" + * obtained by composing the intermediate contractions. + * + * We start out with an identity mapping between the domain elements + * that reach "node" and compose it with all the contractions + * on a path from "node" to a leaf while traversing the subtree. + * Within the children of an a sequence or set node, the + * accumulated contraction is restricted to the elements selected + * by the filter child. + */ +__isl_give isl_union_pw_multi_aff *isl_schedule_node_get_subtree_contraction( + __isl_keep isl_schedule_node *node) +{ + struct isl_subtree_contraction_data data; + isl_space *space; + isl_union_set *domain; + isl_union_pw_multi_aff *contraction; + + if (!node) + return NULL; + + domain = isl_schedule_node_get_universe_domain(node); + space = isl_union_set_get_space(domain); + contraction = isl_union_set_identity_union_pw_multi_aff(domain); + data.res = isl_union_pw_multi_aff_empty(space); + data.contractions = + isl_union_pw_multi_aff_list_from_union_pw_multi_aff(contraction); + + node = isl_schedule_node_copy(node); + node = traverse(node, &subtree_contraction_enter, + &subtree_contraction_leave, &data); + if (!node) + data.res = isl_union_pw_multi_aff_free(data.res); + isl_schedule_node_free(node); + + isl_union_pw_multi_aff_list_free(data.contractions); + + return data.res; +} + +/* Do the nearest "n" ancestors of "node" have the types given in "types" + * (starting at the parent of "node")? + */ +static int has_ancestors(__isl_keep isl_schedule_node *node, + int n, enum isl_schedule_node_type *types) +{ + int i, n_ancestor; + + if (!node) + return -1; + + n_ancestor = isl_schedule_tree_list_n_schedule_tree(node->ancestors); + if (n_ancestor < n) + return 0; + + for (i = 0; i < n; ++i) { + isl_schedule_tree *tree; + int correct_type; + + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, + n_ancestor - 1 - i); + if (!tree) + return -1; + correct_type = isl_schedule_tree_get_type(tree) == types[i]; + isl_schedule_tree_free(tree); + if (!correct_type) + return 0; + } + + return 1; +} + +/* Given a node "node" that appears in an extension (i.e., it is the child + * of a filter in a sequence inside an extension node), are the spaces + * of the extension specified by "extension" disjoint from those + * of both the original extension and the domain elements that reach + * that original extension? + */ +static int is_disjoint_extension(__isl_keep isl_schedule_node *node, + __isl_keep isl_union_map *extension) +{ + isl_union_map *old; + isl_union_set *domain; + int empty; + + node = isl_schedule_node_copy(node); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_parent(node); + old = isl_schedule_node_extension_get_extension(node); + domain = isl_schedule_node_get_universe_domain(node); + isl_schedule_node_free(node); + old = isl_union_map_universe(old); + domain = isl_union_set_union(domain, isl_union_map_range(old)); + extension = isl_union_map_copy(extension); + extension = isl_union_map_intersect_range(extension, domain); + empty = isl_union_map_is_empty(extension); + isl_union_map_free(extension); + + return empty; +} + +/* Given a node "node" that is governed by an extension node, extend + * that extension node with "extension". + * + * In particular, "node" is the child of a filter in a sequence that + * is in turn a child of an extension node. Extend that extension node + * with "extension". + * + * Return a pointer to the parent of the original node (i.e., a filter). + */ +static __isl_give isl_schedule_node *extend_extension( + __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension) +{ + int pos; + int disjoint; + isl_union_map *node_extension; + + node = isl_schedule_node_parent(node); + pos = isl_schedule_node_get_child_position(node); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_parent(node); + node_extension = isl_schedule_node_extension_get_extension(node); + disjoint = isl_union_map_is_disjoint(extension, node_extension); + extension = isl_union_map_union(extension, node_extension); + node = isl_schedule_node_extension_set_extension(node, extension); + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_child(node, pos); + + if (disjoint < 0) + return isl_schedule_node_free(node); + if (!node) + return NULL; + if (!disjoint) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "extension domain should be disjoint from earlier " + "extensions", return isl_schedule_node_free(node)); + + return node; +} + +/* Return the universe of "uset" if this universe is disjoint from "ref". + * Otherwise, return "uset". + * + * Also check if "uset" itself is disjoint from "ref", reporting + * an error if it is not. + */ +static __isl_give isl_union_set *replace_by_universe_if_disjoint( + __isl_take isl_union_set *uset, __isl_keep isl_union_set *ref) +{ + int disjoint; + isl_union_set *universe; + + disjoint = isl_union_set_is_disjoint(uset, ref); + if (disjoint < 0) + return isl_union_set_free(uset); + if (!disjoint) + isl_die(isl_union_set_get_ctx(uset), isl_error_invalid, + "extension domain should be disjoint from " + "current domain", return isl_union_set_free(uset)); + + universe = isl_union_set_universe(isl_union_set_copy(uset)); + disjoint = isl_union_set_is_disjoint(universe, ref); + if (disjoint >= 0 && disjoint) { + isl_union_set_free(uset); + return universe; + } + isl_union_set_free(universe); + + if (disjoint < 0) + return isl_union_set_free(uset); + return uset; +} + +/* Insert an extension node on top of "node" with extension "extension". + * In addition, insert a filter that separates node from the extension + * between the extension node and "node". + * Return a pointer to the inserted filter node. + * + * If "node" already appears in an extension (i.e., if it is the child + * of a filter in a sequence inside an extension node), then extend that + * extension with "extension" instead. + * In this case, a pointer to the original filter node is returned. + * Note that if some of the elements in the new extension live in the + * same space as those of the original extension or the domain elements + * reaching the original extension, then we insert a new extension anyway. + * Otherwise, we would have to adjust the filters in the sequence child + * of the extension to ensure that the elements in the new extension + * are filtered out. + */ +static __isl_give isl_schedule_node *insert_extension( + __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension) +{ + enum isl_schedule_node_type ancestors[] = + { isl_schedule_node_filter, isl_schedule_node_sequence, + isl_schedule_node_extension }; + isl_union_set *domain; + isl_union_set *filter; + int in_ext; + + in_ext = has_ancestors(node, 3, ancestors); + if (in_ext < 0) + goto error; + if (in_ext) { + int disjoint; + + disjoint = is_disjoint_extension(node, extension); + if (disjoint < 0) + goto error; + if (disjoint) + return extend_extension(node, extension); + } + + filter = isl_schedule_node_get_domain(node); + domain = isl_union_map_range(isl_union_map_copy(extension)); + filter = replace_by_universe_if_disjoint(filter, domain); + isl_union_set_free(domain); + + node = isl_schedule_node_insert_filter(node, filter); + node = isl_schedule_node_insert_extension(node, extension); + node = isl_schedule_node_child(node, 0); + return node; +error: + isl_schedule_node_free(node); + isl_union_map_free(extension); + return NULL; +} + +/* Replace the subtree that "node" points to by "tree" (which has + * a sequence root with two children), except if the parent of "node" + * is a sequence as well, in which case "tree" is spliced at the position + * of "node" in its parent. + * Return a pointer to the child of the "tree_pos" (filter) child of "tree" + * in the updated schedule tree. + */ +static __isl_give isl_schedule_node *graft_or_splice( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_tree *tree, + int tree_pos) +{ + int pos; + + if (isl_schedule_node_get_parent_type(node) == + isl_schedule_node_sequence) { + pos = isl_schedule_node_get_child_position(node); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_sequence_splice(node, pos, tree); + } else { + pos = 0; + node = isl_schedule_node_graft_tree(node, tree); + } + node = isl_schedule_node_child(node, pos + tree_pos); + node = isl_schedule_node_child(node, 0); + + return node; +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed before (if "before" is set) or after (if "before" is not set) + * the node that "node" points to. + * The root of "graft" is an extension node. + * Return a pointer to the node that "node" pointed to. + * + * We first insert an extension node on top of "node" (or extend + * the extension node if there already is one), with a filter on "node" + * separating it from the extension. + * We then insert a filter in the graft to separate it from the original + * domain elements and combine the original and new tree in a sequence. + * If we have extended an extension node, then the children of this + * sequence are spliced in the sequence of the extended extension + * at the position where "node" appears in the original extension. + * Otherwise, the sequence pair is attached to the new extension node. + */ +static __isl_give isl_schedule_node *graft_extension( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_node *graft, + int before) +{ + isl_union_map *extension; + isl_union_set *graft_domain; + isl_union_set *node_domain; + isl_schedule_tree *tree, *tree_graft; + + extension = isl_schedule_node_extension_get_extension(graft); + graft_domain = isl_union_map_range(isl_union_map_copy(extension)); + node_domain = isl_schedule_node_get_universe_domain(node); + node = insert_extension(node, extension); + + graft_domain = replace_by_universe_if_disjoint(graft_domain, + node_domain); + isl_union_set_free(node_domain); + + tree = isl_schedule_node_get_tree(node); + if (!isl_schedule_node_has_children(graft)) { + tree_graft = isl_schedule_tree_from_filter(graft_domain); + } else { + graft = isl_schedule_node_child(graft, 0); + tree_graft = isl_schedule_node_get_tree(graft); + tree_graft = isl_schedule_tree_insert_filter(tree_graft, + graft_domain); + } + if (before) + tree = isl_schedule_tree_sequence_pair(tree_graft, tree); + else + tree = isl_schedule_tree_sequence_pair(tree, tree_graft); + node = graft_or_splice(node, tree, before); + + isl_schedule_node_free(graft); + + return node; +} + +/* Replace the root domain node of "node" by an extension node suitable + * for insertion at "pos". + * That is, create an extension node that maps the outer band nodes + * at "pos" to the domain of the root node of "node" and attach + * the child of this root node to the extension node. + */ +static __isl_give isl_schedule_node *extension_from_domain( + __isl_take isl_schedule_node *node, __isl_keep isl_schedule_node *pos) +{ + isl_union_set *universe; + isl_union_set *domain; + isl_union_map *ext; + int depth; + int anchored; + isl_space *space; + isl_schedule_node *res; + isl_schedule_tree *tree; + + anchored = isl_schedule_node_is_subtree_anchored(node); + if (anchored < 0) + return isl_schedule_node_free(node); + if (anchored) + isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported, + "cannot graft anchored tree with domain root", + return isl_schedule_node_free(node)); + + depth = isl_schedule_node_get_schedule_depth(pos); + domain = isl_schedule_node_domain_get_domain(node); + space = isl_union_set_get_space(domain); + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, depth); + universe = isl_union_set_from_set(isl_set_universe(space)); + ext = isl_union_map_from_domain_and_range(universe, domain); + res = isl_schedule_node_from_extension(ext); + node = isl_schedule_node_child(node, 0); + if (!node) + return isl_schedule_node_free(res); + if (!isl_schedule_tree_is_leaf(node->tree)) { + tree = isl_schedule_node_get_tree(node); + res = isl_schedule_node_child(res, 0); + res = isl_schedule_node_graft_tree(res, tree); + res = isl_schedule_node_parent(res); + } + isl_schedule_node_free(node); + + return res; +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed before (if "before" is set) or after (if "before" is not set) + * the node that "node" points to. + * The root of "graft" may be either a domain or an extension node. + * In the latter case, the domain of the extension needs to correspond + * to the outer band nodes of "node". + * The elements of the domain or the range of the extension may not + * intersect with the domain elements that reach "node". + * The schedule tree of "graft" may not be anchored. + * + * The schedule tree of "node" is modified to include an extension node + * corresponding to the root node of "graft" as a child of the original + * parent of "node". The original node that "node" points to and the + * child of the root node of "graft" are attached to this extension node + * through a sequence, with appropriate filters and with the child + * of "graft" appearing before or after the original "node". + * + * If "node" already appears inside a sequence that is the child of + * an extension node and if the spaces of the new domain elements + * do not overlap with those of the original domain elements, + * then that extension node is extended with the new extension + * rather than introducing a new segment of extension and sequence nodes. + * + * Return a pointer to the same node in the modified tree that + * "node" pointed to in the original tree. + */ +static __isl_give isl_schedule_node *isl_schedule_node_graft_before_or_after( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_node *graft, + int before) +{ + if (!node || !graft) + goto error; + if (check_insert(node) < 0) + goto error; + + if (isl_schedule_node_get_type(graft) == isl_schedule_node_domain) + graft = extension_from_domain(graft, node); + + if (isl_schedule_node_get_type(graft) != isl_schedule_node_extension) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "expecting domain or extension as root of graft", + goto error); + + return graft_extension(node, graft, before); +error: + isl_schedule_node_free(node); + isl_schedule_node_free(graft); + return NULL; +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed before the node that "node" points to. + * The root of "graft" may be either a domain or an extension node. + * In the latter case, the domain of the extension needs to correspond + * to the outer band nodes of "node". + * The elements of the domain or the range of the extension may not + * intersect with the domain elements that reach "node". + * The schedule tree of "graft" may not be anchored. + * + * Return a pointer to the same node in the modified tree that + * "node" pointed to in the original tree. + */ +__isl_give isl_schedule_node *isl_schedule_node_graft_before( + __isl_take isl_schedule_node *node, __isl_take isl_schedule_node *graft) +{ + return isl_schedule_node_graft_before_or_after(node, graft, 1); +} + +/* Insert a node "graft" into the schedule tree of "node" such that it + * is executed after the node that "node" points to. + * The root of "graft" may be either a domain or an extension node. + * In the latter case, the domain of the extension needs to correspond + * to the outer band nodes of "node". + * The elements of the domain or the range of the extension may not + * intersect with the domain elements that reach "node". + * The schedule tree of "graft" may not be anchored. + * + * Return a pointer to the same node in the modified tree that + * "node" pointed to in the original tree. + */ +__isl_give isl_schedule_node *isl_schedule_node_graft_after( + __isl_take isl_schedule_node *node, + __isl_take isl_schedule_node *graft) +{ + return isl_schedule_node_graft_before_or_after(node, graft, 0); +} + +/* Split the domain elements that reach "node" into those that satisfy + * "filter" and those that do not. Arrange for the first subset to be + * executed after the second subset. + * Return a pointer to the tree corresponding to the second subset, + * except when this subset is empty in which case the original pointer + * is returned. + * If both subsets are non-empty, then a sequence node is introduced + * to impose the order. If the grandparent of the original node was + * itself a sequence, then the original child is replaced by two children + * in this sequence instead. + * The children in the sequence are copies of the original subtree, + * simplified with respect to their filters. + */ +__isl_give isl_schedule_node *isl_schedule_node_order_after( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter) +{ + enum isl_schedule_node_type ancestors[] = + { isl_schedule_node_filter, isl_schedule_node_sequence }; + isl_union_set *node_domain, *node_filter = NULL; + isl_schedule_node *node2; + isl_schedule_tree *tree1, *tree2; + int empty1, empty2; + int in_seq; + + if (!node || !filter) + goto error; + if (check_insert(node) < 0) + goto error; + + in_seq = has_ancestors(node, 2, ancestors); + if (in_seq < 0) + goto error; + if (in_seq) + node = isl_schedule_node_parent(node); + node_domain = isl_schedule_node_get_domain(node); + filter = isl_union_set_gist(filter, isl_union_set_copy(node_domain)); + node_filter = isl_union_set_copy(node_domain); + node_filter = isl_union_set_subtract(node_filter, + isl_union_set_copy(filter)); + node_filter = isl_union_set_gist(node_filter, node_domain); + empty1 = isl_union_set_is_empty(filter); + empty2 = isl_union_set_is_empty(node_filter); + if (empty1 < 0 || empty2 < 0) + goto error; + if (empty1 || empty2) { + isl_union_set_free(filter); + isl_union_set_free(node_filter); + return node; + } + + node2 = isl_schedule_node_copy(node); + node = isl_schedule_node_gist(node, isl_union_set_copy(node_filter)); + node2 = isl_schedule_node_gist(node2, isl_union_set_copy(filter)); + tree1 = isl_schedule_node_get_tree(node); + tree2 = isl_schedule_node_get_tree(node2); + isl_schedule_node_free(node2); + tree1 = isl_schedule_tree_insert_filter(tree1, node_filter); + tree2 = isl_schedule_tree_insert_filter(tree2, filter); + tree1 = isl_schedule_tree_sequence_pair(tree1, tree2); + + node = graft_or_splice(node, tree1, 0); + + return node; +error: + isl_schedule_node_free(node); + isl_union_set_free(filter); + isl_union_set_free(node_filter); + return NULL; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in the schedule node "node". + */ +__isl_give isl_schedule_node *isl_schedule_node_reset_user( + __isl_take isl_schedule_node *node) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_reset_user(tree); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Align the parameters of the schedule node "node" to those of "space". + */ +__isl_give isl_schedule_node *isl_schedule_node_align_params( + __isl_take isl_schedule_node *node, __isl_take isl_space *space) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_align_params(tree, space); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Compute the pullback of schedule node "node" + * by the function represented by "upma". + * In other words, plug in "upma" in the iteration domains + * of schedule node "node". + * We currently do not handle expansion nodes. + * + * Note that this is only a helper function for + * isl_schedule_pullback_union_pw_multi_aff. In order to maintain consistency, + * this function should not be called on a single node without also + * calling it on all the other nodes. + */ +__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *upma) +{ + isl_schedule_tree *tree; + + tree = isl_schedule_node_get_tree(node); + tree = isl_schedule_tree_pullback_union_pw_multi_aff(tree, upma); + node = isl_schedule_node_graft_tree(node, tree); + + return node; +} + +/* Return the position of the subtree containing "node" among the children + * of "ancestor". "node" is assumed to be a descendant of "ancestor". + * In particular, both nodes should point to the same schedule tree. + * + * Return -1 on error. + */ +int isl_schedule_node_get_ancestor_child_position( + __isl_keep isl_schedule_node *node, + __isl_keep isl_schedule_node *ancestor) +{ + int n1, n2; + isl_schedule_tree *tree; + + if (!node || !ancestor) + return -1; + + if (node->schedule != ancestor->schedule) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a descendant", return -1); + + n1 = isl_schedule_node_get_tree_depth(ancestor); + n2 = isl_schedule_node_get_tree_depth(node); + + if (n1 >= n2) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a descendant", return -1); + tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n1); + isl_schedule_tree_free(tree); + if (tree != ancestor->tree) + isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid, + "not a descendant", return -1); + + return node->child_pos[n1]; +} + +/* Given two nodes that point to the same schedule tree, return their + * closest shared ancestor. + * + * Since the two nodes point to the same schedule, they share at least + * one ancestor, the root of the schedule. We move down from the root + * to the first ancestor where the respective children have a different + * child position. This is the requested ancestor. + * If there is no ancestor where the children have a different position, + * then one node is an ancestor of the other and then this node is + * the requested ancestor. + */ +__isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor( + __isl_keep isl_schedule_node *node1, + __isl_keep isl_schedule_node *node2) +{ + int i, n1, n2; + + if (!node1 || !node2) + return NULL; + if (node1->schedule != node2->schedule) + isl_die(isl_schedule_node_get_ctx(node1), isl_error_invalid, + "not part of same schedule", return NULL); + n1 = isl_schedule_node_get_tree_depth(node1); + n2 = isl_schedule_node_get_tree_depth(node2); + if (n2 < n1) + return isl_schedule_node_get_shared_ancestor(node2, node1); + if (n1 == 0) + return isl_schedule_node_copy(node1); + if (isl_schedule_node_is_equal(node1, node2)) + return isl_schedule_node_copy(node1); + + for (i = 0; i < n1; ++i) + if (node1->child_pos[i] != node2->child_pos[i]) + break; + + node1 = isl_schedule_node_copy(node1); + return isl_schedule_node_ancestor(node1, n1 - i); +} + +/* Print "node" to "p". + */ +__isl_give isl_printer *isl_printer_print_schedule_node( + __isl_take isl_printer *p, __isl_keep isl_schedule_node *node) +{ + if (!node) + return isl_printer_free(p); + return isl_printer_print_schedule_tree_mark(p, node->schedule->root, + isl_schedule_tree_list_n_schedule_tree(node->ancestors), + node->child_pos); +} + +void isl_schedule_node_dump(__isl_keep isl_schedule_node *node) +{ + isl_ctx *ctx; + isl_printer *printer; + + if (!node) + return; + + ctx = isl_schedule_node_get_ctx(node); + printer = isl_printer_to_file(ctx, stderr); + printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK); + printer = isl_printer_print_schedule_node(printer, node); + + isl_printer_free(printer); +} diff -Nru isl-0.12.2/isl_schedule_node_private.h isl-0.15/isl_schedule_node_private.h --- isl-0.12.2/isl_schedule_node_private.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_node_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,56 @@ +#ifndef ISL_SCHEDLUE_NODE_PRIVATE_H +#define ISL_SCHEDLUE_NODE_PRIVATE_H + +#include +#include + +/* An isl_schedule_node points to a particular location in a schedule tree. + * + * "schedule" is the schedule that the node is pointing to. + * "ancestors" is a list of the n ancestors of the node + * that is being pointed to. + * The first ancestor is the root of "schedule", while the last ancestor + * is the parent of the specified location. + * "child_pos" is an array of child positions of the same length as "ancestors", + * where ancestor i (i > 0) appears in child_pos[i - 1] of ancestor i - 1 and + * "tree" appears in child_pos[n - 1] of ancestor n - 1. + * "tree" is the subtree at the specified location. + * + * Note that the same isl_schedule_tree object may appear several times + * in a schedule tree and therefore does not uniquely identify a position + * in the schedule tree. + */ +struct isl_schedule_node { + int ref; + + isl_schedule *schedule; + isl_schedule_tree_list *ancestors; + int *child_pos; + isl_schedule_tree *tree; +}; + +__isl_give isl_schedule_node *isl_schedule_node_alloc( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree, + __isl_take isl_schedule_tree_list *ancestors, int *child_pos); +__isl_give isl_schedule_node *isl_schedule_node_graft_tree( + __isl_take isl_schedule_node *pos, __isl_take isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_node_get_tree( + __isl_keep isl_schedule_node *node); + +__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_schedule_node *isl_schedule_node_domain_intersect_domain( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *domain); + +__isl_give isl_schedule_node *isl_schedule_node_insert_expansion( + __isl_take isl_schedule_node *node, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_schedule_node *isl_schedule_node_insert_extension( + __isl_take isl_schedule_node *node, + __isl_take isl_union_map *extension); + +#endif diff -Nru isl-0.12.2/isl_schedule_private.h isl-0.15/isl_schedule_private.h --- isl-0.12.2/isl_schedule_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_schedule_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -3,43 +3,39 @@ #include #include +#include -/* The schedule for an individual domain, plus information about the bands - * and scheduling dimensions. - * In particular, we keep track of the number of bands and for each - * band, the starting position of the next band. The first band starts at - * position 0. - * For each scheduling dimension, we keep track of whether it result - * in zero dependence distances (within its band) with respect - * to the proximity edges. - */ -struct isl_schedule_node { - isl_multi_aff *sched; - int n_band; - int *band_end; - int *band_id; - int *zero; -}; - -/* Information about the computed schedule. - * n is the number of nodes/domains/statements. - * n_band is the maximal number of bands. - * n_total_row is the number of coordinates of the schedule. - * dim contains a description of the parameters. +/* A complete schedule tree. + * * band_forest points to a band forest representation of the schedule * and may be NULL if the forest hasn't been created yet. + * + * "root" is the root of the schedule tree and may be NULL if we + * have created a band forest corresponding to the schedule. + * + * A pointer to "leaf" may be used to represent a leaf of the schedule. + * It should not appear as a child to any other isl_schedule_tree objects, + * but an isl_schedule_node may point to "leaf" if it refers to + * a leaf of this schedule tree. */ struct isl_schedule { int ref; - int n; - int n_band; - int n_total_row; - isl_space *dim; - isl_band_list *band_forest; + isl_schedule_tree *root; - struct isl_schedule_node node[1]; + struct isl_schedule_tree leaf; }; +__isl_give isl_schedule *isl_schedule_from_schedule_tree(isl_ctx *ctx, + __isl_take isl_schedule_tree *tree); +__isl_give isl_schedule *isl_schedule_set_root( + __isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree); +__isl_give isl_space *isl_schedule_get_space( + __isl_keep isl_schedule *schedule); +__isl_give isl_union_set *isl_schedule_get_domain( + __isl_keep isl_schedule *schedule); +__isl_keep isl_schedule_tree *isl_schedule_peek_leaf( + __isl_keep isl_schedule *schedule); + #endif diff -Nru isl-0.12.2/isl_scheduler.c isl-0.15/isl_scheduler.c --- isl-0.12.2/isl_scheduler.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_scheduler.c 2015-06-10 19:10:55.000000000 +0000 @@ -0,0 +1,4364 @@ +/* + * Copyright 2011 INRIA Saclay + * Copyright 2012-2014 Ecole Normale Superieure + * Copyright 2015 Sven Verdoolaege + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, + * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, + * 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The scheduling algorithm implemented in this file was inspired by + * Bondhugula et al., "Automatic Transformations for Communication-Minimized + * Parallelization and Locality Optimization in the Polyhedral Model". + */ + +enum isl_edge_type { + isl_edge_validity = 0, + isl_edge_first = isl_edge_validity, + isl_edge_coincidence, + isl_edge_condition, + isl_edge_conditional_validity, + isl_edge_proximity, + isl_edge_last = isl_edge_proximity +}; + +/* The constraints that need to be satisfied by a schedule on "domain". + * + * "context" specifies extra constraints on the parameters. + * + * "validity" constraints map domain elements i to domain elements + * that should be scheduled after i. (Hard constraint) + * "proximity" constraints map domain elements i to domains elements + * that should be scheduled as early as possible after i (or before i). + * (Soft constraint) + * + * "condition" and "conditional_validity" constraints map possibly "tagged" + * domain elements i -> s to "tagged" domain elements j -> t. + * The elements of the "conditional_validity" constraints, but without the + * tags (i.e., the elements i -> j) are treated as validity constraints, + * except that during the construction of a tilable band, + * the elements of the "conditional_validity" constraints may be violated + * provided that all adjacent elements of the "condition" constraints + * are local within the band. + * A dependence is local within a band if domain and range are mapped + * to the same schedule point by the band. + */ +struct isl_schedule_constraints { + isl_union_set *domain; + isl_set *context; + + isl_union_map *constraint[isl_edge_last + 1]; +}; + +__isl_give isl_schedule_constraints *isl_schedule_constraints_copy( + __isl_keep isl_schedule_constraints *sc) +{ + isl_ctx *ctx; + isl_schedule_constraints *sc_copy; + enum isl_edge_type i; + + ctx = isl_union_set_get_ctx(sc->domain); + sc_copy = isl_calloc_type(ctx, struct isl_schedule_constraints); + if (!sc_copy) + return NULL; + + sc_copy->domain = isl_union_set_copy(sc->domain); + sc_copy->context = isl_set_copy(sc->context); + if (!sc_copy->domain || !sc_copy->context) + return isl_schedule_constraints_free(sc_copy); + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + sc_copy->constraint[i] = isl_union_map_copy(sc->constraint[i]); + if (!sc_copy->constraint[i]) + return isl_schedule_constraints_free(sc_copy); + } + + return sc_copy; +} + + +/* Construct an isl_schedule_constraints object for computing a schedule + * on "domain". The initial object does not impose any constraints. + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain( + __isl_take isl_union_set *domain) +{ + isl_ctx *ctx; + isl_space *space; + isl_schedule_constraints *sc; + isl_union_map *empty; + enum isl_edge_type i; + + if (!domain) + return NULL; + + ctx = isl_union_set_get_ctx(domain); + sc = isl_calloc_type(ctx, struct isl_schedule_constraints); + if (!sc) + goto error; + + space = isl_union_set_get_space(domain); + sc->domain = domain; + sc->context = isl_set_universe(isl_space_copy(space)); + empty = isl_union_map_empty(space); + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + sc->constraint[i] = isl_union_map_copy(empty); + if (!sc->constraint[i]) + sc->domain = isl_union_set_free(sc->domain); + } + isl_union_map_free(empty); + + if (!sc->domain || !sc->context) + return isl_schedule_constraints_free(sc); + + return sc; +error: + isl_union_set_free(domain); + return NULL; +} + +/* Replace the context of "sc" by "context". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_context( + __isl_take isl_schedule_constraints *sc, __isl_take isl_set *context) +{ + if (!sc || !context) + goto error; + + isl_set_free(sc->context); + sc->context = context; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_set_free(context); + return NULL; +} + +/* Replace the validity constraints of "sc" by "validity". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *validity) +{ + if (!sc || !validity) + goto error; + + isl_union_map_free(sc->constraint[isl_edge_validity]); + sc->constraint[isl_edge_validity] = validity; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(validity); + return NULL; +} + +/* Replace the coincidence constraints of "sc" by "coincidence". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_coincidence( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *coincidence) +{ + if (!sc || !coincidence) + goto error; + + isl_union_map_free(sc->constraint[isl_edge_coincidence]); + sc->constraint[isl_edge_coincidence] = coincidence; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(coincidence); + return NULL; +} + +/* Replace the proximity constraints of "sc" by "proximity". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_set_proximity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *proximity) +{ + if (!sc || !proximity) + goto error; + + isl_union_map_free(sc->constraint[isl_edge_proximity]); + sc->constraint[isl_edge_proximity] = proximity; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(proximity); + return NULL; +} + +/* Replace the conditional validity constraints of "sc" by "condition" + * and "validity". + */ +__isl_give isl_schedule_constraints * +isl_schedule_constraints_set_conditional_validity( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_map *condition, + __isl_take isl_union_map *validity) +{ + if (!sc || !condition || !validity) + goto error; + + isl_union_map_free(sc->constraint[isl_edge_condition]); + sc->constraint[isl_edge_condition] = condition; + isl_union_map_free(sc->constraint[isl_edge_conditional_validity]); + sc->constraint[isl_edge_conditional_validity] = validity; + + return sc; +error: + isl_schedule_constraints_free(sc); + isl_union_map_free(condition); + isl_union_map_free(validity); + return NULL; +} + +__isl_null isl_schedule_constraints *isl_schedule_constraints_free( + __isl_take isl_schedule_constraints *sc) +{ + enum isl_edge_type i; + + if (!sc) + return NULL; + + isl_union_set_free(sc->domain); + isl_set_free(sc->context); + for (i = isl_edge_first; i <= isl_edge_last; ++i) + isl_union_map_free(sc->constraint[i]); + + free(sc); + + return NULL; +} + +isl_ctx *isl_schedule_constraints_get_ctx( + __isl_keep isl_schedule_constraints *sc) +{ + return sc ? isl_union_set_get_ctx(sc->domain) : NULL; +} + +/* Return the validity constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_validity( + __isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return NULL; + + return isl_union_map_copy(sc->constraint[isl_edge_validity]); +} + +/* Return the coincidence constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_coincidence( + __isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return NULL; + + return isl_union_map_copy(sc->constraint[isl_edge_coincidence]); +} + +/* Return the conditional validity constraints of "sc". + */ +__isl_give isl_union_map *isl_schedule_constraints_get_conditional_validity( + __isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return NULL; + + return + isl_union_map_copy(sc->constraint[isl_edge_conditional_validity]); +} + +/* Return the conditions for the conditional validity constraints of "sc". + */ +__isl_give isl_union_map * +isl_schedule_constraints_get_conditional_validity_condition( + __isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return NULL; + + return isl_union_map_copy(sc->constraint[isl_edge_condition]); +} + +void isl_schedule_constraints_dump(__isl_keep isl_schedule_constraints *sc) +{ + if (!sc) + return; + + fprintf(stderr, "domain: "); + isl_union_set_dump(sc->domain); + fprintf(stderr, "context: "); + isl_set_dump(sc->context); + fprintf(stderr, "validity: "); + isl_union_map_dump(sc->constraint[isl_edge_validity]); + fprintf(stderr, "proximity: "); + isl_union_map_dump(sc->constraint[isl_edge_proximity]); + fprintf(stderr, "coincidence: "); + isl_union_map_dump(sc->constraint[isl_edge_coincidence]); + fprintf(stderr, "condition: "); + isl_union_map_dump(sc->constraint[isl_edge_condition]); + fprintf(stderr, "conditional_validity: "); + isl_union_map_dump(sc->constraint[isl_edge_conditional_validity]); +} + +/* Align the parameters of the fields of "sc". + */ +static __isl_give isl_schedule_constraints * +isl_schedule_constraints_align_params(__isl_take isl_schedule_constraints *sc) +{ + isl_space *space; + enum isl_edge_type i; + + if (!sc) + return NULL; + + space = isl_union_set_get_space(sc->domain); + space = isl_space_align_params(space, isl_set_get_space(sc->context)); + for (i = isl_edge_first; i <= isl_edge_last; ++i) + space = isl_space_align_params(space, + isl_union_map_get_space(sc->constraint[i])); + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + sc->constraint[i] = isl_union_map_align_params( + sc->constraint[i], isl_space_copy(space)); + if (!sc->constraint[i]) + space = isl_space_free(space); + } + sc->context = isl_set_align_params(sc->context, isl_space_copy(space)); + sc->domain = isl_union_set_align_params(sc->domain, space); + if (!sc->context || !sc->domain) + return isl_schedule_constraints_free(sc); + + return sc; +} + +/* Return the total number of isl_maps in the constraints of "sc". + */ +static __isl_give int isl_schedule_constraints_n_map( + __isl_keep isl_schedule_constraints *sc) +{ + enum isl_edge_type i; + int n = 0; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) + n += isl_union_map_n_map(sc->constraint[i]); + + return n; +} + +/* Internal information about a node that is used during the construction + * of a schedule. + * space represents the space in which the domain lives + * sched is a matrix representation of the schedule being constructed + * for this node; if compressed is set, then this schedule is + * defined over the compressed domain space + * sched_map is an isl_map representation of the same (partial) schedule + * sched_map may be NULL; if compressed is set, then this map + * is defined over the uncompressed domain space + * rank is the number of linearly independent rows in the linear part + * of sched + * the columns of cmap represent a change of basis for the schedule + * coefficients; the first rank columns span the linear part of + * the schedule rows + * cinv is the inverse of cmap. + * start is the first variable in the LP problem in the sequences that + * represents the schedule coefficients of this node + * nvar is the dimension of the domain + * nparam is the number of parameters or 0 if we are not constructing + * a parametric schedule + * + * If compressed is set, then hull represents the constraints + * that were used to derive the compression, while compress and + * decompress map the original space to the compressed space and + * vice versa. + * + * scc is the index of SCC (or WCC) this node belongs to + * + * coincident contains a boolean for each of the rows of the schedule, + * indicating whether the corresponding scheduling dimension satisfies + * the coincidence constraints in the sense that the corresponding + * dependence distances are zero. + */ +struct isl_sched_node { + isl_space *space; + int compressed; + isl_set *hull; + isl_multi_aff *compress; + isl_multi_aff *decompress; + isl_mat *sched; + isl_map *sched_map; + int rank; + isl_mat *cmap; + isl_mat *cinv; + int start; + int nvar; + int nparam; + + int scc; + + int *coincident; +}; + +static int node_has_space(const void *entry, const void *val) +{ + struct isl_sched_node *node = (struct isl_sched_node *)entry; + isl_space *dim = (isl_space *)val; + + return isl_space_is_equal(node->space, dim); +} + +static int node_scc_exactly(struct isl_sched_node *node, int scc) +{ + return node->scc == scc; +} + +static int node_scc_at_most(struct isl_sched_node *node, int scc) +{ + return node->scc <= scc; +} + +static int node_scc_at_least(struct isl_sched_node *node, int scc) +{ + return node->scc >= scc; +} + +/* An edge in the dependence graph. An edge may be used to + * ensure validity of the generated schedule, to minimize the dependence + * distance or both + * + * map is the dependence relation, with i -> j in the map if j depends on i + * tagged_condition and tagged_validity contain the union of all tagged + * condition or conditional validity dependence relations that + * specialize the dependence relation "map"; that is, + * if (i -> a) -> (j -> b) is an element of "tagged_condition" + * or "tagged_validity", then i -> j is an element of "map". + * If these fields are NULL, then they represent the empty relation. + * src is the source node + * dst is the sink node + * validity is set if the edge is used to ensure correctness + * coincidence is used to enforce zero dependence distances + * proximity is set if the edge is used to minimize dependence distances + * condition is set if the edge represents a condition + * for a conditional validity schedule constraint + * local can only be set for condition edges and indicates that + * the dependence distance over the edge should be zero + * conditional_validity is set if the edge is used to conditionally + * ensure correctness + * + * For validity edges, start and end mark the sequence of inequality + * constraints in the LP problem that encode the validity constraint + * corresponding to this edge. + */ +struct isl_sched_edge { + isl_map *map; + isl_union_map *tagged_condition; + isl_union_map *tagged_validity; + + struct isl_sched_node *src; + struct isl_sched_node *dst; + + unsigned validity : 1; + unsigned coincidence : 1; + unsigned proximity : 1; + unsigned local : 1; + unsigned condition : 1; + unsigned conditional_validity : 1; + + int start; + int end; +}; + +/* Internal information about the dependence graph used during + * the construction of the schedule. + * + * intra_hmap is a cache, mapping dependence relations to their dual, + * for dependences from a node to itself + * inter_hmap is a cache, mapping dependence relations to their dual, + * for dependences between distinct nodes + * if compression is involved then the key for these maps + * it the original, uncompressed dependence relation, while + * the value is the dual of the compressed dependence relation. + * + * n is the number of nodes + * node is the list of nodes + * maxvar is the maximal number of variables over all nodes + * max_row is the allocated number of rows in the schedule + * n_row is the current (maximal) number of linearly independent + * rows in the node schedules + * n_total_row is the current number of rows in the node schedules + * band_start is the starting row in the node schedules of the current band + * root is set if this graph is the original dependence graph, + * without any splitting + * + * sorted contains a list of node indices sorted according to the + * SCC to which a node belongs + * + * n_edge is the number of edges + * edge is the list of edges + * max_edge contains the maximal number of edges of each type; + * in particular, it contains the number of edges in the inital graph. + * edge_table contains pointers into the edge array, hashed on the source + * and sink spaces; there is one such table for each type; + * a given edge may be referenced from more than one table + * if the corresponding relation appears in more than one of the + * sets of dependences + * + * node_table contains pointers into the node array, hashed on the space + * + * region contains a list of variable sequences that should be non-trivial + * + * lp contains the (I)LP problem used to obtain new schedule rows + * + * src_scc and dst_scc are the source and sink SCCs of an edge with + * conflicting constraints + * + * scc represents the number of components + * weak is set if the components are weakly connected + */ +struct isl_sched_graph { + isl_map_to_basic_set *intra_hmap; + isl_map_to_basic_set *inter_hmap; + + struct isl_sched_node *node; + int n; + int maxvar; + int max_row; + int n_row; + + int *sorted; + + int n_total_row; + int band_start; + + int root; + + struct isl_sched_edge *edge; + int n_edge; + int max_edge[isl_edge_last + 1]; + struct isl_hash_table *edge_table[isl_edge_last + 1]; + + struct isl_hash_table *node_table; + struct isl_region *region; + + isl_basic_set *lp; + + int src_scc; + int dst_scc; + + int scc; + int weak; +}; + +/* Initialize node_table based on the list of nodes. + */ +static int graph_init_table(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + graph->node_table = isl_hash_table_alloc(ctx, graph->n); + if (!graph->node_table) + return -1; + + for (i = 0; i < graph->n; ++i) { + struct isl_hash_table_entry *entry; + uint32_t hash; + + hash = isl_space_get_hash(graph->node[i].space); + entry = isl_hash_table_find(ctx, graph->node_table, hash, + &node_has_space, + graph->node[i].space, 1); + if (!entry) + return -1; + entry->data = &graph->node[i]; + } + + return 0; +} + +/* Return a pointer to the node that lives within the given space, + * or NULL if there is no such node. + */ +static struct isl_sched_node *graph_find_node(isl_ctx *ctx, + struct isl_sched_graph *graph, __isl_keep isl_space *dim) +{ + struct isl_hash_table_entry *entry; + uint32_t hash; + + hash = isl_space_get_hash(dim); + entry = isl_hash_table_find(ctx, graph->node_table, hash, + &node_has_space, dim, 0); + + return entry ? entry->data : NULL; +} + +static int edge_has_src_and_dst(const void *entry, const void *val) +{ + const struct isl_sched_edge *edge = entry; + const struct isl_sched_edge *temp = val; + + return edge->src == temp->src && edge->dst == temp->dst; +} + +/* Add the given edge to graph->edge_table[type]. + */ +static isl_stat graph_edge_table_add(isl_ctx *ctx, + struct isl_sched_graph *graph, enum isl_edge_type type, + struct isl_sched_edge *edge) +{ + struct isl_hash_table_entry *entry; + uint32_t hash; + + hash = isl_hash_init(); + hash = isl_hash_builtin(hash, edge->src); + hash = isl_hash_builtin(hash, edge->dst); + entry = isl_hash_table_find(ctx, graph->edge_table[type], hash, + &edge_has_src_and_dst, edge, 1); + if (!entry) + return isl_stat_error; + entry->data = edge; + + return isl_stat_ok; +} + +/* Allocate the edge_tables based on the maximal number of edges of + * each type. + */ +static int graph_init_edge_tables(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i <= isl_edge_last; ++i) { + graph->edge_table[i] = isl_hash_table_alloc(ctx, + graph->max_edge[i]); + if (!graph->edge_table[i]) + return -1; + } + + return 0; +} + +/* If graph->edge_table[type] contains an edge from the given source + * to the given destination, then return the hash table entry of this edge. + * Otherwise, return NULL. + */ +static struct isl_hash_table_entry *graph_find_edge_entry( + struct isl_sched_graph *graph, + enum isl_edge_type type, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + isl_ctx *ctx = isl_space_get_ctx(src->space); + uint32_t hash; + struct isl_sched_edge temp = { .src = src, .dst = dst }; + + hash = isl_hash_init(); + hash = isl_hash_builtin(hash, temp.src); + hash = isl_hash_builtin(hash, temp.dst); + return isl_hash_table_find(ctx, graph->edge_table[type], hash, + &edge_has_src_and_dst, &temp, 0); +} + + +/* If graph->edge_table[type] contains an edge from the given source + * to the given destination, then return this edge. + * Otherwise, return NULL. + */ +static struct isl_sched_edge *graph_find_edge(struct isl_sched_graph *graph, + enum isl_edge_type type, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + struct isl_hash_table_entry *entry; + + entry = graph_find_edge_entry(graph, type, src, dst); + if (!entry) + return NULL; + + return entry->data; +} + +/* Check whether the dependence graph has an edge of the given type + * between the given two nodes. + */ +static isl_bool graph_has_edge(struct isl_sched_graph *graph, + enum isl_edge_type type, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + struct isl_sched_edge *edge; + isl_bool empty; + + edge = graph_find_edge(graph, type, src, dst); + if (!edge) + return 0; + + empty = isl_map_plain_is_empty(edge->map); + if (empty < 0) + return isl_bool_error; + + return !empty; +} + +/* Look for any edge with the same src, dst and map fields as "model". + * + * Return the matching edge if one can be found. + * Return "model" if no matching edge is found. + * Return NULL on error. + */ +static struct isl_sched_edge *graph_find_matching_edge( + struct isl_sched_graph *graph, struct isl_sched_edge *model) +{ + enum isl_edge_type i; + struct isl_sched_edge *edge; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + int is_equal; + + edge = graph_find_edge(graph, i, model->src, model->dst); + if (!edge) + continue; + is_equal = isl_map_plain_is_equal(model->map, edge->map); + if (is_equal < 0) + return NULL; + if (is_equal) + return edge; + } + + return model; +} + +/* Remove the given edge from all the edge_tables that refer to it. + */ +static void graph_remove_edge(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + isl_ctx *ctx = isl_map_get_ctx(edge->map); + enum isl_edge_type i; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + struct isl_hash_table_entry *entry; + + entry = graph_find_edge_entry(graph, i, edge->src, edge->dst); + if (!entry) + continue; + if (entry->data != edge) + continue; + isl_hash_table_remove(ctx, graph->edge_table[i], entry); + } +} + +/* Check whether the dependence graph has any edge + * between the given two nodes. + */ +static isl_bool graph_has_any_edge(struct isl_sched_graph *graph, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + enum isl_edge_type i; + isl_bool r; + + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + r = graph_has_edge(graph, i, src, dst); + if (r < 0 || r) + return r; + } + + return r; +} + +/* Check whether the dependence graph has a validity edge + * between the given two nodes. + * + * Conditional validity edges are essentially validity edges that + * can be ignored if the corresponding condition edges are iteration private. + * Here, we are only checking for the presence of validity + * edges, so we need to consider the conditional validity edges too. + * In particular, this function is used during the detection + * of strongly connected components and we cannot ignore + * conditional validity edges during this detection. + */ +static isl_bool graph_has_validity_edge(struct isl_sched_graph *graph, + struct isl_sched_node *src, struct isl_sched_node *dst) +{ + isl_bool r; + + r = graph_has_edge(graph, isl_edge_validity, src, dst); + if (r < 0 || r) + return r; + + return graph_has_edge(graph, isl_edge_conditional_validity, src, dst); +} + +static int graph_alloc(isl_ctx *ctx, struct isl_sched_graph *graph, + int n_node, int n_edge) +{ + int i; + + graph->n = n_node; + graph->n_edge = n_edge; + graph->node = isl_calloc_array(ctx, struct isl_sched_node, graph->n); + graph->sorted = isl_calloc_array(ctx, int, graph->n); + graph->region = isl_alloc_array(ctx, struct isl_region, graph->n); + graph->edge = isl_calloc_array(ctx, + struct isl_sched_edge, graph->n_edge); + + graph->intra_hmap = isl_map_to_basic_set_alloc(ctx, 2 * n_edge); + graph->inter_hmap = isl_map_to_basic_set_alloc(ctx, 2 * n_edge); + + if (!graph->node || !graph->region || (graph->n_edge && !graph->edge) || + !graph->sorted) + return -1; + + for(i = 0; i < graph->n; ++i) + graph->sorted[i] = i; + + return 0; +} + +static void graph_free(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + isl_map_to_basic_set_free(graph->intra_hmap); + isl_map_to_basic_set_free(graph->inter_hmap); + + if (graph->node) + for (i = 0; i < graph->n; ++i) { + isl_space_free(graph->node[i].space); + isl_set_free(graph->node[i].hull); + isl_multi_aff_free(graph->node[i].compress); + isl_multi_aff_free(graph->node[i].decompress); + isl_mat_free(graph->node[i].sched); + isl_map_free(graph->node[i].sched_map); + isl_mat_free(graph->node[i].cmap); + isl_mat_free(graph->node[i].cinv); + if (graph->root) + free(graph->node[i].coincident); + } + free(graph->node); + free(graph->sorted); + if (graph->edge) + for (i = 0; i < graph->n_edge; ++i) { + isl_map_free(graph->edge[i].map); + isl_union_map_free(graph->edge[i].tagged_condition); + isl_union_map_free(graph->edge[i].tagged_validity); + } + free(graph->edge); + free(graph->region); + for (i = 0; i <= isl_edge_last; ++i) + isl_hash_table_free(ctx, graph->edge_table[i]); + isl_hash_table_free(ctx, graph->node_table); + isl_basic_set_free(graph->lp); +} + +/* For each "set" on which this function is called, increment + * graph->n by one and update graph->maxvar. + */ +static isl_stat init_n_maxvar(__isl_take isl_set *set, void *user) +{ + struct isl_sched_graph *graph = user; + int nvar = isl_set_dim(set, isl_dim_set); + + graph->n++; + if (nvar > graph->maxvar) + graph->maxvar = nvar; + + isl_set_free(set); + + return isl_stat_ok; +} + +/* Add the number of basic maps in "map" to *n. + */ +static isl_stat add_n_basic_map(__isl_take isl_map *map, void *user) +{ + int *n = user; + + *n += isl_map_n_basic_map(map); + isl_map_free(map); + + return isl_stat_ok; +} + +/* Compute the number of rows that should be allocated for the schedule. + * In particular, we need one row for each variable or one row + * for each basic map in the dependences. + * Note that it is practically impossible to exhaust both + * the number of dependences and the number of variables. + */ +static int compute_max_row(struct isl_sched_graph *graph, + __isl_keep isl_schedule_constraints *sc) +{ + enum isl_edge_type i; + int n_edge; + + graph->n = 0; + graph->maxvar = 0; + if (isl_union_set_foreach_set(sc->domain, &init_n_maxvar, graph) < 0) + return -1; + n_edge = 0; + for (i = isl_edge_first; i <= isl_edge_last; ++i) + if (isl_union_map_foreach_map(sc->constraint[i], + &add_n_basic_map, &n_edge) < 0) + return -1; + graph->max_row = n_edge + graph->maxvar; + + return 0; +} + +/* Does "bset" have any defining equalities for its set variables? + */ +static int has_any_defining_equality(__isl_keep isl_basic_set *bset) +{ + int i, n; + + if (!bset) + return -1; + + n = isl_basic_set_dim(bset, isl_dim_set); + for (i = 0; i < n; ++i) { + int has; + + has = isl_basic_set_has_defining_equality(bset, isl_dim_set, i, + NULL); + if (has < 0 || has) + return has; + } + + return 0; +} + +/* Add a new node to the graph representing the given space. + * "nvar" is the (possibly compressed) number of variables and + * may be smaller than then number of set variables in "space" + * if "compressed" is set. + * If "compressed" is set, then "hull" represents the constraints + * that were used to derive the compression, while "compress" and + * "decompress" map the original space to the compressed space and + * vice versa. + * If "compressed" is not set, then "hull", "compress" and "decompress" + * should be NULL. + */ +static isl_stat add_node(struct isl_sched_graph *graph, + __isl_take isl_space *space, int nvar, int compressed, + __isl_take isl_set *hull, __isl_take isl_multi_aff *compress, + __isl_take isl_multi_aff *decompress) +{ + int nparam; + isl_ctx *ctx; + isl_mat *sched; + int *coincident; + + if (!space) + return isl_stat_error; + + ctx = isl_space_get_ctx(space); + nparam = isl_space_dim(space, isl_dim_param); + if (!ctx->opt->schedule_parametric) + nparam = 0; + sched = isl_mat_alloc(ctx, 0, 1 + nparam + nvar); + graph->node[graph->n].space = space; + graph->node[graph->n].nvar = nvar; + graph->node[graph->n].nparam = nparam; + graph->node[graph->n].sched = sched; + graph->node[graph->n].sched_map = NULL; + coincident = isl_calloc_array(ctx, int, graph->max_row); + graph->node[graph->n].coincident = coincident; + graph->node[graph->n].compressed = compressed; + graph->node[graph->n].hull = hull; + graph->node[graph->n].compress = compress; + graph->node[graph->n].decompress = decompress; + graph->n++; + + if (!space || !sched || (graph->max_row && !coincident)) + return isl_stat_error; + if (compressed && (!hull || !compress || !decompress)) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Add a new node to the graph representing the given set. + * + * If any of the set variables is defined by an equality, then + * we perform variable compression such that we can perform + * the scheduling on the compressed domain. + */ +static isl_stat extract_node(__isl_take isl_set *set, void *user) +{ + int nvar; + int has_equality; + isl_space *space; + isl_basic_set *hull; + isl_set *hull_set; + isl_morph *morph; + isl_multi_aff *compress, *decompress; + struct isl_sched_graph *graph = user; + + space = isl_set_get_space(set); + hull = isl_set_affine_hull(set); + hull = isl_basic_set_remove_divs(hull); + nvar = isl_space_dim(space, isl_dim_set); + has_equality = has_any_defining_equality(hull); + + if (has_equality < 0) + goto error; + if (!has_equality) { + isl_basic_set_free(hull); + return add_node(graph, space, nvar, 0, NULL, NULL, NULL); + } + + morph = isl_basic_set_variable_compression(hull, isl_dim_set); + nvar = isl_morph_ran_dim(morph, isl_dim_set); + compress = isl_morph_get_var_multi_aff(morph); + morph = isl_morph_inverse(morph); + decompress = isl_morph_get_var_multi_aff(morph); + isl_morph_free(morph); + + hull_set = isl_set_from_basic_set(hull); + return add_node(graph, space, nvar, 1, hull_set, compress, decompress); +error: + isl_basic_set_free(hull); + isl_space_free(space); + return isl_stat_error; +} + +struct isl_extract_edge_data { + enum isl_edge_type type; + struct isl_sched_graph *graph; +}; + +/* Merge edge2 into edge1, freeing the contents of edge2. + * "type" is the type of the schedule constraint from which edge2 was + * extracted. + * Return 0 on success and -1 on failure. + * + * edge1 and edge2 are assumed to have the same value for the map field. + */ +static int merge_edge(enum isl_edge_type type, struct isl_sched_edge *edge1, + struct isl_sched_edge *edge2) +{ + edge1->validity |= edge2->validity; + edge1->coincidence |= edge2->coincidence; + edge1->proximity |= edge2->proximity; + edge1->condition |= edge2->condition; + edge1->conditional_validity |= edge2->conditional_validity; + isl_map_free(edge2->map); + + if (type == isl_edge_condition) { + if (!edge1->tagged_condition) + edge1->tagged_condition = edge2->tagged_condition; + else + edge1->tagged_condition = + isl_union_map_union(edge1->tagged_condition, + edge2->tagged_condition); + } + + if (type == isl_edge_conditional_validity) { + if (!edge1->tagged_validity) + edge1->tagged_validity = edge2->tagged_validity; + else + edge1->tagged_validity = + isl_union_map_union(edge1->tagged_validity, + edge2->tagged_validity); + } + + if (type == isl_edge_condition && !edge1->tagged_condition) + return -1; + if (type == isl_edge_conditional_validity && !edge1->tagged_validity) + return -1; + + return 0; +} + +/* Insert dummy tags in domain and range of "map". + * + * In particular, if "map" is of the form + * + * A -> B + * + * then return + * + * [A -> dummy_tag] -> [B -> dummy_tag] + * + * where the dummy_tags are identical and equal to any dummy tags + * introduced by any other call to this function. + */ +static __isl_give isl_map *insert_dummy_tags(__isl_take isl_map *map) +{ + static char dummy; + isl_ctx *ctx; + isl_id *id; + isl_space *space; + isl_set *domain, *range; + + ctx = isl_map_get_ctx(map); + + id = isl_id_alloc(ctx, NULL, &dummy); + space = isl_space_params(isl_map_get_space(map)); + space = isl_space_set_from_params(space); + space = isl_space_set_tuple_id(space, isl_dim_set, id); + space = isl_space_map_from_set(space); + + domain = isl_map_wrap(map); + range = isl_map_wrap(isl_map_universe(space)); + map = isl_map_from_domain_and_range(domain, range); + map = isl_map_zip(map); + + return map; +} + +/* Given that at least one of "src" or "dst" is compressed, return + * a map between the spaces of these nodes restricted to the affine + * hull that was used in the compression. + */ +static __isl_give isl_map *extract_hull(struct isl_sched_node *src, + struct isl_sched_node *dst) +{ + isl_set *dom, *ran; + + if (src->compressed) + dom = isl_set_copy(src->hull); + else + dom = isl_set_universe(isl_space_copy(src->space)); + if (dst->compressed) + ran = isl_set_copy(dst->hull); + else + ran = isl_set_universe(isl_space_copy(dst->space)); + + return isl_map_from_domain_and_range(dom, ran); +} + +/* Intersect the domains of the nested relations in domain and range + * of "tagged" with "map". + */ +static __isl_give isl_map *map_intersect_domains(__isl_take isl_map *tagged, + __isl_keep isl_map *map) +{ + isl_set *set; + + tagged = isl_map_zip(tagged); + set = isl_map_wrap(isl_map_copy(map)); + tagged = isl_map_intersect_domain(tagged, set); + tagged = isl_map_zip(tagged); + return tagged; +} + +/* Add a new edge to the graph based on the given map + * and add it to data->graph->edge_table[data->type]. + * If a dependence relation of a given type happens to be identical + * to one of the dependence relations of a type that was added before, + * then we don't create a new edge, but instead mark the original edge + * as also representing a dependence of the current type. + * + * Edges of type isl_edge_condition or isl_edge_conditional_validity + * may be specified as "tagged" dependence relations. That is, "map" + * may contain elements (i -> a) -> (j -> b), where i -> j denotes + * the dependence on iterations and a and b are tags. + * edge->map is set to the relation containing the elements i -> j, + * while edge->tagged_condition and edge->tagged_validity contain + * the union of all the "map" relations + * for which extract_edge is called that result in the same edge->map. + * + * If the source or the destination node is compressed, then + * intersect both "map" and "tagged" with the constraints that + * were used to construct the compression. + * This ensures that there are no schedule constraints defined + * outside of these domains, while the scheduler no longer has + * any control over those outside parts. + */ +static isl_stat extract_edge(__isl_take isl_map *map, void *user) +{ + isl_ctx *ctx = isl_map_get_ctx(map); + struct isl_extract_edge_data *data = user; + struct isl_sched_graph *graph = data->graph; + struct isl_sched_node *src, *dst; + isl_space *dim; + struct isl_sched_edge *edge; + isl_map *tagged = NULL; + + if (data->type == isl_edge_condition || + data->type == isl_edge_conditional_validity) { + if (isl_map_can_zip(map)) { + tagged = isl_map_copy(map); + map = isl_set_unwrap(isl_map_domain(isl_map_zip(map))); + } else { + tagged = insert_dummy_tags(isl_map_copy(map)); + } + } + + dim = isl_space_domain(isl_map_get_space(map)); + src = graph_find_node(ctx, graph, dim); + isl_space_free(dim); + dim = isl_space_range(isl_map_get_space(map)); + dst = graph_find_node(ctx, graph, dim); + isl_space_free(dim); + + if (!src || !dst) { + isl_map_free(map); + isl_map_free(tagged); + return isl_stat_ok; + } + + if (src->compressed || dst->compressed) { + isl_map *hull; + hull = extract_hull(src, dst); + if (tagged) + tagged = map_intersect_domains(tagged, hull); + map = isl_map_intersect(map, hull); + } + + graph->edge[graph->n_edge].src = src; + graph->edge[graph->n_edge].dst = dst; + graph->edge[graph->n_edge].map = map; + graph->edge[graph->n_edge].validity = 0; + graph->edge[graph->n_edge].coincidence = 0; + graph->edge[graph->n_edge].proximity = 0; + graph->edge[graph->n_edge].condition = 0; + graph->edge[graph->n_edge].local = 0; + graph->edge[graph->n_edge].conditional_validity = 0; + graph->edge[graph->n_edge].tagged_condition = NULL; + graph->edge[graph->n_edge].tagged_validity = NULL; + if (data->type == isl_edge_validity) + graph->edge[graph->n_edge].validity = 1; + if (data->type == isl_edge_coincidence) + graph->edge[graph->n_edge].coincidence = 1; + if (data->type == isl_edge_proximity) + graph->edge[graph->n_edge].proximity = 1; + if (data->type == isl_edge_condition) { + graph->edge[graph->n_edge].condition = 1; + graph->edge[graph->n_edge].tagged_condition = + isl_union_map_from_map(tagged); + } + if (data->type == isl_edge_conditional_validity) { + graph->edge[graph->n_edge].conditional_validity = 1; + graph->edge[graph->n_edge].tagged_validity = + isl_union_map_from_map(tagged); + } + + edge = graph_find_matching_edge(graph, &graph->edge[graph->n_edge]); + if (!edge) { + graph->n_edge++; + return isl_stat_error; + } + if (edge == &graph->edge[graph->n_edge]) + return graph_edge_table_add(ctx, graph, data->type, + &graph->edge[graph->n_edge++]); + + if (merge_edge(data->type, edge, &graph->edge[graph->n_edge]) < 0) + return -1; + + return graph_edge_table_add(ctx, graph, data->type, edge); +} + +/* Check whether there is any dependence from node[j] to node[i] + * or from node[i] to node[j]. + */ +static isl_bool node_follows_weak(int i, int j, void *user) +{ + isl_bool f; + struct isl_sched_graph *graph = user; + + f = graph_has_any_edge(graph, &graph->node[j], &graph->node[i]); + if (f < 0 || f) + return f; + return graph_has_any_edge(graph, &graph->node[i], &graph->node[j]); +} + +/* Check whether there is a (conditional) validity dependence from node[j] + * to node[i], forcing node[i] to follow node[j]. + */ +static isl_bool node_follows_strong(int i, int j, void *user) +{ + struct isl_sched_graph *graph = user; + + return graph_has_validity_edge(graph, &graph->node[j], &graph->node[i]); +} + +/* Use Tarjan's algorithm for computing the strongly connected components + * in the dependence graph (only validity edges). + * If weak is set, we consider the graph to be undirected and + * we effectively compute the (weakly) connected components. + * Additionally, we also consider other edges when weak is set. + */ +static int detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph, int weak) +{ + int i, n; + struct isl_tarjan_graph *g = NULL; + + g = isl_tarjan_graph_init(ctx, graph->n, + weak ? &node_follows_weak : &node_follows_strong, graph); + if (!g) + return -1; + + graph->weak = weak; + graph->scc = 0; + i = 0; + n = graph->n; + while (n) { + while (g->order[i] != -1) { + graph->node[g->order[i]].scc = graph->scc; + --n; + ++i; + } + ++i; + graph->scc++; + } + + isl_tarjan_graph_free(g); + + return 0; +} + +/* Apply Tarjan's algorithm to detect the strongly connected components + * in the dependence graph. + */ +static int detect_sccs(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + return detect_ccs(ctx, graph, 0); +} + +/* Apply Tarjan's algorithm to detect the (weakly) connected components + * in the dependence graph. + */ +static int detect_wccs(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + return detect_ccs(ctx, graph, 1); +} + +static int cmp_scc(const void *a, const void *b, void *data) +{ + struct isl_sched_graph *graph = data; + const int *i1 = a; + const int *i2 = b; + + return graph->node[*i1].scc - graph->node[*i2].scc; +} + +/* Sort the elements of graph->sorted according to the corresponding SCCs. + */ +static int sort_sccs(struct isl_sched_graph *graph) +{ + return isl_sort(graph->sorted, graph->n, sizeof(int), &cmp_scc, graph); +} + +/* Given a dependence relation R from "node" to itself, + * construct the set of coefficients of valid constraints for elements + * in that dependence relation. + * In particular, the result contains tuples of coefficients + * c_0, c_n, c_x such that + * + * c_0 + c_n n + c_x y - c_x x >= 0 for each (x,y) in R + * + * or, equivalently, + * + * c_0 + c_n n + c_x d >= 0 for each d in delta R = { y - x | (x,y) in R } + * + * We choose here to compute the dual of delta R. + * Alternatively, we could have computed the dual of R, resulting + * in a set of tuples c_0, c_n, c_x, c_y, and then + * plugged in (c_0, c_n, c_x, -c_x). + * + * If "node" has been compressed, then the dependence relation + * is also compressed before the set of coefficients is computed. + */ +static __isl_give isl_basic_set *intra_coefficients( + struct isl_sched_graph *graph, struct isl_sched_node *node, + __isl_take isl_map *map) +{ + isl_set *delta; + isl_map *key; + isl_basic_set *coef; + + if (isl_map_to_basic_set_has(graph->intra_hmap, map)) + return isl_map_to_basic_set_get(graph->intra_hmap, map); + + key = isl_map_copy(map); + if (node->compressed) { + map = isl_map_preimage_domain_multi_aff(map, + isl_multi_aff_copy(node->decompress)); + map = isl_map_preimage_range_multi_aff(map, + isl_multi_aff_copy(node->decompress)); + } + delta = isl_set_remove_divs(isl_map_deltas(map)); + coef = isl_set_coefficients(delta); + graph->intra_hmap = isl_map_to_basic_set_set(graph->intra_hmap, key, + isl_basic_set_copy(coef)); + + return coef; +} + +/* Given a dependence relation R, construct the set of coefficients + * of valid constraints for elements in that dependence relation. + * In particular, the result contains tuples of coefficients + * c_0, c_n, c_x, c_y such that + * + * c_0 + c_n n + c_x x + c_y y >= 0 for each (x,y) in R + * + * If the source or destination nodes of "edge" have been compressed, + * then the dependence relation is also compressed before + * the set of coefficients is computed. + */ +static __isl_give isl_basic_set *inter_coefficients( + struct isl_sched_graph *graph, struct isl_sched_edge *edge, + __isl_take isl_map *map) +{ + isl_set *set; + isl_map *key; + isl_basic_set *coef; + + if (isl_map_to_basic_set_has(graph->inter_hmap, map)) + return isl_map_to_basic_set_get(graph->inter_hmap, map); + + key = isl_map_copy(map); + if (edge->src->compressed) + map = isl_map_preimage_domain_multi_aff(map, + isl_multi_aff_copy(edge->src->decompress)); + if (edge->dst->compressed) + map = isl_map_preimage_range_multi_aff(map, + isl_multi_aff_copy(edge->dst->decompress)); + set = isl_map_wrap(isl_map_remove_divs(map)); + coef = isl_set_coefficients(set); + graph->inter_hmap = isl_map_to_basic_set_set(graph->inter_hmap, key, + isl_basic_set_copy(coef)); + + return coef; +} + +/* Add constraints to graph->lp that force validity for the given + * dependence from a node i to itself. + * That is, add constraints that enforce + * + * (c_i_0 + c_i_n n + c_i_x y) - (c_i_0 + c_i_n n + c_i_x x) + * = c_i_x (y - x) >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x) + * of valid constraints for (y - x) and then plug in (0, 0, c_i_x^+ - c_i_x^-), + * where c_i_x = c_i_x^+ - c_i_x^-, with c_i_x^+ and c_i_x^- non-negative. + * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart. + * + * Actually, we do not construct constraints for the c_i_x themselves, + * but for the coefficients of c_i_x written as a linear combination + * of the columns in node->cmap. + */ +static int add_intra_validity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + unsigned total; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_space *dim; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *node = edge->src; + + coef = intra_coefficients(graph, node, map); + + dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); + + coef = isl_basic_set_transform_dims(coef, isl_dim_set, + isl_space_dim(dim, isl_dim_set), isl_mat_copy(node->cmap)); + if (!coef) + goto error; + + total = isl_basic_set_total_dim(graph->lp); + dim_map = isl_dim_map_alloc(ctx, total); + isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set), 1, + node->nvar, -1); + isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set), 1, + node->nvar, 1); + graph->lp = isl_basic_set_extend_constraints(graph->lp, + coef->n_eq, coef->n_ineq); + graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, + coef, dim_map); + isl_space_free(dim); + + return 0; +error: + isl_space_free(dim); + return -1; +} + +/* Add constraints to graph->lp that force validity for the given + * dependence from node i to node j. + * That is, add constraints that enforce + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y) + * of valid constraints for R and then plug in + * (c_j_0 - c_i_0, c_j_n^+ - c_j_n^- - (c_i_n^+ - c_i_n^-), + * c_j_x^+ - c_j_x^- - (c_i_x^+ - c_i_x^-)), + * where c_* = c_*^+ - c_*^-, with c_*^+ and c_*^- non-negative. + * In graph->lp, the c_*^- appear before their c_*^+ counterpart. + * + * Actually, we do not construct constraints for the c_*_x themselves, + * but for the coefficients of c_*_x written as a linear combination + * of the columns in node->cmap. + */ +static int add_inter_validity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + unsigned total; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_space *dim; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *src = edge->src; + struct isl_sched_node *dst = edge->dst; + + coef = inter_coefficients(graph, edge, map); + + dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); + + coef = isl_basic_set_transform_dims(coef, isl_dim_set, + isl_space_dim(dim, isl_dim_set), isl_mat_copy(src->cmap)); + coef = isl_basic_set_transform_dims(coef, isl_dim_set, + isl_space_dim(dim, isl_dim_set) + src->nvar, + isl_mat_copy(dst->cmap)); + if (!coef) + goto error; + + total = isl_basic_set_total_dim(graph->lp); + dim_map = isl_dim_map_alloc(ctx, total); + + isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, 1); + isl_dim_map_range(dim_map, dst->start + 1, 2, 1, 1, dst->nparam, -1); + isl_dim_map_range(dim_map, dst->start + 2, 2, 1, 1, dst->nparam, 1); + isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set) + src->nvar, 1, + dst->nvar, -1); + isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set) + src->nvar, 1, + dst->nvar, 1); + + isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, -1); + isl_dim_map_range(dim_map, src->start + 1, 2, 1, 1, src->nparam, 1); + isl_dim_map_range(dim_map, src->start + 2, 2, 1, 1, src->nparam, -1); + isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set), 1, + src->nvar, 1); + isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set), 1, + src->nvar, -1); + + edge->start = graph->lp->n_ineq; + graph->lp = isl_basic_set_extend_constraints(graph->lp, + coef->n_eq, coef->n_ineq); + graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, + coef, dim_map); + if (!graph->lp) + goto error; + isl_space_free(dim); + edge->end = graph->lp->n_ineq; + + return 0; +error: + isl_space_free(dim); + return -1; +} + +/* Add constraints to graph->lp that bound the dependence distance for the given + * dependence from a node i to itself. + * If s = 1, we add the constraint + * + * c_i_x (y - x) <= m_0 + m_n n + * + * or + * + * -c_i_x (y - x) + m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * If s = -1, we add the constraint + * + * -c_i_x (y - x) <= m_0 + m_n n + * + * or + * + * c_i_x (y - x) + m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x) + * of valid constraints for (y - x) and then plug in (m_0, m_n, -s * c_i_x), + * with each coefficient (except m_0) represented as a pair of non-negative + * coefficients. + * + * Actually, we do not construct constraints for the c_i_x themselves, + * but for the coefficients of c_i_x written as a linear combination + * of the columns in node->cmap. + * + * + * If "local" is set, then we add constraints + * + * c_i_x (y - x) <= 0 + * + * or + * + * -c_i_x (y - x) <= 0 + * + * instead, forcing the dependence distance to be (less than or) equal to 0. + * That is, we plug in (0, 0, -s * c_i_x), + * Note that dependences marked local are treated as validity constraints + * by add_all_validity_constraints and therefore also have + * their distances bounded by 0 from below. + */ +static int add_intra_proximity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, int s, int local) +{ + unsigned total; + unsigned nparam; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_space *dim; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *node = edge->src; + + coef = intra_coefficients(graph, node, map); + + dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); + + coef = isl_basic_set_transform_dims(coef, isl_dim_set, + isl_space_dim(dim, isl_dim_set), isl_mat_copy(node->cmap)); + if (!coef) + goto error; + + nparam = isl_space_dim(node->space, isl_dim_param); + total = isl_basic_set_total_dim(graph->lp); + dim_map = isl_dim_map_alloc(ctx, total); + + if (!local) { + isl_dim_map_range(dim_map, 1, 0, 0, 0, 1, 1); + isl_dim_map_range(dim_map, 4, 2, 1, 1, nparam, -1); + isl_dim_map_range(dim_map, 5, 2, 1, 1, nparam, 1); + } + isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set), 1, + node->nvar, s); + isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set), 1, + node->nvar, -s); + graph->lp = isl_basic_set_extend_constraints(graph->lp, + coef->n_eq, coef->n_ineq); + graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, + coef, dim_map); + isl_space_free(dim); + + return 0; +error: + isl_space_free(dim); + return -1; +} + +/* Add constraints to graph->lp that bound the dependence distance for the given + * dependence from node i to node j. + * If s = 1, we add the constraint + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) + * <= m_0 + m_n n + * + * or + * + * -(c_j_0 + c_j_n n + c_j_x y) + (c_i_0 + c_i_n n + c_i_x x) + + * m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * If s = -1, we add the constraint + * + * -((c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x)) + * <= m_0 + m_n n + * + * or + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) + + * m_0 + m_n n >= 0 + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y) + * of valid constraints for R and then plug in + * (m_0 - s*c_j_0 + s*c_i_0, m_n - s*c_j_n + s*c_i_n, + * -s*c_j_x+s*c_i_x) + * with each coefficient (except m_0, c_j_0 and c_i_0) + * represented as a pair of non-negative coefficients. + * + * Actually, we do not construct constraints for the c_*_x themselves, + * but for the coefficients of c_*_x written as a linear combination + * of the columns in node->cmap. + * + * + * If "local" is set, then we add constraints + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x) <= 0 + * + * or + * + * -((c_j_0 + c_j_n n + c_j_x y) - (c_i_0 + c_i_n n + c_i_x x)) <= 0 + * + * instead, forcing the dependence distance to be (less than or) equal to 0. + * That is, we plug in + * (-s*c_j_0 + s*c_i_0, -s*c_j_n + s*c_i_n, -s*c_j_x+s*c_i_x). + * Note that dependences marked local are treated as validity constraints + * by add_all_validity_constraints and therefore also have + * their distances bounded by 0 from below. + */ +static int add_inter_proximity_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, int s, int local) +{ + unsigned total; + unsigned nparam; + isl_map *map = isl_map_copy(edge->map); + isl_ctx *ctx = isl_map_get_ctx(map); + isl_space *dim; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *src = edge->src; + struct isl_sched_node *dst = edge->dst; + + coef = inter_coefficients(graph, edge, map); + + dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); + + coef = isl_basic_set_transform_dims(coef, isl_dim_set, + isl_space_dim(dim, isl_dim_set), isl_mat_copy(src->cmap)); + coef = isl_basic_set_transform_dims(coef, isl_dim_set, + isl_space_dim(dim, isl_dim_set) + src->nvar, + isl_mat_copy(dst->cmap)); + if (!coef) + goto error; + + nparam = isl_space_dim(src->space, isl_dim_param); + total = isl_basic_set_total_dim(graph->lp); + dim_map = isl_dim_map_alloc(ctx, total); + + if (!local) { + isl_dim_map_range(dim_map, 1, 0, 0, 0, 1, 1); + isl_dim_map_range(dim_map, 4, 2, 1, 1, nparam, -1); + isl_dim_map_range(dim_map, 5, 2, 1, 1, nparam, 1); + } + + isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, -s); + isl_dim_map_range(dim_map, dst->start + 1, 2, 1, 1, dst->nparam, s); + isl_dim_map_range(dim_map, dst->start + 2, 2, 1, 1, dst->nparam, -s); + isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set) + src->nvar, 1, + dst->nvar, s); + isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set) + src->nvar, 1, + dst->nvar, -s); + + isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, s); + isl_dim_map_range(dim_map, src->start + 1, 2, 1, 1, src->nparam, -s); + isl_dim_map_range(dim_map, src->start + 2, 2, 1, 1, src->nparam, s); + isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set), 1, + src->nvar, -s); + isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set), 1, + src->nvar, s); + + graph->lp = isl_basic_set_extend_constraints(graph->lp, + coef->n_eq, coef->n_ineq); + graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, + coef, dim_map); + isl_space_free(dim); + + return 0; +error: + isl_space_free(dim); + return -1; +} + +/* Add all validity constraints to graph->lp. + * + * An edge that is forced to be local needs to have its dependence + * distances equal to zero. We take care of bounding them by 0 from below + * here. add_all_proximity_constraints takes care of bounding them by 0 + * from above. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int add_all_validity_constraints(struct isl_sched_graph *graph, + int use_coincidence) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge= &graph->edge[i]; + int local; + + local = edge->local || (edge->coincidence && use_coincidence); + if (!edge->validity && !local) + continue; + if (edge->src != edge->dst) + continue; + if (add_intra_validity_constraints(graph, edge) < 0) + return -1; + } + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge = &graph->edge[i]; + int local; + + local = edge->local || (edge->coincidence && use_coincidence); + if (!edge->validity && !local) + continue; + if (edge->src == edge->dst) + continue; + if (add_inter_validity_constraints(graph, edge) < 0) + return -1; + } + + return 0; +} + +/* Add constraints to graph->lp that bound the dependence distance + * for all dependence relations. + * If a given proximity dependence is identical to a validity + * dependence, then the dependence distance is already bounded + * from below (by zero), so we only need to bound the distance + * from above. (This includes the case of "local" dependences + * which are treated as validity dependence by add_all_validity_constraints.) + * Otherwise, we need to bound the distance both from above and from below. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int add_all_proximity_constraints(struct isl_sched_graph *graph, + int use_coincidence) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge= &graph->edge[i]; + int local; + + local = edge->local || (edge->coincidence && use_coincidence); + if (!edge->proximity && !local) + continue; + if (edge->src == edge->dst && + add_intra_proximity_constraints(graph, edge, 1, local) < 0) + return -1; + if (edge->src != edge->dst && + add_inter_proximity_constraints(graph, edge, 1, local) < 0) + return -1; + if (edge->validity || local) + continue; + if (edge->src == edge->dst && + add_intra_proximity_constraints(graph, edge, -1, 0) < 0) + return -1; + if (edge->src != edge->dst && + add_inter_proximity_constraints(graph, edge, -1, 0) < 0) + return -1; + } + + return 0; +} + +/* Compute a basis for the rows in the linear part of the schedule + * and extend this basis to a full basis. The remaining rows + * can then be used to force linear independence from the rows + * in the schedule. + * + * In particular, given the schedule rows S, we compute + * + * S = H Q + * S U = H + * + * with H the Hermite normal form of S. That is, all but the + * first rank columns of H are zero and so each row in S is + * a linear combination of the first rank rows of Q. + * The matrix Q is then transposed because we will write the + * coefficients of the next schedule row as a column vector s + * and express this s as a linear combination s = Q c of the + * computed basis. + * Similarly, the matrix U is transposed such that we can + * compute the coefficients c = U s from a schedule row s. + */ +static int node_update_cmap(struct isl_sched_node *node) +{ + isl_mat *H, *U, *Q; + int n_row = isl_mat_rows(node->sched); + + H = isl_mat_sub_alloc(node->sched, 0, n_row, + 1 + node->nparam, node->nvar); + + H = isl_mat_left_hermite(H, 0, &U, &Q); + isl_mat_free(node->cmap); + isl_mat_free(node->cinv); + node->cmap = isl_mat_transpose(Q); + node->cinv = isl_mat_transpose(U); + node->rank = isl_mat_initial_non_zero_cols(H); + isl_mat_free(H); + + if (!node->cmap || !node->cinv || node->rank < 0) + return -1; + return 0; +} + +/* How many times should we count the constraints in "edge"? + * + * If carry is set, then we are counting the number of + * (validity or conditional validity) constraints that will be added + * in setup_carry_lp and we count each edge exactly once. + * + * Otherwise, we count as follows + * validity -> 1 (>= 0) + * validity+proximity -> 2 (>= 0 and upper bound) + * proximity -> 2 (lower and upper bound) + * local(+any) -> 2 (>= 0 and <= 0) + * + * If an edge is only marked conditional_validity then it counts + * as zero since it is only checked afterwards. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int edge_multiplicity(struct isl_sched_edge *edge, int carry, + int use_coincidence) +{ + if (carry && !edge->validity && !edge->conditional_validity) + return 0; + if (carry) + return 1; + if (edge->proximity || edge->local) + return 2; + if (use_coincidence && edge->coincidence) + return 2; + if (edge->validity) + return 1; + return 0; +} + +/* Count the number of equality and inequality constraints + * that will be added for the given map. + * + * "use_coincidence" is set if we should take into account coincidence edges. + */ +static int count_map_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, __isl_take isl_map *map, + int *n_eq, int *n_ineq, int carry, int use_coincidence) +{ + isl_basic_set *coef; + int f = edge_multiplicity(edge, carry, use_coincidence); + + if (f == 0) { + isl_map_free(map); + return 0; + } + + if (edge->src == edge->dst) + coef = intra_coefficients(graph, edge->src, map); + else + coef = inter_coefficients(graph, edge, map); + if (!coef) + return -1; + *n_eq += f * coef->n_eq; + *n_ineq += f * coef->n_ineq; + isl_basic_set_free(coef); + + return 0; +} + +/* Count the number of equality and inequality constraints + * that will be added to the main lp problem. + * We count as follows + * validity -> 1 (>= 0) + * validity+proximity -> 2 (>= 0 and upper bound) + * proximity -> 2 (lower and upper bound) + * local(+any) -> 2 (>= 0 and <= 0) + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int count_constraints(struct isl_sched_graph *graph, + int *n_eq, int *n_ineq, int use_coincidence) +{ + int i; + + *n_eq = *n_ineq = 0; + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge= &graph->edge[i]; + isl_map *map = isl_map_copy(edge->map); + + if (count_map_constraints(graph, edge, map, n_eq, n_ineq, + 0, use_coincidence) < 0) + return -1; + } + + return 0; +} + +/* Count the number of constraints that will be added by + * add_bound_coefficient_constraints and increment *n_eq and *n_ineq + * accordingly. + * + * In practice, add_bound_coefficient_constraints only adds inequalities. + */ +static int count_bound_coefficient_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph, int *n_eq, int *n_ineq) +{ + int i; + + if (ctx->opt->schedule_max_coefficient == -1) + return 0; + + for (i = 0; i < graph->n; ++i) + *n_ineq += 2 * graph->node[i].nparam + 2 * graph->node[i].nvar; + + return 0; +} + +/* Add constraints that bound the values of the variable and parameter + * coefficients of the schedule. + * + * The maximal value of the coefficients is defined by the option + * 'schedule_max_coefficient'. + */ +static int add_bound_coefficient_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i, j, k; + int max_coefficient; + int total; + + max_coefficient = ctx->opt->schedule_max_coefficient; + + if (max_coefficient == -1) + return 0; + + total = isl_basic_set_total_dim(graph->lp); + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + for (j = 0; j < 2 * node->nparam + 2 * node->nvar; ++j) { + int dim; + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return -1; + dim = 1 + node->start + 1 + j; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + isl_int_set_si(graph->lp->ineq[k][dim], -1); + isl_int_set_si(graph->lp->ineq[k][0], max_coefficient); + } + } + + return 0; +} + +/* Construct an ILP problem for finding schedule coefficients + * that result in non-negative, but small dependence distances + * over all dependences. + * In particular, the dependence distances over proximity edges + * are bounded by m_0 + m_n n and we compute schedule coefficients + * with small values (preferably zero) of m_n and m_0. + * + * All variables of the ILP are non-negative. The actual coefficients + * may be negative, so each coefficient is represented as the difference + * of two non-negative variables. The negative part always appears + * immediately before the positive part. + * Other than that, the variables have the following order + * + * - sum of positive and negative parts of m_n coefficients + * - m_0 + * - sum of positive and negative parts of all c_n coefficients + * (unconstrained when computing non-parametric schedules) + * - sum of positive and negative parts of all c_x coefficients + * - positive and negative parts of m_n coefficients + * - for each node + * - c_i_0 + * - positive and negative parts of c_i_n (if parametric) + * - positive and negative parts of c_i_x + * + * The c_i_x are not represented directly, but through the columns of + * node->cmap. That is, the computed values are for variable t_i_x + * such that c_i_x = Q t_i_x with Q equal to node->cmap. + * + * The constraints are those from the edges plus two or three equalities + * to express the sums. + * + * If "use_coincidence" is set, then we treat coincidence edges as local edges. + * Otherwise, we ignore them. + */ +static int setup_lp(isl_ctx *ctx, struct isl_sched_graph *graph, + int use_coincidence) +{ + int i, j; + int k; + unsigned nparam; + unsigned total; + isl_space *dim; + int parametric; + int param_pos; + int n_eq, n_ineq; + int max_constant_term; + + max_constant_term = ctx->opt->schedule_max_constant_term; + + parametric = ctx->opt->schedule_parametric; + nparam = isl_space_dim(graph->node[0].space, isl_dim_param); + param_pos = 4; + total = param_pos + 2 * nparam; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[graph->sorted[i]]; + if (node_update_cmap(node) < 0) + return -1; + node->start = total; + total += 1 + 2 * (node->nparam + node->nvar); + } + + if (count_constraints(graph, &n_eq, &n_ineq, use_coincidence) < 0) + return -1; + if (count_bound_coefficient_constraints(ctx, graph, &n_eq, &n_ineq) < 0) + return -1; + + dim = isl_space_set_alloc(ctx, 0, total); + isl_basic_set_free(graph->lp); + n_eq += 2 + parametric; + if (max_constant_term != -1) + n_ineq += graph->n; + + graph->lp = isl_basic_set_alloc_space(dim, 0, n_eq, n_ineq); + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][1], -1); + for (i = 0; i < 2 * nparam; ++i) + isl_int_set_si(graph->lp->eq[k][1 + param_pos + i], 1); + + if (parametric) { + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][3], -1); + for (i = 0; i < graph->n; ++i) { + int pos = 1 + graph->node[i].start + 1; + + for (j = 0; j < 2 * graph->node[i].nparam; ++j) + isl_int_set_si(graph->lp->eq[k][pos + j], 1); + } + } + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][4], -1); + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int pos = 1 + node->start + 1 + 2 * node->nparam; + + for (j = 0; j < 2 * node->nvar; ++j) + isl_int_set_si(graph->lp->eq[k][pos + j], 1); + } + + if (max_constant_term != -1) + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + isl_int_set_si(graph->lp->ineq[k][1 + node->start], -1); + isl_int_set_si(graph->lp->ineq[k][0], max_constant_term); + } + + if (add_bound_coefficient_constraints(ctx, graph) < 0) + return -1; + if (add_all_validity_constraints(graph, use_coincidence) < 0) + return -1; + if (add_all_proximity_constraints(graph, use_coincidence) < 0) + return -1; + + return 0; +} + +/* Analyze the conflicting constraint found by + * isl_tab_basic_set_non_trivial_lexmin. If it corresponds to the validity + * constraint of one of the edges between distinct nodes, living, moreover + * in distinct SCCs, then record the source and sink SCC as this may + * be a good place to cut between SCCs. + */ +static int check_conflict(int con, void *user) +{ + int i; + struct isl_sched_graph *graph = user; + + if (graph->src_scc >= 0) + return 0; + + con -= graph->lp->n_eq; + + if (con >= graph->lp->n_ineq) + return 0; + + for (i = 0; i < graph->n_edge; ++i) { + if (!graph->edge[i].validity) + continue; + if (graph->edge[i].src == graph->edge[i].dst) + continue; + if (graph->edge[i].src->scc == graph->edge[i].dst->scc) + continue; + if (graph->edge[i].start > con) + continue; + if (graph->edge[i].end <= con) + continue; + graph->src_scc = graph->edge[i].src->scc; + graph->dst_scc = graph->edge[i].dst->scc; + } + + return 0; +} + +/* Check whether the next schedule row of the given node needs to be + * non-trivial. Lower-dimensional domains may have some trivial rows, + * but as soon as the number of remaining required non-trivial rows + * is as large as the number or remaining rows to be computed, + * all remaining rows need to be non-trivial. + */ +static int needs_row(struct isl_sched_graph *graph, struct isl_sched_node *node) +{ + return node->nvar - node->rank >= graph->maxvar - graph->n_row; +} + +/* Solve the ILP problem constructed in setup_lp. + * For each node such that all the remaining rows of its schedule + * need to be non-trivial, we construct a non-triviality region. + * This region imposes that the next row is independent of previous rows. + * In particular the coefficients c_i_x are represented by t_i_x + * variables with c_i_x = Q t_i_x and Q a unimodular matrix such that + * its first columns span the rows of the previously computed part + * of the schedule. The non-triviality region enforces that at least + * one of the remaining components of t_i_x is non-zero, i.e., + * that the new schedule row depends on at least one of the remaining + * columns of Q. + */ +static __isl_give isl_vec *solve_lp(struct isl_sched_graph *graph) +{ + int i; + isl_vec *sol; + isl_basic_set *lp; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int skip = node->rank; + graph->region[i].pos = node->start + 1 + 2*(node->nparam+skip); + if (needs_row(graph, node)) + graph->region[i].len = 2 * (node->nvar - skip); + else + graph->region[i].len = 0; + } + lp = isl_basic_set_copy(graph->lp); + sol = isl_tab_basic_set_non_trivial_lexmin(lp, 2, graph->n, + graph->region, &check_conflict, graph); + return sol; +} + +/* Update the schedules of all nodes based on the given solution + * of the LP problem. + * The new row is added to the current band. + * All possibly negative coefficients are encoded as a difference + * of two non-negative variables, so we need to perform the subtraction + * here. Moreover, if use_cmap is set, then the solution does + * not refer to the actual coefficients c_i_x, but instead to variables + * t_i_x such that c_i_x = Q t_i_x and Q is equal to node->cmap. + * In this case, we then also need to perform this multiplication + * to obtain the values of c_i_x. + * + * If coincident is set, then the caller guarantees that the new + * row satisfies the coincidence constraints. + */ +static int update_schedule(struct isl_sched_graph *graph, + __isl_take isl_vec *sol, int use_cmap, int coincident) +{ + int i, j; + isl_vec *csol = NULL; + + if (!sol) + goto error; + if (sol->size == 0) + isl_die(sol->ctx, isl_error_internal, + "no solution found", goto error); + if (graph->n_total_row >= graph->max_row) + isl_die(sol->ctx, isl_error_internal, + "too many schedule rows", goto error); + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int pos = node->start; + int row = isl_mat_rows(node->sched); + + isl_vec_free(csol); + csol = isl_vec_alloc(sol->ctx, node->nvar); + if (!csol) + goto error; + + isl_map_free(node->sched_map); + node->sched_map = NULL; + node->sched = isl_mat_add_rows(node->sched, 1); + if (!node->sched) + goto error; + node->sched = isl_mat_set_element(node->sched, row, 0, + sol->el[1 + pos]); + for (j = 0; j < node->nparam + node->nvar; ++j) + isl_int_sub(sol->el[1 + pos + 1 + 2 * j + 1], + sol->el[1 + pos + 1 + 2 * j + 1], + sol->el[1 + pos + 1 + 2 * j]); + for (j = 0; j < node->nparam; ++j) + node->sched = isl_mat_set_element(node->sched, + row, 1 + j, sol->el[1+pos+1+2*j+1]); + for (j = 0; j < node->nvar; ++j) + isl_int_set(csol->el[j], + sol->el[1+pos+1+2*(node->nparam+j)+1]); + if (use_cmap) + csol = isl_mat_vec_product(isl_mat_copy(node->cmap), + csol); + if (!csol) + goto error; + for (j = 0; j < node->nvar; ++j) + node->sched = isl_mat_set_element(node->sched, + row, 1 + node->nparam + j, csol->el[j]); + node->coincident[graph->n_total_row] = coincident; + } + isl_vec_free(sol); + isl_vec_free(csol); + + graph->n_row++; + graph->n_total_row++; + + return 0; +error: + isl_vec_free(sol); + isl_vec_free(csol); + return -1; +} + +/* Convert row "row" of node->sched into an isl_aff living in "ls" + * and return this isl_aff. + */ +static __isl_give isl_aff *extract_schedule_row(__isl_take isl_local_space *ls, + struct isl_sched_node *node, int row) +{ + int j; + isl_int v; + isl_aff *aff; + + isl_int_init(v); + + aff = isl_aff_zero_on_domain(ls); + isl_mat_get_element(node->sched, row, 0, &v); + aff = isl_aff_set_constant(aff, v); + for (j = 0; j < node->nparam; ++j) { + isl_mat_get_element(node->sched, row, 1 + j, &v); + aff = isl_aff_set_coefficient(aff, isl_dim_param, j, v); + } + for (j = 0; j < node->nvar; ++j) { + isl_mat_get_element(node->sched, row, 1 + node->nparam + j, &v); + aff = isl_aff_set_coefficient(aff, isl_dim_in, j, v); + } + + isl_int_clear(v); + + return aff; +} + +/* Convert the "n" rows starting at "first" of node->sched into a multi_aff + * and return this multi_aff. + * + * The result is defined over the uncompressed node domain. + */ +static __isl_give isl_multi_aff *node_extract_partial_schedule_multi_aff( + struct isl_sched_node *node, int first, int n) +{ + int i; + isl_space *space; + isl_local_space *ls; + isl_aff *aff; + isl_multi_aff *ma; + int nrow; + + nrow = isl_mat_rows(node->sched); + if (node->compressed) + space = isl_multi_aff_get_domain_space(node->decompress); + else + space = isl_space_copy(node->space); + ls = isl_local_space_from_space(isl_space_copy(space)); + space = isl_space_from_domain(space); + space = isl_space_add_dims(space, isl_dim_out, n); + ma = isl_multi_aff_zero(space); + + for (i = first; i < first + n; ++i) { + aff = extract_schedule_row(isl_local_space_copy(ls), node, i); + ma = isl_multi_aff_set_aff(ma, i - first, aff); + } + + isl_local_space_free(ls); + + if (node->compressed) + ma = isl_multi_aff_pullback_multi_aff(ma, + isl_multi_aff_copy(node->compress)); + + return ma; +} + +/* Convert node->sched into a multi_aff and return this multi_aff. + * + * The result is defined over the uncompressed node domain. + */ +static __isl_give isl_multi_aff *node_extract_schedule_multi_aff( + struct isl_sched_node *node) +{ + int nrow; + + nrow = isl_mat_rows(node->sched); + return node_extract_partial_schedule_multi_aff(node, 0, nrow); +} + +/* Convert node->sched into a map and return this map. + * + * The result is cached in node->sched_map, which needs to be released + * whenever node->sched is updated. + * It is defined over the uncompressed node domain. + */ +static __isl_give isl_map *node_extract_schedule(struct isl_sched_node *node) +{ + if (!node->sched_map) { + isl_multi_aff *ma; + + ma = node_extract_schedule_multi_aff(node); + node->sched_map = isl_map_from_multi_aff(ma); + } + + return isl_map_copy(node->sched_map); +} + +/* Construct a map that can be used to update a dependence relation + * based on the current schedule. + * That is, construct a map expressing that source and sink + * are executed within the same iteration of the current schedule. + * This map can then be intersected with the dependence relation. + * This is not the most efficient way, but this shouldn't be a critical + * operation. + */ +static __isl_give isl_map *specializer(struct isl_sched_node *src, + struct isl_sched_node *dst) +{ + isl_map *src_sched, *dst_sched; + + src_sched = node_extract_schedule(src); + dst_sched = node_extract_schedule(dst); + return isl_map_apply_range(src_sched, isl_map_reverse(dst_sched)); +} + +/* Intersect the domains of the nested relations in domain and range + * of "umap" with "map". + */ +static __isl_give isl_union_map *intersect_domains( + __isl_take isl_union_map *umap, __isl_keep isl_map *map) +{ + isl_union_set *uset; + + umap = isl_union_map_zip(umap); + uset = isl_union_set_from_set(isl_map_wrap(isl_map_copy(map))); + umap = isl_union_map_intersect_domain(umap, uset); + umap = isl_union_map_zip(umap); + return umap; +} + +/* Update the dependence relation of the given edge based + * on the current schedule. + * If the dependence is carried completely by the current schedule, then + * it is removed from the edge_tables. It is kept in the list of edges + * as otherwise all edge_tables would have to be recomputed. + */ +static int update_edge(struct isl_sched_graph *graph, + struct isl_sched_edge *edge) +{ + int empty; + isl_map *id; + + id = specializer(edge->src, edge->dst); + edge->map = isl_map_intersect(edge->map, isl_map_copy(id)); + if (!edge->map) + goto error; + + if (edge->tagged_condition) { + edge->tagged_condition = + intersect_domains(edge->tagged_condition, id); + if (!edge->tagged_condition) + goto error; + } + if (edge->tagged_validity) { + edge->tagged_validity = + intersect_domains(edge->tagged_validity, id); + if (!edge->tagged_validity) + goto error; + } + + empty = isl_map_plain_is_empty(edge->map); + if (empty < 0) + goto error; + if (empty) + graph_remove_edge(graph, edge); + + isl_map_free(id); + return 0; +error: + isl_map_free(id); + return -1; +} + +/* Does the domain of "umap" intersect "uset"? + */ +static int domain_intersects(__isl_keep isl_union_map *umap, + __isl_keep isl_union_set *uset) +{ + int empty; + + umap = isl_union_map_copy(umap); + umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(uset)); + empty = isl_union_map_is_empty(umap); + isl_union_map_free(umap); + + return empty < 0 ? -1 : !empty; +} + +/* Does the range of "umap" intersect "uset"? + */ +static int range_intersects(__isl_keep isl_union_map *umap, + __isl_keep isl_union_set *uset) +{ + int empty; + + umap = isl_union_map_copy(umap); + umap = isl_union_map_intersect_range(umap, isl_union_set_copy(uset)); + empty = isl_union_map_is_empty(umap); + isl_union_map_free(umap); + + return empty < 0 ? -1 : !empty; +} + +/* Are the condition dependences of "edge" local with respect to + * the current schedule? + * + * That is, are domain and range of the condition dependences mapped + * to the same point? + * + * In other words, is the condition false? + */ +static int is_condition_false(struct isl_sched_edge *edge) +{ + isl_union_map *umap; + isl_map *map, *sched, *test; + int empty, local; + + empty = isl_union_map_is_empty(edge->tagged_condition); + if (empty < 0 || empty) + return empty; + + umap = isl_union_map_copy(edge->tagged_condition); + umap = isl_union_map_zip(umap); + umap = isl_union_set_unwrap(isl_union_map_domain(umap)); + map = isl_map_from_union_map(umap); + + sched = node_extract_schedule(edge->src); + map = isl_map_apply_domain(map, sched); + sched = node_extract_schedule(edge->dst); + map = isl_map_apply_range(map, sched); + + test = isl_map_identity(isl_map_get_space(map)); + local = isl_map_is_subset(map, test); + isl_map_free(map); + isl_map_free(test); + + return local; +} + +/* For each conditional validity constraint that is adjacent + * to a condition with domain in condition_source or range in condition_sink, + * turn it into an unconditional validity constraint. + */ +static int unconditionalize_adjacent_validity(struct isl_sched_graph *graph, + __isl_take isl_union_set *condition_source, + __isl_take isl_union_set *condition_sink) +{ + int i; + + condition_source = isl_union_set_coalesce(condition_source); + condition_sink = isl_union_set_coalesce(condition_sink); + + for (i = 0; i < graph->n_edge; ++i) { + int adjacent; + isl_union_map *validity; + + if (!graph->edge[i].conditional_validity) + continue; + if (graph->edge[i].validity) + continue; + + validity = graph->edge[i].tagged_validity; + adjacent = domain_intersects(validity, condition_sink); + if (adjacent >= 0 && !adjacent) + adjacent = range_intersects(validity, condition_source); + if (adjacent < 0) + goto error; + if (!adjacent) + continue; + + graph->edge[i].validity = 1; + } + + isl_union_set_free(condition_source); + isl_union_set_free(condition_sink); + return 0; +error: + isl_union_set_free(condition_source); + isl_union_set_free(condition_sink); + return -1; +} + +/* Update the dependence relations of all edges based on the current schedule + * and enforce conditional validity constraints that are adjacent + * to satisfied condition constraints. + * + * First check if any of the condition constraints are satisfied + * (i.e., not local to the outer schedule) and keep track of + * their domain and range. + * Then update all dependence relations (which removes the non-local + * constraints). + * Finally, if any condition constraints turned out to be satisfied, + * then turn all adjacent conditional validity constraints into + * unconditional validity constraints. + */ +static int update_edges(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + int any = 0; + isl_union_set *source, *sink; + + source = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + sink = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + for (i = 0; i < graph->n_edge; ++i) { + int local; + isl_union_set *uset; + isl_union_map *umap; + + if (!graph->edge[i].condition) + continue; + if (graph->edge[i].local) + continue; + local = is_condition_false(&graph->edge[i]); + if (local < 0) + goto error; + if (local) + continue; + + any = 1; + + umap = isl_union_map_copy(graph->edge[i].tagged_condition); + uset = isl_union_map_domain(umap); + source = isl_union_set_union(source, uset); + + umap = isl_union_map_copy(graph->edge[i].tagged_condition); + uset = isl_union_map_range(umap); + sink = isl_union_set_union(sink, uset); + } + + for (i = graph->n_edge - 1; i >= 0; --i) { + if (update_edge(graph, &graph->edge[i]) < 0) + goto error; + } + + if (any) + return unconditionalize_adjacent_validity(graph, source, sink); + + isl_union_set_free(source); + isl_union_set_free(sink); + return 0; +error: + isl_union_set_free(source); + isl_union_set_free(sink); + return -1; +} + +static void next_band(struct isl_sched_graph *graph) +{ + graph->band_start = graph->n_total_row; +} + +/* Return the union of the universe domains of the nodes in "graph" + * that satisfy "pred". + */ +static __isl_give isl_union_set *isl_sched_graph_domain(isl_ctx *ctx, + struct isl_sched_graph *graph, + int (*pred)(struct isl_sched_node *node, int data), int data) +{ + int i; + isl_set *set; + isl_union_set *dom; + + for (i = 0; i < graph->n; ++i) + if (pred(&graph->node[i], data)) + break; + + if (i >= graph->n) + isl_die(ctx, isl_error_internal, + "empty component", return NULL); + + set = isl_set_universe(isl_space_copy(graph->node[i].space)); + dom = isl_union_set_from_set(set); + + for (i = i + 1; i < graph->n; ++i) { + if (!pred(&graph->node[i], data)) + continue; + set = isl_set_universe(isl_space_copy(graph->node[i].space)); + dom = isl_union_set_union(dom, isl_union_set_from_set(set)); + } + + return dom; +} + +/* Return a list of unions of universe domains, where each element + * in the list corresponds to an SCC (or WCC) indexed by node->scc. + */ +static __isl_give isl_union_set_list *extract_sccs(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(ctx, graph->scc); + for (i = 0; i < graph->scc; ++i) { + isl_union_set *dom; + + dom = isl_sched_graph_domain(ctx, graph, &node_scc_exactly, i); + filters = isl_union_set_list_add(filters, dom); + } + + return filters; +} + +/* Return a list of two unions of universe domains, one for the SCCs up + * to and including graph->src_scc and another for the other SCCS. + */ +static __isl_give isl_union_set_list *extract_split(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + isl_union_set *dom; + isl_union_set_list *filters; + + filters = isl_union_set_list_alloc(ctx, 2); + dom = isl_sched_graph_domain(ctx, graph, + &node_scc_at_most, graph->src_scc); + filters = isl_union_set_list_add(filters, dom); + dom = isl_sched_graph_domain(ctx, graph, + &node_scc_at_least, graph->src_scc + 1); + filters = isl_union_set_list_add(filters, dom); + + return filters; +} + +/* Copy nodes that satisfy node_pred from the src dependence graph + * to the dst dependence graph. + */ +static int copy_nodes(struct isl_sched_graph *dst, struct isl_sched_graph *src, + int (*node_pred)(struct isl_sched_node *node, int data), int data) +{ + int i; + + dst->n = 0; + for (i = 0; i < src->n; ++i) { + int j; + + if (!node_pred(&src->node[i], data)) + continue; + + j = dst->n; + dst->node[j].space = isl_space_copy(src->node[i].space); + dst->node[j].compressed = src->node[i].compressed; + dst->node[j].hull = isl_set_copy(src->node[i].hull); + dst->node[j].compress = + isl_multi_aff_copy(src->node[i].compress); + dst->node[j].decompress = + isl_multi_aff_copy(src->node[i].decompress); + dst->node[j].nvar = src->node[i].nvar; + dst->node[j].nparam = src->node[i].nparam; + dst->node[j].sched = isl_mat_copy(src->node[i].sched); + dst->node[j].sched_map = isl_map_copy(src->node[i].sched_map); + dst->node[j].coincident = src->node[i].coincident; + dst->n++; + + if (!dst->node[j].space || !dst->node[j].sched) + return -1; + if (dst->node[j].compressed && + (!dst->node[j].hull || !dst->node[j].compress || + !dst->node[j].decompress)) + return -1; + } + + return 0; +} + +/* Copy non-empty edges that satisfy edge_pred from the src dependence graph + * to the dst dependence graph. + * If the source or destination node of the edge is not in the destination + * graph, then it must be a backward proximity edge and it should simply + * be ignored. + */ +static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst, + struct isl_sched_graph *src, + int (*edge_pred)(struct isl_sched_edge *edge, int data), int data) +{ + int i; + enum isl_edge_type t; + + dst->n_edge = 0; + for (i = 0; i < src->n_edge; ++i) { + struct isl_sched_edge *edge = &src->edge[i]; + isl_map *map; + isl_union_map *tagged_condition; + isl_union_map *tagged_validity; + struct isl_sched_node *dst_src, *dst_dst; + + if (!edge_pred(edge, data)) + continue; + + if (isl_map_plain_is_empty(edge->map)) + continue; + + dst_src = graph_find_node(ctx, dst, edge->src->space); + dst_dst = graph_find_node(ctx, dst, edge->dst->space); + if (!dst_src || !dst_dst) { + if (edge->validity || edge->conditional_validity) + isl_die(ctx, isl_error_internal, + "backward (conditional) validity edge", + return -1); + continue; + } + + map = isl_map_copy(edge->map); + tagged_condition = isl_union_map_copy(edge->tagged_condition); + tagged_validity = isl_union_map_copy(edge->tagged_validity); + + dst->edge[dst->n_edge].src = dst_src; + dst->edge[dst->n_edge].dst = dst_dst; + dst->edge[dst->n_edge].map = map; + dst->edge[dst->n_edge].tagged_condition = tagged_condition; + dst->edge[dst->n_edge].tagged_validity = tagged_validity; + dst->edge[dst->n_edge].validity = edge->validity; + dst->edge[dst->n_edge].proximity = edge->proximity; + dst->edge[dst->n_edge].coincidence = edge->coincidence; + dst->edge[dst->n_edge].condition = edge->condition; + dst->edge[dst->n_edge].conditional_validity = + edge->conditional_validity; + dst->n_edge++; + + if (edge->tagged_condition && !tagged_condition) + return -1; + if (edge->tagged_validity && !tagged_validity) + return -1; + + for (t = isl_edge_first; t <= isl_edge_last; ++t) { + if (edge != + graph_find_edge(src, t, edge->src, edge->dst)) + continue; + if (graph_edge_table_add(ctx, dst, t, + &dst->edge[dst->n_edge - 1]) < 0) + return -1; + } + } + + return 0; +} + +/* Compute the maximal number of variables over all nodes. + * This is the maximal number of linearly independent schedule + * rows that we need to compute. + * Just in case we end up in a part of the dependence graph + * with only lower-dimensional domains, we make sure we will + * compute the required amount of extra linearly independent rows. + */ +static int compute_maxvar(struct isl_sched_graph *graph) +{ + int i; + + graph->maxvar = 0; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int nvar; + + if (node_update_cmap(node) < 0) + return -1; + nvar = node->nvar + graph->n_row - node->rank; + if (nvar > graph->maxvar) + graph->maxvar = nvar; + } + + return 0; +} + +static __isl_give isl_schedule_node *compute_schedule(isl_schedule_node *node, + struct isl_sched_graph *graph); +static __isl_give isl_schedule_node *compute_schedule_wcc( + isl_schedule_node *node, struct isl_sched_graph *graph); + +/* Compute a schedule for a subgraph of "graph". In particular, for + * the graph composed of nodes that satisfy node_pred and edges that + * that satisfy edge_pred. The caller should precompute the number + * of nodes and edges that satisfy these predicates and pass them along + * as "n" and "n_edge". + * If the subgraph is known to consist of a single component, then wcc should + * be set and then we call compute_schedule_wcc on the constructed subgraph. + * Otherwise, we call compute_schedule, which will check whether the subgraph + * is connected. + * + * The schedule is inserted at "node" and the updated schedule node + * is returned. + */ +static __isl_give isl_schedule_node *compute_sub_schedule( + __isl_take isl_schedule_node *node, isl_ctx *ctx, + struct isl_sched_graph *graph, int n, int n_edge, + int (*node_pred)(struct isl_sched_node *node, int data), + int (*edge_pred)(struct isl_sched_edge *edge, int data), + int data, int wcc) +{ + struct isl_sched_graph split = { 0 }; + int t; + + if (graph_alloc(ctx, &split, n, n_edge) < 0) + goto error; + if (copy_nodes(&split, graph, node_pred, data) < 0) + goto error; + if (graph_init_table(ctx, &split) < 0) + goto error; + for (t = 0; t <= isl_edge_last; ++t) + split.max_edge[t] = graph->max_edge[t]; + if (graph_init_edge_tables(ctx, &split) < 0) + goto error; + if (copy_edges(ctx, &split, graph, edge_pred, data) < 0) + goto error; + split.n_row = graph->n_row; + split.max_row = graph->max_row; + split.n_total_row = graph->n_total_row; + split.band_start = graph->band_start; + + if (wcc) + node = compute_schedule_wcc(node, &split); + else + node = compute_schedule(node, &split); + + graph_free(ctx, &split); + return node; +error: + graph_free(ctx, &split); + return isl_schedule_node_free(node); +} + +static int edge_scc_exactly(struct isl_sched_edge *edge, int scc) +{ + return edge->src->scc == scc && edge->dst->scc == scc; +} + +static int edge_dst_scc_at_most(struct isl_sched_edge *edge, int scc) +{ + return edge->dst->scc <= scc; +} + +static int edge_src_scc_at_least(struct isl_sched_edge *edge, int scc) +{ + return edge->src->scc >= scc; +} + +/* Reset the current band by dropping all its schedule rows. + */ +static int reset_band(struct isl_sched_graph *graph) +{ + int i; + int drop; + + drop = graph->n_total_row - graph->band_start; + graph->n_total_row -= drop; + graph->n_row -= drop; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + isl_map_free(node->sched_map); + node->sched_map = NULL; + + node->sched = isl_mat_drop_rows(node->sched, + graph->band_start, drop); + + if (!node->sched) + return -1; + } + + return 0; +} + +/* Split the current graph into two parts and compute a schedule for each + * part individually. In particular, one part consists of all SCCs up + * to and including graph->src_scc, while the other part contains the other + * SCCS. The split is enforced by a sequence node inserted at position "node" + * in the schedule tree. Return the updated schedule node. + * + * The current band is reset. It would be possible to reuse + * the previously computed rows as the first rows in the next + * band, but recomputing them may result in better rows as we are looking + * at a smaller part of the dependence graph. + */ +static __isl_give isl_schedule_node *compute_split_schedule( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + int i, n, e1, e2; + isl_ctx *ctx; + isl_union_set_list *filters; + + if (!node) + return NULL; + + if (reset_band(graph) < 0) + return isl_schedule_node_free(node); + + n = 0; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int before = node->scc <= graph->src_scc; + + if (before) + n++; + } + + e1 = e2 = 0; + for (i = 0; i < graph->n_edge; ++i) { + if (graph->edge[i].dst->scc <= graph->src_scc) + e1++; + if (graph->edge[i].src->scc > graph->src_scc) + e2++; + } + + next_band(graph); + + ctx = isl_schedule_node_get_ctx(node); + filters = extract_split(ctx, graph); + node = isl_schedule_node_insert_sequence(node, filters); + node = isl_schedule_node_child(node, 0); + node = isl_schedule_node_child(node, 0); + + node = compute_sub_schedule(node, ctx, graph, n, e1, + &node_scc_at_most, &edge_dst_scc_at_most, + graph->src_scc, 0); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_next_sibling(node); + node = isl_schedule_node_child(node, 0); + node = compute_sub_schedule(node, ctx, graph, graph->n - n, e2, + &node_scc_at_least, &edge_src_scc_at_least, + graph->src_scc + 1, 0); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_parent(node); + + return node; +} + +/* Insert a band node at position "node" in the schedule tree corresponding + * to the current band in "graph". Mark the band node permutable + * if "permutable" is set. + * The partial schedules and the coincidence property are extracted + * from the graph nodes. + * Return the updated schedule node. + */ +static __isl_give isl_schedule_node *insert_current_band( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int permutable) +{ + int i; + int start, end, n; + isl_multi_aff *ma; + isl_multi_pw_aff *mpa; + isl_multi_union_pw_aff *mupa; + + if (!node) + return NULL; + + if (graph->n < 1) + isl_die(isl_schedule_node_get_ctx(node), isl_error_internal, + "graph should have at least one node", + return isl_schedule_node_free(node)); + + start = graph->band_start; + end = graph->n_total_row; + n = end - start; + + ma = node_extract_partial_schedule_multi_aff(&graph->node[0], start, n); + mpa = isl_multi_pw_aff_from_multi_aff(ma); + mupa = isl_multi_union_pw_aff_from_multi_pw_aff(mpa); + + for (i = 1; i < graph->n; ++i) { + isl_multi_union_pw_aff *mupa_i; + + ma = node_extract_partial_schedule_multi_aff(&graph->node[i], + start, n); + mpa = isl_multi_pw_aff_from_multi_aff(ma); + mupa_i = isl_multi_union_pw_aff_from_multi_pw_aff(mpa); + mupa = isl_multi_union_pw_aff_union_add(mupa, mupa_i); + } + node = isl_schedule_node_insert_partial_schedule(node, mupa); + + for (i = 0; i < n; ++i) + node = isl_schedule_node_band_member_set_coincident(node, i, + graph->node[0].coincident[start + i]); + node = isl_schedule_node_band_set_permutable(node, permutable); + + return node; +} + +/* Update the dependence relations based on the current schedule, + * add the current band to "node" and then continue with the computation + * of the next band. + * Return the updated schedule node. + */ +static __isl_give isl_schedule_node *compute_next_band( + __isl_take isl_schedule_node *node, + struct isl_sched_graph *graph, int permutable) +{ + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (update_edges(ctx, graph) < 0) + return isl_schedule_node_free(node); + node = insert_current_band(node, graph, permutable); + next_band(graph); + + node = isl_schedule_node_child(node, 0); + node = compute_schedule(node, graph); + node = isl_schedule_node_parent(node); + + return node; +} + +/* Add constraints to graph->lp that force the dependence "map" (which + * is part of the dependence relation of "edge") + * to be respected and attempt to carry it, where the edge is one from + * a node j to itself. "pos" is the sequence number of the given map. + * That is, add constraints that enforce + * + * (c_j_0 + c_j_n n + c_j_x y) - (c_j_0 + c_j_n n + c_j_x x) + * = c_j_x (y - x) >= e_i + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x) + * of valid constraints for (y - x) and then plug in (-e_i, 0, c_j_x), + * with each coefficient in c_j_x represented as a pair of non-negative + * coefficients. + */ +static int add_intra_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, __isl_take isl_map *map, int pos) +{ + unsigned total; + isl_ctx *ctx = isl_map_get_ctx(map); + isl_space *dim; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *node = edge->src; + + coef = intra_coefficients(graph, node, map); + if (!coef) + return -1; + + dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); + + total = isl_basic_set_total_dim(graph->lp); + dim_map = isl_dim_map_alloc(ctx, total); + isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1); + isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set), 1, + node->nvar, -1); + isl_dim_map_range(dim_map, node->start + 2 * node->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set), 1, + node->nvar, 1); + graph->lp = isl_basic_set_extend_constraints(graph->lp, + coef->n_eq, coef->n_ineq); + graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, + coef, dim_map); + isl_space_free(dim); + + return 0; +} + +/* Add constraints to graph->lp that force the dependence "map" (which + * is part of the dependence relation of "edge") + * to be respected and attempt to carry it, where the edge is one from + * node j to node k. "pos" is the sequence number of the given map. + * That is, add constraints that enforce + * + * (c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= e_i + * + * for each (x,y) in R. + * We obtain general constraints on coefficients (c_0, c_n, c_x) + * of valid constraints for R and then plug in + * (-e_i + c_k_0 - c_j_0, c_k_n - c_j_n, c_k_x - c_j_x) + * with each coefficient (except e_i, c_k_0 and c_j_0) + * represented as a pair of non-negative coefficients. + */ +static int add_inter_constraints(struct isl_sched_graph *graph, + struct isl_sched_edge *edge, __isl_take isl_map *map, int pos) +{ + unsigned total; + isl_ctx *ctx = isl_map_get_ctx(map); + isl_space *dim; + isl_dim_map *dim_map; + isl_basic_set *coef; + struct isl_sched_node *src = edge->src; + struct isl_sched_node *dst = edge->dst; + + coef = inter_coefficients(graph, edge, map); + if (!coef) + return -1; + + dim = isl_space_domain(isl_space_unwrap(isl_basic_set_get_space(coef))); + + total = isl_basic_set_total_dim(graph->lp); + dim_map = isl_dim_map_alloc(ctx, total); + + isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1); + + isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, 1); + isl_dim_map_range(dim_map, dst->start + 1, 2, 1, 1, dst->nparam, -1); + isl_dim_map_range(dim_map, dst->start + 2, 2, 1, 1, dst->nparam, 1); + isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set) + src->nvar, 1, + dst->nvar, -1); + isl_dim_map_range(dim_map, dst->start + 2 * dst->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set) + src->nvar, 1, + dst->nvar, 1); + + isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, -1); + isl_dim_map_range(dim_map, src->start + 1, 2, 1, 1, src->nparam, 1); + isl_dim_map_range(dim_map, src->start + 2, 2, 1, 1, src->nparam, -1); + isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 1, 2, + isl_space_dim(dim, isl_dim_set), 1, + src->nvar, 1); + isl_dim_map_range(dim_map, src->start + 2 * src->nparam + 2, 2, + isl_space_dim(dim, isl_dim_set), 1, + src->nvar, -1); + + graph->lp = isl_basic_set_extend_constraints(graph->lp, + coef->n_eq, coef->n_ineq); + graph->lp = isl_basic_set_add_constraints_dim_map(graph->lp, + coef, dim_map); + isl_space_free(dim); + + return 0; +} + +/* Add constraints to graph->lp that force all (conditional) validity + * dependences to be respected and attempt to carry them. + */ +static int add_all_constraints(struct isl_sched_graph *graph) +{ + int i, j; + int pos; + + pos = 0; + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge= &graph->edge[i]; + + if (!edge->validity && !edge->conditional_validity) + continue; + + for (j = 0; j < edge->map->n; ++j) { + isl_basic_map *bmap; + isl_map *map; + + bmap = isl_basic_map_copy(edge->map->p[j]); + map = isl_map_from_basic_map(bmap); + + if (edge->src == edge->dst && + add_intra_constraints(graph, edge, map, pos) < 0) + return -1; + if (edge->src != edge->dst && + add_inter_constraints(graph, edge, map, pos) < 0) + return -1; + ++pos; + } + } + + return 0; +} + +/* Count the number of equality and inequality constraints + * that will be added to the carry_lp problem. + * We count each edge exactly once. + */ +static int count_all_constraints(struct isl_sched_graph *graph, + int *n_eq, int *n_ineq) +{ + int i, j; + + *n_eq = *n_ineq = 0; + for (i = 0; i < graph->n_edge; ++i) { + struct isl_sched_edge *edge= &graph->edge[i]; + for (j = 0; j < edge->map->n; ++j) { + isl_basic_map *bmap; + isl_map *map; + + bmap = isl_basic_map_copy(edge->map->p[j]); + map = isl_map_from_basic_map(bmap); + + if (count_map_constraints(graph, edge, map, + n_eq, n_ineq, 1, 0) < 0) + return -1; + } + } + + return 0; +} + +/* Construct an LP problem for finding schedule coefficients + * such that the schedule carries as many dependences as possible. + * In particular, for each dependence i, we bound the dependence distance + * from below by e_i, with 0 <= e_i <= 1 and then maximize the sum + * of all e_i's. Dependences with e_i = 0 in the solution are simply + * respected, while those with e_i > 0 (in practice e_i = 1) are carried. + * Note that if the dependence relation is a union of basic maps, + * then we have to consider each basic map individually as it may only + * be possible to carry the dependences expressed by some of those + * basic maps and not all of them. + * Below, we consider each of those basic maps as a separate "edge". + * + * All variables of the LP are non-negative. The actual coefficients + * may be negative, so each coefficient is represented as the difference + * of two non-negative variables. The negative part always appears + * immediately before the positive part. + * Other than that, the variables have the following order + * + * - sum of (1 - e_i) over all edges + * - sum of positive and negative parts of all c_n coefficients + * (unconstrained when computing non-parametric schedules) + * - sum of positive and negative parts of all c_x coefficients + * - for each edge + * - e_i + * - for each node + * - c_i_0 + * - positive and negative parts of c_i_n (if parametric) + * - positive and negative parts of c_i_x + * + * The constraints are those from the (validity) edges plus three equalities + * to express the sums and n_edge inequalities to express e_i <= 1. + */ +static int setup_carry_lp(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i, j; + int k; + isl_space *dim; + unsigned total; + int n_eq, n_ineq; + int n_edge; + + n_edge = 0; + for (i = 0; i < graph->n_edge; ++i) + n_edge += graph->edge[i].map->n; + + total = 3 + n_edge; + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[graph->sorted[i]]; + node->start = total; + total += 1 + 2 * (node->nparam + node->nvar); + } + + if (count_all_constraints(graph, &n_eq, &n_ineq) < 0) + return -1; + + dim = isl_space_set_alloc(ctx, 0, total); + isl_basic_set_free(graph->lp); + n_eq += 3; + n_ineq += n_edge; + graph->lp = isl_basic_set_alloc_space(dim, 0, n_eq, n_ineq); + graph->lp = isl_basic_set_set_rational(graph->lp); + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][0], -n_edge); + isl_int_set_si(graph->lp->eq[k][1], 1); + for (i = 0; i < n_edge; ++i) + isl_int_set_si(graph->lp->eq[k][4 + i], 1); + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][2], -1); + for (i = 0; i < graph->n; ++i) { + int pos = 1 + graph->node[i].start + 1; + + for (j = 0; j < 2 * graph->node[i].nparam; ++j) + isl_int_set_si(graph->lp->eq[k][pos + j], 1); + } + + k = isl_basic_set_alloc_equality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->eq[k], 1 + total); + isl_int_set_si(graph->lp->eq[k][3], -1); + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int pos = 1 + node->start + 1 + 2 * node->nparam; + + for (j = 0; j < 2 * node->nvar; ++j) + isl_int_set_si(graph->lp->eq[k][pos + j], 1); + } + + for (i = 0; i < n_edge; ++i) { + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return -1; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + isl_int_set_si(graph->lp->ineq[k][4 + i], -1); + isl_int_set_si(graph->lp->ineq[k][0], 1); + } + + if (add_all_constraints(graph) < 0) + return -1; + + return 0; +} + +static __isl_give isl_schedule_node *compute_component_schedule( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int wcc); + +/* Comparison function for sorting the statements based on + * the corresponding value in "r". + */ +static int smaller_value(const void *a, const void *b, void *data) +{ + isl_vec *r = data; + const int *i1 = a; + const int *i2 = b; + + return isl_int_cmp(r->el[*i1], r->el[*i2]); +} + +/* If the schedule_split_scaled option is set and if the linear + * parts of the scheduling rows for all nodes in the graphs have + * a non-trivial common divisor, then split off the remainder of the + * constant term modulo this common divisor from the linear part. + * Otherwise, insert a band node directly and continue with + * the construction of the schedule. + * + * If a non-trivial common divisor is found, then + * the linear part is reduced and the remainder is enforced + * by a sequence node with the children placed in the order + * of this remainder. + * In particular, we assign an scc index based on the remainder and + * then rely on compute_component_schedule to insert the sequence and + * to continue the schedule construction on each part. + */ +static __isl_give isl_schedule_node *split_scaled( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + int i; + int row; + int scc; + isl_ctx *ctx; + isl_int gcd, gcd_i; + isl_vec *r; + int *order; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (!ctx->opt->schedule_split_scaled) + return compute_next_band(node, graph, 0); + if (graph->n <= 1) + return compute_next_band(node, graph, 0); + + isl_int_init(gcd); + isl_int_init(gcd_i); + + isl_int_set_si(gcd, 0); + + row = isl_mat_rows(graph->node[0].sched) - 1; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int cols = isl_mat_cols(node->sched); + + isl_seq_gcd(node->sched->row[row] + 1, cols - 1, &gcd_i); + isl_int_gcd(gcd, gcd, gcd_i); + } + + isl_int_clear(gcd_i); + + if (isl_int_cmp_si(gcd, 1) <= 0) { + isl_int_clear(gcd); + return compute_next_band(node, graph, 0); + } + + r = isl_vec_alloc(ctx, graph->n); + order = isl_calloc_array(ctx, int, graph->n); + if (!r || !order) + goto error; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + order[i] = i; + isl_int_fdiv_r(r->el[i], node->sched->row[row][0], gcd); + isl_int_fdiv_q(node->sched->row[row][0], + node->sched->row[row][0], gcd); + isl_int_mul(node->sched->row[row][0], + node->sched->row[row][0], gcd); + node->sched = isl_mat_scale_down_row(node->sched, row, gcd); + if (!node->sched) + goto error; + } + + if (isl_sort(order, graph->n, sizeof(order[0]), &smaller_value, r) < 0) + goto error; + + scc = 0; + for (i = 0; i < graph->n; ++i) { + if (i > 0 && isl_int_ne(r->el[order[i - 1]], r->el[order[i]])) + ++scc; + graph->node[order[i]].scc = scc; + } + graph->scc = ++scc; + graph->weak = 0; + + isl_int_clear(gcd); + isl_vec_free(r); + free(order); + + if (update_edges(ctx, graph) < 0) + return isl_schedule_node_free(node); + node = insert_current_band(node, graph, 0); + next_band(graph); + + node = isl_schedule_node_child(node, 0); + node = compute_component_schedule(node, graph, 0); + node = isl_schedule_node_parent(node); + + return node; +error: + isl_vec_free(r); + free(order); + isl_int_clear(gcd); + return isl_schedule_node_free(node); +} + +/* Is the schedule row "sol" trivial on node "node"? + * That is, is the solution zero on the dimensions orthogonal to + * the previously found solutions? + * Return 1 if the solution is trivial, 0 if it is not and -1 on error. + * + * Each coefficient is represented as the difference between + * two non-negative values in "sol". "sol" has been computed + * in terms of the original iterators (i.e., without use of cmap). + * We construct the schedule row s and write it as a linear + * combination of (linear combinations of) previously computed schedule rows. + * s = Q c or c = U s. + * If the final entries of c are all zero, then the solution is trivial. + */ +static int is_trivial(struct isl_sched_node *node, __isl_keep isl_vec *sol) +{ + int i; + int pos; + int trivial; + isl_ctx *ctx; + isl_vec *node_sol; + + if (!sol) + return -1; + if (node->nvar == node->rank) + return 0; + + ctx = isl_vec_get_ctx(sol); + node_sol = isl_vec_alloc(ctx, node->nvar); + if (!node_sol) + return -1; + + pos = 1 + node->start + 1 + 2 * node->nparam; + + for (i = 0; i < node->nvar; ++i) + isl_int_sub(node_sol->el[i], + sol->el[pos + 2 * i + 1], sol->el[pos + 2 * i]); + + node_sol = isl_mat_vec_product(isl_mat_copy(node->cinv), node_sol); + + if (!node_sol) + return -1; + + trivial = isl_seq_first_non_zero(node_sol->el + node->rank, + node->nvar - node->rank) == -1; + + isl_vec_free(node_sol); + + return trivial; +} + +/* Is the schedule row "sol" trivial on any node where it should + * not be trivial? + * "sol" has been computed in terms of the original iterators + * (i.e., without use of cmap). + * Return 1 if any solution is trivial, 0 if they are not and -1 on error. + */ +static int is_any_trivial(struct isl_sched_graph *graph, + __isl_keep isl_vec *sol) +{ + int i; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + int trivial; + + if (!needs_row(graph, node)) + continue; + trivial = is_trivial(node, sol); + if (trivial < 0 || trivial) + return trivial; + } + + return 0; +} + +/* Construct a schedule row for each node such that as many dependences + * as possible are carried and then continue with the next band. + * + * If the computed schedule row turns out to be trivial on one or + * more nodes where it should not be trivial, then we throw it away + * and try again on each component separately. + * + * If there is only one component, then we accept the schedule row anyway, + * but we do not consider it as a complete row and therefore do not + * increment graph->n_row. Note that the ranks of the nodes that + * do get a non-trivial schedule part will get updated regardless and + * graph->maxvar is computed based on these ranks. The test for + * whether more schedule rows are required in compute_schedule_wcc + * is therefore not affected. + * + * Insert a band corresponding to the schedule row at position "node" + * of the schedule tree and continue with the construction of the schedule. + * This insertion and the continued construction is performed by split_scaled + * after optionally checking for non-trivial common divisors. + */ +static __isl_give isl_schedule_node *carry_dependences( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + int i; + int n_edge; + int trivial; + isl_ctx *ctx; + isl_vec *sol; + isl_basic_set *lp; + + if (!node) + return NULL; + + n_edge = 0; + for (i = 0; i < graph->n_edge; ++i) + n_edge += graph->edge[i].map->n; + + ctx = isl_schedule_node_get_ctx(node); + if (setup_carry_lp(ctx, graph) < 0) + return isl_schedule_node_free(node); + + lp = isl_basic_set_copy(graph->lp); + sol = isl_tab_basic_set_non_neg_lexmin(lp); + if (!sol) + return isl_schedule_node_free(node); + + if (sol->size == 0) { + isl_vec_free(sol); + isl_die(ctx, isl_error_internal, + "error in schedule construction", + return isl_schedule_node_free(node)); + } + + isl_int_divexact(sol->el[1], sol->el[1], sol->el[0]); + if (isl_int_cmp_si(sol->el[1], n_edge) >= 0) { + isl_vec_free(sol); + isl_die(ctx, isl_error_unknown, + "unable to carry dependences", + return isl_schedule_node_free(node)); + } + + trivial = is_any_trivial(graph, sol); + if (trivial < 0) { + sol = isl_vec_free(sol); + } else if (trivial && graph->scc > 1) { + isl_vec_free(sol); + return compute_component_schedule(node, graph, 1); + } + + if (update_schedule(graph, sol, 0, 0) < 0) + return isl_schedule_node_free(node); + if (trivial) + graph->n_row--; + + return split_scaled(node, graph); +} + +/* Topologically sort statements mapped to the same schedule iteration + * and add insert a sequence node in front of "node" + * corresponding to this order. + * + * If it turns out to be impossible to sort the statements apart, + * because different dependences impose different orderings + * on the statements, then we extend the schedule such that + * it carries at least one more dependence. + */ +static __isl_give isl_schedule_node *sort_statements( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + isl_union_set_list *filters; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (graph->n < 1) + isl_die(ctx, isl_error_internal, + "graph should have at least one node", + return isl_schedule_node_free(node)); + + if (graph->n == 1) + return node; + + if (update_edges(ctx, graph) < 0) + return isl_schedule_node_free(node); + + if (graph->n_edge == 0) + return node; + + if (detect_sccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + + next_band(graph); + if (graph->scc < graph->n) + return carry_dependences(node, graph); + + filters = extract_sccs(ctx, graph); + node = isl_schedule_node_insert_sequence(node, filters); + + return node; +} + +/* Are there any (non-empty) (conditional) validity edges in the graph? + */ +static int has_validity_edges(struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) { + int empty; + + empty = isl_map_plain_is_empty(graph->edge[i].map); + if (empty < 0) + return -1; + if (empty) + continue; + if (graph->edge[i].validity || + graph->edge[i].conditional_validity) + return 1; + } + + return 0; +} + +/* Should we apply a Feautrier step? + * That is, did the user request the Feautrier algorithm and are + * there any validity dependences (left)? + */ +static int need_feautrier_step(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + if (ctx->opt->schedule_algorithm != ISL_SCHEDULE_ALGORITHM_FEAUTRIER) + return 0; + + return has_validity_edges(graph); +} + +/* Compute a schedule for a connected dependence graph using Feautrier's + * multi-dimensional scheduling algorithm and return the updated schedule node. + * + * The original algorithm is described in [1]. + * The main idea is to minimize the number of scheduling dimensions, by + * trying to satisfy as many dependences as possible per scheduling dimension. + * + * [1] P. Feautrier, Some Efficient Solutions to the Affine Scheduling + * Problem, Part II: Multi-Dimensional Time. + * In Intl. Journal of Parallel Programming, 1992. + */ +static __isl_give isl_schedule_node *compute_schedule_wcc_feautrier( + isl_schedule_node *node, struct isl_sched_graph *graph) +{ + return carry_dependences(node, graph); +} + +/* Turn off the "local" bit on all (condition) edges. + */ +static void clear_local_edges(struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) + if (graph->edge[i].condition) + graph->edge[i].local = 0; +} + +/* Does "graph" have both condition and conditional validity edges? + */ +static int need_condition_check(struct isl_sched_graph *graph) +{ + int i; + int any_condition = 0; + int any_conditional_validity = 0; + + for (i = 0; i < graph->n_edge; ++i) { + if (graph->edge[i].condition) + any_condition = 1; + if (graph->edge[i].conditional_validity) + any_conditional_validity = 1; + } + + return any_condition && any_conditional_validity; +} + +/* Does "graph" contain any coincidence edge? + */ +static int has_any_coincidence(struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n_edge; ++i) + if (graph->edge[i].coincidence) + return 1; + + return 0; +} + +/* Extract the final schedule row as a map with the iteration domain + * of "node" as domain. + */ +static __isl_give isl_map *final_row(struct isl_sched_node *node) +{ + isl_local_space *ls; + isl_aff *aff; + int row; + + row = isl_mat_rows(node->sched) - 1; + ls = isl_local_space_from_space(isl_space_copy(node->space)); + aff = extract_schedule_row(ls, node, row); + return isl_map_from_aff(aff); +} + +/* Is the conditional validity dependence in the edge with index "edge_index" + * violated by the latest (i.e., final) row of the schedule? + * That is, is i scheduled after j + * for any conditional validity dependence i -> j? + */ +static int is_violated(struct isl_sched_graph *graph, int edge_index) +{ + isl_map *src_sched, *dst_sched, *map; + struct isl_sched_edge *edge = &graph->edge[edge_index]; + int empty; + + src_sched = final_row(edge->src); + dst_sched = final_row(edge->dst); + map = isl_map_copy(edge->map); + map = isl_map_apply_domain(map, src_sched); + map = isl_map_apply_range(map, dst_sched); + map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_out, 0); + empty = isl_map_is_empty(map); + isl_map_free(map); + + if (empty < 0) + return -1; + + return !empty; +} + +/* Does "graph" have any satisfied condition edges that + * are adjacent to the conditional validity constraint with + * domain "conditional_source" and range "conditional_sink"? + * + * A satisfied condition is one that is not local. + * If a condition was forced to be local already (i.e., marked as local) + * then there is no need to check if it is in fact local. + * + * Additionally, mark all adjacent condition edges found as local. + */ +static int has_adjacent_true_conditions(struct isl_sched_graph *graph, + __isl_keep isl_union_set *conditional_source, + __isl_keep isl_union_set *conditional_sink) +{ + int i; + int any = 0; + + for (i = 0; i < graph->n_edge; ++i) { + int adjacent, local; + isl_union_map *condition; + + if (!graph->edge[i].condition) + continue; + if (graph->edge[i].local) + continue; + + condition = graph->edge[i].tagged_condition; + adjacent = domain_intersects(condition, conditional_sink); + if (adjacent >= 0 && !adjacent) + adjacent = range_intersects(condition, + conditional_source); + if (adjacent < 0) + return -1; + if (!adjacent) + continue; + + graph->edge[i].local = 1; + + local = is_condition_false(&graph->edge[i]); + if (local < 0) + return -1; + if (!local) + any = 1; + } + + return any; +} + +/* Are there any violated conditional validity dependences with + * adjacent condition dependences that are not local with respect + * to the current schedule? + * That is, is the conditional validity constraint violated? + * + * Additionally, mark all those adjacent condition dependences as local. + * We also mark those adjacent condition dependences that were not marked + * as local before, but just happened to be local already. This ensures + * that they remain local if the schedule is recomputed. + * + * We first collect domain and range of all violated conditional validity + * dependences and then check if there are any adjacent non-local + * condition dependences. + */ +static int has_violated_conditional_constraint(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i; + int any = 0; + isl_union_set *source, *sink; + + source = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + sink = isl_union_set_empty(isl_space_params_alloc(ctx, 0)); + for (i = 0; i < graph->n_edge; ++i) { + isl_union_set *uset; + isl_union_map *umap; + int violated; + + if (!graph->edge[i].conditional_validity) + continue; + + violated = is_violated(graph, i); + if (violated < 0) + goto error; + if (!violated) + continue; + + any = 1; + + umap = isl_union_map_copy(graph->edge[i].tagged_validity); + uset = isl_union_map_domain(umap); + source = isl_union_set_union(source, uset); + source = isl_union_set_coalesce(source); + + umap = isl_union_map_copy(graph->edge[i].tagged_validity); + uset = isl_union_map_range(umap); + sink = isl_union_set_union(sink, uset); + sink = isl_union_set_coalesce(sink); + } + + if (any) + any = has_adjacent_true_conditions(graph, source, sink); + + isl_union_set_free(source); + isl_union_set_free(sink); + return any; +error: + isl_union_set_free(source); + isl_union_set_free(sink); + return -1; +} + +/* Compute a schedule for a connected dependence graph and return + * the updated schedule node. + * + * We try to find a sequence of as many schedule rows as possible that result + * in non-negative dependence distances (independent of the previous rows + * in the sequence, i.e., such that the sequence is tilable), with as + * many of the initial rows as possible satisfying the coincidence constraints. + * If we can't find any more rows we either + * - split between SCCs and start over (assuming we found an interesting + * pair of SCCs between which to split) + * - continue with the next band (assuming the current band has at least + * one row) + * - try to carry as many dependences as possible and continue with the next + * band + * In each case, we first insert a band node in the schedule tree + * if any rows have been computed. + * + * If Feautrier's algorithm is selected, we first recursively try to satisfy + * as many validity dependences as possible. When all validity dependences + * are satisfied we extend the schedule to a full-dimensional schedule. + * + * If we manage to complete the schedule, we insert a band node + * (if any schedule rows were computed) and we finish off by topologically + * sorting the statements based on the remaining dependences. + * + * If ctx->opt->schedule_outer_coincidence is set, then we force the + * outermost dimension to satisfy the coincidence constraints. If this + * turns out to be impossible, we fall back on the general scheme above + * and try to carry as many dependences as possible. + * + * If "graph" contains both condition and conditional validity dependences, + * then we need to check that that the conditional schedule constraint + * is satisfied, i.e., there are no violated conditional validity dependences + * that are adjacent to any non-local condition dependences. + * If there are, then we mark all those adjacent condition dependences + * as local and recompute the current band. Those dependences that + * are marked local will then be forced to be local. + * The initial computation is performed with no dependences marked as local. + * If we are lucky, then there will be no violated conditional validity + * dependences adjacent to any non-local condition dependences. + * Otherwise, we mark some additional condition dependences as local and + * recompute. We continue this process until there are no violations left or + * until we are no longer able to compute a schedule. + * Since there are only a finite number of dependences, + * there will only be a finite number of iterations. + */ +static __isl_give isl_schedule_node *compute_schedule_wcc( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph) +{ + int has_coincidence; + int use_coincidence; + int force_coincidence = 0; + int check_conditional; + int insert; + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (detect_sccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + if (sort_sccs(graph) < 0) + return isl_schedule_node_free(node); + + if (compute_maxvar(graph) < 0) + return isl_schedule_node_free(node); + + if (need_feautrier_step(ctx, graph)) + return compute_schedule_wcc_feautrier(node, graph); + + clear_local_edges(graph); + check_conditional = need_condition_check(graph); + has_coincidence = has_any_coincidence(graph); + + if (ctx->opt->schedule_outer_coincidence) + force_coincidence = 1; + + use_coincidence = has_coincidence; + while (graph->n_row < graph->maxvar) { + isl_vec *sol; + int violated; + int coincident; + + graph->src_scc = -1; + graph->dst_scc = -1; + + if (setup_lp(ctx, graph, use_coincidence) < 0) + return isl_schedule_node_free(node); + sol = solve_lp(graph); + if (!sol) + return isl_schedule_node_free(node); + if (sol->size == 0) { + int empty = graph->n_total_row == graph->band_start; + + isl_vec_free(sol); + if (use_coincidence && (!force_coincidence || !empty)) { + use_coincidence = 0; + continue; + } + if (!ctx->opt->schedule_maximize_band_depth && !empty) + return compute_next_band(node, graph, 1); + if (graph->src_scc >= 0) + return compute_split_schedule(node, graph); + if (!empty) + return compute_next_band(node, graph, 1); + return carry_dependences(node, graph); + } + coincident = !has_coincidence || use_coincidence; + if (update_schedule(graph, sol, 1, coincident) < 0) + return isl_schedule_node_free(node); + + if (!check_conditional) + continue; + violated = has_violated_conditional_constraint(ctx, graph); + if (violated < 0) + return isl_schedule_node_free(node); + if (!violated) + continue; + if (reset_band(graph) < 0) + return isl_schedule_node_free(node); + use_coincidence = has_coincidence; + } + + insert = graph->n_total_row > graph->band_start; + if (insert) { + node = insert_current_band(node, graph, 1); + node = isl_schedule_node_child(node, 0); + } + node = sort_statements(node, graph); + if (insert) + node = isl_schedule_node_parent(node); + + return node; +} + +/* Compute a schedule for each group of nodes identified by node->scc + * separately and then combine them in a sequence node (or as set node + * if graph->weak is set) inserted at position "node" of the schedule tree. + * Return the updated schedule node. + * + * If "wcc" is set then each of the groups belongs to a single + * weakly connected component in the dependence graph so that + * there is no need for compute_sub_schedule to look for weakly + * connected components. + */ +static __isl_give isl_schedule_node *compute_component_schedule( + __isl_take isl_schedule_node *node, struct isl_sched_graph *graph, + int wcc) +{ + int component, i; + int n, n_edge; + isl_ctx *ctx; + isl_union_set_list *filters; + + if (!node) + return NULL; + ctx = isl_schedule_node_get_ctx(node); + + filters = extract_sccs(ctx, graph); + if (graph->weak) + node = isl_schedule_node_insert_set(node, filters); + else + node = isl_schedule_node_insert_sequence(node, filters); + + for (component = 0; component < graph->scc; ++component) { + n = 0; + for (i = 0; i < graph->n; ++i) + if (graph->node[i].scc == component) + n++; + n_edge = 0; + for (i = 0; i < graph->n_edge; ++i) + if (graph->edge[i].src->scc == component && + graph->edge[i].dst->scc == component) + n_edge++; + + node = isl_schedule_node_child(node, component); + node = isl_schedule_node_child(node, 0); + node = compute_sub_schedule(node, ctx, graph, n, n_edge, + &node_scc_exactly, + &edge_scc_exactly, component, wcc); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_parent(node); + } + + return node; +} + +/* Compute a schedule for the given dependence graph and insert it at "node". + * Return the updated schedule node. + * + * We first check if the graph is connected (through validity and conditional + * validity dependences) and, if not, compute a schedule + * for each component separately. + * If the schedule_serialize_sccs option is set, then we check for strongly + * connected components instead and compute a separate schedule for + * each such strongly connected component. + */ +static __isl_give isl_schedule_node *compute_schedule(isl_schedule_node *node, + struct isl_sched_graph *graph) +{ + isl_ctx *ctx; + + if (!node) + return NULL; + + ctx = isl_schedule_node_get_ctx(node); + if (isl_options_get_schedule_serialize_sccs(ctx)) { + if (detect_sccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + } else { + if (detect_wccs(ctx, graph) < 0) + return isl_schedule_node_free(node); + } + + if (graph->scc > 1) + return compute_component_schedule(node, graph, 1); + + return compute_schedule_wcc(node, graph); +} + +/* Compute a schedule on sc->domain that respects the given schedule + * constraints. + * + * In particular, the schedule respects all the validity dependences. + * If the default isl scheduling algorithm is used, it tries to minimize + * the dependence distances over the proximity dependences. + * If Feautrier's scheduling algorithm is used, the proximity dependence + * distances are only minimized during the extension to a full-dimensional + * schedule. + * + * If there are any condition and conditional validity dependences, + * then the conditional validity dependences may be violated inside + * a tilable band, provided they have no adjacent non-local + * condition dependences. + * + * The context is included in the domain before the nodes of + * the graphs are extracted in order to be able to exploit + * any possible additional equalities. + * However, the returned schedule contains the original domain + * (before this intersection). + */ +__isl_give isl_schedule *isl_schedule_constraints_compute_schedule( + __isl_take isl_schedule_constraints *sc) +{ + isl_ctx *ctx = isl_schedule_constraints_get_ctx(sc); + struct isl_sched_graph graph = { 0 }; + isl_schedule *sched; + isl_schedule_node *node; + isl_union_set *domain; + struct isl_extract_edge_data data; + enum isl_edge_type i; + int r; + + sc = isl_schedule_constraints_align_params(sc); + if (!sc) + return NULL; + + graph.n = isl_union_set_n_set(sc->domain); + if (graph.n == 0) { + isl_union_set *domain = isl_union_set_copy(sc->domain); + sched = isl_schedule_from_domain(domain); + goto done; + } + if (graph_alloc(ctx, &graph, graph.n, + isl_schedule_constraints_n_map(sc)) < 0) + goto error; + if (compute_max_row(&graph, sc) < 0) + goto error; + graph.root = 1; + graph.n = 0; + domain = isl_union_set_copy(sc->domain); + domain = isl_union_set_intersect_params(domain, + isl_set_copy(sc->context)); + r = isl_union_set_foreach_set(domain, &extract_node, &graph); + isl_union_set_free(domain); + if (r < 0) + goto error; + if (graph_init_table(ctx, &graph) < 0) + goto error; + for (i = isl_edge_first; i <= isl_edge_last; ++i) + graph.max_edge[i] = isl_union_map_n_map(sc->constraint[i]); + if (graph_init_edge_tables(ctx, &graph) < 0) + goto error; + graph.n_edge = 0; + data.graph = &graph; + for (i = isl_edge_first; i <= isl_edge_last; ++i) { + data.type = i; + if (isl_union_map_foreach_map(sc->constraint[i], + &extract_edge, &data) < 0) + goto error; + } + + node = isl_schedule_node_from_domain(isl_union_set_copy(sc->domain)); + node = isl_schedule_node_child(node, 0); + if (graph.n > 0) + node = compute_schedule(node, &graph); + sched = isl_schedule_node_get_schedule(node); + isl_schedule_node_free(node); + +done: + graph_free(ctx, &graph); + isl_schedule_constraints_free(sc); + + return sched; +error: + graph_free(ctx, &graph); + isl_schedule_constraints_free(sc); + return NULL; +} + +/* Compute a schedule for the given union of domains that respects + * all the validity dependences and minimizes + * the dependence distances over the proximity dependences. + * + * This function is kept for backward compatibility. + */ +__isl_give isl_schedule *isl_union_set_compute_schedule( + __isl_take isl_union_set *domain, + __isl_take isl_union_map *validity, + __isl_take isl_union_map *proximity) +{ + isl_schedule_constraints *sc; + + sc = isl_schedule_constraints_on_domain(domain); + sc = isl_schedule_constraints_set_validity(sc, validity); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + + return isl_schedule_constraints_compute_schedule(sc); +} diff -Nru isl-0.12.2/isl_schedule_read.c isl-0.15/isl_schedule_read.c --- isl-0.12.2/isl_schedule_read.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_read.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,820 @@ +#include + +#include +#include +#include +#include + +/* An enumeration of the various keys that may appear in a YAML mapping + * of a schedule. + */ +enum isl_schedule_key { + isl_schedule_key_error = -1, + isl_schedule_key_child, + isl_schedule_key_coincident, + isl_schedule_key_context, + isl_schedule_key_contraction, + isl_schedule_key_domain, + isl_schedule_key_expansion, + isl_schedule_key_extension, + isl_schedule_key_filter, + isl_schedule_key_guard, + isl_schedule_key_leaf, + isl_schedule_key_mark, + isl_schedule_key_options, + isl_schedule_key_permutable, + isl_schedule_key_schedule, + isl_schedule_key_sequence, + isl_schedule_key_set +}; + +/* Extract a mapping key from the token "tok". + * Return isl_schedule_key_error on error, i.e., if "tok" does not + * correspond to any known key. + */ +static enum isl_schedule_key extract_key(__isl_keep isl_stream *s, + struct isl_token *tok) +{ + int type; + char *name; + enum isl_schedule_key key; + isl_ctx *ctx; + + ctx = isl_stream_get_ctx(s); + type = isl_token_get_type(tok); + if (type != ISL_TOKEN_IDENT && type != ISL_TOKEN_STRING) { + isl_stream_error(s, tok, "expecting key"); + return isl_schedule_key_error; + } + name = isl_token_get_str(ctx, tok); + if (!strcmp(name, "child")) + key = isl_schedule_key_child; + else if (!strcmp(name, "coincident")) + key = isl_schedule_key_coincident; + else if (!strcmp(name, "context")) + key = isl_schedule_key_context; + else if (!strcmp(name, "contraction")) + key = isl_schedule_key_contraction; + else if (!strcmp(name, "domain")) + key = isl_schedule_key_domain; + else if (!strcmp(name, "expansion")) + key = isl_schedule_key_expansion; + else if (!strcmp(name, "extension")) + key = isl_schedule_key_extension; + else if (!strcmp(name, "filter")) + key = isl_schedule_key_filter; + else if (!strcmp(name, "guard")) + key = isl_schedule_key_guard; + else if (!strcmp(name, "leaf")) + key = isl_schedule_key_leaf; + else if (!strcmp(name, "mark")) + key = isl_schedule_key_mark; + else if (!strcmp(name, "options")) + key = isl_schedule_key_options; + else if (!strcmp(name, "schedule")) + key = isl_schedule_key_schedule; + else if (!strcmp(name, "sequence")) + key = isl_schedule_key_sequence; + else if (!strcmp(name, "set")) + key = isl_schedule_key_set; + else if (!strcmp(name, "permutable")) + key = isl_schedule_key_permutable; + else + isl_die(ctx, isl_error_invalid, "unknown key", + key = isl_schedule_key_error); + free(name); + return key; +} + +/* Read a key from "s" and return the corresponding enum. + * Return isl_schedule_key_error on error, i.e., if the first token + * on the stream does not correspond to any known key. + */ +static enum isl_schedule_key get_key(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + enum isl_schedule_key key; + + tok = isl_stream_next_token(s); + key = extract_key(s, tok); + isl_token_free(tok); + + return key; +} + +static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree( + __isl_keep isl_stream *s); + +/* Read a subtree with context root node from "s". + */ +static __isl_give isl_schedule_tree *read_context(__isl_keep isl_stream *s) +{ + isl_set *context = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + int more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + context = isl_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_context(context); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_context(tree, context); + } + + return tree; +error: + isl_set_free(context); + return NULL; +} + +/* Read a subtree with domain root node from "s". + */ +static __isl_give isl_schedule_tree *read_domain(__isl_keep isl_stream *s) +{ + isl_union_set *domain = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + int more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + domain = isl_union_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_domain(domain); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_domain(tree, domain); + } + + return tree; +error: + isl_union_set_free(domain); + return NULL; +} + +/* Read a subtree with expansion root node from "s". + */ +static __isl_give isl_schedule_tree *read_expansion(isl_stream *s) +{ + isl_ctx *ctx; + isl_union_pw_multi_aff *contraction = NULL; + isl_union_map *expansion = NULL; + isl_schedule_tree *tree = NULL; + int more; + + ctx = isl_stream_get_ctx(s); + + do { + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + goto error; + + switch (key) { + case isl_schedule_key_contraction: + isl_union_pw_multi_aff_free(contraction); + tok = isl_stream_next_token(s); + str = isl_token_get_str(ctx, tok); + contraction = isl_union_pw_multi_aff_read_from_str(ctx, + str); + free(str); + isl_token_free(tok); + if (!contraction) + goto error; + break; + case isl_schedule_key_expansion: + isl_union_map_free(expansion); + tok = isl_stream_next_token(s); + str = isl_token_get_str(ctx, tok); + expansion = isl_union_map_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + if (!expansion) + goto error; + break; + case isl_schedule_key_child: + isl_schedule_tree_free(tree); + tree = isl_stream_read_schedule_tree(s); + if (!tree) + goto error; + break; + default: + isl_die(ctx, isl_error_invalid, "unexpected key", + goto error); + } + } while ((more = isl_stream_yaml_next(s)) > 0); + + if (more < 0) + goto error; + + if (!contraction) + isl_die(ctx, isl_error_invalid, "missing contraction", + goto error); + if (!expansion) + isl_die(ctx, isl_error_invalid, "missing expansion", + goto error); + + if (!tree) + return isl_schedule_tree_from_expansion(contraction, expansion); + return isl_schedule_tree_insert_expansion(tree, contraction, expansion); +error: + isl_schedule_tree_free(tree); + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Read a subtree with extension root node from "s". + */ +static __isl_give isl_schedule_tree *read_extension(isl_stream *s) +{ + isl_union_map *extension = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + int more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + extension = isl_union_map_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_extension(extension); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_extension(tree, extension); + } + + return tree; +error: + isl_union_map_free(extension); + return NULL; +} + +/* Read a subtree with filter root node from "s". + */ +static __isl_give isl_schedule_tree *read_filter(__isl_keep isl_stream *s) +{ + isl_union_set *filter = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + int more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + filter = isl_union_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_filter(filter); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_filter(tree, filter); + } + + return tree; +error: + isl_union_set_free(filter); + return NULL; +} + +/* Read a subtree with guard root node from "s". + */ +static __isl_give isl_schedule_tree *read_guard(isl_stream *s) +{ + isl_set *guard = NULL; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + int more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + guard = isl_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + tree = isl_schedule_tree_from_guard(guard); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_guard(tree, guard); + } + + return tree; +error: + isl_set_free(guard); + return NULL; +} + +/* Read a subtree with mark root node from "s". + */ +static __isl_give isl_schedule_tree *read_mark(isl_stream *s) +{ + isl_id *mark; + isl_schedule_tree *tree; + isl_ctx *ctx; + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + int more; + + ctx = isl_stream_get_ctx(s); + + key = get_key(s); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + return NULL; + } + str = isl_token_get_str(ctx, tok); + mark = isl_id_alloc(ctx, str, NULL); + free(str); + isl_token_free(tok); + + more = isl_stream_yaml_next(s); + if (more < 0) + goto error; + if (!more) { + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + } else { + key = get_key(s); + if (key != isl_schedule_key_child) + isl_die(ctx, isl_error_invalid, "expecting child", + goto error); + if (isl_stream_yaml_next(s) < 0) + goto error; + tree = isl_stream_read_schedule_tree(s); + tree = isl_schedule_tree_insert_mark(tree, mark); + } + + return tree; +error: + isl_id_free(mark); + return NULL; +} + +/* Read a sequence of integers from "s" (representing the coincident + * property of a band node). + */ +static __isl_give isl_val_list *read_coincident(__isl_keep isl_stream *s) +{ + isl_ctx *ctx; + isl_val_list *list; + int more; + + ctx = isl_stream_get_ctx(s); + + if (isl_stream_yaml_read_start_sequence(s) < 0) + return NULL; + + list = isl_val_list_alloc(ctx, 0); + while ((more = isl_stream_yaml_next(s)) > 0) { + isl_val *val; + + val = isl_stream_read_val(s); + list = isl_val_list_add(list, val); + } + + if (more < 0 || isl_stream_yaml_read_end_sequence(s)) + list = isl_val_list_free(list); + + return list; +} + +/* Set the (initial) coincident properties of "band" according to + * the (initial) elements of "coincident". + */ +static __isl_give isl_schedule_band *set_coincident( + __isl_take isl_schedule_band *band, __isl_take isl_val_list *coincident) +{ + int i; + int n, m; + + n = isl_schedule_band_n_member(band); + m = isl_val_list_n_val(coincident); + + for (i = 0; i < n && i < m; ++i) { + isl_val *v; + + v = isl_val_list_get_val(coincident, i); + if (!v) + band = isl_schedule_band_free(band); + band = isl_schedule_band_member_set_coincident(band, i, + !isl_val_is_zero(v)); + isl_val_free(v); + } + isl_val_list_free(coincident); + return band; +} + +/* Read a subtree with band root node from "s". + */ +static __isl_give isl_schedule_tree *read_band(isl_stream *s) +{ + isl_multi_union_pw_aff *schedule = NULL; + isl_schedule_tree *tree = NULL; + isl_val_list *coincident = NULL; + isl_union_set *options = NULL; + isl_ctx *ctx; + isl_schedule_band *band; + int permutable = 0; + int more; + + ctx = isl_stream_get_ctx(s); + + do { + struct isl_token *tok; + enum isl_schedule_key key; + char *str; + isl_val *v; + + key = get_key(s); + if (isl_stream_yaml_next(s) < 0) + goto error; + + switch (key) { + case isl_schedule_key_schedule: + isl_multi_union_pw_aff_free(schedule); + tok = isl_stream_next_token(s); + if (!tok) { + isl_stream_error(s, NULL, "unexpected EOF"); + goto error; + } + str = isl_token_get_str(ctx, tok); + schedule = isl_multi_union_pw_aff_read_from_str(ctx, + str); + free(str); + isl_token_free(tok); + if (!schedule) + goto error; + break; + case isl_schedule_key_coincident: + coincident = read_coincident(s); + if (!coincident) + goto error; + break; + case isl_schedule_key_permutable: + v = isl_stream_read_val(s); + permutable = !isl_val_is_zero(v); + isl_val_free(v); + break; + case isl_schedule_key_options: + isl_union_set_free(options); + tok = isl_stream_next_token(s); + str = isl_token_get_str(ctx, tok); + options = isl_union_set_read_from_str(ctx, str); + free(str); + isl_token_free(tok); + if (!options) + goto error; + break; + case isl_schedule_key_child: + isl_schedule_tree_free(tree); + tree = isl_stream_read_schedule_tree(s); + if (!tree) + goto error; + break; + default: + isl_die(ctx, isl_error_invalid, "unexpected key", + goto error); + } + } while ((more = isl_stream_yaml_next(s)) > 0); + + if (more < 0) + goto error; + + if (!schedule) + isl_die(ctx, isl_error_invalid, "missing schedule", goto error); + + band = isl_schedule_band_from_multi_union_pw_aff(schedule); + band = isl_schedule_band_set_permutable(band, permutable); + if (coincident) + band = set_coincident(band, coincident); + if (options) + band = isl_schedule_band_set_ast_build_options(band, options); + if (tree) + tree = isl_schedule_tree_insert_band(tree, band); + else + tree = isl_schedule_tree_from_band(band); + + return tree; +error: + isl_val_list_free(coincident); + isl_union_set_free(options); + isl_schedule_tree_free(tree); + isl_multi_union_pw_aff_free(schedule); + return NULL; +} + +/* Read a subtree with root node of type "type" from "s". + * The node is represented by a sequence of children. + */ +static __isl_give isl_schedule_tree *read_children(isl_stream *s, + enum isl_schedule_node_type type) +{ + isl_ctx *ctx; + isl_schedule_tree_list *list; + int more; + + ctx = isl_stream_get_ctx(s); + + isl_token_free(isl_stream_next_token(s)); + + if (isl_stream_yaml_next(s) < 0) + return NULL; + + if (isl_stream_yaml_read_start_sequence(s)) + return NULL; + + list = isl_schedule_tree_list_alloc(ctx, 0); + while ((more = isl_stream_yaml_next(s)) > 0) { + isl_schedule_tree *tree; + + tree = isl_stream_read_schedule_tree(s); + list = isl_schedule_tree_list_add(list, tree); + } + + if (more < 0 || isl_stream_yaml_read_end_sequence(s)) + list = isl_schedule_tree_list_free(list); + + return isl_schedule_tree_from_children(type, list); +} + +/* Read a subtree with sequence root node from "s". + */ +static __isl_give isl_schedule_tree *read_sequence(isl_stream *s) +{ + return read_children(s, isl_schedule_node_sequence); +} + +/* Read a subtree with set root node from "s". + */ +static __isl_give isl_schedule_tree *read_set(isl_stream *s) +{ + return read_children(s, isl_schedule_node_set); +} + +/* Read a schedule (sub)tree from "s". + * + * We first determine the type of the root node based on the first + * mapping key and then hand over to a function tailored to reading + * nodes of this type. + */ +static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree( + struct isl_stream *s) +{ + enum isl_schedule_key key; + struct isl_token *tok; + isl_schedule_tree *tree = NULL; + int more; + + if (isl_stream_yaml_read_start_mapping(s)) + return NULL; + more = isl_stream_yaml_next(s); + if (more < 0) + return NULL; + if (!more) { + isl_stream_error(s, NULL, "missing key"); + return NULL; + } + + tok = isl_stream_next_token(s); + key = extract_key(s, tok); + isl_stream_push_token(s, tok); + if (key < 0) + return NULL; + switch (key) { + case isl_schedule_key_context: + tree = read_context(s); + break; + case isl_schedule_key_domain: + tree = read_domain(s); + break; + case isl_schedule_key_contraction: + case isl_schedule_key_expansion: + tree = read_expansion(s); + break; + case isl_schedule_key_extension: + tree = read_extension(s); + break; + case isl_schedule_key_filter: + tree = read_filter(s); + break; + case isl_schedule_key_guard: + tree = read_guard(s); + break; + case isl_schedule_key_leaf: + isl_token_free(isl_stream_next_token(s)); + tree = isl_schedule_tree_leaf(isl_stream_get_ctx(s)); + break; + case isl_schedule_key_mark: + tree = read_mark(s); + break; + case isl_schedule_key_sequence: + tree = read_sequence(s); + break; + case isl_schedule_key_set: + tree = read_set(s); + break; + case isl_schedule_key_schedule: + case isl_schedule_key_coincident: + case isl_schedule_key_options: + case isl_schedule_key_permutable: + tree = read_band(s); + break; + case isl_schedule_key_child: + isl_die(isl_stream_get_ctx(s), isl_error_unsupported, + "cannot identity node type", return NULL); + case isl_schedule_key_error: + return NULL; + } + + if (isl_stream_yaml_read_end_mapping(s) < 0) { + isl_stream_error(s, NULL, "unexpected extra elements"); + return isl_schedule_tree_free(tree); + } + + return tree; +} + +/* Read an isl_schedule from "s". + */ +__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!s) + return NULL; + + ctx = isl_stream_get_ctx(s); + tree = isl_stream_read_schedule_tree(s); + return isl_schedule_from_schedule_tree(ctx, tree); +} + +/* Read an isl_schedule from "input". + */ +__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input) +{ + struct isl_stream *s; + isl_schedule *schedule; + + s = isl_stream_new_file(ctx, input); + if (!s) + return NULL; + schedule = isl_stream_read_schedule(s); + isl_stream_free(s); + + return schedule; +} + +/* Read an isl_schedule from "str". + */ +__isl_give isl_schedule *isl_schedule_read_from_str(isl_ctx *ctx, + const char *str) +{ + struct isl_stream *s; + isl_schedule *schedule; + + s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + schedule = isl_stream_read_schedule(s); + isl_stream_free(s); + + return schedule; +} diff -Nru isl-0.12.2/isl_schedule_tree.c isl-0.15/isl_schedule_tree.c --- isl-0.12.2/isl_schedule_tree.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_tree.c 2015-06-10 18:25:33.000000000 +0000 @@ -0,0 +1,2699 @@ +/* + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, + * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France + */ + +#include +#include +#include + +#undef EL +#define EL isl_schedule_tree + +#include + +#undef BASE +#define BASE schedule_tree + +#include + +/* Is "tree" the leaf of a schedule tree? + */ +int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree) +{ + return isl_schedule_tree_get_type(tree) == isl_schedule_node_leaf; +} + +/* Create a new schedule tree of type "type". + * The caller is responsible for filling in the type specific fields and + * the children. + * + * By default, the single node tree does not have any anchored nodes. + * The caller is responsible for updating the anchored field if needed. + */ +static __isl_give isl_schedule_tree *isl_schedule_tree_alloc(isl_ctx *ctx, + enum isl_schedule_node_type type) +{ + isl_schedule_tree *tree; + + if (type == isl_schedule_node_error) + return NULL; + + tree = isl_calloc_type(ctx, isl_schedule_tree); + if (!tree) + return NULL; + + tree->ref = 1; + tree->ctx = ctx; + isl_ctx_ref(ctx); + tree->type = type; + tree->anchored = 0; + + return tree; +} + +/* Return a fresh copy of "tree". + */ +__isl_take isl_schedule_tree *isl_schedule_tree_dup( + __isl_keep isl_schedule_tree *tree) +{ + isl_ctx *ctx; + isl_schedule_tree *dup; + + if (!tree) + return NULL; + + ctx = isl_schedule_tree_get_ctx(tree); + dup = isl_schedule_tree_alloc(ctx, tree->type); + if (!dup) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + isl_die(ctx, isl_error_internal, + "allocation should have failed", + isl_schedule_tree_free(dup)); + case isl_schedule_node_band: + dup->band = isl_schedule_band_copy(tree->band); + if (!dup->band) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_context: + dup->context = isl_set_copy(tree->context); + if (!dup->context) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_domain: + dup->domain = isl_union_set_copy(tree->domain); + if (!dup->domain) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_expansion: + dup->contraction = + isl_union_pw_multi_aff_copy(tree->contraction); + dup->expansion = isl_union_map_copy(tree->expansion); + if (!dup->contraction || !dup->expansion) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_extension: + dup->extension = isl_union_map_copy(tree->extension); + if (!dup->extension) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_filter: + dup->filter = isl_union_set_copy(tree->filter); + if (!dup->filter) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_guard: + dup->guard = isl_set_copy(tree->guard); + if (!dup->guard) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_mark: + dup->mark = isl_id_copy(tree->mark); + if (!dup->mark) + return isl_schedule_tree_free(dup); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + if (tree->children) { + dup->children = isl_schedule_tree_list_copy(tree->children); + if (!dup->children) + return isl_schedule_tree_free(dup); + } + dup->anchored = tree->anchored; + + return dup; +} + +/* Return an isl_schedule_tree that is equal to "tree" and that has only + * a single reference. + * + * This function is called before a tree is modified. + * A static tree (with negative reference count) should never be modified, + * so it is not allowed to call this function on a static tree. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_cow( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->ref < 0) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "static trees cannot be modified", + return isl_schedule_tree_free(tree)); + + if (tree->ref == 1) + return tree; + tree->ref--; + return isl_schedule_tree_dup(tree); +} + +/* Return a new reference to "tree". + * + * A static tree (with negative reference count) does not keep track + * of the number of references and should not be modified. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_copy( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->ref < 0) + return tree; + + tree->ref++; + return tree; +} + +/* Free "tree" and return NULL. + */ +__isl_null isl_schedule_tree *isl_schedule_tree_free( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + if (tree->ref < 0) + return NULL; + if (--tree->ref > 0) + return NULL; + + switch (tree->type) { + case isl_schedule_node_band: + isl_schedule_band_free(tree->band); + break; + case isl_schedule_node_context: + isl_set_free(tree->context); + break; + case isl_schedule_node_domain: + isl_union_set_free(tree->domain); + break; + case isl_schedule_node_expansion: + isl_union_pw_multi_aff_free(tree->contraction); + isl_union_map_free(tree->expansion); + break; + case isl_schedule_node_extension: + isl_union_map_free(tree->extension); + break; + case isl_schedule_node_filter: + isl_union_set_free(tree->filter); + break; + case isl_schedule_node_guard: + isl_set_free(tree->guard); + break; + case isl_schedule_node_mark: + isl_id_free(tree->mark); + break; + case isl_schedule_node_sequence: + case isl_schedule_node_set: + case isl_schedule_node_error: + case isl_schedule_node_leaf: + break; + } + isl_schedule_tree_list_free(tree->children); + isl_ctx_deref(tree->ctx); + free(tree); + + return NULL; +} + +/* Create and return a new leaf schedule tree. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx) +{ + return isl_schedule_tree_alloc(ctx, isl_schedule_node_leaf); +} + +/* Create a new band schedule tree referring to "band" + * with no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_band( + __isl_take isl_schedule_band *band) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!band) + return NULL; + + ctx = isl_schedule_band_get_ctx(band); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_band); + if (!tree) + goto error; + + tree->band = band; + tree->anchored = isl_schedule_band_is_anchored(band); + + return tree; +error: + isl_schedule_band_free(band); + return NULL; +} + +/* Create a new context schedule tree with the given context and no children. + * Since the context references the outer schedule dimension, + * the tree is anchored. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_context( + __isl_take isl_set *context) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!context) + return NULL; + + ctx = isl_set_get_ctx(context); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_context); + if (!tree) + goto error; + + tree->context = context; + tree->anchored = 1; + + return tree; +error: + isl_set_free(context); + return NULL; +} + +/* Create a new domain schedule tree with the given domain and no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_domain( + __isl_take isl_union_set *domain) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!domain) + return NULL; + + ctx = isl_union_set_get_ctx(domain); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_domain); + if (!tree) + goto error; + + tree->domain = domain; + + return tree; +error: + isl_union_set_free(domain); + return NULL; +} + +/* Create a new expansion schedule tree with the given contraction and + * expansion and no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_expansion( + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!contraction || !expansion) + goto error; + + ctx = isl_union_map_get_ctx(expansion); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_expansion); + if (!tree) + goto error; + + tree->contraction = contraction; + tree->expansion = expansion; + + return tree; +error: + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Create a new extension schedule tree with the given extension and + * no children. + * Since the domain of the extension refers to the outer schedule dimension, + * the tree is anchored. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_extension( + __isl_take isl_union_map *extension) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!extension) + return NULL; + + ctx = isl_union_map_get_ctx(extension); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_extension); + if (!tree) + goto error; + + tree->extension = extension; + tree->anchored = 1; + + return tree; +error: + isl_union_map_free(extension); + return NULL; +} + +/* Create a new filter schedule tree with the given filter and no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_filter( + __isl_take isl_union_set *filter) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!filter) + return NULL; + + ctx = isl_union_set_get_ctx(filter); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_filter); + if (!tree) + goto error; + + tree->filter = filter; + + return tree; +error: + isl_union_set_free(filter); + return NULL; +} + +/* Create a new guard schedule tree with the given guard and no children. + * Since the guard references the outer schedule dimension, + * the tree is anchored. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_guard( + __isl_take isl_set *guard) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!guard) + return NULL; + + ctx = isl_set_get_ctx(guard); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_guard); + if (!tree) + goto error; + + tree->guard = guard; + tree->anchored = 1; + + return tree; +error: + isl_set_free(guard); + return NULL; +} + +/* Create a new mark schedule tree with the given mark identifier and + * no children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_mark( + __isl_take isl_id *mark) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!mark) + return NULL; + + ctx = isl_id_get_ctx(mark); + tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_mark); + if (!tree) + goto error; + + tree->mark = mark; + + return tree; +error: + isl_id_free(mark); + return NULL; +} + +/* Does "tree" have any node that depends on its position + * in the complete schedule tree? + */ +isl_bool isl_schedule_tree_is_subtree_anchored( + __isl_keep isl_schedule_tree *tree) +{ + return tree ? tree->anchored : isl_bool_error; +} + +/* Does the root node of "tree" depend on its position in the complete + * schedule tree? + * Band nodes may be anchored depending on the associated AST build options. + * Context, extension and guard nodes are always anchored. + */ +int isl_schedule_tree_is_anchored(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + switch (isl_schedule_tree_get_type(tree)) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_band: + return isl_schedule_band_is_anchored(tree->band); + case isl_schedule_node_context: + case isl_schedule_node_extension: + case isl_schedule_node_guard: + return 1; + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_filter: + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return 0; + } + + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "unhandled case", return -1); +} + +/* Update the anchored field of "tree" based on whether the root node + * itself in anchored and the anchored fields of the children. + * + * This function should be called whenever the children of a tree node + * are changed or the anchoredness of the tree root itself changes. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_update_anchored( + __isl_take isl_schedule_tree *tree) +{ + int i, n; + int anchored; + + if (!tree) + return NULL; + + anchored = isl_schedule_tree_is_anchored(tree); + if (anchored < 0) + return isl_schedule_tree_free(tree); + + n = isl_schedule_tree_list_n_schedule_tree(tree->children); + for (i = 0; !anchored && i < n; ++i) { + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree, i); + if (!child) + return isl_schedule_tree_free(tree); + anchored = child->anchored; + isl_schedule_tree_free(child); + } + + if (anchored == tree->anchored) + return tree; + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + tree->anchored = anchored; + return tree; +} + +/* Create a new tree of the given type (isl_schedule_node_sequence or + * isl_schedule_node_set) with the given children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_children( + enum isl_schedule_node_type type, + __isl_take isl_schedule_tree_list *list) +{ + isl_ctx *ctx; + isl_schedule_tree *tree; + + if (!list) + return NULL; + + ctx = isl_schedule_tree_list_get_ctx(list); + tree = isl_schedule_tree_alloc(ctx, type); + if (!tree) + goto error; + + tree->children = list; + tree = isl_schedule_tree_update_anchored(tree); + + return tree; +error: + isl_schedule_tree_list_free(list); + return NULL; +} + +/* Construct a tree with a root node of type "type" and as children + * "tree1" and "tree2". + * If the root of one (or both) of the input trees is itself of type "type", + * then the tree is replaced by its children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_from_pair( + enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + isl_ctx *ctx; + isl_schedule_tree_list *list; + + if (!tree1 || !tree2) + goto error; + + ctx = isl_schedule_tree_get_ctx(tree1); + if (isl_schedule_tree_get_type(tree1) == type) { + list = isl_schedule_tree_list_copy(tree1->children); + isl_schedule_tree_free(tree1); + } else { + list = isl_schedule_tree_list_alloc(ctx, 2); + list = isl_schedule_tree_list_add(list, tree1); + } + if (isl_schedule_tree_get_type(tree2) == type) { + isl_schedule_tree_list *children; + + children = isl_schedule_tree_list_copy(tree2->children); + list = isl_schedule_tree_list_concat(list, children); + isl_schedule_tree_free(tree2); + } else { + list = isl_schedule_tree_list_add(list, tree2); + } + + return isl_schedule_tree_from_children(type, list); +error: + isl_schedule_tree_free(tree1); + isl_schedule_tree_free(tree2); + return NULL; +} + +/* Construct a tree with a sequence root node and as children + * "tree1" and "tree2". + * If the root of one (or both) of the input trees is itself a sequence, + * then the tree is replaced by its children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_pair( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + return isl_schedule_tree_from_pair(isl_schedule_node_sequence, + tree1, tree2); +} + +/* Return the isl_ctx to which "tree" belongs. + */ +isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree) +{ + return tree ? tree->ctx : NULL; +} + +/* Return the type of the root of the tree or isl_schedule_node_error + * on error. + */ +enum isl_schedule_node_type isl_schedule_tree_get_type( + __isl_keep isl_schedule_tree *tree) +{ + return tree ? tree->type : isl_schedule_node_error; +} + +/* Are "tree1" and "tree2" obviously equal to each other? + */ +isl_bool isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1, + __isl_keep isl_schedule_tree *tree2) +{ + isl_bool equal; + int i, n; + + if (!tree1 || !tree2) + return isl_bool_error; + if (tree1 == tree2) + return isl_bool_true; + if (tree1->type != tree2->type) + return isl_bool_false; + + switch (tree1->type) { + case isl_schedule_node_band: + equal = isl_schedule_band_plain_is_equal(tree1->band, + tree2->band); + break; + case isl_schedule_node_context: + equal = isl_set_is_equal(tree1->context, tree2->context); + break; + case isl_schedule_node_domain: + equal = isl_union_set_is_equal(tree1->domain, tree2->domain); + break; + case isl_schedule_node_expansion: + equal = isl_union_map_is_equal(tree1->expansion, + tree2->expansion); + if (equal >= 0 && equal) + equal = isl_union_pw_multi_aff_plain_is_equal( + tree1->contraction, tree2->contraction); + break; + case isl_schedule_node_extension: + equal = isl_union_map_is_equal(tree1->extension, + tree2->extension); + break; + case isl_schedule_node_filter: + equal = isl_union_set_is_equal(tree1->filter, tree2->filter); + break; + case isl_schedule_node_guard: + equal = isl_set_is_equal(tree1->guard, tree2->guard); + break; + case isl_schedule_node_mark: + equal = tree1->mark == tree2->mark; + break; + case isl_schedule_node_leaf: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + equal = isl_bool_true; + break; + case isl_schedule_node_error: + equal = isl_bool_error; + break; + } + + if (equal < 0 || !equal) + return equal; + + n = isl_schedule_tree_n_children(tree1); + if (n != isl_schedule_tree_n_children(tree2)) + return isl_bool_false; + for (i = 0; i < n; ++i) { + isl_schedule_tree *child1, *child2; + + child1 = isl_schedule_tree_get_child(tree1, i); + child2 = isl_schedule_tree_get_child(tree2, i); + equal = isl_schedule_tree_plain_is_equal(child1, child2); + isl_schedule_tree_free(child1); + isl_schedule_tree_free(child2); + + if (equal < 0 || !equal) + return equal; + } + + return isl_bool_true; +} + +/* Does "tree" have any children, other than an implicit leaf. + */ +int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + return tree->children != NULL; +} + +/* Return the number of children of "tree", excluding implicit leaves. + */ +int isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + return isl_schedule_tree_list_n_schedule_tree(tree->children); +} + +/* Return a copy of the (explicit) child at position "pos" of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_get_child( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return NULL; + if (!tree->children) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "schedule tree has no explicit children", return NULL); + return isl_schedule_tree_list_get_schedule_tree(tree->children, pos); +} + +/* Return a copy of the (explicit) child at position "pos" of "tree" and + * free "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_child( + __isl_take isl_schedule_tree *tree, int pos) +{ + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree, pos); + isl_schedule_tree_free(tree); + return child; +} + +/* Remove all (explicit) children from "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_reset_children( + __isl_take isl_schedule_tree *tree) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + tree->children = isl_schedule_tree_list_free(tree->children); + return tree; +} + +/* Remove the child at position "pos" from the children of "tree". + * If there was only one child to begin with, then remove all children. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_drop_child( + __isl_take isl_schedule_tree *tree, int pos) +{ + int n; + + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + if (!isl_schedule_tree_has_children(tree)) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "tree does not have any explicit children", + return isl_schedule_tree_free(tree)); + n = isl_schedule_tree_list_n_schedule_tree(tree->children); + if (pos < 0 || pos >= n) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "position out of bounds", + return isl_schedule_tree_free(tree)); + if (n == 1) + return isl_schedule_tree_reset_children(tree); + + tree->children = isl_schedule_tree_list_drop(tree->children, pos, 1); + if (!tree->children) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Replace the child at position "pos" of "tree" by "child". + * + * If the new child is a leaf, then it is not explicitly + * recorded in the list of children. Instead, the list of children + * (which is assumed to have only one element) is removed. + * Note that the children of set and sequence nodes are always + * filters, so they cannot be replaced by empty trees. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_replace_child( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *child) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !child) + goto error; + + if (isl_schedule_tree_is_leaf(child)) { + isl_schedule_tree_free(child); + if (!tree->children && pos == 0) + return tree; + if (isl_schedule_tree_n_children(tree) != 1) + isl_die(isl_schedule_tree_get_ctx(tree), + isl_error_internal, + "can only replace single child by leaf", + goto error); + return isl_schedule_tree_reset_children(tree); + } + + if (!tree->children && pos == 0) + tree->children = + isl_schedule_tree_list_from_schedule_tree(child); + else + tree->children = isl_schedule_tree_list_set_schedule_tree( + tree->children, pos, child); + + if (!tree->children) + return isl_schedule_tree_free(tree); + tree = isl_schedule_tree_update_anchored(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_schedule_tree_free(child); + return NULL; +} + +/* Replace the (explicit) children of "tree" by "children"? + */ +__isl_give isl_schedule_tree *isl_schedule_tree_set_children( + __isl_take isl_schedule_tree *tree, + __isl_take isl_schedule_tree_list *children) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !children) + goto error; + isl_schedule_tree_list_free(tree->children); + tree->children = children; + return tree; +error: + isl_schedule_tree_free(tree); + isl_schedule_tree_list_free(children); + return NULL; +} + +/* Create a new band schedule tree referring to "band" + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_band( + __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_band(band); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new context schedule tree with the given context and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_context( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *context) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_context(context); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new domain schedule tree with the given domain and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_domain(domain); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new expansion schedule tree with the given contraction and + * expansion and with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_expansion(contraction, expansion); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new extension schedule tree with the given extension and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_extension( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_extension(extension); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new filter schedule tree with the given filter and single child. + * + * If the root of "tree" is itself a filter node, then the two + * filter nodes are merged into one node. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) +{ + isl_schedule_tree *res; + + if (isl_schedule_tree_get_type(tree) == isl_schedule_node_filter) { + isl_union_set *tree_filter; + + tree_filter = isl_schedule_tree_filter_get_filter(tree); + tree_filter = isl_union_set_intersect(tree_filter, filter); + tree = isl_schedule_tree_filter_set_filter(tree, tree_filter); + return tree; + } + + res = isl_schedule_tree_from_filter(filter); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Insert a filter node with filter set "filter" + * in each of the children of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) +{ + int i, n; + + if (!tree || !filter) + goto error; + + n = isl_schedule_tree_n_children(tree); + for (i = 0; i < n; ++i) { + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree, i); + child = isl_schedule_tree_insert_filter(child, + isl_union_set_copy(filter)); + tree = isl_schedule_tree_replace_child(tree, i, child); + } + + isl_union_set_free(filter); + return tree; +error: + isl_union_set_free(filter); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Create a new guard schedule tree with the given guard and + * with "tree" as single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_guard( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *guard) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_guard(guard); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Create a new mark schedule tree with the given mark identifier and + * single child. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_insert_mark( + __isl_take isl_schedule_tree *tree, __isl_take isl_id *mark) +{ + isl_schedule_tree *res; + + res = isl_schedule_tree_from_mark(mark); + return isl_schedule_tree_replace_child(res, 0, tree); +} + +/* Return the number of members in the band tree root. + */ +unsigned isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return 0; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return 0); + + return isl_schedule_band_n_member(tree->band); +} + +/* Is the band member at position "pos" of the band tree root + * marked coincident? + */ +isl_bool isl_schedule_tree_band_member_get_coincident( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return isl_bool_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_bool_error); + + return isl_schedule_band_member_get_coincident(tree->band, pos); +} + +/* Mark the given band member as being coincident or not + * according to "coincident". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident( + __isl_take isl_schedule_tree *tree, int pos, int coincident) +{ + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + if (isl_schedule_tree_band_member_get_coincident(tree, pos) == + coincident) + return tree; + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + tree->band = isl_schedule_band_member_set_coincident(tree->band, pos, + coincident); + if (!tree->band) + return isl_schedule_tree_free(tree); + return tree; +} + +/* Is the band tree root marked permutable? + */ +isl_bool isl_schedule_tree_band_get_permutable( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return isl_bool_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_bool_error); + + return isl_schedule_band_get_permutable(tree->band); +} + +/* Mark the band tree root permutable or not according to "permutable"? + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable( + __isl_take isl_schedule_tree *tree, int permutable) +{ + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + if (isl_schedule_tree_band_get_permutable(tree) == permutable) + return tree; + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + tree->band = isl_schedule_band_set_permutable(tree->band, permutable); + if (!tree->band) + return isl_schedule_tree_free(tree); + return tree; +} + +/* Return the schedule space of the band tree root. + */ +__isl_give isl_space *isl_schedule_tree_band_get_space( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_space(tree->band); +} + +/* Intersect the domain of the band schedule of the band tree root + * with "domain". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_intersect_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) +{ + if (!tree || !domain) + goto error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree->band = isl_schedule_band_intersect_domain(tree->band, domain); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(domain); + return NULL; +} + +/* Return the schedule of the band tree root in isolation. + */ +__isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_partial_schedule(tree->band); +} + +/* Replace the schedule of the band tree root by "schedule". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_partial_schedule( + __isl_take isl_schedule_tree *tree, + __isl_take isl_multi_union_pw_aff *schedule) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !schedule) + goto error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + tree->band = isl_schedule_band_set_partial_schedule(tree->band, + schedule); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_union_pw_aff_free(schedule); + return NULL; +} + +/* Return the loop AST generation type for the band member + * of the band tree root at position "pos". + */ +enum isl_ast_loop_type isl_schedule_tree_band_member_get_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return isl_ast_loop_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_ast_loop_error); + + return isl_schedule_band_member_get_ast_loop_type(tree->band, pos); +} + +/* Set the loop AST generation type for the band member of the band tree root + * at position "pos" to "type". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + + tree->band = isl_schedule_band_member_set_ast_loop_type(tree->band, + pos, type); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Return the loop AST generation type for the band member + * of the band tree root at position "pos" for the isolated part. + */ +enum isl_ast_loop_type isl_schedule_tree_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos) +{ + if (!tree) + return isl_ast_loop_error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_ast_loop_error); + + return isl_schedule_band_member_get_isolate_ast_loop_type(tree->band, + pos); +} + +/* Set the loop AST generation type for the band member of the band tree root + * at position "pos" for the isolated part to "type". + */ +__isl_give isl_schedule_tree * +isl_schedule_tree_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + + tree->band = isl_schedule_band_member_set_isolate_ast_loop_type( + tree->band, pos, type); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +} + +/* Return the AST build options associated to the band tree root. + */ +__isl_give isl_union_set *isl_schedule_tree_band_get_ast_build_options( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return NULL); + + return isl_schedule_band_get_ast_build_options(tree->band); +} + +/* Replace the AST build options associated to band tree root by "options". + * Updated the anchored field if the anchoredness of the root node itself + * changes. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_ast_build_options( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *options) +{ + int was_anchored; + + tree = isl_schedule_tree_cow(tree); + if (!tree || !options) + goto error; + + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + was_anchored = isl_schedule_tree_is_anchored(tree); + tree->band = isl_schedule_band_set_ast_build_options(tree->band, + options); + if (!tree->band) + return isl_schedule_tree_free(tree); + if (isl_schedule_tree_is_anchored(tree) != was_anchored) + tree = isl_schedule_tree_update_anchored(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(options); + return NULL; +} + +/* Return the context of the context tree root. + */ +__isl_give isl_set *isl_schedule_tree_context_get_context( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_context) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a context node", return NULL); + + return isl_set_copy(tree->context); +} + +/* Return the domain of the domain tree root. + */ +__isl_give isl_union_set *isl_schedule_tree_domain_get_domain( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_domain) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a domain node", return NULL); + + return isl_union_set_copy(tree->domain); +} + +/* Replace the domain of domain tree root "tree" by "domain". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !domain) + goto error; + + if (tree->type != isl_schedule_node_domain) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a domain node", goto error); + + isl_union_set_free(tree->domain); + tree->domain = domain; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(domain); + return NULL; +} + +/* Return the contraction of the expansion tree root. + */ +__isl_give isl_union_pw_multi_aff *isl_schedule_tree_expansion_get_contraction( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_expansion) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an expansion node", return NULL); + + return isl_union_pw_multi_aff_copy(tree->contraction); +} + +/* Return the expansion of the expansion tree root. + */ +__isl_give isl_union_map *isl_schedule_tree_expansion_get_expansion( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_expansion) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an expansion node", return NULL); + + return isl_union_map_copy(tree->expansion); +} + +/* Replace the contraction and the expansion of the expansion tree root "tree" + * by "contraction" and "expansion". + */ +__isl_give isl_schedule_tree * +isl_schedule_tree_expansion_set_contraction_and_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !contraction || !expansion) + goto error; + + if (tree->type != isl_schedule_node_expansion) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an expansion node", return NULL); + + isl_union_pw_multi_aff_free(tree->contraction); + tree->contraction = contraction; + isl_union_map_free(tree->expansion); + tree->expansion = expansion; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_pw_multi_aff_free(contraction); + isl_union_map_free(expansion); + return NULL; +} + +/* Return the extension of the extension tree root. + */ +__isl_give isl_union_map *isl_schedule_tree_extension_get_extension( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_extension) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an extension node", return NULL); + + return isl_union_map_copy(tree->extension); +} + +/* Replace the extension of extension tree root "tree" by "extension". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_extension_set_extension( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !extension) + goto error; + + if (tree->type != isl_schedule_node_extension) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not an extension node", return NULL); + isl_union_map_free(tree->extension); + tree->extension = extension; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_map_free(extension); + return NULL; +} + +/* Return the filter of the filter tree root. + */ +__isl_give isl_union_set *isl_schedule_tree_filter_get_filter( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_filter) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a filter node", return NULL); + + return isl_union_set_copy(tree->filter); +} + +/* Replace the filter of the filter tree root by "filter". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) +{ + tree = isl_schedule_tree_cow(tree); + if (!tree || !filter) + goto error; + + if (tree->type != isl_schedule_node_filter) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a filter node", return NULL); + + isl_union_set_free(tree->filter); + tree->filter = filter; + + return tree; +error: + isl_schedule_tree_free(tree); + isl_union_set_free(filter); + return NULL; +} + +/* Return the guard of the guard tree root. + */ +__isl_give isl_set *isl_schedule_tree_guard_get_guard( + __isl_take isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_guard) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a guard node", return NULL); + + return isl_set_copy(tree->guard); +} + +/* Return the mark identifier of the mark tree root "tree". + */ +__isl_give isl_id *isl_schedule_tree_mark_get_id( + __isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return NULL; + + if (tree->type != isl_schedule_node_mark) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a mark node", return NULL); + + return isl_id_copy(tree->mark); +} + +/* Set dim to the range dimension of "map" and abort the search. + */ +static isl_stat set_range_dim(__isl_take isl_map *map, void *user) +{ + int *dim = user; + + *dim = isl_map_dim(map, isl_dim_out); + isl_map_free(map); + + return isl_stat_error; +} + +/* Return the dimension of the range of "umap". + * "umap" is assumed not to be empty and + * all maps inside "umap" are assumed to have the same range. + * + * We extract the range dimension from the first map in "umap". + */ +static int range_dim(__isl_keep isl_union_map *umap) +{ + int dim = -1; + + if (!umap) + return -1; + if (isl_union_map_n_map(umap) == 0) + isl_die(isl_union_map_get_ctx(umap), isl_error_internal, + "unexpected empty input", return -1); + + isl_union_map_foreach_map(umap, &set_range_dim, &dim); + + return dim; +} + +/* Append an "extra" number of zeros to the range of "umap" and + * return the result. + */ +static __isl_give isl_union_map *append_range(__isl_take isl_union_map *umap, + int extra) +{ + isl_union_set *dom; + isl_space *space; + isl_multi_val *mv; + isl_union_pw_multi_aff *suffix; + isl_union_map *universe; + isl_union_map *suffix_umap; + + universe = isl_union_map_universe(isl_union_map_copy(umap)); + dom = isl_union_map_domain(universe); + space = isl_union_set_get_space(dom); + space = isl_space_set_from_params(space); + space = isl_space_add_dims(space, isl_dim_set, extra); + mv = isl_multi_val_zero(space); + + suffix = isl_union_pw_multi_aff_multi_val_on_domain(dom, mv); + suffix_umap = isl_union_map_from_union_pw_multi_aff(suffix); + umap = isl_union_map_flat_range_product(umap, suffix_umap); + + return umap; +} + +/* Should we skip the root of "tree" while looking for the first + * descendant with schedule information? + * That is, is it impossible to derive any information about + * the iteration domain from this node? + * + * We do not want to skip leaf or error nodes because there is + * no point in looking any deeper from these nodes. + * We can only extract partial iteration domain information + * from an extension node, but extension nodes are not supported + * by the caller and it will error out on them. + */ +static int domain_less(__isl_keep isl_schedule_tree *tree) +{ + enum isl_schedule_node_type type; + + type = isl_schedule_tree_get_type(tree); + switch (type) { + case isl_schedule_node_band: + return isl_schedule_tree_band_n_member(tree) == 0; + case isl_schedule_node_context: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + return 1; + case isl_schedule_node_leaf: + case isl_schedule_node_error: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_filter: + case isl_schedule_node_set: + case isl_schedule_node_sequence: + return 0; + } + + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "unhandled case", return 0); +} + +/* Move down to the first descendant of "tree" that contains any schedule + * information or return "leaf" if there is no such descendant. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf) +{ + while (domain_less(tree)) { + if (!isl_schedule_tree_has_children(tree)) { + isl_schedule_tree_free(tree); + return isl_schedule_tree_copy(leaf); + } + tree = isl_schedule_tree_child(tree, 0); + } + + return tree; +} + +static __isl_give isl_union_map *subtree_schedule_extend( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer); + +/* Extend the schedule map "outer" with the subtree schedule + * of the (single) child of "tree", if any. + * + * If "tree" does not have any descendants (apart from those that + * do not carry any schedule information), then we simply return "outer". + * Otherwise, we extend the schedule map "outer" with the subtree schedule + * of the single child. + */ +static __isl_give isl_union_map *subtree_schedule_extend_child( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) +{ + isl_schedule_tree *child; + isl_union_map *res; + + if (!tree) + return isl_union_map_free(outer); + if (!isl_schedule_tree_has_children(tree)) + return outer; + child = isl_schedule_tree_get_child(tree, 0); + if (!child) + return isl_union_map_free(outer); + res = subtree_schedule_extend(child, outer); + isl_schedule_tree_free(child); + return res; +} + +/* Extract the parameter space from one of the children of "tree", + * which are assumed to be filters. + */ +static __isl_give isl_space *extract_space_from_filter_child( + __isl_keep isl_schedule_tree *tree) +{ + isl_space *space; + isl_union_set *dom; + isl_schedule_tree *child; + + child = isl_schedule_tree_list_get_schedule_tree(tree->children, 0); + dom = isl_schedule_tree_filter_get_filter(child); + space = isl_union_set_get_space(dom); + isl_union_set_free(dom); + isl_schedule_tree_free(child); + + return space; +} + +/* Extend the schedule map "outer" with the subtree schedule + * of a set or sequence node. + * + * The schedule for the set or sequence node itself is composed of + * pieces of the form + * + * filter -> [] + * + * or + * + * filter -> [index] + * + * The first form is used if there is only a single child or + * if the current node is a set node and the schedule_separate_components + * option is not set. + * + * Each of the pieces above is extended with the subtree schedule of + * the child of the corresponding filter, if any, padded with zeros + * to ensure that all pieces have the same range dimension. + */ +static __isl_give isl_union_map *subtree_schedule_extend_from_children( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) +{ + int i, n; + int dim; + int separate; + isl_ctx *ctx; + isl_val *v = NULL; + isl_multi_val *mv; + isl_space *space; + isl_union_map *umap; + + if (!tree) + return NULL; + + ctx = isl_schedule_tree_get_ctx(tree); + if (!tree->children) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "missing children", return NULL); + n = isl_schedule_tree_list_n_schedule_tree(tree->children); + if (n == 0) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "missing children", return NULL); + + separate = n > 1 && (tree->type == isl_schedule_node_sequence || + isl_options_get_schedule_separate_components(ctx)); + + space = extract_space_from_filter_child(tree); + + umap = isl_union_map_empty(isl_space_copy(space)); + space = isl_space_set_from_params(space); + if (separate) { + space = isl_space_add_dims(space, isl_dim_set, 1); + v = isl_val_zero(ctx); + } + mv = isl_multi_val_zero(space); + + dim = isl_multi_val_dim(mv, isl_dim_set); + for (i = 0; i < n; ++i) { + isl_union_pw_multi_aff *upma; + isl_union_map *umap_i; + isl_union_set *dom; + isl_schedule_tree *child; + int dim_i; + int empty; + + child = isl_schedule_tree_list_get_schedule_tree( + tree->children, i); + dom = isl_schedule_tree_filter_get_filter(child); + + if (separate) { + mv = isl_multi_val_set_val(mv, 0, isl_val_copy(v)); + v = isl_val_add_ui(v, 1); + } + upma = isl_union_pw_multi_aff_multi_val_on_domain(dom, + isl_multi_val_copy(mv)); + umap_i = isl_union_map_from_union_pw_multi_aff(upma); + umap_i = isl_union_map_flat_range_product( + isl_union_map_copy(outer), umap_i); + umap_i = subtree_schedule_extend_child(child, umap_i); + isl_schedule_tree_free(child); + + empty = isl_union_map_is_empty(umap_i); + if (empty < 0) + umap_i = isl_union_map_free(umap_i); + else if (empty) { + isl_union_map_free(umap_i); + continue; + } + + dim_i = range_dim(umap_i); + if (dim_i < 0) { + umap = isl_union_map_free(umap); + } else if (dim < dim_i) { + umap = append_range(umap, dim_i - dim); + dim = dim_i; + } else if (dim_i < dim) { + umap_i = append_range(umap_i, dim - dim_i); + } + umap = isl_union_map_union(umap, umap_i); + } + + isl_val_free(v); + isl_multi_val_free(mv); + isl_union_map_free(outer); + + return umap; +} + +/* Extend the schedule map "outer" with the subtree schedule of "tree". + * + * If the root of the tree is a set or a sequence, then we extend + * the schedule map in subtree_schedule_extend_from_children. + * Otherwise, we extend the schedule map with the partial schedule + * corresponding to the root of the tree and then continue with + * the single child of this root. + * In the special case of an expansion, the schedule map is "extended" + * by applying the expansion to the domain of the schedule map. + */ +static __isl_give isl_union_map *subtree_schedule_extend( + __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) +{ + isl_multi_union_pw_aff *mupa; + isl_union_map *umap; + isl_union_set *domain; + + if (!tree) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + return isl_union_map_free(outer); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot construct subtree schedule of tree " + "with extension nodes", + return isl_union_map_free(outer)); + case isl_schedule_node_context: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + return subtree_schedule_extend_child(tree, outer); + case isl_schedule_node_band: + if (isl_schedule_tree_band_n_member(tree) == 0) + return subtree_schedule_extend_child(tree, outer); + mupa = isl_schedule_band_get_partial_schedule(tree->band); + umap = isl_union_map_from_multi_union_pw_aff(mupa); + outer = isl_union_map_flat_range_product(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_domain: + domain = isl_schedule_tree_domain_get_domain(tree); + umap = isl_union_map_from_domain(domain); + outer = isl_union_map_flat_range_product(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_expansion: + umap = isl_schedule_tree_expansion_get_expansion(tree); + outer = isl_union_map_apply_domain(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_filter: + domain = isl_schedule_tree_filter_get_filter(tree); + umap = isl_union_map_from_domain(domain); + outer = isl_union_map_flat_range_product(outer, umap); + umap = subtree_schedule_extend_child(tree, outer); + break; + case isl_schedule_node_leaf: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "leaf node should be handled by caller", return NULL); + case isl_schedule_node_set: + case isl_schedule_node_sequence: + umap = subtree_schedule_extend_from_children(tree, outer); + break; + } + + return umap; +} + +static __isl_give isl_union_set *initial_domain( + __isl_keep isl_schedule_tree *tree); + +/* Extract a universe domain from the children of the tree root "tree", + * which is a set or sequence, meaning that its children are filters. + * In particular, return the union of the universes of the filters. + */ +static __isl_give isl_union_set *initial_domain_from_children( + __isl_keep isl_schedule_tree *tree) +{ + int i, n; + isl_space *space; + isl_union_set *domain; + + if (!tree->children) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "missing children", return NULL); + n = isl_schedule_tree_list_n_schedule_tree(tree->children); + if (n == 0) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "missing children", return NULL); + + space = extract_space_from_filter_child(tree); + domain = isl_union_set_empty(space); + + for (i = 0; i < n; ++i) { + isl_schedule_tree *child; + isl_union_set *domain_i; + + child = isl_schedule_tree_get_child(tree, i); + domain_i = initial_domain(child); + domain = isl_union_set_union(domain, domain_i); + isl_schedule_tree_free(child); + } + + return domain; +} + +/* Extract a universe domain from the tree root "tree". + * The caller is responsible for making sure that this node + * would not be skipped by isl_schedule_tree_first_schedule_descendant + * and that it is not a leaf node. + */ +static __isl_give isl_union_set *initial_domain( + __isl_keep isl_schedule_tree *tree) +{ + isl_multi_union_pw_aff *mupa; + isl_union_set *domain; + isl_union_map *exp; + + if (!tree) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + return NULL; + case isl_schedule_node_context: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "context node should be handled by caller", + return NULL); + case isl_schedule_node_guard: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "guard node should be handled by caller", + return NULL); + case isl_schedule_node_mark: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "mark node should be handled by caller", + return NULL); + case isl_schedule_node_extension: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "cannot construct subtree schedule of tree " + "with extension nodes", return NULL); + case isl_schedule_node_band: + if (isl_schedule_tree_band_n_member(tree) == 0) + isl_die(isl_schedule_tree_get_ctx(tree), + isl_error_internal, + "0D band should be handled by caller", + return NULL); + mupa = isl_schedule_band_get_partial_schedule(tree->band); + domain = isl_multi_union_pw_aff_domain(mupa); + domain = isl_union_set_universe(domain); + break; + case isl_schedule_node_domain: + domain = isl_schedule_tree_domain_get_domain(tree); + domain = isl_union_set_universe(domain); + break; + case isl_schedule_node_expansion: + exp = isl_schedule_tree_expansion_get_expansion(tree); + exp = isl_union_map_universe(exp); + domain = isl_union_map_domain(exp); + break; + case isl_schedule_node_filter: + domain = isl_schedule_tree_filter_get_filter(tree); + domain = isl_union_set_universe(domain); + break; + case isl_schedule_node_leaf: + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "leaf node should be handled by caller", return NULL); + case isl_schedule_node_set: + case isl_schedule_node_sequence: + domain = initial_domain_from_children(tree); + break; + } + + return domain; +} + +/* Return the subtree schedule of a node that contains some schedule + * information, i.e., a node that would not be skipped by + * isl_schedule_tree_first_schedule_descendant and that is not a leaf. + * + * If the tree contains any expansions, then the returned subtree + * schedule is formulated in terms of the expanded domains. + * The tree is not allowed to contain any extension nodes. + * + * We start with an initial zero-dimensional subtree schedule based + * on the domain information in the root node and then extend it + * based on the schedule information in the root node and its descendants. + */ +__isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map( + __isl_keep isl_schedule_tree *tree) +{ + isl_union_set *domain; + isl_union_map *umap; + + domain = initial_domain(tree); + umap = isl_union_map_from_domain(domain); + return subtree_schedule_extend(tree, umap); +} + +/* Multiply the partial schedule of the band root node of "tree" + * with the factors in "mv". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) +{ + if (!tree || !mv) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_scale(tree->band, mv); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_val_free(mv); + return NULL; +} + +/* Divide the partial schedule of the band root node of "tree" + * by the factors in "mv". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) +{ + if (!tree || !mv) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_scale_down(tree->band, mv); + if (!tree->band) + return isl_schedule_tree_free(tree); + + return tree; +error: + isl_schedule_tree_free(tree); + isl_multi_val_free(mv); + return NULL; +} + +/* Given two trees with sequence roots, replace the child at position + * "pos" of "tree" with the children of "child". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *child) +{ + int n; + isl_schedule_tree_list *list1, *list2; + + tree = isl_schedule_tree_cow(tree); + if (!tree || !child) + goto error; + if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a sequence node", goto error); + n = isl_schedule_tree_n_children(tree); + if (pos < 0 || pos >= n) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "position out of bounds", goto error); + if (isl_schedule_tree_get_type(child) != isl_schedule_node_sequence) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a sequence node", goto error); + + list1 = isl_schedule_tree_list_copy(tree->children); + list1 = isl_schedule_tree_list_drop(list1, pos, n - pos); + list2 = isl_schedule_tree_list_copy(tree->children); + list2 = isl_schedule_tree_list_drop(list2, 0, pos + 1); + list1 = isl_schedule_tree_list_concat(list1, + isl_schedule_tree_list_copy(child->children)); + list1 = isl_schedule_tree_list_concat(list1, list2); + + isl_schedule_tree_free(tree); + isl_schedule_tree_free(child); + return isl_schedule_tree_from_children(isl_schedule_node_sequence, + list1); +error: + isl_schedule_tree_free(tree); + isl_schedule_tree_free(child); + return NULL; +} + +/* Tile the band root node of "tree" with tile sizes "sizes". + * + * We duplicate the band node, change the schedule of one of them + * to the tile schedule and the other to the point schedule and then + * attach the point band as a child to the tile band. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_tile( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes) +{ + isl_schedule_tree *child = NULL; + + if (!tree || !sizes) + goto error; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + + child = isl_schedule_tree_copy(tree); + tree = isl_schedule_tree_cow(tree); + child = isl_schedule_tree_cow(child); + if (!tree || !child) + goto error; + + tree->band = isl_schedule_band_tile(tree->band, + isl_multi_val_copy(sizes)); + if (!tree->band) + goto error; + child->band = isl_schedule_band_point(child->band, tree->band, sizes); + if (!child->band) + child = isl_schedule_tree_free(child); + + tree = isl_schedule_tree_replace_child(tree, 0, child); + + return tree; +error: + isl_schedule_tree_free(child); + isl_schedule_tree_free(tree); + isl_multi_val_free(sizes); + return NULL; +} + +/* Split the band root node of "tree" into two nested band nodes, + * one with the first "pos" dimensions and + * one with the remaining dimensions. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_split( + __isl_take isl_schedule_tree *tree, int pos) +{ + int n; + isl_schedule_tree *child; + + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", return isl_schedule_tree_free(tree)); + + n = isl_schedule_tree_band_n_member(tree); + if (pos < 0 || pos > n) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "position out of bounds", + return isl_schedule_tree_free(tree)); + + child = isl_schedule_tree_copy(tree); + tree = isl_schedule_tree_cow(tree); + child = isl_schedule_tree_cow(child); + if (!tree || !child) + goto error; + + child->band = isl_schedule_band_drop(child->band, 0, pos); + tree->band = isl_schedule_band_drop(tree->band, pos, n - pos); + if (!child->band || !tree->band) + goto error; + + tree = isl_schedule_tree_replace_child(tree, 0, child); + + return tree; +error: + isl_schedule_tree_free(child); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Attach "tree2" at each of the leaves of "tree1". + * + * If "tree1" does not have any explicit children, then make "tree2" + * its single child. Otherwise, attach "tree2" to the leaves of + * each of the children of "tree1". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2) +{ + int i, n; + + if (!tree1 || !tree2) + goto error; + n = isl_schedule_tree_n_children(tree1); + if (n == 0) { + isl_schedule_tree_list *list; + list = isl_schedule_tree_list_from_schedule_tree(tree2); + tree1 = isl_schedule_tree_set_children(tree1, list); + return tree1; + } + for (i = 0; i < n; ++i) { + isl_schedule_tree *child; + + child = isl_schedule_tree_get_child(tree1, i); + child = isl_schedule_tree_append_to_leaves(child, + isl_schedule_tree_copy(tree2)); + tree1 = isl_schedule_tree_replace_child(tree1, i, child); + } + + isl_schedule_tree_free(tree2); + return tree1; +error: + isl_schedule_tree_free(tree1); + isl_schedule_tree_free(tree2); + return NULL; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * in the root of "tree". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_reset_user( + __isl_take isl_schedule_tree *tree) +{ + if (isl_schedule_tree_is_leaf(tree)) + return tree; + + tree = isl_schedule_tree_cow(tree); + if (!tree) + return NULL; + + switch (tree->type) { + case isl_schedule_node_error: + return isl_schedule_tree_free(tree); + case isl_schedule_node_band: + tree->band = isl_schedule_band_reset_user(tree->band); + if (!tree->band) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_context: + tree->context = isl_set_reset_user(tree->context); + if (!tree->context) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_domain: + tree->domain = isl_union_set_reset_user(tree->domain); + if (!tree->domain) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_expansion: + tree->contraction = + isl_union_pw_multi_aff_reset_user(tree->contraction); + tree->expansion = isl_union_map_reset_user(tree->expansion); + if (!tree->contraction || !tree->expansion) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_extension: + tree->extension = isl_union_map_reset_user(tree->extension); + if (!tree->extension) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_filter: + tree->filter = isl_union_set_reset_user(tree->filter); + if (!tree->filter) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_guard: + tree->guard = isl_set_reset_user(tree->guard); + if (!tree->guard) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + break; + } + + return tree; +} + +/* Align the parameters of the root of "tree" to those of "space". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_align_params( + __isl_take isl_schedule_tree *tree, __isl_take isl_space *space) +{ + if (!space) + goto error; + + if (isl_schedule_tree_is_leaf(tree)) { + isl_space_free(space); + return tree; + } + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + switch (tree->type) { + case isl_schedule_node_error: + goto error; + case isl_schedule_node_band: + tree->band = isl_schedule_band_align_params(tree->band, space); + if (!tree->band) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_context: + tree->context = isl_set_align_params(tree->context, space); + if (!tree->context) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_domain: + tree->domain = isl_union_set_align_params(tree->domain, space); + if (!tree->domain) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_expansion: + tree->contraction = + isl_union_pw_multi_aff_align_params(tree->contraction, + isl_space_copy(space)); + tree->expansion = isl_union_map_align_params(tree->expansion, + space); + if (!tree->contraction || !tree->expansion) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_extension: + tree->extension = isl_union_map_align_params(tree->extension, + space); + if (!tree->extension) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_filter: + tree->filter = isl_union_set_align_params(tree->filter, space); + if (!tree->filter) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_guard: + tree->guard = isl_set_align_params(tree->guard, space); + if (!tree->guard) + return isl_schedule_tree_free(tree); + break; + case isl_schedule_node_leaf: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + isl_space_free(space); + break; + } + + return tree; +error: + isl_space_free(space); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Does "tree" involve the iteration domain? + * That is, does it need to be modified + * by isl_schedule_tree_pullback_union_pw_multi_aff? + */ +static int involves_iteration_domain(__isl_keep isl_schedule_tree *tree) +{ + if (!tree) + return -1; + + switch (tree->type) { + case isl_schedule_node_error: + return -1; + case isl_schedule_node_band: + case isl_schedule_node_domain: + case isl_schedule_node_expansion: + case isl_schedule_node_extension: + case isl_schedule_node_filter: + return 1; + case isl_schedule_node_context: + case isl_schedule_node_leaf: + case isl_schedule_node_guard: + case isl_schedule_node_mark: + case isl_schedule_node_sequence: + case isl_schedule_node_set: + return 0; + } + + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal, + "unhandled case", return -1); +} + +/* Compute the pullback of the root node of "tree" by the function + * represented by "upma". + * In other words, plug in "upma" in the iteration domains of + * the root node of "tree". + * We currently do not handle expansion nodes. + * + * We first check if the root node involves any iteration domains. + * If so, we handle the specific cases. + */ +__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *upma) +{ + int involves; + + if (!tree || !upma) + goto error; + + involves = involves_iteration_domain(tree); + if (involves < 0) + goto error; + if (!involves) { + isl_union_pw_multi_aff_free(upma); + return tree; + } + + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + if (tree->type == isl_schedule_node_band) { + tree->band = isl_schedule_band_pullback_union_pw_multi_aff( + tree->band, upma); + if (!tree->band) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_domain) { + tree->domain = + isl_union_set_preimage_union_pw_multi_aff(tree->domain, + upma); + if (!tree->domain) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_expansion) { + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported, + "cannot pullback expansion node", goto error); + } else if (tree->type == isl_schedule_node_extension) { + tree->extension = + isl_union_map_preimage_range_union_pw_multi_aff( + tree->extension, upma); + if (!tree->extension) + return isl_schedule_tree_free(tree); + } else if (tree->type == isl_schedule_node_filter) { + tree->filter = + isl_union_set_preimage_union_pw_multi_aff(tree->filter, + upma); + if (!tree->filter) + return isl_schedule_tree_free(tree); + } + + return tree; +error: + isl_union_pw_multi_aff_free(upma); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Compute the gist of the band tree root with respect to "context". + */ +__isl_give isl_schedule_tree *isl_schedule_tree_band_gist( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context) +{ + if (!tree) + return NULL; + if (tree->type != isl_schedule_node_band) + isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid, + "not a band node", goto error); + tree = isl_schedule_tree_cow(tree); + if (!tree) + goto error; + + tree->band = isl_schedule_band_gist(tree->band, context); + if (!tree->band) + return isl_schedule_tree_free(tree); + return tree; +error: + isl_union_set_free(context); + isl_schedule_tree_free(tree); + return NULL; +} + +/* Are any members in "band" marked coincident? + */ +static int any_coincident(__isl_keep isl_schedule_band *band) +{ + int i, n; + + n = isl_schedule_band_n_member(band); + for (i = 0; i < n; ++i) + if (isl_schedule_band_member_get_coincident(band, i)) + return 1; + + return 0; +} + +/* Print the band node "band" to "p". + * + * The permutable and coincident properties are only printed if they + * are different from the defaults. + * The coincident property is always printed in YAML flow style. + */ +static __isl_give isl_printer *print_tree_band(__isl_take isl_printer *p, + __isl_keep isl_schedule_band *band) +{ + isl_union_set *options; + int empty; + + p = isl_printer_print_str(p, "schedule"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_multi_union_pw_aff(p, band->mupa); + p = isl_printer_print_str(p, "\""); + if (isl_schedule_band_get_permutable(band)) { + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "permutable"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_int(p, 1); + } + if (any_coincident(band)) { + int i, n; + int style; + + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "coincident"); + p = isl_printer_yaml_next(p); + style = isl_printer_get_yaml_style(p); + p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW); + p = isl_printer_yaml_start_sequence(p); + n = isl_schedule_band_n_member(band); + for (i = 0; i < n; ++i) { + p = isl_printer_print_int(p, + isl_schedule_band_member_get_coincident(band, i)); + p = isl_printer_yaml_next(p); + } + p = isl_printer_yaml_end_sequence(p); + p = isl_printer_set_yaml_style(p, style); + } + options = isl_schedule_band_get_ast_build_options(band); + empty = isl_union_set_is_empty(options); + if (empty < 0) + p = isl_printer_free(p); + if (!empty) { + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "options"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_set(p, options); + p = isl_printer_print_str(p, "\""); + } + isl_union_set_free(options); + + return p; +} + +/* Print "tree" to "p". + * + * If "n_ancestor" is non-negative, then "child_pos" contains the child + * positions of a descendant of the current node that should be marked + * (by the comment "YOU ARE HERE"). In particular, if "n_ancestor" + * is zero, then the current node should be marked. + * The marking is only printed in YAML block format. + * + * Implicit leaf nodes are not printed, except if they correspond + * to the node that should be marked. + */ +__isl_give isl_printer *isl_printer_print_schedule_tree_mark( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree, + int n_ancestor, int *child_pos) +{ + int i, n; + int sequence = 0; + int block; + + block = isl_printer_get_yaml_style(p) == ISL_YAML_STYLE_BLOCK; + + p = isl_printer_yaml_start_mapping(p); + if (n_ancestor == 0 && block) { + p = isl_printer_print_str(p, "# YOU ARE HERE"); + p = isl_printer_end_line(p); + p = isl_printer_start_line(p); + } + switch (tree->type) { + case isl_schedule_node_error: + p = isl_printer_print_str(p, "ERROR"); + break; + case isl_schedule_node_leaf: + p = isl_printer_print_str(p, "leaf"); + break; + case isl_schedule_node_sequence: + p = isl_printer_print_str(p, "sequence"); + sequence = 1; + break; + case isl_schedule_node_set: + p = isl_printer_print_str(p, "set"); + sequence = 1; + break; + case isl_schedule_node_context: + p = isl_printer_print_str(p, "context"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_set(p, tree->context); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_domain: + p = isl_printer_print_str(p, "domain"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_set(p, tree->domain); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_expansion: + p = isl_printer_print_str(p, "contraction"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_pw_multi_aff(p, tree->contraction); + p = isl_printer_print_str(p, "\""); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "expansion"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_map(p, tree->expansion); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_extension: + p = isl_printer_print_str(p, "extension"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_map(p, tree->extension); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_filter: + p = isl_printer_print_str(p, "filter"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_union_set(p, tree->filter); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_guard: + p = isl_printer_print_str(p, "guard"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_set(p, tree->guard); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_mark: + p = isl_printer_print_str(p, "mark"); + p = isl_printer_yaml_next(p); + p = isl_printer_print_str(p, "\""); + p = isl_printer_print_str(p, isl_id_get_name(tree->mark)); + p = isl_printer_print_str(p, "\""); + break; + case isl_schedule_node_band: + p = print_tree_band(p, tree->band); + break; + } + p = isl_printer_yaml_next(p); + + if (!tree->children) { + if (n_ancestor > 0 && block) { + isl_schedule_tree *leaf; + + p = isl_printer_print_str(p, "child"); + p = isl_printer_yaml_next(p); + leaf = isl_schedule_tree_leaf(isl_printer_get_ctx(p)); + p = isl_printer_print_schedule_tree_mark(p, + leaf, 0, NULL); + isl_schedule_tree_free(leaf); + p = isl_printer_yaml_next(p); + } + return isl_printer_yaml_end_mapping(p); + } + + if (sequence) { + p = isl_printer_yaml_start_sequence(p); + } else { + p = isl_printer_print_str(p, "child"); + p = isl_printer_yaml_next(p); + } + + n = isl_schedule_tree_list_n_schedule_tree(tree->children); + for (i = 0; i < n; ++i) { + isl_schedule_tree *t; + + t = isl_schedule_tree_get_child(tree, i); + if (n_ancestor > 0 && child_pos[0] == i) + p = isl_printer_print_schedule_tree_mark(p, t, + n_ancestor - 1, child_pos + 1); + else + p = isl_printer_print_schedule_tree_mark(p, t, + -1, NULL); + isl_schedule_tree_free(t); + + p = isl_printer_yaml_next(p); + } + + if (sequence) + p = isl_printer_yaml_end_sequence(p); + p = isl_printer_yaml_end_mapping(p); + + return p; +} + +/* Print "tree" to "p". + */ +__isl_give isl_printer *isl_printer_print_schedule_tree( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree) +{ + return isl_printer_print_schedule_tree_mark(p, tree, -1, NULL); +} + +void isl_schedule_tree_dump(__isl_keep isl_schedule_tree *tree) +{ + isl_ctx *ctx; + isl_printer *printer; + + if (!tree) + return; + + ctx = isl_schedule_tree_get_ctx(tree); + printer = isl_printer_to_file(ctx, stderr); + printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK); + printer = isl_printer_print_schedule_tree(printer, tree); + + isl_printer_free(printer); +} diff -Nru isl-0.12.2/isl_schedule_tree.h isl-0.15/isl_schedule_tree.h --- isl-0.12.2/isl_schedule_tree.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_schedule_tree.h 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,260 @@ +#ifndef ISL_SCHEDLUE_TREE_H +#define ISL_SCHEDLUE_TREE_H + +#include +#include +#include +#include + +struct isl_schedule_tree; +typedef struct isl_schedule_tree isl_schedule_tree; + +ISL_DECLARE_LIST(schedule_tree) + +/* A schedule (sub)tree. + * + * The leaves of a tree are not explicitly represented inside + * the isl_schedule_tree. If a tree consists of only a leaf, + * then it is equal to the static object isl_schedule_tree_empty. + * + * ctx may be NULL if type is isl_schedule_node_leaf. + * In this case, ref has a negative value. + * + * The "band" field is valid when type is isl_schedule_node_band. + * The "context" field is valid when type is isl_schedule_node_context + * and represents constraints on the flat product of the outer band nodes, + * possibly introducing additional parameters. + * The "domain" field is valid when type is isl_schedule_node_domain + * and introduces the statement instances scheduled by the tree. + * + * The "contraction" and "expansion" fields are valid when type + * is isl_schedule_node_expansion. + * "expansion" expands the reaching domain elements to one or more + * domain elements for the subtree. + * "contraction" maps these elements back to the corresponding + * reaching domain element. It does not involve any domain constraints. + * + * The "extension" field is valid when the is isl_schedule_node_extension + * maps outer schedule dimenions (the flat product of the outer band nodes) + * to additional iteration domains. + * + * The "filter" field is valid when type is isl_schedule_node_filter + * and represents the statement instances selected by the node. + * + * The "guard" field is valid when type is isl_schedule_node_guard + * and represents constraints on the flat product of the outer band nodes + * that need to be enforced by the outer nodes in the generated AST. + * + * The "mark" field is valid when type is isl_schedule_node_mark and + * identifies the mark. + * + * The "children" field is valid for all types except + * isl_schedule_node_leaf. This field is NULL if there are + * no children (except for the implicit leaves). + * + * anchored is set if the node or any of its descendants depends + * on its position in the schedule tree. + */ +struct isl_schedule_tree { + int ref; + isl_ctx *ctx; + int anchored; + enum isl_schedule_node_type type; + union { + isl_schedule_band *band; + isl_set *context; + isl_union_set *domain; + struct { + isl_union_pw_multi_aff *contraction; + isl_union_map *expansion; + }; + isl_union_map *extension; + isl_union_set *filter; + isl_set *guard; + isl_id *mark; + }; + isl_schedule_tree_list *children; +}; + +isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree); +enum isl_schedule_node_type isl_schedule_tree_get_type( + __isl_keep isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx); +int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree); + +isl_bool isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1, + __isl_keep isl_schedule_tree *tree2); + +__isl_give isl_schedule_tree *isl_schedule_tree_copy( + __isl_keep isl_schedule_tree *tree); +__isl_null isl_schedule_tree *isl_schedule_tree_free( + __isl_take isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_tree_from_band( + __isl_take isl_schedule_band *band); +__isl_give isl_schedule_tree *isl_schedule_tree_from_context( + __isl_take isl_set *context); +__isl_give isl_schedule_tree *isl_schedule_tree_from_domain( + __isl_take isl_union_set *domain); +__isl_give isl_schedule_tree *isl_schedule_tree_from_expansion( + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_schedule_tree *isl_schedule_tree_from_extension( + __isl_take isl_union_map *extension); +__isl_give isl_schedule_tree *isl_schedule_tree_from_filter( + __isl_take isl_union_set *filter); +__isl_give isl_schedule_tree *isl_schedule_tree_from_guard( + __isl_take isl_set *guard); +__isl_give isl_schedule_tree *isl_schedule_tree_from_children( + enum isl_schedule_node_type type, + __isl_take isl_schedule_tree_list *list); +__isl_give isl_schedule_tree *isl_schedule_tree_from_pair( + enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_pair( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); + +isl_bool isl_schedule_tree_is_subtree_anchored( + __isl_keep isl_schedule_tree *tree); + +__isl_give isl_space *isl_schedule_tree_band_get_space( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_intersect_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain); +__isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_partial_schedule( + __isl_take isl_schedule_tree *tree, + __isl_take isl_multi_union_pw_aff *schedule); +enum isl_ast_loop_type isl_schedule_tree_band_member_get_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type); +enum isl_ast_loop_type isl_schedule_tree_band_member_get_isolate_ast_loop_type( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree * +isl_schedule_tree_band_member_set_isolate_ast_loop_type( + __isl_take isl_schedule_tree *tree, int pos, + enum isl_ast_loop_type type); +__isl_give isl_union_set *isl_schedule_tree_band_get_ast_build_options( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_ast_build_options( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *options); +__isl_give isl_set *isl_schedule_tree_context_get_context( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_union_set *isl_schedule_tree_domain_get_domain( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain); +__isl_give isl_union_pw_multi_aff *isl_schedule_tree_expansion_get_contraction( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_union_map *isl_schedule_tree_expansion_get_expansion( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree * +isl_schedule_tree_expansion_set_contraction_and_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_union_map *isl_schedule_tree_extension_get_extension( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_extension_set_extension( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_map *extension); +__isl_give isl_union_set *isl_schedule_tree_filter_get_filter( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter); +__isl_give isl_set *isl_schedule_tree_guard_get_guard( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_id *isl_schedule_tree_mark_get_id( + __isl_keep isl_schedule_tree *tree); + +__isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant( + __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf); +__isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map( + __isl_keep isl_schedule_tree *tree); + +unsigned isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree); + +isl_bool isl_schedule_tree_band_member_get_coincident( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident( + __isl_take isl_schedule_tree *tree, int pos, int coincident); +isl_bool isl_schedule_tree_band_get_permutable( + __isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable( + __isl_take isl_schedule_tree *tree, int permutable); + +int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree); +int isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_get_child( + __isl_keep isl_schedule_tree *tree, int pos); + +__isl_give isl_schedule_tree *isl_schedule_tree_insert_band( + __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_context( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *context); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_domain( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_expansion( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *contraction, + __isl_take isl_union_map *expansion); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_extension( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_map *extension); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter); +__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_guard( + __isl_take isl_schedule_tree *tree, __isl_take isl_set *guard); +__isl_give isl_schedule_tree *isl_schedule_tree_insert_mark( + __isl_take isl_schedule_tree *tree, __isl_take isl_id *mark); + +__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves( + __isl_take isl_schedule_tree *tree1, + __isl_take isl_schedule_tree *tree2); + +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv); +__isl_give isl_schedule_tree *isl_schedule_tree_band_tile( + __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes); +__isl_give isl_schedule_tree *isl_schedule_tree_band_split( + __isl_take isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_band_gist( + __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context); + +__isl_give isl_schedule_tree *isl_schedule_tree_child( + __isl_take isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_reset_children( + __isl_take isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_drop_child( + __isl_take isl_schedule_tree *tree, int pos); +__isl_give isl_schedule_tree *isl_schedule_tree_replace_child( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *new_child); +__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *child); + +__isl_give isl_schedule_tree *isl_schedule_tree_reset_user( + __isl_take isl_schedule_tree *tree); +__isl_give isl_schedule_tree *isl_schedule_tree_align_params( + __isl_take isl_schedule_tree *tree, __isl_take isl_space *space); +__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff( + __isl_take isl_schedule_tree *tree, + __isl_take isl_union_pw_multi_aff *upma); + +__isl_give isl_printer *isl_printer_print_schedule_tree( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree); +__isl_give isl_printer *isl_printer_print_schedule_tree_mark( + __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree, + int n_ancestor, int *child_pos); + +#endif diff -Nru isl-0.12.2/isl_seq.c isl-0.15/isl_seq.c --- isl-0.12.2/isl_seq.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_seq.c 2015-06-02 09:28:10.000000000 +0000 @@ -8,7 +8,7 @@ */ #include -#include +#include void isl_seq_clr(isl_int *p, unsigned len) { @@ -107,6 +107,14 @@ int i; isl_int tmp; + if (dst == src1 && isl_int_is_one(m1)) { + if (isl_int_is_zero(m2)) + return; + for (i = 0; i < len; ++i) + isl_int_addmul(src1[i], m2, src2[i]); + return; + } + isl_int_init(tmp); for (i = 0; i < len; ++i) { isl_int_mul(tmp, m1, src1[i]); diff -Nru isl-0.12.2/isl_seq.h isl-0.15/isl_seq.h --- isl-0.12.2/isl_seq.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_seq.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * 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_SEQ_H +#define ISL_SEQ_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Some common operations on sequences of isl_int's */ + +void isl_seq_clr(isl_int *p, unsigned len); +void isl_seq_set(isl_int *p, isl_int v, unsigned len); +void isl_seq_set_si(isl_int *p, int v, unsigned len); +void isl_seq_neg(isl_int *dst, isl_int *src, unsigned len); +void isl_seq_cpy(isl_int *dst, isl_int *src, unsigned len); +void isl_seq_addmul(isl_int *dst, isl_int f, isl_int *src, unsigned len); +void isl_seq_submul(isl_int *dst, isl_int f, isl_int *src, unsigned len); +void isl_seq_swp_or_cpy(isl_int *dst, isl_int *src, unsigned len); +void isl_seq_scale(isl_int *dst, isl_int *src, isl_int f, unsigned len); +void isl_seq_scale_down(isl_int *dst, isl_int *src, isl_int f, unsigned len); +void isl_seq_cdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len); +void isl_seq_fdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len); +void isl_seq_fdiv_r(isl_int *dst, isl_int *src, isl_int m, unsigned len); +void isl_seq_combine(isl_int *dst, isl_int m1, isl_int *src1, + isl_int m2, isl_int *src2, unsigned len); +void isl_seq_elim(isl_int *dst, isl_int *src, unsigned pos, unsigned len, + isl_int *m); +void isl_seq_abs_max(isl_int *p, unsigned len, isl_int *max); +void isl_seq_gcd(isl_int *p, unsigned len, isl_int *gcd); +void isl_seq_lcm(isl_int *p, unsigned len, isl_int *lcm); +void isl_seq_normalize(struct isl_ctx *ctx, isl_int *p, unsigned len); +void isl_seq_inner_product(isl_int *p1, isl_int *p2, unsigned len, + isl_int *prod); +int isl_seq_first_non_zero(isl_int *p, unsigned len); +int isl_seq_last_non_zero(isl_int *p, unsigned len); +int isl_seq_abs_min_non_zero(isl_int *p, unsigned len); +int isl_seq_eq(isl_int *p1, isl_int *p2, unsigned len); +int isl_seq_cmp(isl_int *p1, isl_int *p2, unsigned len); +int isl_seq_is_neg(isl_int *p1, isl_int *p2, unsigned len); + +uint32_t isl_seq_get_hash(isl_int *p, unsigned len); +uint32_t isl_seq_get_hash_bits(isl_int *p, unsigned len, unsigned bits); + +#if defined(__cplusplus) +} +#endif + +#endif diff -Nru isl-0.12.2/isl_set_list.c isl-0.15/isl_set_list.c --- isl-0.12.2/isl_set_list.c 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/isl_set_list.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,4 +1,5 @@ #include +#include #undef EL #define EL isl_basic_set @@ -10,6 +11,11 @@ #include +#undef EL +#define EL isl_union_set + +#include + #undef BASE #define BASE basic_set @@ -19,3 +25,8 @@ #define BASE set #include + +#undef BASE +#define BASE union_set + +#include diff -Nru isl-0.12.2/isl_space.c isl-0.15/isl_space.c --- isl-0.12.2/isl_space.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_space.c 2015-06-10 18:25:33.000000000 +0000 @@ -1,6 +1,7 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2010 INRIA Saclay + * Copyright 2013-2014 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -8,6 +9,7 @@ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France */ #include @@ -63,23 +65,23 @@ /* Is the space that of a set? */ -int isl_space_is_set(__isl_keep isl_space *space) +isl_bool isl_space_is_set(__isl_keep isl_space *space) { if (!space) - return -1; + return isl_bool_error; if (space->n_in != 0 || space->nested[0]) - return 0; + return isl_bool_false; if (space->tuple_id[0] != &isl_id_none) - return 0; - return 1; + return isl_bool_false; + return isl_bool_true; } /* Is the given space that of a map? */ -int isl_space_is_map(__isl_keep isl_space *space) +isl_bool isl_space_is_map(__isl_keep isl_space *space) { if (!space) - return -1; + return isl_bool_error; return space->tuple_id[0] != &isl_id_none && space->tuple_id[1] != &isl_id_none; } @@ -107,18 +109,18 @@ /* Is the space that of a parameter domain? */ -int isl_space_is_params(__isl_keep isl_space *space) +isl_bool isl_space_is_params(__isl_keep isl_space *space) { if (!space) - return -1; + return isl_bool_error; if (space->n_in != 0 || space->nested[0] || space->n_out != 0 || space->nested[1]) - return 0; + return isl_bool_false; if (space->tuple_id[0] != &isl_id_none) - return 0; + return isl_bool_false; if (space->tuple_id[1] != &isl_id_none) - return 0; - return 1; + return isl_bool_false; + return isl_bool_true; } /* Create a space for a parameter domain. @@ -336,28 +338,28 @@ return dim; } -void *isl_space_free(__isl_take isl_space *dim) +__isl_null isl_space *isl_space_free(__isl_take isl_space *space) { int i; - if (!dim) + if (!space) return NULL; - if (--dim->ref > 0) + if (--space->ref > 0) return NULL; - isl_id_free(dim->tuple_id[0]); - isl_id_free(dim->tuple_id[1]); + isl_id_free(space->tuple_id[0]); + isl_id_free(space->tuple_id[1]); - isl_space_free(dim->nested[0]); - isl_space_free(dim->nested[1]); + isl_space_free(space->nested[0]); + isl_space_free(space->nested[1]); - for (i = 0; i < dim->n_id; ++i) - isl_id_free(dim->ids[i]); - free(dim->ids); - isl_ctx_deref(dim->ctx); + for (i = 0; i < space->n_id; ++i) + isl_id_free(space->ids[i]); + free(space->ids); + isl_ctx_deref(space->ctx); - free(dim); + free(space); return NULL; } @@ -403,10 +405,11 @@ /* Does the tuple have an id? */ -int isl_space_has_tuple_id(__isl_keep isl_space *dim, enum isl_dim_type type) +isl_bool isl_space_has_tuple_id(__isl_keep isl_space *dim, + enum isl_dim_type type) { if (!space_can_have_id(dim, type)) - return -1; + return isl_bool_error; return dim->tuple_id[type - isl_dim_in] != NULL; } @@ -534,11 +537,11 @@ return NULL; } -int isl_space_has_dim_id(__isl_keep isl_space *dim, +isl_bool isl_space_has_dim_id(__isl_keep isl_space *dim, enum isl_dim_type type, unsigned pos) { if (!dim) - return -1; + return isl_bool_error; return get_id(dim, type, pos) != NULL; } @@ -576,13 +579,13 @@ /* Does the tuple have a name? */ -int isl_space_has_tuple_name(__isl_keep isl_space *space, +isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space, enum isl_dim_type type) { isl_id *id; if (!space_can_have_id(space, type)) - return -1; + return isl_bool_error; id = space->tuple_id[type - isl_dim_in]; return id && id->name; } @@ -620,13 +623,13 @@ /* Does the given dimension have a name? */ -int isl_space_has_dim_name(__isl_keep isl_space *space, +isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, enum isl_dim_type type, unsigned pos) { isl_id *id; if (!space) - return -1; + return isl_bool_error; id = get_id(space, type, pos); return id && id->name; } @@ -677,6 +680,65 @@ return -1; } +/* Reset the user pointer on all identifiers of parameters and tuples + * of "space". + */ +__isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space) +{ + int i; + isl_ctx *ctx; + isl_id *id; + const char *name; + + if (!space) + return NULL; + + ctx = isl_space_get_ctx(space); + + for (i = 0; i < space->nparam && i < space->n_id; ++i) { + if (!isl_id_get_user(space->ids[i])) + continue; + space = isl_space_cow(space); + if (!space) + return NULL; + name = isl_id_get_name(space->ids[i]); + id = isl_id_alloc(ctx, name, NULL); + isl_id_free(space->ids[i]); + space->ids[i] = id; + if (!id) + return isl_space_free(space); + } + + for (i = 0; i < 2; ++i) { + if (!space->tuple_id[i]) + continue; + if (!isl_id_get_user(space->tuple_id[i])) + continue; + space = isl_space_cow(space); + if (!space) + return NULL; + name = isl_id_get_name(space->tuple_id[i]); + id = isl_id_alloc(ctx, name, NULL); + isl_id_free(space->tuple_id[i]); + space->tuple_id[i] = id; + if (!id) + return isl_space_free(space); + } + + for (i = 0; i < 2; ++i) { + if (!space->nested[i]) + continue; + space = isl_space_cow(space); + if (!space) + return NULL; + space->nested[i] = isl_space_reset_user(space->nested[i]); + if (!space->nested[i]) + return isl_space_free(space); + } + + return space; +} + static __isl_keep isl_id *tuple_id(__isl_keep isl_space *dim, enum isl_dim_type type) { @@ -701,33 +763,70 @@ return NULL; } -int isl_space_tuple_match(__isl_keep isl_space *dim1, enum isl_dim_type dim1_type, - __isl_keep isl_space *dim2, enum isl_dim_type dim2_type) +/* Are the two spaces the same, apart from positions and names of parameters? + */ +static int isl_space_has_equal_tuples(__isl_keep isl_space *space1, + __isl_keep isl_space *space2) +{ + if (!space1 || !space2) + return -1; + if (space1 == space2) + return 1; + return isl_space_tuple_is_equal(space1, isl_dim_in, + space2, isl_dim_in) && + isl_space_tuple_is_equal(space1, isl_dim_out, + space2, isl_dim_out); +} + +/* Check if the tuple of type "type1" of "space1" is the same as + * the tuple of type "type2" of "space2". + * + * That is, check if the tuples have the same identifier, the same dimension + * and the same internal structure. + * The identifiers of the dimensions inside the tuples do not affect the result. + * + * Note that this function only checks the tuples themselves. + * If nested tuples are involved, then we need to be careful not + * to have result affected by possibly differing parameters + * in those nested tuples. + */ +isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1, + enum isl_dim_type type1, __isl_keep isl_space *space2, + enum isl_dim_type type2) { isl_id *id1, *id2; isl_space *nested1, *nested2; - if (!dim1 || !dim2) - return -1; + if (!space1 || !space2) + return isl_bool_error; - if (dim1 == dim2 && dim1_type == dim2_type) - return 1; + if (space1 == space2 && type1 == type2) + return isl_bool_true; - if (n(dim1, dim1_type) != n(dim2, dim2_type)) - return 0; - id1 = tuple_id(dim1, dim1_type); - id2 = tuple_id(dim2, dim2_type); + if (n(space1, type1) != n(space2, type2)) + return isl_bool_false; + id1 = tuple_id(space1, type1); + id2 = tuple_id(space2, type2); if (!id1 ^ !id2) - return 0; + return isl_bool_false; if (id1 && id1 != id2) - return 0; - nested1 = nested(dim1, dim1_type); - nested2 = nested(dim2, dim2_type); + return isl_bool_false; + nested1 = nested(space1, type1); + nested2 = nested(space2, type2); if (!nested1 ^ !nested2) - return 0; - if (nested1 && !isl_space_is_equal(nested1, nested2)) - return 0; - return 1; + return isl_bool_false; + if (nested1 && !isl_space_has_equal_tuples(nested1, nested2)) + return isl_bool_false; + return isl_bool_true; +} + +/* This is the old, undocumented, name for isl_space_tuple_is_equal. + * It will be removed at some point. + */ +int isl_space_tuple_match(__isl_keep isl_space *space1, enum isl_dim_type type1, + __isl_keep isl_space *space2, enum isl_dim_type type2) +{ + return isl_space_tuple_is_equal(space1, type1, space2, type2); } static int match(__isl_keep isl_space *dim1, enum isl_dim_type dim1_type, @@ -738,7 +837,7 @@ if (dim1 == dim2 && dim1_type == dim2_type) return 1; - if (!isl_space_tuple_match(dim1, dim1_type, dim2, dim2_type)) + if (!isl_space_tuple_is_equal(dim1, dim1_type, dim2, dim2_type)) return 0; if (!dim1->ids && !dim2->ids) @@ -769,53 +868,60 @@ ids[i] = get_id(dim, type, first + i); } -__isl_give isl_space *isl_space_extend(__isl_take isl_space *dim, +__isl_give isl_space *isl_space_extend(__isl_take isl_space *space, unsigned nparam, unsigned n_in, unsigned n_out) { isl_id **ids = NULL; - if (!dim) + if (!space) return NULL; - if (dim->nparam == nparam && dim->n_in == n_in && dim->n_out == n_out) - return dim; + if (space->nparam == nparam && + space->n_in == n_in && space->n_out == n_out) + return space; - isl_assert(dim->ctx, dim->nparam <= nparam, goto error); - isl_assert(dim->ctx, dim->n_in <= n_in, goto error); - isl_assert(dim->ctx, dim->n_out <= n_out, goto error); + isl_assert(space->ctx, space->nparam <= nparam, goto error); + isl_assert(space->ctx, space->n_in <= n_in, goto error); + isl_assert(space->ctx, space->n_out <= n_out, goto error); - dim = isl_space_cow(dim); - if (!dim) + space = isl_space_cow(space); + if (!space) goto error; - if (dim->ids) { - ids = isl_calloc_array(dim->ctx, isl_id *, - nparam + n_in + n_out); + if (space->ids) { + unsigned n; + n = nparam + n_in + n_out; + if (n < nparam || n < n_in || n < n_out) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "overflow in total number of dimensions", + goto error); + ids = isl_calloc_array(space->ctx, isl_id *, n); if (!ids) goto error; - get_ids(dim, isl_dim_param, 0, dim->nparam, ids); - get_ids(dim, isl_dim_in, 0, dim->n_in, ids + nparam); - get_ids(dim, isl_dim_out, 0, dim->n_out, ids + nparam + n_in); - free(dim->ids); - dim->ids = ids; - dim->n_id = nparam + n_in + n_out; - } - dim->nparam = nparam; - dim->n_in = n_in; - dim->n_out = n_out; + get_ids(space, isl_dim_param, 0, space->nparam, ids); + get_ids(space, isl_dim_in, 0, space->n_in, ids + nparam); + get_ids(space, isl_dim_out, 0, space->n_out, + ids + nparam + n_in); + free(space->ids); + space->ids = ids; + space->n_id = nparam + n_in + n_out; + } + space->nparam = nparam; + space->n_in = n_in; + space->n_out = n_out; - return dim; + return space; error: free(ids); - isl_space_free(dim); + isl_space_free(space); return NULL; } __isl_give isl_space *isl_space_add_dims(__isl_take isl_space *dim, enum isl_dim_type type, unsigned n) { + dim = isl_space_reset(dim, type); if (!dim) return NULL; - dim = isl_space_reset(dim, type); switch (type) { case isl_dim_param: dim = isl_space_extend(dim, @@ -941,8 +1047,10 @@ if (!dim) return NULL; - if (n == 0) - return dim; + if (n == 0) { + dim = isl_space_reset(dim, src_type); + return isl_space_reset(dim, dst_type); + } isl_assert(dim->ctx, src_pos + n <= isl_space_dim(dim, src_type), goto error); @@ -1040,7 +1148,7 @@ isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param), goto error); isl_assert(left->ctx, - isl_space_tuple_match(left, isl_dim_out, right, isl_dim_in), + isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in), goto error); dim = isl_space_alloc(left->ctx, left->nparam, left->n_in, right->n_out); @@ -1074,14 +1182,27 @@ return NULL; } +/* Given two map spaces { A -> C } and { B -> D }, construct the space + * { [A -> B] -> [C -> D] }. + * Given two set spaces { A } and { B }, construct the space { [A -> B] }. + */ __isl_give isl_space *isl_space_product(__isl_take isl_space *left, __isl_take isl_space *right) { isl_space *dom1, *dom2, *nest1, *nest2; + int is_set; if (!left || !right) goto error; + is_set = isl_space_is_set(left); + if (is_set != isl_space_is_set(right)) + isl_die(isl_space_get_ctx(left), isl_error_invalid, + "expecting either two set spaces or two map spaces", + goto error); + if (is_set) + return isl_space_range_product(left, right); + isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param), goto error); @@ -1114,7 +1235,7 @@ if (!match(left, isl_dim_param, right, isl_dim_param)) isl_die(left->ctx, isl_error_invalid, "parameters need to match", goto error); - if (!isl_space_tuple_match(left, isl_dim_out, right, isl_dim_out)) + if (!isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_out)) isl_die(left->ctx, isl_error_invalid, "ranges need to match", goto error); @@ -1141,7 +1262,7 @@ isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param), goto error); - if (!isl_space_tuple_match(left, isl_dim_in, right, isl_dim_in)) + if (!isl_space_tuple_is_equal(left, isl_dim_in, right, isl_dim_in)) isl_die(left->ctx, isl_error_invalid, "domains need to match", goto error); @@ -1158,6 +1279,178 @@ return NULL; } +/* Given a space of the form [A -> B] -> [C -> D], return the space A -> C. + */ +__isl_give isl_space *isl_space_factor_domain(__isl_take isl_space *space) +{ + space = isl_space_domain_factor_domain(space); + space = isl_space_range_factor_domain(space); + return space; +} + +/* Given a space of the form [A -> B] -> [C -> D], return the space B -> D. + */ +__isl_give isl_space *isl_space_factor_range(__isl_take isl_space *space) +{ + space = isl_space_domain_factor_range(space); + space = isl_space_range_factor_range(space); + return space; +} + +/* Given a space of the form [A -> B] -> C, return the space A -> C. + */ +__isl_give isl_space *isl_space_domain_factor_domain( + __isl_take isl_space *space) +{ + isl_space *nested; + isl_space *domain; + + if (!space) + return NULL; + if (!isl_space_domain_is_wrapping(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "domain not a product", return isl_space_free(space)); + + nested = space->nested[0]; + domain = isl_space_copy(space); + domain = isl_space_drop_dims(domain, isl_dim_in, + nested->n_in, nested->n_out); + if (!domain) + return isl_space_free(space); + if (nested->tuple_id[0]) { + domain->tuple_id[0] = isl_id_copy(nested->tuple_id[0]); + if (!domain->tuple_id[0]) + goto error; + } + if (nested->nested[0]) { + domain->nested[0] = isl_space_copy(nested->nested[0]); + if (!domain->nested[0]) + goto error; + } + + isl_space_free(space); + return domain; +error: + isl_space_free(space); + isl_space_free(domain); + return NULL; +} + +/* Given a space of the form [A -> B] -> C, return the space B -> C. + */ +__isl_give isl_space *isl_space_domain_factor_range( + __isl_take isl_space *space) +{ + isl_space *nested; + isl_space *range; + + if (!space) + return NULL; + if (!isl_space_domain_is_wrapping(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "domain not a product", return isl_space_free(space)); + + nested = space->nested[0]; + range = isl_space_copy(space); + range = isl_space_drop_dims(range, isl_dim_in, 0, nested->n_in); + if (!range) + return isl_space_free(space); + if (nested->tuple_id[1]) { + range->tuple_id[0] = isl_id_copy(nested->tuple_id[1]); + if (!range->tuple_id[0]) + goto error; + } + if (nested->nested[1]) { + range->nested[0] = isl_space_copy(nested->nested[1]); + if (!range->nested[0]) + goto error; + } + + isl_space_free(space); + return range; +error: + isl_space_free(space); + isl_space_free(range); + return NULL; +} + +/* Given a space of the form A -> [B -> C], return the space A -> B. + */ +__isl_give isl_space *isl_space_range_factor_domain( + __isl_take isl_space *space) +{ + isl_space *nested; + isl_space *domain; + + if (!space) + return NULL; + if (!isl_space_range_is_wrapping(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "range not a product", return isl_space_free(space)); + + nested = space->nested[1]; + domain = isl_space_copy(space); + domain = isl_space_drop_dims(domain, isl_dim_out, + nested->n_in, nested->n_out); + if (!domain) + return isl_space_free(space); + if (nested->tuple_id[0]) { + domain->tuple_id[1] = isl_id_copy(nested->tuple_id[0]); + if (!domain->tuple_id[1]) + goto error; + } + if (nested->nested[0]) { + domain->nested[1] = isl_space_copy(nested->nested[0]); + if (!domain->nested[1]) + goto error; + } + + isl_space_free(space); + return domain; +error: + isl_space_free(space); + isl_space_free(domain); + return NULL; +} + +/* Given a space of the form A -> [B -> C], return the space A -> C. + */ +__isl_give isl_space *isl_space_range_factor_range( + __isl_take isl_space *space) +{ + isl_space *nested; + isl_space *range; + + if (!space) + return NULL; + if (!isl_space_range_is_wrapping(space)) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "range not a product", return isl_space_free(space)); + + nested = space->nested[1]; + range = isl_space_copy(space); + range = isl_space_drop_dims(range, isl_dim_out, 0, nested->n_in); + if (!range) + return isl_space_free(space); + if (nested->tuple_id[1]) { + range->tuple_id[1] = isl_id_copy(nested->tuple_id[1]); + if (!range->tuple_id[1]) + goto error; + } + if (nested->nested[1]) { + range->nested[1] = isl_space_copy(nested->nested[1]); + if (!range->nested[1]) + goto error; + } + + isl_space_free(space); + return range; +error: + isl_space_free(space); + isl_space_free(range); + return NULL; +} + __isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *dim) { isl_ctx *ctx; @@ -1403,6 +1696,32 @@ return NULL; } +/* Given a map space A -> B, return the map space [A -> B] -> A. + */ +__isl_give isl_space *isl_space_domain_map(__isl_take isl_space *space) +{ + isl_space *domain; + + domain = isl_space_from_range(isl_space_domain(isl_space_copy(space))); + space = isl_space_from_domain(isl_space_wrap(space)); + space = isl_space_join(space, domain); + + return space; +} + +/* Given a map space A -> B, return the map space [A -> B] -> B. + */ +__isl_give isl_space *isl_space_range_map(__isl_take isl_space *space) +{ + isl_space *range; + + range = isl_space_from_range(isl_space_range(isl_space_copy(space))); + space = isl_space_from_domain(isl_space_wrap(space)); + space = isl_space_join(space, range); + + return space; +} + __isl_give isl_space *isl_space_params(__isl_take isl_space *space) { if (isl_space_is_params(space)) @@ -1470,15 +1789,16 @@ /* Are the two spaces the same, including positions and names of parameters? */ -int isl_space_is_equal(__isl_keep isl_space *dim1, __isl_keep isl_space *dim2) +isl_bool isl_space_is_equal(__isl_keep isl_space *dim1, + __isl_keep isl_space *dim2) { if (!dim1 || !dim2) - return -1; + return isl_bool_error; if (dim1 == dim2) - return 1; + return isl_bool_true; return match(dim1, isl_dim_param, dim2, isl_dim_param) && - isl_space_tuple_match(dim1, isl_dim_in, dim2, isl_dim_in) && - isl_space_tuple_match(dim1, isl_dim_out, dim2, isl_dim_out); + isl_space_tuple_is_equal(dim1, isl_dim_in, dim2, isl_dim_in) && + isl_space_tuple_is_equal(dim1, isl_dim_out, dim2, isl_dim_out); } /* Is space1 equal to the domain of space2? @@ -1486,26 +1806,27 @@ * In the internal version we also allow space2 to be the space of a set, * provided space1 is a parameter space. */ -int isl_space_is_domain_internal(__isl_keep isl_space *space1, +isl_bool isl_space_is_domain_internal(__isl_keep isl_space *space1, __isl_keep isl_space *space2) { if (!space1 || !space2) - return -1; + return isl_bool_error; if (!isl_space_is_set(space1)) - return 0; + return isl_bool_false; return match(space1, isl_dim_param, space2, isl_dim_param) && - isl_space_tuple_match(space1, isl_dim_set, space2, isl_dim_in); + isl_space_tuple_is_equal(space1, isl_dim_set, + space2, isl_dim_in); } /* Is space1 equal to the domain of space2? */ -int isl_space_is_domain(__isl_keep isl_space *space1, +isl_bool isl_space_is_domain(__isl_keep isl_space *space1, __isl_keep isl_space *space2) { if (!space2) - return -1; + return isl_bool_error; if (!isl_space_is_map(space2)) - return 0; + return isl_bool_false; return isl_space_is_domain_internal(space1, space2); } @@ -1514,26 +1835,27 @@ * In the internal version, space2 is allowed to be the space of a set, * in which case it should be equal to space1. */ -int isl_space_is_range_internal(__isl_keep isl_space *space1, +isl_bool isl_space_is_range_internal(__isl_keep isl_space *space1, __isl_keep isl_space *space2) { if (!space1 || !space2) - return -1; + return isl_bool_error; if (!isl_space_is_set(space1)) - return 0; + return isl_bool_false; return match(space1, isl_dim_param, space2, isl_dim_param) && - isl_space_tuple_match(space1, isl_dim_set, space2, isl_dim_out); + isl_space_tuple_is_equal(space1, isl_dim_set, + space2, isl_dim_out); } /* Is space1 equal to the range of space2? */ -int isl_space_is_range(__isl_keep isl_space *space1, +isl_bool isl_space_is_range(__isl_keep isl_space *space1, __isl_keep isl_space *space2) { if (!space2) - return -1; + return isl_bool_error; if (!isl_space_is_map(space2)) - return 0; + return isl_bool_false; return isl_space_is_range_internal(space1, space2); } @@ -1585,17 +1907,43 @@ return hash; } -int isl_space_is_wrapping(__isl_keep isl_space *dim) +isl_bool isl_space_is_wrapping(__isl_keep isl_space *dim) { if (!dim) - return -1; + return isl_bool_error; if (!isl_space_is_set(dim)) - return 0; + return isl_bool_false; return dim->nested[1] != NULL; } +/* Is "space" the space of a map where the domain is a wrapped map space? + */ +isl_bool isl_space_domain_is_wrapping(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + + if (isl_space_is_set(space)) + return isl_bool_false; + + return space->nested[0] != NULL; +} + +/* Is "space" the space of a map where the range is a wrapped map space? + */ +isl_bool isl_space_range_is_wrapping(__isl_keep isl_space *space) +{ + if (!space) + return isl_bool_error; + + if (isl_space_is_set(space)) + return isl_bool_false; + + return space->nested[1] != NULL; +} + __isl_give isl_space *isl_space_wrap(__isl_take isl_space *dim) { isl_space *wrap; @@ -1776,10 +2124,10 @@ return dim; } -int isl_space_can_zip(__isl_keep isl_space *dim) +isl_bool isl_space_can_zip(__isl_keep isl_space *dim) { if (!dim) - return -1; + return isl_bool_error; return dim->nested[0] && dim->nested[1]; } @@ -1815,10 +2163,10 @@ /* Can we apply isl_space_curry to "space"? * That is, does it have a nested relation in its domain? */ -int isl_space_can_curry(__isl_keep isl_space *space) +isl_bool isl_space_can_curry(__isl_keep isl_space *space) { if (!space) - return -1; + return isl_bool_error; return !!space->nested[0]; } @@ -1854,10 +2202,10 @@ /* Can we apply isl_space_uncurry to "space"? * That is, does it have a nested relation in its range? */ -int isl_space_can_uncurry(__isl_keep isl_space *space) +isl_bool isl_space_can_uncurry(__isl_keep isl_space *space) { if (!space) - return -1; + return isl_bool_error; return !!space->nested[1]; } @@ -1970,3 +2318,71 @@ isl_space_free(space); return NULL; } + +/* Compare the "type" dimensions of two isl_spaces. + * + * The order is fairly arbitrary. + */ +static int isl_space_cmp_type(__isl_keep isl_space *space1, + __isl_keep isl_space *space2, enum isl_dim_type type) +{ + int cmp; + isl_space *nested1, *nested2; + + if (isl_space_dim(space1, type) != isl_space_dim(space2, type)) + return isl_space_dim(space1, type) - + isl_space_dim(space2, type); + + cmp = isl_id_cmp(tuple_id(space1, type), tuple_id(space2, type)); + if (cmp != 0) + return cmp; + + nested1 = nested(space1, type); + nested2 = nested(space2, type); + if (!nested1 != !nested2) + return !nested1 - !nested2; + + if (nested1) + return isl_space_cmp(nested1, nested2); + + return 0; +} + +/* Compare two isl_spaces. + * + * The order is fairly arbitrary. + */ +int isl_space_cmp(__isl_keep isl_space *space1, __isl_keep isl_space *space2) +{ + int i; + int cmp; + + if (space1 == space2) + return 0; + if (!space1) + return -1; + if (!space2) + return 1; + + cmp = isl_space_cmp_type(space1, space2, isl_dim_param); + if (cmp != 0) + return cmp; + cmp = isl_space_cmp_type(space1, space2, isl_dim_in); + if (cmp != 0) + return cmp; + cmp = isl_space_cmp_type(space1, space2, isl_dim_out); + if (cmp != 0) + return cmp; + + if (!space1->ids && !space2->ids) + return 0; + + for (i = 0; i < n(space1, isl_dim_param); ++i) { + cmp = isl_id_cmp(get_id(space1, isl_dim_param, i), + get_id(space2, isl_dim_param, i)); + if (cmp != 0) + return cmp; + } + + return 0; +} diff -Nru isl-0.12.2/isl_space_private.h isl-0.15/isl_space_private.h --- isl-0.12.2/isl_space_private.h 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/isl_space_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -29,9 +29,9 @@ uint32_t isl_space_get_hash(__isl_keep isl_space *dim); -int isl_space_is_domain_internal(__isl_keep isl_space *space1, +isl_bool isl_space_is_domain_internal(__isl_keep isl_space *space1, __isl_keep isl_space *space2); -int isl_space_is_range_internal(__isl_keep isl_space *space1, +isl_bool isl_space_is_range_internal(__isl_keep isl_space *space1, __isl_keep isl_space *space2); __isl_give isl_space *isl_space_as_set_space(__isl_take isl_space *dim); @@ -55,4 +55,6 @@ __isl_give isl_space *isl_space_extend_domain_with_range( __isl_take isl_space *domain, __isl_take isl_space *model); +int isl_space_cmp(__isl_keep isl_space *space1, __isl_keep isl_space *space2); + #endif diff -Nru isl-0.12.2/isl_stream.c isl-0.15/isl_stream.c --- isl-0.12.2/isl_stream.c 2013-10-16 16:33:51.000000000 +0000 +++ isl-0.15/isl_stream.c 2015-06-02 09:28:10.000000000 +0000 @@ -28,7 +28,7 @@ return !strcmp(keyword->name, val); } -enum isl_token_type isl_stream_register_keyword(struct isl_stream *s, +enum isl_token_type isl_stream_register_keyword(__isl_keep isl_stream *s, const char *name) { struct isl_hash_table_entry *entry; @@ -101,14 +101,15 @@ return isl_val_int_from_isl_int(ctx, tok->u.v); } -/* Given a token of type ISL_TOKEN_STRING, return the string it represents. +/* Given a token with a string representation, return a copy of this string. */ __isl_give char *isl_token_get_str(isl_ctx *ctx, struct isl_token *tok) { if (!tok) return NULL; - if (tok->type != ISL_TOKEN_STRING) - isl_die(ctx, isl_error_invalid, "not a string token", + if (!tok->u.s) + isl_die(ctx, isl_error_invalid, + "token does not have a string representation", return NULL); return strdup(tok->u.s); @@ -129,7 +130,8 @@ free(tok); } -void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg) +void isl_stream_error(__isl_keep isl_stream *s, struct isl_token *tok, + char *msg) { int line = tok ? tok->line : s->line; int col = tok ? tok->col : s->col; @@ -166,10 +168,10 @@ } } -static struct isl_stream* isl_stream_new(struct isl_ctx *ctx) +static __isl_give isl_stream* isl_stream_new(struct isl_ctx *ctx) { int i; - struct isl_stream *s = isl_alloc_type(ctx, struct isl_stream); + isl_stream *s = isl_calloc_type(ctx, struct isl_stream); if (!s) return NULL; s->ctx = ctx; @@ -178,8 +180,9 @@ s->str = NULL; s->len = 0; s->line = 1; - s->col = 0; + s->col = 1; s->eof = 0; + s->last_line = 0; s->c = -1; s->n_un = 0; for (i = 0; i < 5; ++i) @@ -196,18 +199,18 @@ return NULL; } -struct isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file) +__isl_give isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file) { - struct isl_stream *s = isl_stream_new(ctx); + isl_stream *s = isl_stream_new(ctx); if (!s) return NULL; s->file = file; return s; } -struct isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str) +__isl_give isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str) { - struct isl_stream *s; + isl_stream *s; if (!str) return NULL; s = isl_stream_new(ctx); @@ -217,7 +220,10 @@ return s; } -static int stream_getc(struct isl_stream *s) +/* Read a character from the stream and advance s->line and s->col + * to point to the next character. + */ +static int stream_getc(__isl_keep isl_stream *s) { int c; if (s->eof) @@ -233,29 +239,33 @@ } if (c == -1) s->eof = 1; - if (!s->eof) { - if (s->c == '\n') { - s->line++; - s->col = 0; - } else - s->col++; - } + else if (c == '\n') { + s->line++; + s->col = 1; + } else + s->col++; s->c = c; return c; } -static void isl_stream_ungetc(struct isl_stream *s, int c) +static void isl_stream_ungetc(__isl_keep isl_stream *s, int c) { isl_assert(s->ctx, s->n_un < 5, return); s->un[s->n_un++] = c; s->c = -1; } -static int isl_stream_getc(struct isl_stream *s) +/* Read a character from the stream, skipping pairs of '\\' and '\n'. + * Set s->start_line and s->start_col to the line and column + * of the returned character. + */ +static int isl_stream_getc(__isl_keep isl_stream *s) { int c; do { + s->start_line = s->line; + s->start_col = s->col; c = stream_getc(s); if (c != '\\') return c; @@ -267,7 +277,7 @@ return '\\'; } -static int isl_stream_push_char(struct isl_stream *s, int c) +static int isl_stream_push_char(__isl_keep isl_stream *s, int c) { if (s->len >= s->size) { char *buffer; @@ -281,13 +291,13 @@ return 0; } -void isl_stream_push_token(struct isl_stream *s, struct isl_token *tok) +void isl_stream_push_token(__isl_keep isl_stream *s, struct isl_token *tok) { isl_assert(s->ctx, s->n_token < 5, return); s->tokens[s->n_token++] = tok; } -static enum isl_token_type check_keywords(struct isl_stream *s) +static enum isl_token_type check_keywords(__isl_keep isl_stream *s) { struct isl_hash_table_entry *entry; struct isl_keyword *keyword; @@ -344,7 +354,7 @@ return ISL_TOKEN_IDENT; } -int isl_stream_skip_line(struct isl_stream *s) +int isl_stream_skip_line(__isl_keep isl_stream *s) { int c; @@ -355,12 +365,12 @@ return c == -1 ? -1 : 0; } -static struct isl_token *next_token(struct isl_stream *s, int same_line) +static struct isl_token *next_token(__isl_keep isl_stream *s, int same_line) { int c; struct isl_token *tok = NULL; int line, col; - int old_line = s->line; + int old_line = s->last_line; if (s->n_token) { if (same_line && s->tokens[s->n_token - 1]->on_new_line) @@ -385,11 +395,13 @@ break; } - line = s->line; - col = s->col; + line = s->start_line; + col = s->start_col; if (c == -1 || (same_line && c == '\n')) return NULL; + s->last_line = line; + if (c == '(' || c == ')' || c == '+' || @@ -655,17 +667,17 @@ return NULL; } -struct isl_token *isl_stream_next_token(struct isl_stream *s) +struct isl_token *isl_stream_next_token(__isl_keep isl_stream *s) { return next_token(s, 0); } -struct isl_token *isl_stream_next_token_on_same_line(struct isl_stream *s) +struct isl_token *isl_stream_next_token_on_same_line(__isl_keep isl_stream *s) { return next_token(s, 1); } -int isl_stream_eat_if_available(struct isl_stream *s, int type) +int isl_stream_eat_if_available(__isl_keep isl_stream *s, int type) { struct isl_token *tok; @@ -680,7 +692,7 @@ return 0; } -int isl_stream_next_token_is(struct isl_stream *s, int type) +int isl_stream_next_token_is(__isl_keep isl_stream *s, int type) { struct isl_token *tok; int r; @@ -693,7 +705,7 @@ return r; } -char *isl_stream_read_ident_if_available(struct isl_stream *s) +char *isl_stream_read_ident_if_available(__isl_keep isl_stream *s) { struct isl_token *tok; @@ -709,7 +721,7 @@ return NULL; } -int isl_stream_eat(struct isl_stream *s, int type) +int isl_stream_eat(__isl_keep isl_stream *s, int type) { struct isl_token *tok; @@ -725,7 +737,7 @@ return -1; } -int isl_stream_is_empty(struct isl_stream *s) +int isl_stream_is_empty(__isl_keep isl_stream *s) { struct isl_token *tok; @@ -738,17 +750,17 @@ return 0; } -static int free_keyword(void **p, void *user) +static isl_stat free_keyword(void **p, void *user) { struct isl_keyword *keyword = *p; free(keyword->name); free(keyword); - return 0; + return isl_stat_ok; } -void isl_stream_flush_tokens(struct isl_stream *s) +void isl_stream_flush_tokens(__isl_keep isl_stream *s) { int i; @@ -759,7 +771,12 @@ s->n_token = 0; } -void isl_stream_free(struct isl_stream *s) +isl_ctx *isl_stream_get_ctx(__isl_keep isl_stream *s) +{ + return s ? s->ctx : NULL; +} + +void isl_stream_free(__isl_take isl_stream *s) { if (!s) return; @@ -773,6 +790,382 @@ isl_hash_table_foreach(s->ctx, s->keywords, &free_keyword, NULL); isl_hash_table_free(s->ctx, s->keywords); } + free(s->yaml_state); + free(s->yaml_indent); isl_ctx_deref(s->ctx); free(s); } + +/* Push "state" onto the stack of currently active YAML elements. + * The caller is responsible for setting the corresponding indentation. + * Return 0 on success and -1 on failure. + */ +static int push_state(__isl_keep isl_stream *s, enum isl_yaml_state state) +{ + if (s->yaml_size < s->yaml_depth + 1) { + int *indent; + enum isl_yaml_state *state; + + state = isl_realloc_array(s->ctx, s->yaml_state, + enum isl_yaml_state, s->yaml_depth + 1); + if (!state) + return -1; + s->yaml_state = state; + + indent = isl_realloc_array(s->ctx, s->yaml_indent, + int, s->yaml_depth + 1); + if (!indent) + return -1; + s->yaml_indent = indent; + + s->yaml_size = s->yaml_depth + 1; + } + + s->yaml_state[s->yaml_depth] = state; + s->yaml_depth++; + + return 0; +} + +/* Remove the innermost active YAML element from the stack. + * Return 0 on success and -1 on failure. + */ +static int pop_state(__isl_keep isl_stream *s) +{ + if (!s) + return -1; + if (s->yaml_depth < 1) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "not in YAML construct", return -1); + + s->yaml_depth--; + + return 0; +} + +/* Set the state of the innermost active YAML element to "state". + * Return 0 on success and -1 on failure. + */ +static int update_state(__isl_keep isl_stream *s, enum isl_yaml_state state) +{ + if (!s) + return -1; + if (s->yaml_depth < 1) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "not in YAML construct", return -1); + + s->yaml_state[s->yaml_depth - 1] = state; + + return 0; +} + +/* Return the state of the innermost active YAML element. + * Return isl_yaml_none if we are not inside any YAML element. + */ +static enum isl_yaml_state current_state(__isl_keep isl_stream *s) +{ + if (!s) + return isl_yaml_none; + if (s->yaml_depth < 1) + return isl_yaml_none; + return s->yaml_state[s->yaml_depth - 1]; +} + +/* Set the indentation of the innermost active YAML element to "indent". + * If "indent" is equal to ISL_YAML_INDENT_FLOW, then this means + * that the current elemient is in flow format. + */ +static int set_yaml_indent(__isl_keep isl_stream *s, int indent) +{ + if (s->yaml_depth < 1) + isl_die(s->ctx, isl_error_internal, + "not in YAML element", return -1); + + s->yaml_indent[s->yaml_depth - 1] = indent; + + return 0; +} + +/* Return the indentation of the innermost active YAML element + * of -1 on error. + */ +static int get_yaml_indent(__isl_keep isl_stream *s) +{ + if (s->yaml_depth < 1) + isl_die(s->ctx, isl_error_internal, + "not in YAML element", return -1); + + return s->yaml_indent[s->yaml_depth - 1]; +} + +/* Move to the next state at the innermost level. + * Return 1 if successful. + * Return 0 if we are at the end of the innermost level. + * Return -1 on error. + * + * If we are in state isl_yaml_mapping_key_start, then we have just + * started a mapping and we are expecting a key. If the mapping started + * with a '{', then we check if the next token is a '}'. If so, + * then the mapping is empty and there is no next state at this level. + * Otherwise, we assume that there is at least one key (the one from + * which we derived the indentation in isl_stream_yaml_read_start_mapping. + * + * If we are in state isl_yaml_mapping_key, then the we expect a colon + * followed by a value, so there is always a next state unless + * some error occurs. + * + * If we are in state isl_yaml_mapping_val, then there may or may + * not be a subsequent key in the same mapping. + * In flow format, the next key is preceded by a comma. + * In block format, the next key has the same indentation as the first key. + * If the first token has a smaller indentation, then we have reached + * the end of the current mapping. + * + * If we are in state isl_yaml_sequence_start, then we have just + * started a sequence. If the sequence started with a '[', + * then we check if the next token is a ']'. If so, then the sequence + * is empty and there is no next state at this level. + * Otherwise, we assume that there is at least one element in the sequence + * (the one from which we derived the indentation in + * isl_stream_yaml_read_start_sequence. + * + * If we are in state isl_yaml_sequence, then there may or may + * not be a subsequent element in the same sequence. + * In flow format, the next element is preceded by a comma. + * In block format, the next element is introduced by a dash with + * the same indentation as that of the first element. + * If the first token is not a dash or if it has a smaller indentation, + * then we have reached the end of the current sequence. + */ +int isl_stream_yaml_next(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + enum isl_yaml_state state; + int indent; + + state = current_state(s); + if (state == isl_yaml_none) + isl_die(s->ctx, isl_error_invalid, + "not in YAML element", return -1); + switch (state) { + case isl_yaml_mapping_key_start: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW && + isl_stream_next_token_is(s, '}')) + return 0; + if (update_state(s, isl_yaml_mapping_key) < 0) + return -1; + return 1; + case isl_yaml_mapping_key: + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return -1; + } + if (tok->type == ':') { + isl_token_free(tok); + if (update_state(s, isl_yaml_mapping_val) < 0) + return -1; + return 1; + } + isl_stream_error(s, tok, "expecting ':'"); + isl_stream_push_token(s, tok); + return -1; + case isl_yaml_mapping_val: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (!isl_stream_eat_if_available(s, ',')) + return 0; + if (update_state(s, isl_yaml_mapping_key) < 0) + return -1; + return 1; + } + tok = isl_stream_next_token(s); + if (!tok) + return 0; + indent = tok->col - 1; + isl_stream_push_token(s, tok); + if (indent < get_yaml_indent(s)) + return 0; + if (update_state(s, isl_yaml_mapping_key) < 0) + return -1; + return 1; + case isl_yaml_sequence_start: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (isl_stream_next_token_is(s, ']')) + return 0; + if (update_state(s, isl_yaml_sequence) < 0) + return -1; + return 1; + } + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return -1; + } + if (tok->type == '-') { + isl_token_free(tok); + if (update_state(s, isl_yaml_sequence) < 0) + return -1; + return 1; + } + isl_stream_error(s, tok, "expecting '-'"); + isl_stream_push_token(s, tok); + return 0; + case isl_yaml_sequence: + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) + return isl_stream_eat_if_available(s, ','); + tok = isl_stream_next_token(s); + if (!tok) + return 0; + indent = tok->col - 1; + if (indent < get_yaml_indent(s) || tok->type != '-') { + isl_stream_push_token(s, tok); + return 0; + } + isl_token_free(tok); + return 1; + default: + isl_die(s->ctx, isl_error_internal, + "unexpected state", return 0); + } +} + +/* Start reading a YAML mapping. + * Return 0 on success and -1 on error. + * + * If the first token on the stream is a '{' then we remove this token + * from the stream and keep track of the fact that the mapping + * is given in flow format. + * Otherwise, we assume the first token is the first key of the mapping and + * keep track of its indentation, but keep the token on the stream. + * In both cases, the next token we expect is the first key of the mapping. + */ +int isl_stream_yaml_read_start_mapping(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + + if (push_state(s, isl_yaml_mapping_key_start) < 0) + return -1; + + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return -1; + } + if (isl_token_get_type(tok) == '{') { + isl_token_free(tok); + return set_yaml_indent(s, ISL_YAML_INDENT_FLOW); + } + indent = tok->col - 1; + isl_stream_push_token(s, tok); + + return set_yaml_indent(s, indent); +} + +/* Finish reading a YAML mapping. + * Return 0 on success and -1 on error. + * + * If the mapping started with a '{', then we expect a '}' to close + * the mapping. + * Otherwise, we double-check that the next token (if any) + * has a smaller indentation than that of the current mapping. + */ +int isl_stream_yaml_read_end_mapping(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (isl_stream_eat(s, '}') < 0) + return -1; + return pop_state(s); + } + + tok = isl_stream_next_token(s); + if (!tok) + return pop_state(s); + + indent = tok->col - 1; + isl_stream_push_token(s, tok); + + if (indent >= get_yaml_indent(s)) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "mapping not finished", return -1); + + return pop_state(s); +} + +/* Start reading a YAML sequence. + * Return 0 on success and -1 on error. + * + * If the first token on the stream is a '[' then we remove this token + * from the stream and keep track of the fact that the sequence + * is given in flow format. + * Otherwise, we assume the first token is the dash that introduces + * the first element of the sequence and keep track of its indentation, + * but keep the token on the stream. + * In both cases, the next token we expect is the first element + * of the sequence. + */ +int isl_stream_yaml_read_start_sequence(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + + if (push_state(s, isl_yaml_sequence_start) < 0) + return -1; + + tok = isl_stream_next_token(s); + if (!tok) { + if (s->eof) + isl_stream_error(s, NULL, "unexpected EOF"); + return -1; + } + if (isl_token_get_type(tok) == '[') { + isl_token_free(tok); + return set_yaml_indent(s, ISL_YAML_INDENT_FLOW); + } + indent = tok->col - 1; + isl_stream_push_token(s, tok); + + return set_yaml_indent(s, indent); +} + +/* Finish reading a YAML sequence. + * Return 0 on success and -1 on error. + * + * If the sequence started with a '[', then we expect a ']' to close + * the sequence. + * Otherwise, we double-check that the next token (if any) + * is not a dash or that it has a smaller indentation than + * that of the current sequence. + */ +int isl_stream_yaml_read_end_sequence(__isl_keep isl_stream *s) +{ + struct isl_token *tok; + int indent; + int dash; + + if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) { + if (isl_stream_eat(s, ']') < 0) + return -1; + return pop_state(s); + } + + tok = isl_stream_next_token(s); + if (!tok) + return pop_state(s); + + indent = tok->col - 1; + dash = tok->type == '-'; + isl_stream_push_token(s, tok); + + if (indent >= get_yaml_indent(s) && dash) + isl_die(isl_stream_get_ctx(s), isl_error_invalid, + "sequence not finished", return -1); + + return pop_state(s); +} diff -Nru isl-0.12.2/isl_stream_private.h isl-0.15/isl_stream_private.h --- isl-0.12.2/isl_stream_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_stream_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -1,4 +1,69 @@ +#include #include +#include + +struct isl_token { + int type; + + unsigned int on_new_line : 1; + unsigned is_keyword : 1; + int line; + int col; + + union { + isl_int v; + char *s; + isl_map *map; + isl_pw_aff *pwaff; + } u; +}; struct isl_token *isl_token_new(isl_ctx *ctx, int line, int col, unsigned on_new_line); + +/* An input stream that may be either a file or a string. + * + * line and col are the line and column number of the next character (1-based). + * start_line and start_col are set by isl_stream_getc to point + * to the position of the returned character. + * last_line is the line number of the previous token. + * + * yaml_state and yaml_indent keep track of the currently active YAML + * elements. yaml_size is the size of these arrays, while yaml_depth + * is the number of elements currently in use. + * yaml_state and yaml_indent may be NULL if no YAML parsing is being + * performed. + * yaml_state keeps track of what is expected next at each level. + * yaml_indent keeps track of the indentation at each level, with + * ISL_YAML_INDENT_FLOW meaning that the element is in flow format + * (such that the indentation is not relevant). + */ +struct isl_stream { + struct isl_ctx *ctx; + FILE *file; + const char *str; + int line; + int col; + int start_line; + int start_col; + int last_line; + int eof; + + char *buffer; + size_t size; + size_t len; + int c; + int un[5]; + int n_un; + + struct isl_token *tokens[5]; + int n_token; + + struct isl_hash_table *keywords; + enum isl_token_type next_type; + + int yaml_depth; + int yaml_size; + enum isl_yaml_state *yaml_state; + int *yaml_indent; +}; diff -Nru isl-0.12.2/isl_tab.c isl-0.15/isl_tab.c --- isl-0.12.2/isl_tab.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_tab.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,19 +1,23 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven * Copyright 2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * 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 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include #include +#include #include "isl_map_private.h" #include "isl_tab.h" -#include +#include #include /* @@ -151,7 +155,7 @@ if (!var) return -1; tab->var = var; - tab->max_var += n_new; + tab->max_var = tab->n_var + n_new; } if (tab->mat->n_col < off + tab->n_col + n_new) { @@ -171,15 +175,6 @@ return 0; } -struct isl_tab *isl_tab_extend(struct isl_tab *tab, unsigned n_new) -{ - if (isl_tab_extend_cons(tab, n_new) >= 0) - return tab; - - isl_tab_free(tab); - return NULL; -} - static void free_undo_record(struct isl_tab_undo *undo) { switch (undo->type) { @@ -869,8 +864,7 @@ return NULL; } -struct isl_tab *isl_tab_add_sample(struct isl_tab *tab, - __isl_take isl_vec *sample) +int isl_tab_add_sample(struct isl_tab *tab, __isl_take isl_vec *sample) { if (!tab || !sample) goto error; @@ -893,11 +887,10 @@ tab->sample_index[tab->n_sample] = tab->n_sample; tab->n_sample++; - return tab; + return 0; error: isl_vec_free(sample); - isl_tab_free(tab); - return NULL; + return -1; } struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s) @@ -967,6 +960,22 @@ } } +/* Mark "tab" as a rational tableau. + * If it wasn't marked as a rational tableau already and if we may + * need to undo changes, then arrange for the marking to be undone + * during the undo. + */ +int isl_tab_mark_rational(struct isl_tab *tab) +{ + if (!tab) + return -1; + if (!tab->rational && tab->need_undo) + if (isl_tab_push(tab, isl_tab_undo_rational) < 0) + return -1; + tab->rational = 1; + return 0; +} + int isl_tab_mark_empty(struct isl_tab *tab) { if (!tab) @@ -1101,14 +1110,14 @@ int i, j; int sgn; int t; + isl_ctx *ctx; struct isl_mat *mat = tab->mat; struct isl_tab_var *var; unsigned off = 2 + tab->M; - if (tab->mat->ctx->abort) { - isl_ctx_set_error(tab->mat->ctx, isl_error_abort); + ctx = isl_tab_get_ctx(tab); + if (isl_ctx_next_operation(ctx) < 0) return -1; - } isl_int_swap(mat->row[row][0], mat->row[row][off + col]); sgn = isl_int_sgn(mat->row[row][0]); @@ -1419,7 +1428,8 @@ /* Return 1 if "var" can attain values <= -1. * Return 0 otherwise. * - * The sample value of "var" is assumed to be non-negative when the + * If the variable "var" is supposed to be non-negative (is_nonneg is set), + * then the sample value of "var" is assumed to be non-negative when the * the function is called. If 1 is returned then the constraint * is not redundant and the sample value is made non-negative again before * the function returns. @@ -1457,7 +1467,7 @@ do { find_pivot(tab, var, var, -1, &row, &col); if (row == var->index) { - if (restore_row(tab, var) < -1) + if (var->is_nonneg && restore_row(tab, var) < -1) return -1; return 1; } @@ -1653,19 +1663,75 @@ return r; } -/* Add a variable to the tableau and allocate a column for it. - * Return the index into the variable array "var". +/* Move the entries in tab->var up one position, starting at "first", + * creating room for an extra entry at position "first". + * Since some of the entries of tab->row_var and tab->col_var contain + * indices into this array, they have to be updated accordingly. + */ +static int var_insert_entry(struct isl_tab *tab, int first) +{ + int i; + + if (tab->n_var >= tab->max_var) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "not enough room for new variable", return -1); + if (first > tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "invalid initial position", return -1); + + for (i = tab->n_var - 1; i >= first; --i) { + tab->var[i + 1] = tab->var[i]; + if (tab->var[i + 1].is_row) + tab->row_var[tab->var[i + 1].index]++; + else + tab->col_var[tab->var[i + 1].index]++; + } + + tab->n_var++; + + return 0; +} + +/* Drop the entry at position "first" in tab->var, moving all + * subsequent entries down. + * Since some of the entries of tab->row_var and tab->col_var contain + * indices into this array, they have to be updated accordingly. */ -int isl_tab_allocate_var(struct isl_tab *tab) +static int var_drop_entry(struct isl_tab *tab, int first) +{ + int i; + + if (first >= tab->n_var) + isl_die(isl_tab_get_ctx(tab), isl_error_internal, + "invalid initial position", return -1); + + tab->n_var--; + + for (i = first; i < tab->n_var; ++i) { + tab->var[i] = tab->var[i + 1]; + if (tab->var[i + 1].is_row) + tab->row_var[tab->var[i].index]--; + else + tab->col_var[tab->var[i].index]--; + } + + return 0; +} + +/* Add a variable to the tableau at position "r" and allocate a column for it. + * Return the index into the variable array "var", i.e., "r", + * or -1 on error. + */ +int isl_tab_insert_var(struct isl_tab *tab, int r) { - int r; int i; unsigned off = 2 + tab->M; isl_assert(tab->mat->ctx, tab->n_col < tab->mat->n_col, return -1); - isl_assert(tab->mat->ctx, tab->n_var < tab->max_var, return -1); - r = tab->n_var; + if (var_insert_entry(tab, r) < 0) + return -1; + tab->var[r].index = tab->n_col; tab->var[r].is_row = 0; tab->var[r].is_nonneg = 0; @@ -1678,7 +1744,6 @@ for (i = 0; i < tab->n_row; ++i) isl_int_set_si(tab->mat->row[i][off + tab->n_col], 0); - tab->n_var++; tab->n_col++; if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->var[r]) < 0) return -1; @@ -1686,6 +1751,17 @@ return r; } +/* Add a variable to the tableau and allocate a column for it. + * Return the index into the variable array "var". + */ +int isl_tab_allocate_var(struct isl_tab *tab) +{ + if (!tab) + return -1; + + return isl_tab_insert_var(tab, tab->n_var); +} + /* Add a row to the tableau. The row is given as an affine combination * of the original variables and needs to be expressed in terms of the * column variables. @@ -1763,13 +1839,22 @@ return 0; } +/* Drop the variable in column "col" along with the column. + * The column is removed first because it may need to be moved + * into the last position and this process requires + * the contents of the col_var array in a state + * before the removal of the variable. + */ static int drop_col(struct isl_tab *tab, int col) { - isl_assert(tab->mat->ctx, tab->col_var[col] == tab->n_var - 1, return -1); + int var; + + var = tab->col_var[col]; if (col != tab->n_col - 1) swap_cols(tab, col, tab->n_col - 1); tab->n_col--; - tab->n_var--; + if (var_drop_entry(tab, var) < 0) + return -1; return 0; } @@ -1992,12 +2077,9 @@ var = &tab->con[r]; row = var->index; if (row_is_manifestly_zero(tab, row)) { - if (snap) { - if (isl_tab_rollback(tab, snap) < 0) - return -1; - } else - drop_row(tab, row); - return 0; + if (snap) + return isl_tab_rollback(tab, snap); + return drop_row(tab, row); } if (tab->bmap) { @@ -2555,37 +2637,37 @@ * even after the relaxation, so we need to restore it. * We therefore prefer to pivot a column up to a row, if possible. */ -struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con) +int isl_tab_relax(struct isl_tab *tab, int con) { struct isl_tab_var *var; - unsigned off = 2 + tab->M; if (!tab) - return NULL; + return -1; var = &tab->con[con]; if (var->is_row && (var->index < 0 || var->index < tab->n_redundant)) isl_die(tab->mat->ctx, isl_error_invalid, - "cannot relax redundant constraint", goto error); + "cannot relax redundant constraint", return -1); if (!var->is_row && (var->index < 0 || var->index < tab->n_dead)) isl_die(tab->mat->ctx, isl_error_invalid, - "cannot relax dead constraint", goto error); + "cannot relax dead constraint", return -1); if (!var->is_row && !max_is_manifestly_unbounded(tab, var)) if (to_row(tab, var, 1) < 0) - goto error; + return -1; if (!var->is_row && !min_is_manifestly_unbounded(tab, var)) if (to_row(tab, var, -1) < 0) - goto error; + return -1; if (var->is_row) { isl_int_add(tab->mat->row[var->index][1], tab->mat->row[var->index][1], tab->mat->row[var->index][0]); if (restore_row(tab, var) < 0) - goto error; + return -1; } else { int i; + unsigned off = 2 + tab->M; for (i = 0; i < tab->n_row; ++i) { if (isl_int_is_zero(tab->mat->row[i][off + var->index])) @@ -2597,12 +2679,67 @@ } if (isl_tab_push_var(tab, isl_tab_undo_relax, var) < 0) - goto error; + return -1; - return tab; -error: - isl_tab_free(tab); - return NULL; + return 0; +} + +/* Replace the variable v at position "pos" in the tableau "tab" + * by v' = v + shift. + * + * If the variable is in a column, then we first check if we can + * simply plug in v = v' - shift. The effect on a row with + * coefficient f/d for variable v is that the constant term c/d + * is replaced by (c - f * shift)/d. If shift is positive and + * f is negative for each row that needs to remain non-negative, + * then this is clearly safe. In other words, if the minimum of v + * is manifestly unbounded, then we can keep v in a column position. + * Otherwise, we can pivot it down to a row. + * Similarly, if shift is negative, we need to check if the maximum + * of is manifestly unbounded. + * + * If the variable is in a row (from the start or after pivoting), + * then the constant term c/d is replaced by (c + d * shift)/d. + */ +int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift) +{ + struct isl_tab_var *var; + + if (!tab) + return -1; + if (isl_int_is_zero(shift)) + return 0; + + var = &tab->var[pos]; + if (!var->is_row) { + if (isl_int_is_neg(shift)) { + if (!max_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, 1) < 0) + return -1; + } else { + if (!min_is_manifestly_unbounded(tab, var)) + if (to_row(tab, var, -1) < 0) + return -1; + } + } + + if (var->is_row) { + isl_int_addmul(tab->mat->row[var->index][1], + shift, tab->mat->row[var->index][0]); + } else { + int i; + unsigned off = 2 + tab->M; + + for (i = 0; i < tab->n_row; ++i) { + if (isl_int_is_zero(tab->mat->row[i][off + var->index])) + continue; + isl_int_submul(tab->mat->row[i][1], + shift, tab->mat->row[i][off + var->index]); + } + + } + + return 0; } /* Remove the sign constraint from constraint "con". @@ -3024,10 +3161,21 @@ return res; } +/* Is the constraint at position "con" marked as being redundant? + * If it is marked as representing an equality, then it is not + * considered to be redundant. + * Note that isl_tab_mark_redundant marks both the isl_tab_var as + * redundant and moves the corresponding row into the first + * tab->n_redundant positions (or removes the row, assigning it index -1), + * so the final test is actually redundant itself. + */ int isl_tab_is_redundant(struct isl_tab *tab, int con) { if (!tab) return -1; + if (con < 0 || con >= tab->n_con) + isl_die(isl_tab_get_ctx(tab), isl_error_invalid, + "position out of bounds", return -1); if (tab->con[con].is_zero) return 0; if (tab->con[con].is_redundant) @@ -3118,8 +3266,7 @@ case isl_tab_undo_allocate: if (undo->u.var_index >= 0) { isl_assert(tab->mat->ctx, !var->is_row, return -1); - drop_col(tab, var->index); - break; + return drop_col(tab, var->index); } if (!var->is_row) { if (!max_is_manifestly_unbounded(tab, var)) { @@ -3132,8 +3279,7 @@ if (to_row(tab, var, 0) < 0) return -1; } - drop_row(tab, var->index); - break; + return drop_row(tab, var->index); case isl_tab_undo_relax: return unrelax(tab, var); case isl_tab_undo_unrestrict: @@ -3229,6 +3375,9 @@ static int perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo) { switch (undo->type) { + case isl_tab_undo_rational: + tab->rational = 0; + break; case isl_tab_undo_empty: tab->empty = 0; break; diff -Nru isl-0.12.2/isl_tab.h isl-0.15/isl_tab.h --- isl-0.12.2/isl_tab.h 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/isl_tab.h 2015-06-02 09:28:10.000000000 +0000 @@ -14,6 +14,7 @@ #include #include #include +#include struct isl_tab_var { int index; @@ -28,6 +29,7 @@ enum isl_tab_undo_type { isl_tab_undo_bottom, + isl_tab_undo_rational, isl_tab_undo_empty, isl_tab_undo_nonneg, isl_tab_undo_redundant, @@ -204,7 +206,6 @@ isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, unsigned flags) WARN_UNUSED; -struct isl_tab *isl_tab_extend(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; int isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq) WARN_UNUSED; int isl_tab_add_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; @@ -235,7 +236,7 @@ struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab); int isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap) WARN_UNUSED; -struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con) WARN_UNUSED; +int isl_tab_relax(struct isl_tab *tab, int con) WARN_UNUSED; int isl_tab_select_facet(struct isl_tab *tab, int con) WARN_UNUSED; int isl_tab_unrestrict(struct isl_tab *tab, int con) WARN_UNUSED; @@ -267,6 +268,7 @@ struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i); int isl_tab_mark_redundant(struct isl_tab *tab, int row) WARN_UNUSED; +int isl_tab_mark_rational(struct isl_tab *tab) WARN_UNUSED; int isl_tab_mark_empty(struct isl_tab *tab) WARN_UNUSED; struct isl_tab *isl_tab_dup(struct isl_tab *tab); struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2); @@ -274,6 +276,7 @@ int isl_tab_allocate_con(struct isl_tab *tab) WARN_UNUSED; int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; int isl_tab_allocate_var(struct isl_tab *tab) WARN_UNUSED; +int isl_tab_insert_var(struct isl_tab *tab, int pos) WARN_UNUSED; int isl_tab_pivot(struct isl_tab *tab, int row, int col) WARN_UNUSED; int isl_tab_add_row(struct isl_tab *tab, isl_int *line) WARN_UNUSED; int isl_tab_row_is_redundant(struct isl_tab *tab, int row); @@ -287,7 +290,7 @@ int isl_tab_push_basis(struct isl_tab *tab) WARN_UNUSED; struct isl_tab *isl_tab_init_samples(struct isl_tab *tab) WARN_UNUSED; -struct isl_tab *isl_tab_add_sample(struct isl_tab *tab, +int isl_tab_add_sample(struct isl_tab *tab, __isl_take isl_vec *sample) WARN_UNUSED; struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s); int isl_tab_save_samples(struct isl_tab *tab) WARN_UNUSED; @@ -301,4 +304,6 @@ int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div, int (*add_ineq)(void *user, isl_int *), void *user); +int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift) WARN_UNUSED; + #endif diff -Nru isl-0.12.2/isl_tab_pip.c isl-0.15/isl_tab_pip.c --- isl-0.12.2/isl_tab_pip.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_tab_pip.c 2015-06-02 09:28:10.000000000 +0000 @@ -12,10 +12,11 @@ #include #include "isl_map_private.h" -#include +#include #include "isl_tab.h" #include "isl_sample.h" #include +#include #include #include #include @@ -563,9 +564,8 @@ static void sol_map_add_empty(struct isl_sol_map *sol, struct isl_basic_set *bset) { - if (!bset) + if (!bset || !sol->empty) goto error; - isl_assert(bset->ctx, sol->empty, goto error); sol->empty = isl_set_grow(sol->empty, 1); bset = isl_basic_set_simplify(bset); @@ -1799,7 +1799,8 @@ sample = isl_tab_get_sample_value(tab); - tab = isl_tab_add_sample(tab, sample); + if (isl_tab_add_sample(tab, sample) < 0) + goto error; } if (!tab->empty && isl_tab_rollback(tab, snap) < 0) @@ -2075,6 +2076,8 @@ { int i; struct isl_tab *tab; + unsigned n_var; + unsigned o_var; tab = isl_tab_alloc(bmap->ctx, 2 * bmap->n_eq + bmap->n_ineq + 1, isl_basic_map_total_dim(bmap), M); @@ -2100,16 +2103,16 @@ tab->var[i].is_nonneg = 1; tab->var[i].frozen = 1; } + o_var = 1 + tab->n_param; + n_var = tab->n_var - tab->n_param - tab->n_div; for (i = 0; i < bmap->n_eq; ++i) { if (max) - isl_seq_neg(bmap->eq[i] + 1 + tab->n_param, - bmap->eq[i] + 1 + tab->n_param, - tab->n_var - tab->n_param - tab->n_div); + isl_seq_neg(bmap->eq[i] + o_var, + bmap->eq[i] + o_var, n_var); tab = add_lexmin_valid_eq(tab, bmap->eq[i]); if (max) - isl_seq_neg(bmap->eq[i] + 1 + tab->n_param, - bmap->eq[i] + 1 + tab->n_param, - tab->n_var - tab->n_param - tab->n_div); + isl_seq_neg(bmap->eq[i] + o_var, + bmap->eq[i] + o_var, n_var); if (!tab || tab->empty) return tab; } @@ -2117,14 +2120,12 @@ goto error; for (i = 0; i < bmap->n_ineq; ++i) { if (max) - isl_seq_neg(bmap->ineq[i] + 1 + tab->n_param, - bmap->ineq[i] + 1 + tab->n_param, - tab->n_var - tab->n_param - tab->n_div); + isl_seq_neg(bmap->ineq[i] + o_var, + bmap->ineq[i] + o_var, n_var); tab = add_lexmin_ineq(tab, bmap->ineq[i]); if (max) - isl_seq_neg(bmap->ineq[i] + 1 + tab->n_param, - bmap->ineq[i] + 1 + tab->n_param, - tab->n_var - tab->n_param - tab->n_div); + isl_seq_neg(bmap->ineq[i] + o_var, + bmap->ineq[i] + o_var, n_var); if (!tab || tab->empty) return tab; } @@ -2149,6 +2150,13 @@ * * Perhaps it would also be useful to look at the number of constraints * that conflict with any given constraint. + * + * best is the best row so far (-1 when we have not found any row yet). + * best_r is the number of other rows made redundant by row best. + * When best is still -1, bset_r is meaningless, but it is initialized + * to some arbitrary value (0) anyway. Without this redundant initialization + * valgrind may warn about uninitialized memory accesses when isl + * is compiled with some versions of gcc. */ static int best_split(struct isl_tab *tab, struct isl_tab *context_tab) { @@ -2156,7 +2164,7 @@ int split; int row; int best = -1; - int best_r; + int best_r = 0; if (isl_tab_extend_cons(context_tab, 2) < 0) return -1; @@ -2781,7 +2789,7 @@ sample = isl_tab_sample(cgbr->tab); - if (isl_tab_rollback(cgbr->tab, snap) < 0) { + if (!sample || isl_tab_rollback(cgbr->tab, snap) < 0) { isl_vec_free(sample); return NULL; } @@ -2824,7 +2832,8 @@ return; } - cgbr->tab = isl_tab_add_sample(cgbr->tab, sample); + if (isl_tab_add_sample(cgbr->tab, sample) < 0) + goto error; return; error: @@ -3062,8 +3071,10 @@ * that is one or negative one, we use it to kill a column * in the main tableau. Otherwise, we discard the tentatively * added row. + * + * Return 0 on success and -1 on failure. */ -static void propagate_equalities(struct isl_context_gbr *cgbr, +static int propagate_equalities(struct isl_context_gbr *cgbr, struct isl_tab *tab, unsigned first) { int i; @@ -3113,22 +3124,20 @@ isl_vec_free(eq); - return; + return 0; error: isl_vec_free(eq); isl_tab_free(cgbr->tab); cgbr->tab = NULL; + return -1; } static int context_gbr_detect_equalities(struct isl_context *context, struct isl_tab *tab) { struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context; - struct isl_ctx *ctx; unsigned n_ineq; - ctx = cgbr->tab->mat->ctx; - if (!cgbr->cone) { struct isl_basic_set *bset = isl_tab_peek_bset(cgbr->tab); cgbr->cone = isl_tab_from_recession_cone(bset, 0); @@ -3145,8 +3154,9 @@ cgbr->tab = isl_tab_detect_equalities(cgbr->tab, cgbr->cone); if (!cgbr->tab) return -1; - if (cgbr->tab->bmap->n_ineq > n_ineq) - propagate_equalities(cgbr, tab, n_ineq); + if (cgbr->tab->bmap->n_ineq > n_ineq && + propagate_equalities(cgbr, tab, n_ineq) < 0) + return -1; return 0; error: @@ -3255,10 +3265,8 @@ struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save; if (!snap) goto error; - if (isl_tab_rollback(cgbr->tab, snap->tab_snap) < 0) { - isl_tab_free(cgbr->tab); - cgbr->tab = NULL; - } + if (isl_tab_rollback(cgbr->tab, snap->tab_snap) < 0) + goto error; if (snap->shifted_snap) { if (isl_tab_rollback(cgbr->shifted, snap->shifted_snap) < 0) @@ -3819,7 +3827,6 @@ sol_inc_level(sol); find_in_pos(sol, tab, ineq->el); tab->row_sign[split] = isl_tab_row_neg; - row = split; isl_seq_neg(ineq->el, ineq->el, ineq->size); isl_int_sub_ui(ineq->el[0], ineq->el[0], 1); if (!sol->error) @@ -4177,7 +4184,7 @@ int *first, int *second) { int i; - isl_ctx *ctx = isl_basic_map_get_ctx(bmap); + isl_ctx *ctx; struct isl_hash_table *table = NULL; struct isl_hash_table_entry *entry; struct isl_constraint_equal_info info; @@ -4281,13 +4288,11 @@ { int i, k; isl_basic_set *bset = NULL; - isl_ctx *ctx; isl_set *set = NULL; if (!dim || !var) goto error; - ctx = isl_space_get_ctx(dim); set = isl_set_alloc_space(isl_space_copy(dim), var->n_row, ISL_SET_DISJOINT); @@ -4614,7 +4619,7 @@ if (isl_basic_map_drop_inequality(bmap, list[i]) < 0) goto error; - bmap = isl_basic_map_add(bmap, isl_dim_in, 1); + bmap = isl_basic_map_add_dims(bmap, isl_dim_in, 1); bmap = isl_basic_map_extend_constraints(bmap, 0, 1); k = isl_basic_map_alloc_inequality(bmap); if (k < 0) @@ -4747,6 +4752,8 @@ static void sol_for_free(struct isl_sol_for *sol_for) { + if (!sol_for) + return; if (sol_for->sol.context) sol_for->sol.context->op->free(sol_for->sol.context); free(sol_for); @@ -5243,9 +5250,8 @@ static void sol_pma_add_empty(struct isl_sol_pma *sol, __isl_take isl_basic_set *bset) { - if (!bset) + if (!bset || !sol->empty) goto error; - isl_assert(bset->ctx, sol->empty, goto error); sol->empty = isl_set_grow(sol->empty, 1); bset = isl_basic_set_simplify(bset); @@ -5431,7 +5437,6 @@ int i; isl_aff *aff = NULL; isl_basic_set *bset = NULL; - isl_ctx *ctx; isl_pw_aff *paff = NULL; isl_space *pw_space; isl_local_space *ls = NULL; @@ -5439,7 +5444,6 @@ if (!space || !var) goto error; - ctx = isl_space_get_ctx(space); ls = isl_local_space_from_space(isl_space_copy(space)); pw_space = isl_space_copy(space); pw_space = isl_space_from_domain(pw_space); diff -Nru isl-0.12.2/isl_tarjan.c isl-0.15/isl_tarjan.c --- isl-0.12.2/isl_tarjan.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_tarjan.c 2015-06-02 09:28:10.000000000 +0000 @@ -58,8 +58,8 @@ /* Perform Tarjan's algorithm for computing the strongly connected components * in the graph with g->len nodes and with edges defined by "follows". */ -static int isl_tarjan_components(struct isl_tarjan_graph *g, int i, - int (*follows)(int i, int j, void *user), void *user) +static isl_stat isl_tarjan_components(struct isl_tarjan_graph *g, int i, + isl_bool (*follows)(int i, int j, void *user), void *user) { int j; @@ -70,7 +70,7 @@ g->stack[g->sp++] = i; for (j = g->len - 1; j >= 0; --j) { - int f; + isl_bool f; if (j == i) continue; @@ -81,7 +81,7 @@ f = follows(i, j, user); if (f < 0) - return -1; + return isl_stat_error; if (!f) continue; @@ -94,7 +94,7 @@ } if (g->node[i].index != g->node[i].min_index) - return 0; + return isl_stat_ok; do { j = g->stack[--g->sp]; @@ -103,7 +103,7 @@ } while (j != i); g->order[g->op++] = -1; - return 0; + return isl_stat_ok; } /* Decompose the graph with "len" nodes and edges defined by "follows" @@ -116,7 +116,7 @@ * in the result. */ struct isl_tarjan_graph *isl_tarjan_graph_init(isl_ctx *ctx, int len, - int (*follows)(int i, int j, void *user), void *user) + isl_bool (*follows)(int i, int j, void *user), void *user) { int i; struct isl_tarjan_graph *g = NULL; diff -Nru isl-0.12.2/isl_tarjan.h isl-0.15/isl_tarjan.h --- isl-0.12.2/isl_tarjan.h 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/isl_tarjan.h 2015-06-02 09:28:10.000000000 +0000 @@ -34,7 +34,7 @@ }; struct isl_tarjan_graph *isl_tarjan_graph_init(isl_ctx *ctx, int len, - int (*follows)(int i, int j, void *user), void *user); + isl_bool (*follows)(int i, int j, void *user), void *user); void isl_tarjan_graph_free(struct isl_tarjan_graph *g); #endif diff -Nru isl-0.12.2/isl_test.c isl-0.15/isl_test.c --- isl-0.12.2/isl_test.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_test.c 2015-06-11 10:46:17.000000000 +0000 @@ -1,10 +1,18 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2010 INRIA Saclay + * Copyright 2012-2013 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * 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 + * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, + * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #include @@ -15,16 +23,20 @@ #include #include #include -#include +#include #include +#include #include #include #include +#include #include #include #include #include #include +#include +#include #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array)) @@ -94,11 +106,30 @@ isl_pw_aff_free(pwaff); } +/* Check that we can read an isl_multi_val from "str" without errors. + */ +static int test_parse_multi_val(isl_ctx *ctx, const char *str) +{ + isl_multi_val *mv; + + mv = isl_multi_val_read_from_str(ctx, str); + isl_multi_val_free(mv); + + return mv ? 0 : -1; +} + int test_parse(struct isl_ctx *ctx) { isl_map *map, *map2; const char *str, *str2; + if (test_parse_multi_val(ctx, "{ A[B[2] -> C[5, 7]] }") < 0) + return -1; + if (test_parse_multi_val(ctx, "[n] -> { [2] }") < 0) + return -1; + if (test_parse_multi_val(ctx, "{ A[4, infty, NaN, -1/2, 2/3] }") < 0) + return -1; + str = "{ [i] -> [-i] }"; map = isl_map_read_from_str(ctx, str); assert(map); @@ -218,15 +249,40 @@ "{ [a] -> [b] : a != 5 or b = 5 }") < 0) return -1; + if (test_parse_map_equal(ctx, "{ [a] -> [a - 1 : a > 0] }", + "{ [a] -> [a - 1] : a > 0 }") < 0) + return -1; + if (test_parse_map_equal(ctx, + "{ [a] -> [a - 1 : a > 0; a : a <= 0] }", + "{ [a] -> [a - 1] : a > 0; [a] -> [a] : a <= 0 }") < 0) + return -1; + if (test_parse_map_equal(ctx, + "{ [a] -> [(a) * 2 : a >= 0; 0 : a < 0] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }") < 0) + return -1; + if (test_parse_map_equal(ctx, + "{ [a] -> [(a * 2) : a >= 0; 0 : a < 0] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }") < 0) + return -1; + if (test_parse_map_equal(ctx, + "{ [a] -> [(a * 2 : a >= 0); 0 : a < 0] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }") < 0) + return -1; + if (test_parse_map_equal(ctx, + "{ [a] -> [(a * 2 : a >= 0; 0 : a < 0)] }", + "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }") < 0) + return -1; + return 0; } -void test_read(struct isl_ctx *ctx) +static int test_read(isl_ctx *ctx) { char *filename; FILE *input; - struct isl_basic_set *bset1, *bset2; + isl_basic_set *bset1, *bset2; const char *str = "{[y]: Exists ( alpha : 2alpha = y)}"; + int equal; filename = get_filename(ctx, "set", "omega"); assert(filename); @@ -236,44 +292,70 @@ bset1 = isl_basic_set_read_from_file(ctx, input); bset2 = isl_basic_set_read_from_str(ctx, str); - assert(isl_basic_set_is_equal(bset1, bset2) == 1); + equal = isl_basic_set_is_equal(bset1, bset2); isl_basic_set_free(bset1); isl_basic_set_free(bset2); free(filename); fclose(input); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "read sets not equal", return -1); + + return 0; } -void test_bounded(struct isl_ctx *ctx) +static int test_bounded(isl_ctx *ctx) { isl_set *set; int bounded; set = isl_set_read_from_str(ctx, "[n] -> {[i] : 0 <= i <= n }"); bounded = isl_set_is_bounded(set); - assert(bounded); isl_set_free(set); + if (bounded < 0) + return -1; + if (!bounded) + isl_die(ctx, isl_error_unknown, + "set not considered bounded", return -1); + set = isl_set_read_from_str(ctx, "{[n, i] : 0 <= i <= n }"); bounded = isl_set_is_bounded(set); assert(!bounded); isl_set_free(set); + if (bounded < 0) + return -1; + if (bounded) + isl_die(ctx, isl_error_unknown, + "set considered bounded", return -1); + set = isl_set_read_from_str(ctx, "[n] -> {[i] : i <= n }"); bounded = isl_set_is_bounded(set); - assert(!bounded); isl_set_free(set); + + if (bounded < 0) + return -1; + if (bounded) + isl_die(ctx, isl_error_unknown, + "set considered bounded", return -1); + + return 0; } /* Construct the basic set { [i] : 5 <= i <= N } */ -void test_construction(struct isl_ctx *ctx) +static int test_construction(isl_ctx *ctx) { isl_int v; isl_space *dim; isl_local_space *ls; - struct isl_basic_set *bset; - struct isl_constraint *c; + isl_basic_set *bset; + isl_constraint *c; isl_int_init(v); @@ -281,14 +363,14 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_inequality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_param, 0, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_inequality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -5); @@ -299,37 +381,54 @@ isl_basic_set_free(bset); isl_int_clear(v); + + return 0; } -void test_dim(struct isl_ctx *ctx) +static int test_dim(isl_ctx *ctx) { const char *str; isl_map *map1, *map2; + int equal; map1 = isl_map_read_from_str(ctx, "[n] -> { [i] -> [j] : exists (a = [i/10] : i - 10a <= n ) }"); map1 = isl_map_add_dims(map1, isl_dim_in, 1); map2 = isl_map_read_from_str(ctx, "[n] -> { [i,k] -> [j] : exists (a = [i/10] : i - 10a <= n ) }"); - assert(isl_map_is_equal(map1, map2)); + equal = isl_map_is_equal(map1, map2); isl_map_free(map2); map1 = isl_map_project_out(map1, isl_dim_in, 0, 1); map2 = isl_map_read_from_str(ctx, "[n] -> { [i] -> [j] : n >= 0 }"); - assert(isl_map_is_equal(map1, map2)); + if (equal >= 0 && equal) + equal = isl_map_is_equal(map1, map2); isl_map_free(map1); isl_map_free(map2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + str = "[n] -> { [i] -> [] : exists a : 0 <= i <= n and i = 2 a }"; map1 = isl_map_read_from_str(ctx, str); str = "{ [i] -> [j] : exists a : 0 <= i <= j and i = 2 a }"; map2 = isl_map_read_from_str(ctx, str); map1 = isl_map_move_dims(map1, isl_dim_out, 0, isl_dim_param, 0, 1); - assert(isl_map_is_equal(map1, map2)); - + equal = isl_map_is_equal(map1, map2); isl_map_free(map1); isl_map_free(map2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + + return 0; } struct { @@ -375,6 +474,15 @@ { &isl_val_2exp, "1", "2" }, { &isl_val_2exp, "2", "4" }, { &isl_val_2exp, "3", "8" }, + { &isl_val_inv, "1", "1" }, + { &isl_val_inv, "2", "1/2" }, + { &isl_val_inv, "1/2", "2" }, + { &isl_val_inv, "-2", "-1/2" }, + { &isl_val_inv, "-1/2", "-2" }, + { &isl_val_inv, "0", "NaN" }, + { &isl_val_inv, "NaN", "NaN" }, + { &isl_val_inv, "infty", "0" }, + { &isl_val_inv, "-infty", "0" }, }; /* Perform some basic tests of unary operations on isl_val objects. @@ -566,7 +674,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_constant(c, v); isl_int_set_si(v, 1); @@ -575,7 +683,7 @@ isl_constraint_set_coefficient(c, isl_dim_set, 1, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_constant(c, v); isl_int_set_si(v, -1); @@ -595,7 +703,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_constant(c, v); isl_int_set_si(v, -1); @@ -604,7 +712,7 @@ isl_constraint_set_coefficient(c, isl_dim_set, 1, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_constant(c, v); isl_int_set_si(v, 1); @@ -624,7 +732,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_constant(c, v); isl_int_set_si(v, -1); @@ -633,7 +741,7 @@ isl_constraint_set_coefficient(c, isl_dim_set, 1, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -3); isl_constraint_set_constant(c, v); isl_int_set_si(v, 1); @@ -653,7 +761,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 2); isl_constraint_set_constant(c, v); isl_int_set_si(v, -1); @@ -662,7 +770,7 @@ isl_constraint_set_coefficient(c, isl_dim_set, 1, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_constant(c, v); isl_int_set_si(v, 1); @@ -682,14 +790,14 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, 3); isl_constraint_set_coefficient(c, isl_dim_set, 2, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -3); @@ -707,14 +815,14 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, 6); isl_constraint_set_coefficient(c, isl_dim_set, 2, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -3); @@ -741,7 +849,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -3); @@ -766,7 +874,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -3); @@ -777,7 +885,7 @@ isl_constraint_set_coefficient(c, isl_dim_set, 4, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, 1); @@ -800,7 +908,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -1); @@ -809,7 +917,7 @@ isl_constraint_set_coefficient(c, isl_dim_set, 2, v); bset = isl_basic_set_add_constraint(bset, c); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, -1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, 3); @@ -832,7 +940,7 @@ bset = isl_basic_set_universe(isl_space_copy(dim)); ls = isl_local_space_from_space(dim); - c = isl_equality_alloc(isl_local_space_copy(ls)); + c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); isl_int_set_si(v, 1); isl_constraint_set_coefficient(c, isl_dim_set, 0, v); isl_int_set_si(v, -2); @@ -909,10 +1017,12 @@ fclose(input); } -void test_application(struct isl_ctx *ctx) +static int test_application(isl_ctx *ctx) { test_application_case(ctx, "application"); test_application_case(ctx, "application2"); + + return 0; } void test_affine_hull_case(struct isl_ctx *ctx, const char *name) @@ -1023,10 +1133,27 @@ fclose(input); } -void test_convex_hull_algo(struct isl_ctx *ctx, int convex) +struct { + const char *set; + const char *hull; +} convex_hull_tests[] = { + { "{ [i0, i1, i2] : (i2 = 1 and i0 = 0 and i1 >= 0) or " + "(i0 = 1 and i1 = 0 and i2 = 1) or " + "(i0 = 0 and i1 = 0 and i2 = 0) }", + "{ [i0, i1, i2] : i0 >= 0 and i2 >= i0 and i2 <= 1 and i1 >= 0 }" }, + { "[n] -> { [i0, i1, i0] : i0 <= -4 + n; " + "[i0, i0, i2] : n = 6 and i0 >= 0 and i2 <= 7 - i0 and " + "i2 <= 5 and i2 >= 4; " + "[3, i1, 3] : n = 5 and i1 <= 2 and i1 >= 0 }", + "[n] -> { [i0, i1, i2] : i2 <= -1 + n and 2i2 <= -6 + 3n - i0 and " + "i2 <= 5 + i0 and i2 >= i0 }" }, + { "{ [x, y] : 3y <= 2x and y >= -2 + 2x and 2y >= 2 - x }", + "{ [x, y] : 1 = 0 }" }, +}; + +static int test_convex_hull_algo(isl_ctx *ctx, int convex) { - const char *str1, *str2; - isl_set *set1, *set2; + int i; int orig_convex = ctx->opt->convex; ctx->opt->convex = convex; @@ -1047,24 +1174,36 @@ test_convex_hull_case(ctx, "convex14"); test_convex_hull_case(ctx, "convex15"); - str1 = "{ [i0, i1, i2] : (i2 = 1 and i0 = 0 and i1 >= 0) or " - "(i0 = 1 and i1 = 0 and i2 = 1) or " - "(i0 = 0 and i1 = 0 and i2 = 0) }"; - str2 = "{ [i0, i1, i2] : i0 >= 0 and i2 >= i0 and i2 <= 1 and i1 >= 0 }"; - set1 = isl_set_read_from_str(ctx, str1); - set2 = isl_set_read_from_str(ctx, str2); - set1 = isl_set_from_basic_set(isl_set_convex_hull(set1)); - assert(isl_set_is_equal(set1, set2)); - isl_set_free(set1); - isl_set_free(set2); + for (i = 0; i < ARRAY_SIZE(convex_hull_tests); ++i) { + isl_set *set1, *set2; + int equal; + + set1 = isl_set_read_from_str(ctx, convex_hull_tests[i].set); + set2 = isl_set_read_from_str(ctx, convex_hull_tests[i].hull); + set1 = isl_set_from_basic_set(isl_set_convex_hull(set1)); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected convex hull", return -1); + } ctx->opt->convex = orig_convex; + + return 0; } -void test_convex_hull(struct isl_ctx *ctx) +static int test_convex_hull(isl_ctx *ctx) { - test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM); - test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP); + if (test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM) < 0) + return -1; + if (test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP) < 0) + return -1; + return 0; } void test_gist_case(struct isl_ctx *ctx, const char *name) @@ -1094,11 +1233,60 @@ fclose(input); } +struct { + const char *set; + const char *context; + const char *gist; +} gist_tests[] = { + { "{ [a, b, c] : a <= 15 and a >= 1 }", + "{ [a, b, c] : exists (e0 = floor((-1 + a)/16): a >= 1 and " + "c <= 30 and 32e0 >= -62 + 2a + 2b - c and b >= 0) }", + "{ [a, b, c] : a <= 15 }" }, + { "{ : }", "{ : 1 = 0 }", "{ : }" }, + { "{ : 1 = 0 }", "{ : 1 = 0 }", "{ : }" }, + { "[M] -> { [x] : exists (e0 = floor((-2 + x)/3): 3e0 = -2 + x) }", + "[M] -> { [3M] }" , "[M] -> { [x] : 1 = 0 }" }, + { "{ [m, n, a, b] : a <= 2147 + n }", + "{ [m, n, a, b] : (m >= 1 and n >= 1 and a <= 2148 - m and " + "b <= 2148 - n and b >= 0 and b >= 2149 - n - a) or " + "(n >= 1 and a >= 0 and b <= 2148 - n - a and " + "b >= 0) }", + "{ [m, n, ku, kl] }" }, +}; + static int test_gist(struct isl_ctx *ctx) { + int i; const char *str; isl_basic_set *bset1, *bset2; isl_map *map1, *map2; + int equal; + + for (i = 0; i < ARRAY_SIZE(gist_tests); ++i) { + int equal_input; + isl_set *set1, *set2, *copy; + + set1 = isl_set_read_from_str(ctx, gist_tests[i].set); + set2 = isl_set_read_from_str(ctx, gist_tests[i].context); + copy = isl_set_copy(set1); + set1 = isl_set_gist(set1, set2); + set2 = isl_set_read_from_str(ctx, gist_tests[i].gist); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + set1 = isl_set_read_from_str(ctx, gist_tests[i].set); + equal_input = isl_set_is_equal(set1, copy); + isl_set_free(set1); + isl_set_free(copy); + if (equal < 0 || equal_input < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect gist result", return -1); + if (!equal_input) + isl_die(ctx, isl_error_unknown, + "gist modified input", return -1); + } test_gist_case(ctx, "gist1"); @@ -1178,31 +1366,45 @@ return 0; } +/* Inputs for coalescing tests with unbounded wrapping. + * "str" is a string representation of the input set. + * "single_disjunct" is set if we expect the result to consist of + * a single disjunct. + */ +struct { + int single_disjunct; + const char *str; +} coalesce_unbounded_tests[] = { + { 1, "{ [x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and " + "-x - y + 1 >= 0 and -3 <= z <= 3;" + "[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and " + "x-z + 20 >= 0 and x+z + 20 >= 0 and " + "-10 <= y <= 0}" }, + { 1, "{ [x,y] : 0 <= x,y <= 10; [5,y]: 4 <= y <= 11 }" }, + { 1, "{ [x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }" }, + { 1, "{ [x,y] : 0 <= x <= 10 and 0 >= y >= -1 and x+y >= 0; [0,1] }" }, + { 1, "{ [x,y] : (0 <= x,y <= 4) or (2 <= x,y <= 5 and x + y <= 9) }" }, +}; + +/* Test the functionality of isl_set_coalesce with the bounded wrapping + * option turned off. + */ int test_coalesce_unbounded_wrapping(isl_ctx *ctx) { + int i; int r = 0; int bounded; bounded = isl_options_get_coalesce_bounded_wrapping(ctx); isl_options_set_coalesce_bounded_wrapping(ctx, 0); - if (test_coalesce_set(ctx, - "{[x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and " - "-x - y + 1 >= 0 and -3 <= z <= 3;" - "[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and " - "x-z + 20 >= 0 and x+z + 20 >= 0 and " - "-10 <= y <= 0}", 1) < 0) - goto error; - if (test_coalesce_set(ctx, - "{[x,y] : 0 <= x,y <= 10; [5,y]: 4 <=y <= 11}", 1) < 0) - goto error; - if (test_coalesce_set(ctx, - "{[x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }", 1) < 0) - goto error; - - if (0) { -error: + for (i = 0; i < ARRAY_SIZE(coalesce_unbounded_tests); ++i) { + const char *str = coalesce_unbounded_tests[i].str; + int check_one = coalesce_unbounded_tests[i].single_disjunct; + if (test_coalesce_set(ctx, str, check_one) >= 0) + continue; r = -1; + break; } isl_options_set_coalesce_bounded_wrapping(ctx, bounded); @@ -1328,11 +1530,114 @@ "[x,0] : 3 <= x <= 5 }" }, { 0, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + y <= 4; " "[x,0] : 3 <= x <= 4 }" }, - { 1 , "{ [i0, i1] : i0 <= 122 and i0 >= 1 and 128i1 >= -249 + i0 and " + { 1, "{ [i0, i1] : i0 <= 122 and i0 >= 1 and 128i1 >= -249 + i0 and " "i1 <= 0; " "[i0, 0] : i0 >= 123 and i0 <= 124 }" }, + { 1, "{ [0,0]; [1,1] }" }, + { 1, "[n] -> { [k] : 16k <= -1 + n and k >= 1; [0] : n >= 2 }" }, + { 1, "{ [k, ii, k - ii] : ii >= -6 + k and ii <= 6 and ii >= 1 and " + "ii <= k;" + "[k, 0, k] : k <= 6 and k >= 1 }" }, + { 1, "{ [i,j] : i = 4 j and 0 <= i <= 100;" + "[i,j] : 1 <= i <= 100 and i >= 4j + 1 and i <= 4j + 2 }" }, + { 1, "{ [x,y] : x % 2 = 0 and y % 2 = 0; [x,x] : x % 2 = 0 }" }, + { 1, "[n] -> { [1] : n >= 0;" + "[x] : exists (e0 = floor((x)/2): x >= 2 and " + "2e0 >= -1 + x and 2e0 <= x and 2e0 <= n) }" }, + { 1, "[n] -> { [x, y] : exists (e0 = floor((x)/2), e1 = floor((y)/3): " + "3e1 = y and x >= 2 and 2e0 >= -1 + x and " + "2e0 <= x and 2e0 <= n);" + "[1, y] : exists (e0 = floor((y)/3): 3e0 = y and " + "n >= 0) }" }, + { 1, "[t1] -> { [i0] : (exists (e0 = floor((63t1)/64): " + "128e0 >= -134 + 127t1 and t1 >= 2 and " + "64e0 <= 63t1 and 64e0 >= -63 + 63t1)) or " + "t1 = 1 }" }, + { 1, "{ [i, i] : exists (e0 = floor((1 + 2i)/3): 3e0 <= 2i and " + "3e0 >= -1 + 2i and i <= 9 and i >= 1);" + "[0, 0] }" }, + { 1, "{ [t1] : exists (e0 = floor((-11 + t1)/2): 2e0 = -11 + t1 and " + "t1 >= 13 and t1 <= 16);" + "[t1] : t1 <= 15 and t1 >= 12 }" }, + { 1, "{ [x,y] : x = 3y and 0 <= y <= 2; [-3,-1] }" }, + { 1, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-2] }" }, + { 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-2,-2] }" }, + { 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-1] }" }, + { 1, "{ [i] : exists j : i = 4 j and 0 <= i <= 100;" + "[i] : exists j : 1 <= i <= 100 and i >= 4j + 1 and " + "i <= 4j + 2 }" }, + { 1, "{ [c0] : (exists (e0 : c0 - 1 <= 3e0 <= c0)) or " + "(exists (e0 : 3e0 = -2 + c0)) }" }, + { 0, "[n, b0, t0] -> " + "{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : " + "(exists (e0 = floor((-32b0 + i4)/1048576), " + "e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and " + "n <= 2147483647 and b0 <= 32767 and b0 >= 0 and " + "32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 >= 8 + n and " + "3i4 <= -96 + 3t0 + i0 and 3i4 >= -95 - n + 3t0 + i0 and " + "i8 >= -157 + i0 - 4i4 and i8 >= 0 and " + "i8 <= -33 + i0 - 4i4 and 3i8 <= -91 + 4n - i0)) or " + "(exists (e0 = floor((-32b0 + i4)/1048576), " + "e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and " + "n <= 2147483647 and b0 <= 32767 and b0 >= 0 and " + "32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 <= 7 + n and " + "4i4 <= -3 + i0 and 3i4 <= -96 + 3t0 + i0 and " + "3i4 >= -95 - n + 3t0 + i0 and i8 >= -157 + i0 - 4i4 and " + "i8 >= 0 and i8 <= -4 + i0 - 3i4 and i8 <= -41 + i0));" + "[i0, i1, i2, i3, 0, i5, i6, i7, i8, i9, i10, i11, i12] : " + "(exists (e0 = floor((i8)/32): b0 = 0 and 32e0 = i8 and " + "n <= 2147483647 and t0 <= 31 and t0 >= 0 and i0 >= 11 and " + "i0 >= 96 - 3t0 and i0 <= 95 + n - 3t0 and i0 <= 7 + n and " + "i8 >= -40 + i0 and i8 <= -10 + i0)) }" }, + { 0, "{ [i0, i1, i2] : " + "(exists (e0, e1 = floor((i0)/32), e2 = floor((i1)/32): " + "32e1 = i0 and 32e2 = i1 and i1 >= -31 + i0 and " + "i1 <= 31 + i0 and i2 >= -30 + i0 and i2 >= -30 + i1 and " + "32e0 >= -30 + i0 and 32e0 >= -30 + i1 and " + "32e0 >= -31 + i2 and 32e0 <= 30 + i2 and 32e0 <= 31 + i1 and " + "32e0 <= 31 + i0)) or " + "i0 >= 0 }" }, }; +/* A specialized coalescing test case that would result + * in a segmentation fault or a failed assertion in earlier versions of isl. + */ +static int test_coalesce_special(struct isl_ctx *ctx) +{ + const char *str; + isl_map *map1, *map2; + + str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[1, o1]] : " + "(y = 201 and o1 <= 239 and o1 >= 212) or " + "(exists (e0 = [(y)/3]: 3e0 = y and y <= 198 and y >= 3 and " + "o1 <= 239 and o1 >= 212)) or " + "(exists (e0 = [(y)/3]: 3e0 = y and y <= 201 and y >= 3 and " + "o1 <= 241 and o1 >= 240));" + "[S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[0, o1]] : " + "(y = 2 and o1 <= 241 and o1 >= 212) or " + "(exists (e0 = [(-2 + y)/3]: 3e0 = -2 + y and y <= 200 and " + "y >= 5 and o1 <= 241 and o1 >= 212)) }"; + map1 = isl_map_read_from_str(ctx, str); + map1 = isl_map_align_divs(map1); + map1 = isl_map_coalesce(map1); + str = "[y] -> { [S_L220_OUT[] -> T7[]] -> " + "[[S_L309_IN[] -> T11[]] -> ce_imag2[o0, o1]] : " + "exists (e0 = [(-1 - y + o0)/3]: 3e0 = -1 - y + o0 and " + "y <= 201 and o0 <= 2 and o1 >= 212 and o1 <= 241 and " + "o0 >= 3 - y and o0 <= -2 + y and o0 >= 0) }"; + map2 = isl_map_read_from_str(ctx, str); + map2 = isl_map_union(map2, map1); + map2 = isl_map_align_divs(map2); + map2 = isl_map_coalesce(map2); + isl_map_free(map2); + if (!map2) + return -1; + + return 0; +} + /* Test the functionality of isl_set_coalesce. * That is, check that the output is always equal to the input * and in some cases that the result consists of a single disjunct. @@ -1350,11 +1655,13 @@ if (test_coalesce_unbounded_wrapping(ctx) < 0) return -1; + if (test_coalesce_special(ctx) < 0) + return -1; return 0; } -void test_closure(struct isl_ctx *ctx) +static int test_closure(isl_ctx *ctx) { const char *str; isl_set *dom; @@ -1591,17 +1898,28 @@ map = isl_map_transitive_closure(map, NULL); assert(map); isl_map_free(map); + + return 0; } -void test_lex(struct isl_ctx *ctx) +static int test_lex(struct isl_ctx *ctx) { isl_space *dim; isl_map *map; + int empty; dim = isl_space_set_alloc(ctx, 0, 0); map = isl_map_lex_le(dim); - assert(!isl_map_is_empty(map)); + empty = isl_map_is_empty(map); isl_map_free(map); + + if (empty < 0) + return -1; + if (empty) + isl_die(ctx, isl_error_unknown, + "expecting non-empty result", return -1); + + return 0; } static int test_lexmin(struct isl_ctx *ctx) @@ -1759,7 +2077,7 @@ isl_map *may; }; -static int collect_must_may(__isl_take isl_map *dep, int must, +static isl_stat collect_must_may(__isl_take isl_map *dep, int must, void *dep_user, void *user) { struct must_may *mm = (struct must_may *)user; @@ -1769,7 +2087,7 @@ else mm->may = isl_map_union(mm->may, dep); - return 0; + return isl_stat_ok; } static int common_space(void *first, void *second) @@ -1806,7 +2124,7 @@ return 0; } -void test_dep(struct isl_ctx *ctx) +static int test_dep(struct isl_ctx *ctx) { const char *str; isl_space *dim; @@ -1992,89 +2310,135 @@ isl_map_free(mm.must); isl_map_free(mm.may); isl_flow_free(flow); + + return 0; } -int test_sv(isl_ctx *ctx) +/* Check that the dependence analysis proceeds without errors. + * Earlier versions of isl would break down during the analysis + * due to the use of the wrong spaces. + */ +static int test_flow(isl_ctx *ctx) { const char *str; - isl_map *map; - isl_union_map *umap; - int sv; + isl_union_map *access, *schedule; + isl_union_map *must_dep, *may_dep; + int r; + + str = "{ S0[j] -> i[]; S1[j,i] -> i[]; S2[] -> i[]; S3[] -> i[] }"; + access = isl_union_map_read_from_str(ctx, str); + str = "{ S0[j] -> [0,j,0,0] : 0 <= j < 10; " + "S1[j,i] -> [0,j,1,i] : 0 <= j < i < 10; " + "S2[] -> [1,0,0,0]; " + "S3[] -> [-1,0,0,0] }"; + schedule = isl_union_map_read_from_str(ctx, str); + r = isl_union_map_compute_flow(access, isl_union_map_copy(access), + isl_union_map_copy(access), schedule, + &must_dep, &may_dep, NULL, NULL); + isl_union_map_free(may_dep); + isl_union_map_free(must_dep); - str = "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 9 }"; - map = isl_map_read_from_str(ctx, str); - sv = isl_map_is_single_valued(map); - isl_map_free(map); - if (sv < 0) - return -1; - if (!sv) - isl_die(ctx, isl_error_internal, - "map not detected as single valued", return -1); + return r; +} - str = "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 10 }"; - map = isl_map_read_from_str(ctx, str); - sv = isl_map_is_single_valued(map); - isl_map_free(map); - if (sv < 0) - return -1; - if (sv) - isl_die(ctx, isl_error_internal, - "map detected as single valued", return -1); +struct { + const char *map; + int sv; +} sv_tests[] = { + { "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 9 }", 1 }, + { "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 10 }", 0 }, + { "{ [i] -> [3*floor(i/2) + 5*floor(i/3)] }", 1 }, + { "{ S1[i] -> [i] : 0 <= i <= 9; S2[i] -> [i] : 0 <= i <= 9 }", 1 }, + { "{ [i] -> S1[i] : 0 <= i <= 9; [i] -> S2[i] : 0 <= i <= 9 }", 0 }, + { "{ A[i] -> [i]; B[i] -> [i]; B[i] -> [i + 1] }", 0 }, + { "{ A[i] -> [i]; B[i] -> [i] : i < 0; B[i] -> [i + 1] : i > 0 }", 1 }, + { "{ A[i] -> [i]; B[i] -> A[i] : i < 0; B[i] -> [i + 1] : i > 0 }", 1 }, + { "{ A[i] -> [i]; B[i] -> [j] : i - 1 <= j <= i }", 0 }, +}; - str = "{ S1[i] -> [i] : 0 <= i <= 9; S2[i] -> [i] : 0 <= i <= 9 }"; - umap = isl_union_map_read_from_str(ctx, str); - sv = isl_union_map_is_single_valued(umap); - isl_union_map_free(umap); - if (sv < 0) - return -1; - if (!sv) - isl_die(ctx, isl_error_internal, - "map not detected as single valued", return -1); +int test_sv(isl_ctx *ctx) +{ + isl_union_map *umap; + int i; + int sv; - str = "{ [i] -> S1[i] : 0 <= i <= 9; [i] -> S2[i] : 0 <= i <= 9 }"; - umap = isl_union_map_read_from_str(ctx, str); - sv = isl_union_map_is_single_valued(umap); - isl_union_map_free(umap); - if (sv < 0) - return -1; - if (sv) - isl_die(ctx, isl_error_internal, - "map detected as single valued", return -1); + for (i = 0; i < ARRAY_SIZE(sv_tests); ++i) { + umap = isl_union_map_read_from_str(ctx, sv_tests[i].map); + sv = isl_union_map_is_single_valued(umap); + isl_union_map_free(umap); + if (sv < 0) + return -1; + if (sv_tests[i].sv && !sv) + isl_die(ctx, isl_error_internal, + "map not detected as single valued", return -1); + if (!sv_tests[i].sv && sv) + isl_die(ctx, isl_error_internal, + "map detected as single valued", return -1); + } return 0; } -void test_bijective_case(struct isl_ctx *ctx, const char *str, int bijective) +struct { + const char *str; + int bijective; +} bijective_tests[] = { + { "[N,M]->{[i,j] -> [i]}", 0 }, + { "[N,M]->{[i,j] -> [i] : j=i}", 1 }, + { "[N,M]->{[i,j] -> [i] : j=0}", 1 }, + { "[N,M]->{[i,j] -> [i] : j=N}", 1 }, + { "[N,M]->{[i,j] -> [j,i]}", 1 }, + { "[N,M]->{[i,j] -> [i+j]}", 0 }, + { "[N,M]->{[i,j] -> []}", 0 }, + { "[N,M]->{[i,j] -> [i,j,N]}", 1 }, + { "[N,M]->{[i,j] -> [2i]}", 0 }, + { "[N,M]->{[i,j] -> [i,i]}", 0 }, + { "[N,M]->{[i,j] -> [2i,i]}", 0 }, + { "[N,M]->{[i,j] -> [2i,j]}", 1 }, + { "[N,M]->{[i,j] -> [x,y] : 2x=i & y =j}", 1 }, +}; + +static int test_bijective(struct isl_ctx *ctx) { isl_map *map; + int i; + int bijective; - map = isl_map_read_from_str(ctx, str); - if (bijective) - assert(isl_map_is_bijective(map)); - else - assert(!isl_map_is_bijective(map)); - isl_map_free(map); -} + for (i = 0; i < ARRAY_SIZE(bijective_tests); ++i) { + map = isl_map_read_from_str(ctx, bijective_tests[i].str); + bijective = isl_map_is_bijective(map); + isl_map_free(map); + if (bijective < 0) + return -1; + if (bijective_tests[i].bijective && !bijective) + isl_die(ctx, isl_error_internal, + "map not detected as bijective", return -1); + if (!bijective_tests[i].bijective && bijective) + isl_die(ctx, isl_error_internal, + "map detected as bijective", return -1); + } -void test_bijective(struct isl_ctx *ctx) -{ - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i]}", 0); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i] : j=i}", 1); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i] : j=0}", 1); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i] : j=N}", 1); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [j,i]}", 1); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i+j]}", 0); - test_bijective_case(ctx, "[N,M]->{[i,j] -> []}", 0); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i,j,N]}", 1); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [2i]}", 0); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [i,i]}", 0); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [2i,i]}", 0); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [2i,j]}", 1); - test_bijective_case(ctx, "[N,M]->{[i,j] -> [x,y] : 2x=i & y =j}", 1); + return 0; } +/* Inputs for isl_pw_qpolynomial_gist tests. + * "pwqp" is the input, "set" is the context and "gist" is the expected result. + */ +struct { + const char *pwqp; + const char *set; + const char *gist; +} pwqp_gist_tests[] = { + { "{ [i] -> i }", "{ [k] : exists a : k = 2a }", "{ [i] -> i }" }, + { "{ [i] -> i + [ (i + [i/3])/2 ] }", "{ [10] }", "{ [i] -> 16 }" }, + { "{ [i] -> ([(i)/2]) }", "{ [k] : exists a : k = 2a+1 }", + "{ [i] -> -1/2 + 1/2 * i }" }, + { "{ [i] -> i^2 : i != 0 }", "{ [i] : i != 0 }", "{ [i] -> i^2 }" }, +}; + static int test_pwqp(struct isl_ctx *ctx) { + int i; const char *str; isl_set *set; isl_pw_qpolynomial *pwqp1, *pwqp2; @@ -2095,47 +2459,24 @@ isl_pw_qpolynomial_free(pwqp1); - str = "{ [i] -> i }"; - pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); - str = "{ [k] : exists a : k = 2a }"; - set = isl_set_read_from_str(ctx, str); - pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set); - str = "{ [i] -> i }"; - pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); - - pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); - - assert(isl_pw_qpolynomial_is_zero(pwqp1)); - - isl_pw_qpolynomial_free(pwqp1); - - str = "{ [i] -> i + [ (i + [i/3])/2 ] }"; - pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); - str = "{ [10] }"; - set = isl_set_read_from_str(ctx, str); - pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set); - str = "{ [i] -> 16 }"; - pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); - - pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); - - assert(isl_pw_qpolynomial_is_zero(pwqp1)); - - isl_pw_qpolynomial_free(pwqp1); - - str = "{ [i] -> ([(i)/2]) }"; - pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); - str = "{ [k] : exists a : k = 2a+1 }"; - set = isl_set_read_from_str(ctx, str); - pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set); - str = "{ [i] -> -1/2 + 1/2 * i }"; - pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); - - pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); - - assert(isl_pw_qpolynomial_is_zero(pwqp1)); + for (i = 0; i < ARRAY_SIZE(pwqp_gist_tests); ++i) { + str = pwqp_gist_tests[i].pwqp; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + str = pwqp_gist_tests[i].set; + set = isl_set_read_from_str(ctx, str); + pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set); + str = pwqp_gist_tests[i].gist; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + equal = isl_pw_qpolynomial_is_zero(pwqp1); + isl_pw_qpolynomial_free(pwqp1); - isl_pw_qpolynomial_free(pwqp1); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } str = "{ [i] -> ([([i/2] + [i/2])/5]) }"; pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); @@ -2198,7 +2539,7 @@ return 0; } -void test_split_periods(isl_ctx *ctx) +static int test_split_periods(isl_ctx *ctx) { const char *str; isl_pw_qpolynomial *pwqp; @@ -2209,16 +2550,21 @@ pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); pwqp = isl_pw_qpolynomial_split_periods(pwqp, 2); - assert(pwqp); isl_pw_qpolynomial_free(pwqp); + + if (!pwqp) + return -1; + + return 0; } -void test_union(isl_ctx *ctx) +static int test_union(isl_ctx *ctx) { const char *str; isl_union_set *uset1, *uset2; isl_union_map *umap1, *umap2; + int equal; str = "{ [i] : 0 <= i <= 1 }"; uset1 = isl_union_set_read_from_str(ctx, str); @@ -2226,11 +2572,17 @@ umap1 = isl_union_map_read_from_str(ctx, str); umap2 = isl_union_set_lex_gt_union_set(isl_union_set_copy(uset1), uset1); - assert(isl_union_map_is_equal(umap1, umap2)); + equal = isl_union_map_is_equal(umap1, umap2); isl_union_map_free(umap1); isl_union_map_free(umap2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "union maps not equal", + return -1); + str = "{ A[i] -> B[i]; B[i] -> C[i]; A[0] -> C[1] }"; umap1 = isl_union_map_read_from_str(ctx, str); str = "{ A[i]; B[i] }"; @@ -2238,32 +2590,85 @@ uset2 = isl_union_map_domain(umap1); - assert(isl_union_set_is_equal(uset1, uset2)); + equal = isl_union_set_is_equal(uset1, uset2); isl_union_set_free(uset1); isl_union_set_free(uset2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "union sets not equal", + return -1); + + return 0; } -void test_bound(isl_ctx *ctx) +/* Check that computing a bound of a non-zero polynomial over an unbounded + * domain does not produce a rational value. + * Ideally, we want the value to be infinity, but we accept NaN for now. + * We certainly do not want to obtain the value zero. + */ +static int test_bound_unbounded_domain(isl_ctx *ctx) { const char *str; + isl_set *dom; + isl_point *pnt; isl_pw_qpolynomial *pwqp; isl_pw_qpolynomial_fold *pwf; + isl_val *v; + int is_rat; - str = "{ [[a, b, c, d] -> [e]] -> 0 }"; + str = "{ [m,n] -> -m * n }"; pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL); - assert(isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in) == 4); + dom = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf)); + pnt = isl_set_sample_point(dom); + v = isl_pw_qpolynomial_fold_eval(pwf, pnt); + is_rat = isl_val_is_rat(v); + isl_val_free(v); + + if (is_rat < 0) + return -1; + if (is_rat) + isl_die(ctx, isl_error_unknown, + "unexpected rational value", return -1); + + return 0; +} + +static int test_bound(isl_ctx *ctx) +{ + const char *str; + unsigned dim; + isl_pw_qpolynomial *pwqp; + isl_pw_qpolynomial_fold *pwf; + + if (test_bound_unbounded_domain(ctx) < 0) + return -1; + + str = "{ [[a, b, c, d] -> [e]] -> 0 }"; + pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); + pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL); + dim = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in); isl_pw_qpolynomial_fold_free(pwf); + if (dim != 4) + isl_die(ctx, isl_error_unknown, "unexpected input dimension", + return -1); str = "{ [[x]->[x]] -> 1 : exists a : x = 2 a }"; pwqp = isl_pw_qpolynomial_read_from_str(ctx, str); pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL); - assert(isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in) == 1); + dim = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in); isl_pw_qpolynomial_fold_free(pwf); + if (dim != 1) + isl_die(ctx, isl_error_unknown, "unexpected input dimension", + return -1); + + return 0; } -void test_lift(isl_ctx *ctx) +static int test_lift(isl_ctx *ctx) { const char *str; isl_basic_map *bmap; @@ -2275,6 +2680,8 @@ bmap = isl_basic_map_from_range(bset); bset = isl_basic_map_domain(bmap); isl_basic_set_free(bset); + + return 0; } struct { @@ -2350,6 +2757,7 @@ { int i; isl_union_map *umap1, *umap2; + isl_union_pw_multi_aff *upma1, *upma2; isl_union_set *uset; int equal; @@ -2371,6 +2779,24 @@ "incorrect subtract domain result", return -1); } + for (i = 0; i < ARRAY_SIZE(subtract_domain_tests); ++i) { + upma1 = isl_union_pw_multi_aff_read_from_str(ctx, + subtract_domain_tests[i].minuend); + uset = isl_union_set_read_from_str(ctx, + subtract_domain_tests[i].subtrahend); + upma2 = isl_union_pw_multi_aff_read_from_str(ctx, + subtract_domain_tests[i].difference); + upma1 = isl_union_pw_multi_aff_subtract_domain(upma1, uset); + equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2); + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(upma2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect subtract domain result", return -1); + } + return 0; } @@ -2416,7 +2842,7 @@ return 0; } -static int check_injective(__isl_take isl_map *map, void *user) +static isl_stat check_injective(__isl_take isl_map *map, void *user) { int *injective = user; @@ -2424,9 +2850,9 @@ isl_map_free(map); if (*injective < 0 || !*injective) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } int test_one_schedule(isl_ctx *ctx, const char *d, const char *w, @@ -2437,7 +2863,7 @@ isl_union_map *W, *R, *S; isl_union_map *empty; isl_union_map *dep_raw, *dep_war, *dep_waw, *dep; - isl_union_map *validity, *proximity; + isl_union_map *validity, *proximity, *coincidence; isl_union_map *schedule; isl_union_map *test; isl_union_set *delta; @@ -2445,6 +2871,7 @@ isl_set *delta_set; isl_set *slice; isl_set *origin; + isl_schedule_constraints *sc; isl_schedule *sched; int is_nonneg, is_parallel, is_tilable, is_injection, is_complete; @@ -2470,10 +2897,14 @@ dep = isl_union_map_union(dep_waw, dep_war); dep = isl_union_map_union(dep, dep_raw); validity = isl_union_map_copy(dep); + coincidence = isl_union_map_copy(dep); proximity = isl_union_map_copy(dep); - sched = isl_union_set_compute_schedule(isl_union_set_copy(D), - validity, proximity); + sc = isl_schedule_constraints_on_domain(isl_union_set_copy(D)); + sc = isl_schedule_constraints_set_validity(sc, validity); + sc = isl_schedule_constraints_set_coincidence(sc, coincidence); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + sched = isl_schedule_constraints_compute_schedule(sc); schedule = isl_schedule_get_map(sched); isl_schedule_free(sched); isl_union_map_free(W); @@ -2552,25 +2983,47 @@ return 0; } -static __isl_give isl_union_map *compute_schedule(isl_ctx *ctx, - const char *domain, const char *validity, const char *proximity) +/* Compute a schedule for the given instance set, validity constraints, + * proximity constraints and context and return a corresponding union map + * representation. + */ +static __isl_give isl_union_map *compute_schedule_with_context(isl_ctx *ctx, + const char *domain, const char *validity, const char *proximity, + const char *context) { + isl_set *con; isl_union_set *dom; isl_union_map *dep; isl_union_map *prox; + isl_schedule_constraints *sc; isl_schedule *schedule; isl_union_map *sched; + con = isl_set_read_from_str(ctx, context); dom = isl_union_set_read_from_str(ctx, domain); dep = isl_union_map_read_from_str(ctx, validity); prox = isl_union_map_read_from_str(ctx, proximity); - schedule = isl_union_set_compute_schedule(dom, dep, prox); + sc = isl_schedule_constraints_on_domain(dom); + sc = isl_schedule_constraints_set_context(sc, con); + sc = isl_schedule_constraints_set_validity(sc, dep); + sc = isl_schedule_constraints_set_proximity(sc, prox); + schedule = isl_schedule_constraints_compute_schedule(sc); sched = isl_schedule_get_map(schedule); isl_schedule_free(schedule); return sched; } +/* Compute a schedule for the given instance set, validity constraints and + * proximity constraints and return a corresponding union map representation. + */ +static __isl_give isl_union_map *compute_schedule(isl_ctx *ctx, + const char *domain, const char *validity, const char *proximity) +{ + return compute_schedule_with_context(ctx, domain, validity, proximity, + "{ : }"); +} + /* Check that a schedule can be constructed on the given domain * with the given validity and proximity constraints. */ @@ -2617,6 +3070,7 @@ const char *str; isl_union_set *D; isl_union_map *validity, *proximity; + isl_schedule_constraints *sc; isl_schedule *sched; isl_union_map *map1, *map2; isl_band_list *list; @@ -2626,7 +3080,10 @@ D = isl_union_set_read_from_str(ctx, str); validity = isl_union_map_empty(isl_union_set_get_space(D)); proximity = isl_union_map_copy(validity); - sched = isl_union_set_compute_schedule(D, validity, proximity); + sc = isl_schedule_constraints_on_domain(D); + sc = isl_schedule_constraints_set_validity(sc, validity); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + sched = isl_schedule_constraints_compute_schedule(sc); map1 = isl_schedule_get_map(sched); list = isl_schedule_get_band_forest(sched); isl_band_list_free(list); @@ -2646,6 +3103,319 @@ return 0; } +/* Check that conditional validity constraints are also taken into + * account across bands. + * In particular, try to make sure that live ranges D[1,0]->C[2,1] and + * D[2,0]->C[3,0] are not local in the outer band of the generated schedule + * and then check that the adjacent order constraint C[2,1]->D[2,0] + * is enforced by the rest of the schedule. + */ +static int test_special_conditional_schedule_constraints(isl_ctx *ctx) +{ + const char *str; + isl_union_set *domain; + isl_union_map *validity, *proximity, *condition; + isl_union_map *sink, *source, *dep; + isl_schedule_constraints *sc; + isl_schedule *schedule; + isl_union_access_info *access; + isl_union_flow *flow; + int empty; + + str = "[n] -> { C[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k; " + "A[k] : k >= 1 and k <= -1 + n; " + "B[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k; " + "D[k, i] : k <= -1 + n and i >= 0 and i <= -1 + k }"; + domain = isl_union_set_read_from_str(ctx, str); + sc = isl_schedule_constraints_on_domain(domain); + str = "[n] -> { D[k, i] -> C[1 + k, k - i] : " + "k <= -2 + n and i >= 1 and i <= -1 + k; " + "D[k, i] -> C[1 + k, i] : " + "k <= -2 + n and i >= 1 and i <= -1 + k; " + "D[k, 0] -> C[1 + k, k] : k >= 1 and k <= -2 + n; " + "D[k, 0] -> C[1 + k, 0] : k >= 1 and k <= -2 + n }"; + validity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_validity(sc, validity); + str = "[n] -> { C[k, i] -> D[k, i] : " + "0 <= i <= -1 + k and k <= -1 + n }"; + proximity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_proximity(sc, proximity); + str = "[n] -> { [D[k, i] -> a[]] -> [C[1 + k, k - i] -> b[]] : " + "i <= -1 + k and i >= 1 and k <= -2 + n; " + "[B[k, i] -> c[]] -> [B[k, 1 + i] -> c[]] : " + "k <= -1 + n and i >= 0 and i <= -2 + k }"; + condition = isl_union_map_read_from_str(ctx, str); + str = "[n] -> { [B[k, i] -> e[]] -> [D[k, i] -> a[]] : " + "i >= 0 and i <= -1 + k and k <= -1 + n; " + "[C[k, i] -> b[]] -> [D[k', -1 + k - i] -> a[]] : " + "i >= 0 and i <= -1 + k and k <= -1 + n and " + "k' <= -1 + n and k' >= k - i and k' >= 1 + k; " + "[C[k, i] -> b[]] -> [D[k, -1 + k - i] -> a[]] : " + "i >= 0 and i <= -1 + k and k <= -1 + n; " + "[B[k, i] -> c[]] -> [A[k'] -> d[]] : " + "k <= -1 + n and i >= 0 and i <= -1 + k and " + "k' >= 1 and k' <= -1 + n and k' >= 1 + k }"; + validity = isl_union_map_read_from_str(ctx, str); + sc = isl_schedule_constraints_set_conditional_validity(sc, condition, + validity); + schedule = isl_schedule_constraints_compute_schedule(sc); + str = "{ D[2,0] -> [] }"; + sink = isl_union_map_read_from_str(ctx, str); + access = isl_union_access_info_from_sink(sink); + str = "{ C[2,1] -> [] }"; + source = isl_union_map_read_from_str(ctx, str); + access = isl_union_access_info_set_must_source(access, source); + access = isl_union_access_info_set_schedule(access, schedule); + flow = isl_union_access_info_compute_flow(access); + dep = isl_union_flow_get_must_dependence(flow); + isl_union_flow_free(flow); + empty = isl_union_map_is_empty(dep); + isl_union_map_free(dep); + + if (empty < 0) + return -1; + if (empty) + isl_die(ctx, isl_error_unknown, + "conditional validity not respected", return -1); + + return 0; +} + +/* Input for testing of schedule construction based on + * conditional constraints. + * + * domain is the iteration domain + * flow are the flow dependences, which determine the validity and + * proximity constraints + * condition are the conditions on the conditional validity constraints + * conditional_validity are the conditional validity constraints + * outer_band_n is the expected number of members in the outer band + */ +struct { + const char *domain; + const char *flow; + const char *condition; + const char *conditional_validity; + int outer_band_n; +} live_range_tests[] = { + /* Contrived example that illustrates that we need to keep + * track of tagged condition dependences and + * tagged conditional validity dependences + * in isl_sched_edge separately. + * In particular, the conditional validity constraints on A + * cannot be satisfied, + * but they can be ignored because there are no corresponding + * condition constraints. However, we do have an additional + * conditional validity constraint that maps to the same + * dependence relation + * as the condition constraint on B. If we did not make a distinction + * between tagged condition and tagged conditional validity + * dependences, then we + * could end up treating this shared dependence as an condition + * constraint on A, forcing a localization of the conditions, + * which is impossible. + */ + { "{ S[i] : 0 <= 1 < 100; T[i] : 0 <= 1 < 100 }", + "{ S[i] -> S[i+1] : 0 <= i < 99 }", + "{ [S[i] -> B[]] -> [S[i+1] -> B[]] : 0 <= i < 99 }", + "{ [S[i] -> A[]] -> [T[i'] -> A[]] : 0 <= i', i < 100 and i != i';" + "[T[i] -> A[]] -> [S[i'] -> A[]] : 0 <= i', i < 100 and i != i';" + "[S[i] -> A[]] -> [S[i+1] -> A[]] : 0 <= i < 99 }", + 1 + }, + /* TACO 2013 Fig. 7 */ + { "[n] -> { S1[i,j] : 0 <= i,j < n; S2[i,j] : 0 <= i,j < n }", + "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" + "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { [S1[i,j] -> t[]] -> [S2[i,j] -> t[]] : 0 <= i,j < n;" + "[S2[i,j] -> x1[]] -> [S2[i,j+1] -> x1[]] : " + "0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { [S2[i,j] -> t[]] -> [S1[i,j'] -> t[]] : " + "0 <= i < n and 0 <= j < j' < n;" + "[S2[i,j] -> t[]] -> [S1[i',j'] -> t[]] : " + "0 <= i < i' < n and 0 <= j,j' < n;" + "[S2[i,j] -> x1[]] -> [S2[i,j'] -> x1[]] : " + "0 <= i,j,j' < n and j < j' }", + 2 + }, + /* TACO 2013 Fig. 7, without tags */ + { "[n] -> { S1[i,j] : 0 <= i,j < n; S2[i,j] : 0 <= i,j < n }", + "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" + "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { S1[i,j] -> S2[i,j] : 0 <= i,j < n;" + "S2[i,j] -> S2[i,j+1] : 0 <= i < n and 0 <= j < n - 1 }", + "[n] -> { S2[i,j] -> S1[i,j'] : 0 <= i < n and 0 <= j < j' < n;" + "S2[i,j] -> S1[i',j'] : 0 <= i < i' < n and 0 <= j,j' < n;" + "S2[i,j] -> S2[i,j'] : 0 <= i,j,j' < n and j < j' }", + 1 + }, + /* TACO 2013 Fig. 12 */ + { "{ S1[i,0] : 0 <= i <= 1; S2[i,j] : 0 <= i <= 1 and 1 <= j <= 2;" + "S3[i,3] : 0 <= i <= 1 }", + "{ S1[i,0] -> S2[i,1] : 0 <= i <= 1;" + "S2[i,1] -> S2[i,2] : 0 <= i <= 1;" + "S2[i,2] -> S3[i,3] : 0 <= i <= 1 }", + "{ [S1[i,0]->t[]] -> [S2[i,1]->t[]] : 0 <= i <= 1;" + "[S2[i,1]->t[]] -> [S2[i,2]->t[]] : 0 <= i <= 1;" + "[S2[i,2]->t[]] -> [S3[i,3]->t[]] : 0 <= i <= 1 }", + "{ [S2[i,1]->t[]] -> [S2[i,2]->t[]] : 0 <= i <= 1;" + "[S2[0,j]->t[]] -> [S2[1,j']->t[]] : 1 <= j,j' <= 2;" + "[S2[0,j]->t[]] -> [S1[1,0]->t[]] : 1 <= j <= 2;" + "[S3[0,3]->t[]] -> [S2[1,j]->t[]] : 1 <= j <= 2;" + "[S3[0,3]->t[]] -> [S1[1,0]->t[]] }", + 1 + } +}; + +/* Test schedule construction based on conditional constraints. + * In particular, check the number of members in the outer band node + * as an indication of whether tiling is possible or not. + */ +static int test_conditional_schedule_constraints(isl_ctx *ctx) +{ + int i; + isl_union_set *domain; + isl_union_map *condition; + isl_union_map *flow; + isl_union_map *validity; + isl_schedule_constraints *sc; + isl_schedule *schedule; + isl_schedule_node *node; + int n_member; + + if (test_special_conditional_schedule_constraints(ctx) < 0) + return -1; + + for (i = 0; i < ARRAY_SIZE(live_range_tests); ++i) { + domain = isl_union_set_read_from_str(ctx, + live_range_tests[i].domain); + flow = isl_union_map_read_from_str(ctx, + live_range_tests[i].flow); + condition = isl_union_map_read_from_str(ctx, + live_range_tests[i].condition); + validity = isl_union_map_read_from_str(ctx, + live_range_tests[i].conditional_validity); + sc = isl_schedule_constraints_on_domain(domain); + sc = isl_schedule_constraints_set_validity(sc, + isl_union_map_copy(flow)); + sc = isl_schedule_constraints_set_proximity(sc, flow); + sc = isl_schedule_constraints_set_conditional_validity(sc, + condition, validity); + schedule = isl_schedule_constraints_compute_schedule(sc); + node = isl_schedule_get_root(schedule); + while (node && + isl_schedule_node_get_type(node) != isl_schedule_node_band) + node = isl_schedule_node_first_child(node); + n_member = isl_schedule_node_band_n_member(node); + isl_schedule_node_free(node); + isl_schedule_free(schedule); + + if (!schedule) + return -1; + if (n_member != live_range_tests[i].outer_band_n) + isl_die(ctx, isl_error_unknown, + "unexpected number of members in outer band", + return -1); + } + return 0; +} + +/* Check that the schedule computed for the given instance set and + * dependence relation strongly satisfies the dependences. + * In particular, check that no instance is scheduled before + * or together with an instance on which it depends. + * Earlier versions of isl would produce a schedule that + * only weakly satisfies the dependences. + */ +static int test_strongly_satisfying_schedule(isl_ctx *ctx) +{ + const char *domain, *dep; + isl_union_map *D, *schedule; + isl_map *map, *ge; + int empty; + + domain = "{ B[i0, i1] : 0 <= i0 <= 1 and 0 <= i1 <= 11; " + "A[i0] : 0 <= i0 <= 1 }"; + dep = "{ B[i0, i1] -> B[i0, 1 + i1] : 0 <= i0 <= 1 and 0 <= i1 <= 10; " + "B[0, 11] -> A[1]; A[i0] -> B[i0, 0] : 0 <= i0 <= 1 }"; + schedule = compute_schedule(ctx, domain, dep, dep); + D = isl_union_map_read_from_str(ctx, dep); + D = isl_union_map_apply_domain(D, isl_union_map_copy(schedule)); + D = isl_union_map_apply_range(D, schedule); + map = isl_map_from_union_map(D); + ge = isl_map_lex_ge(isl_space_domain(isl_map_get_space(map))); + map = isl_map_intersect(map, ge); + empty = isl_map_is_empty(map); + isl_map_free(map); + + if (empty < 0) + return -1; + if (!empty) + isl_die(ctx, isl_error_unknown, + "dependences not strongly satisfied", return -1); + + return 0; +} + +/* Compute a schedule for input where the instance set constraints + * conflict with the context constraints. + * Earlier versions of isl did not properly handle this situation. + */ +static int test_conflicting_context_schedule(isl_ctx *ctx) +{ + isl_union_map *schedule; + const char *domain, *context; + + domain = "[n] -> { A[] : n >= 0 }"; + context = "[n] -> { : n < 0 }"; + schedule = compute_schedule_with_context(ctx, + domain, "{}", "{}", context); + isl_union_map_free(schedule); + + if (!schedule) + return -1; + + return 0; +} + +/* Check that the dependence carrying step is not confused by + * a bound on the coefficient size. + * In particular, force the scheduler to move to a dependence carrying + * step by demanding outer coincidence and bound the size of + * the coefficients. Earlier versions of isl would take this + * bound into account while carrying dependences, breaking + * fundamental assumptions. + */ +static int test_bounded_coefficients_schedule(isl_ctx *ctx) +{ + const char *domain, *dep; + isl_union_set *I; + isl_union_map *D; + isl_schedule_constraints *sc; + isl_schedule *schedule; + + domain = "{ C[i0, i1] : 2 <= i0 <= 3999 and 0 <= i1 <= -1 + i0 }"; + dep = "{ C[i0, i1] -> C[i0, 1 + i1] : i0 <= 3999 and i1 >= 0 and " + "i1 <= -2 + i0; " + "C[i0, -1 + i0] -> C[1 + i0, 0] : i0 <= 3998 and i0 >= 1 }"; + I = isl_union_set_read_from_str(ctx, domain); + D = isl_union_map_read_from_str(ctx, dep); + sc = isl_schedule_constraints_on_domain(I); + sc = isl_schedule_constraints_set_validity(sc, isl_union_map_copy(D)); + sc = isl_schedule_constraints_set_coincidence(sc, D); + isl_options_set_schedule_outer_coincidence(ctx, 1); + isl_options_set_schedule_max_coefficient(ctx, 20); + schedule = isl_schedule_constraints_compute_schedule(sc); + isl_options_set_schedule_max_coefficient(ctx, -1); + isl_options_set_schedule_outer_coincidence(ctx, 0); + isl_schedule_free(schedule); + + if (!schedule) + return -1; + + return 0; +} + int test_schedule(isl_ctx *ctx) { const char *D, *W, *R, *V, *P, *S; @@ -2814,10 +3584,10 @@ "S_0[j, k] -> A[k] : j <= -1 + n and j >= 0 and " "k <= -1 + n and k >= 0 }"; S = "[n] -> { S_0[j, k] -> [2, j, k] }"; - ctx->opt->schedule_outer_zero_distance = 1; + ctx->opt->schedule_outer_coincidence = 1; if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0) return -1; - ctx->opt->schedule_outer_zero_distance = 0; + ctx->opt->schedule_outer_coincidence = 0; D = "{Stmt_for_body24[i0, i1, i2, i3]:" "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 6 and i2 >= 2 and " @@ -2923,6 +3693,30 @@ return -1; ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + /* Check that we allow schedule rows that are only non-trivial + * on some full-dimensional domains. + */ + D = "{ S1[j] : 0 <= j <= 1; S0[]; S2[k] : 0 <= k <= 1 }"; + V = "{ S0[] -> S1[j] : 0 <= j <= 1; S2[0] -> S0[];" + "S1[j] -> S2[1] : 0 <= j <= 1 }"; + P = "{}"; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER; + if (test_has_schedule(ctx, D, V, P) < 0) + return -1; + ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL; + + if (test_conditional_schedule_constraints(ctx) < 0) + return -1; + + if (test_strongly_satisfying_schedule(ctx) < 0) + return -1; + + if (test_conflicting_context_schedule(ctx) < 0) + return -1; + + if (test_bounded_coefficients_schedule(ctx) < 0) + return -1; + return 0; } @@ -3005,6 +3799,137 @@ return 0; } +struct { + __isl_give isl_aff *(*fn)(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +} aff_bin_op[] = { + ['+'] = { &isl_aff_add }, + ['-'] = { &isl_aff_sub }, + ['*'] = { &isl_aff_mul }, + ['/'] = { &isl_aff_div }, +}; + +struct { + const char *arg1; + unsigned char op; + const char *arg2; + const char *res; +} aff_bin_tests[] = { + { "{ [i] -> [i] }", '+', "{ [i] -> [i] }", + "{ [i] -> [2i] }" }, + { "{ [i] -> [i] }", '-', "{ [i] -> [i] }", + "{ [i] -> [0] }" }, + { "{ [i] -> [i] }", '*', "{ [i] -> [2] }", + "{ [i] -> [2i] }" }, + { "{ [i] -> [2] }", '*', "{ [i] -> [i] }", + "{ [i] -> [2i] }" }, + { "{ [i] -> [i] }", '/', "{ [i] -> [2] }", + "{ [i] -> [i/2] }" }, + { "{ [i] -> [2i] }", '/', "{ [i] -> [2] }", + "{ [i] -> [i] }" }, + { "{ [i] -> [i] }", '+', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '-', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '*', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [2] }", '*', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [i] }", '/', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [2] }", '/', "{ [i] -> [NaN] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '+', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '-', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '*', "{ [i] -> [2] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '*', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '/', "{ [i] -> [2] }", + "{ [i] -> [NaN] }" }, + { "{ [i] -> [NaN] }", '/', "{ [i] -> [i] }", + "{ [i] -> [NaN] }" }, +}; + +/* Perform some basic tests of binary operations on isl_aff objects. + */ +static int test_bin_aff(isl_ctx *ctx) +{ + int i; + isl_aff *aff1, *aff2, *res; + __isl_give isl_aff *(*fn)(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + int ok; + + for (i = 0; i < ARRAY_SIZE(aff_bin_tests); ++i) { + aff1 = isl_aff_read_from_str(ctx, aff_bin_tests[i].arg1); + aff2 = isl_aff_read_from_str(ctx, aff_bin_tests[i].arg2); + res = isl_aff_read_from_str(ctx, aff_bin_tests[i].res); + fn = aff_bin_op[aff_bin_tests[i].op].fn; + aff1 = fn(aff1, aff2); + if (isl_aff_is_nan(res)) + ok = isl_aff_is_nan(aff1); + else + ok = isl_aff_plain_is_equal(aff1, res); + isl_aff_free(aff1); + isl_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + +struct { + __isl_give isl_union_pw_multi_aff *(*fn)( + __isl_take isl_union_pw_multi_aff *upma1, + __isl_take isl_union_pw_multi_aff *upma2); + const char *arg1; + const char *arg2; + const char *res; +} upma_bin_tests[] = { + { &isl_union_pw_multi_aff_add, "{ A[] -> [0]; B[0] -> [1] }", + "{ B[x] -> [2] : x >= 0 }", "{ B[0] -> [3] }" }, + { &isl_union_pw_multi_aff_union_add, "{ A[] -> [0]; B[0] -> [1] }", + "{ B[x] -> [2] : x >= 0 }", + "{ A[] -> [0]; B[0] -> [3]; B[x] -> [2] : x >= 1 }" }, +}; + +/* Perform some basic tests of binary operations on + * isl_union_pw_multi_aff objects. + */ +static int test_bin_upma(isl_ctx *ctx) +{ + int i; + isl_union_pw_multi_aff *upma1, *upma2, *res; + int ok; + + for (i = 0; i < ARRAY_SIZE(upma_bin_tests); ++i) { + upma1 = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_tests[i].arg1); + upma2 = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_tests[i].arg2); + res = isl_union_pw_multi_aff_read_from_str(ctx, + upma_bin_tests[i].res); + upma1 = upma_bin_tests[i].fn(upma1, upma2); + ok = isl_union_pw_multi_aff_plain_is_equal(upma1, res); + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(res); + if (ok < 0) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + return 0; +} + int test_aff(isl_ctx *ctx) { const char *str; @@ -3014,6 +3939,11 @@ isl_aff *aff; int zero, equal; + if (test_bin_aff(ctx) < 0) + return -1; + if (test_bin_upma(ctx) < 0) + return -1; + space = isl_space_set_alloc(ctx, 0, 1); ls = isl_local_space_from_space(space); aff = isl_aff_zero_on_domain(ls); @@ -3148,6 +4078,22 @@ if (!equal) isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + /* Check that empty solution lie in the right space. */ + str = "[n] -> { [t,a] : 1 = 0 }"; + set = isl_set_read_from_str(ctx, str); + pwaff = isl_set_dim_max(set, 0); + set1 = isl_set_from_pw_aff(pwaff); + str = "[n] -> { [t] : 1 = 0 }"; + set2 = isl_set_read_from_str(ctx, str); + equal = isl_set_is_equal(set1, set2); + isl_set_free(set1); + isl_set_free(set2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "unexpected result", return -1); + return 0; } @@ -3338,27 +4284,81 @@ return 0; } -int test_vertices(isl_ctx *ctx) +struct isl_vertices_test_data { + const char *set; + int n; + const char *vertex[2]; +} vertices_tests[] = { + { "{ A[t, i] : t = 12 and i >= 4 and i <= 12 }", + 2, { "{ A[12, 4] }", "{ A[12, 12] }" } }, + { "{ A[t, i] : t = 14 and i = 1 }", + 1, { "{ A[14, 1] }" } }, +}; + +/* Check that "vertex" corresponds to one of the vertices in data->vertex. + */ +static isl_stat find_vertex(__isl_take isl_vertex *vertex, void *user) { - const char *str; + struct isl_vertices_test_data *data = user; + isl_ctx *ctx; + isl_multi_aff *ma; isl_basic_set *bset; - isl_vertices *vertices; + isl_pw_multi_aff *pma; + int i; + isl_bool equal; - str = "{ A[t, i] : t = 12 and i >= 4 and i <= 12 }"; - bset = isl_basic_set_read_from_str(ctx, str); - vertices = isl_basic_set_compute_vertices(bset); - isl_basic_set_free(bset); - isl_vertices_free(vertices); - if (!vertices) - return -1; + ctx = isl_vertex_get_ctx(vertex); + bset = isl_vertex_get_domain(vertex); + ma = isl_vertex_get_expr(vertex); + pma = isl_pw_multi_aff_alloc(isl_set_from_basic_set(bset), ma); + + for (i = 0; i < data->n; ++i) { + isl_pw_multi_aff *pma_i; + + pma_i = isl_pw_multi_aff_read_from_str(ctx, data->vertex[i]); + equal = isl_pw_multi_aff_plain_is_equal(pma, pma_i); + isl_pw_multi_aff_free(pma_i); - str = "{ A[t, i] : t = 14 and i = 1 }"; - bset = isl_basic_set_read_from_str(ctx, str); - vertices = isl_basic_set_compute_vertices(bset); - isl_basic_set_free(bset); - isl_vertices_free(vertices); - if (!vertices) - return -1; + if (equal < 0 || equal) + break; + } + + isl_pw_multi_aff_free(pma); + isl_vertex_free(vertex); + + if (equal < 0) + return isl_stat_error; + + return equal ? isl_stat_ok : isl_stat_error; +} + +int test_vertices(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vertices_tests); ++i) { + isl_basic_set *bset; + isl_vertices *vertices; + int ok = 1; + int n; + + bset = isl_basic_set_read_from_str(ctx, vertices_tests[i].set); + vertices = isl_basic_set_compute_vertices(bset); + n = isl_vertices_get_n_vertices(vertices); + if (vertices_tests[i].n != n) + ok = 0; + if (isl_vertices_foreach_vertex(vertices, &find_vertex, + &vertices_tests[i]) < 0) + ok = 0; + isl_vertices_free(vertices); + isl_basic_set_free(bset); + + if (!vertices) + return -1; + if (!ok) + isl_die(ctx, isl_error_unknown, "unexpected vertices", + return -1); + } return 0; } @@ -3407,7 +4407,7 @@ if (!s) equal = -1; else - equal = !strcmp(s, "(2 - x + 4*floord(x, 4) >= 0) ? (1) : 2"); + equal = !strcmp(s, "4 * floord(x, 4) + 2 >= x ? 1 : 2"); free(s); if (equal < 0) return -1; @@ -3667,6 +4667,7 @@ "[N] -> { [i] : exists a : i = 4 a and N - 1 <= i <= N }", "[N] -> { [i,j] : exists a : i = 4 a and N - 1 <= i, 2j <= N }", "[N] -> { [[i]->[j]] : exists a : i = 4 a and N - 1 <= i, 2j <= N }", + "[N] -> { [3*floor(N/2) + 5*floor(N/3)] }", }; /* Check that converting from isl_set to isl_pw_multi_aff and back @@ -3908,6 +4909,9 @@ { "{ B[i] -> C[([i/2])] }", "{ B[5] }", "{ C[2] }" }, { "[n] -> { B[i,j] -> C[([i/2]) + 2j] }", "[n] -> { B[n,[n/3]] }", "[n] -> { C[([n/2]) + 2*[n/3]] }", }, + { "{ [i, j] -> [floor((i)/4) + floor((2*i+j)/5)] }", + "{ [i, j] -> [floor((i)/3), j] }", + "{ [i, j] -> [(floor((i)/12) + floor((j + 2*floor((i)/3))/5))] }" }, }; static int test_pullback(isl_ctx *ctx) @@ -3935,25 +4939,33 @@ return 0; } -/* Check that negation is printed correctly. +/* Check that negation is printed correctly and that equal expressions + * are correctly identified. */ static int test_ast(isl_ctx *ctx) { isl_ast_expr *expr, *expr1, *expr2, *expr3; char *str; - int ok; + int ok, equal; expr1 = isl_ast_expr_from_id(isl_id_alloc(ctx, "A", NULL)); expr2 = isl_ast_expr_from_id(isl_id_alloc(ctx, "B", NULL)); expr = isl_ast_expr_add(expr1, expr2); + expr2 = isl_ast_expr_copy(expr); expr = isl_ast_expr_neg(expr); + expr2 = isl_ast_expr_neg(expr2); + equal = isl_ast_expr_is_equal(expr, expr2); str = isl_ast_expr_to_str(expr); ok = str ? !strcmp(str, "-(A + B)") : -1; free(str); isl_ast_expr_free(expr); + isl_ast_expr_free(expr2); - if (ok < 0) + if (ok < 0 || equal < 0) return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "equal expressions not considered equal", return -1); if (!ok) isl_die(ctx, isl_error_unknown, "isl_ast_expr printed incorrectly", return -1); @@ -3977,6 +4989,31 @@ return 0; } +/* Check that isl_ast_build_expr_from_set returns a valid expression + * for an empty set. Note that isl_ast_build_expr_from_set getting + * called on an empty set probably indicates a bug in the caller. + */ +static int test_ast_build(isl_ctx *ctx) +{ + isl_set *set; + isl_ast_build *build; + isl_ast_expr *expr; + + set = isl_set_universe(isl_space_params_alloc(ctx, 0)); + build = isl_ast_build_from_context(set); + + set = isl_set_empty(isl_space_params_alloc(ctx, 0)); + expr = isl_ast_build_expr_from_set(build, set); + + isl_ast_expr_free(expr); + isl_ast_build_free(build); + + if (!expr) + return -1; + + return 0; +} + /* Internal data structure for before_for and after_for callbacks. * * depth is the current depth @@ -4117,7 +5154,7 @@ &before_for, &data); build = isl_ast_build_set_after_each_for(build, &after_for, &data); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); if (!tree) return -1; @@ -4132,7 +5169,7 @@ } /* Check that the AST generator handles domains that are integrally disjoint - * but not ratinoally disjoint. + * but not rationally disjoint. */ static int test_ast_gen2(isl_ctx *ctx) { @@ -4151,7 +5188,7 @@ str = "{ [i,j] -> atomic[1] : i + j = 1; [i,j] -> unroll[1] : i = j }"; options = isl_union_map_read_from_str(ctx, str); build = isl_ast_build_set_options(build, options); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); if (!tree) return -1; @@ -4197,7 +5234,7 @@ build = isl_ast_build_set_options(build, options); build = isl_ast_build_set_at_each_domain(build, &count_domains, &n_domain); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); if (!tree) return -1; @@ -4233,7 +5270,7 @@ schedule = isl_union_map_read_from_str(ctx, str); set = isl_set_universe(isl_space_params_alloc(ctx, 0)); build = isl_ast_build_from_context(set); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); if (!tree) return -1; @@ -4250,7 +5287,7 @@ schedule = isl_union_map_read_from_str(ctx, str); set = isl_set_universe(isl_space_params_alloc(ctx, 0)); build = isl_ast_build_from_context(set); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); if (!tree) return -1; @@ -4285,7 +5322,7 @@ extra = isl_union_map_copy(schedule); extra = isl_union_map_from_domain(isl_union_map_domain(extra)); schedule = isl_union_map_range_product(schedule, extra); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); if (!tree) @@ -4328,7 +5365,7 @@ build = isl_ast_build_from_context(set); build = isl_ast_build_set_options(build, options); build = isl_ast_build_set_create_leaf(build, &create_leaf, NULL); - tree = isl_ast_build_ast_from_schedule(build, schedule); + tree = isl_ast_build_node_from_schedule_map(build, schedule); isl_ast_build_free(build); isl_ast_node_free(tree); if (!tree) @@ -4381,6 +5418,54 @@ return 0; } +/* Check that we can properly parse multi piecewise affine expressions + * where the piecewise affine expressions have different domains. + */ +static int test_multi_pw_aff(isl_ctx *ctx) +{ + const char *str; + isl_set *dom, *dom2; + isl_multi_pw_aff *mpa1, *mpa2; + isl_pw_aff *pa; + int equal; + int equal_domain; + + mpa1 = isl_multi_pw_aff_read_from_str(ctx, "{ [i] -> [i] }"); + dom = isl_set_read_from_str(ctx, "{ [i] : i > 0 }"); + mpa1 = isl_multi_pw_aff_intersect_domain(mpa1, dom); + mpa2 = isl_multi_pw_aff_read_from_str(ctx, "{ [i] -> [2i] }"); + mpa2 = isl_multi_pw_aff_flat_range_product(mpa1, mpa2); + str = "{ [i] -> [(i : i > 0), 2i] }"; + mpa1 = isl_multi_pw_aff_read_from_str(ctx, str); + + equal = isl_multi_pw_aff_plain_is_equal(mpa1, mpa2); + + pa = isl_multi_pw_aff_get_pw_aff(mpa1, 0); + dom = isl_pw_aff_domain(pa); + pa = isl_multi_pw_aff_get_pw_aff(mpa1, 1); + dom2 = isl_pw_aff_domain(pa); + equal_domain = isl_set_is_equal(dom, dom2); + + isl_set_free(dom); + isl_set_free(dom2); + isl_multi_pw_aff_free(mpa1); + isl_multi_pw_aff_free(mpa2); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + + if (equal_domain < 0) + return -1; + if (equal_domain) + isl_die(ctx, isl_error_unknown, + "domains unexpectedly equal", return -1); + + return 0; +} + /* This is a regression test for a bug where isl_basic_map_simplify * would end up in an infinite loop. In particular, we construct * an empty basic set that is not obviously empty. @@ -4461,22 +5546,368 @@ return 0; } +/* Check that the reaching domain elements and the prefix schedule + * at a leaf node are the same before and after grouping. + */ +static int test_schedule_tree_group_1(isl_ctx *ctx) +{ + int equal; + const char *str; + isl_id *id; + isl_union_set *uset; + isl_multi_union_pw_aff *mupa; + isl_union_pw_multi_aff *upma1, *upma2; + isl_union_set *domain1, *domain2; + isl_union_map *umap1, *umap2; + isl_schedule_node *node; + + str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10 }"; + uset = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(uset); + node = isl_schedule_node_child(node, 0); + str = "[{ S1[i,j] -> [i]; S2[i,j] -> [9 - i] }]"; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + node = isl_schedule_node_child(node, 0); + str = "[{ S1[i,j] -> [j]; S2[i,j] -> [j] }]"; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + node = isl_schedule_node_child(node, 0); + umap1 = isl_schedule_node_get_prefix_schedule_union_map(node); + upma1 = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); + domain1 = isl_schedule_node_get_domain(node); + id = isl_id_alloc(ctx, "group", NULL); + node = isl_schedule_node_parent(node); + node = isl_schedule_node_group(node, id); + node = isl_schedule_node_child(node, 0); + umap2 = isl_schedule_node_get_prefix_schedule_union_map(node); + upma2 = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(node); + domain2 = isl_schedule_node_get_domain(node); + equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2); + if (equal >= 0 && equal) + equal = isl_union_set_is_equal(domain1, domain2); + if (equal >= 0 && equal) + equal = isl_union_map_is_equal(umap1, umap2); + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_set_free(domain1); + isl_union_set_free(domain2); + isl_union_pw_multi_aff_free(upma1); + isl_union_pw_multi_aff_free(upma2); + isl_schedule_node_free(node); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + + return 0; +} + +/* Check that we can have nested groupings and that the union map + * schedule representation is the same before and after the grouping. + * Note that after the grouping, the union map representation contains + * the domain constraints from the ranges of the expansion nodes, + * while they are missing from the union map representation of + * the tree without expansion nodes. + * + * Also check that the global expansion is as expected. + */ +static int test_schedule_tree_group_2(isl_ctx *ctx) +{ + int equal, equal_expansion; + const char *str; + isl_id *id; + isl_union_set *uset; + isl_union_map *umap1, *umap2; + isl_union_map *expansion1, *expansion2; + isl_union_set_list *filters; + isl_multi_union_pw_aff *mupa; + isl_schedule *schedule; + isl_schedule_node *node; + + str = "{ S1[i,j] : 0 <= i,j < 10; S2[i,j] : 0 <= i,j < 10; " + "S3[i,j] : 0 <= i,j < 10 }"; + uset = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(uset); + node = isl_schedule_node_child(node, 0); + str = "[{ S1[i,j] -> [i]; S2[i,j] -> [i]; S3[i,j] -> [i] }]"; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + node = isl_schedule_node_child(node, 0); + str = "{ S1[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_from_union_set(uset); + str = "{ S2[i,j]; S3[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_add(filters, uset); + node = isl_schedule_node_insert_sequence(node, filters); + node = isl_schedule_node_child(node, 1); + node = isl_schedule_node_child(node, 0); + str = "{ S2[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_from_union_set(uset); + str = "{ S3[i,j] }"; + uset = isl_union_set_read_from_str(ctx, str); + filters = isl_union_set_list_add(filters, uset); + node = isl_schedule_node_insert_sequence(node, filters); + + schedule = isl_schedule_node_get_schedule(node); + umap1 = isl_schedule_get_map(schedule); + uset = isl_schedule_get_domain(schedule); + umap1 = isl_union_map_intersect_domain(umap1, uset); + isl_schedule_free(schedule); + + node = isl_schedule_node_parent(node); + node = isl_schedule_node_parent(node); + id = isl_id_alloc(ctx, "group1", NULL); + node = isl_schedule_node_group(node, id); + node = isl_schedule_node_child(node, 1); + node = isl_schedule_node_child(node, 0); + id = isl_id_alloc(ctx, "group2", NULL); + node = isl_schedule_node_group(node, id); + + schedule = isl_schedule_node_get_schedule(node); + umap2 = isl_schedule_get_map(schedule); + isl_schedule_free(schedule); + + node = isl_schedule_node_root(node); + node = isl_schedule_node_child(node, 0); + expansion1 = isl_schedule_node_get_subtree_expansion(node); + isl_schedule_node_free(node); + + str = "{ group1[i] -> S1[i,j] : 0 <= i,j < 10; " + "group1[i] -> S2[i,j] : 0 <= i,j < 10; " + "group1[i] -> S3[i,j] : 0 <= i,j < 10 }"; + + expansion2 = isl_union_map_read_from_str(ctx, str); + + equal = isl_union_map_is_equal(umap1, umap2); + equal_expansion = isl_union_map_is_equal(expansion1, expansion2); + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + isl_union_map_free(expansion1); + isl_union_map_free(expansion2); + + if (equal < 0 || equal_expansion < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "expressions not equal", return -1); + if (!equal_expansion) + isl_die(ctx, isl_error_unknown, + "unexpected expansion", return -1); + + return 0; +} + +/* Some tests for the isl_schedule_node_group function. + */ +static int test_schedule_tree_group(isl_ctx *ctx) +{ + if (test_schedule_tree_group_1(ctx) < 0) + return -1; + if (test_schedule_tree_group_2(ctx) < 0) + return -1; + return 0; +} + +struct { + const char *set; + const char *dual; +} coef_tests[] = { + { "{ rat: [i] : 0 <= i <= 10 }", + "{ rat: coefficients[[cst] -> [a]] : cst >= 0 and 10a + cst >= 0 }" }, + { "{ rat: [i] : FALSE }", + "{ rat: coefficients[[cst] -> [a]] }" }, + { "{ rat: [i] : }", + "{ rat: coefficients[[cst] -> [0]] : cst >= 0 }" }, +}; + +struct { + const char *set; + const char *dual; +} sol_tests[] = { + { "{ rat: coefficients[[cst] -> [a]] : cst >= 0 and 10a + cst >= 0 }", + "{ rat: [i] : 0 <= i <= 10 }" }, + { "{ rat: coefficients[[cst] -> [a]] : FALSE }", + "{ rat: [i] }" }, + { "{ rat: coefficients[[cst] -> [a]] }", + "{ rat: [i] : FALSE }" }, +}; + +/* Test the basic functionality of isl_basic_set_coefficients and + * isl_basic_set_solutions. + */ +static int test_dual(isl_ctx *ctx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coef_tests); ++i) { + int equal; + isl_basic_set *bset1, *bset2; + + bset1 = isl_basic_set_read_from_str(ctx, coef_tests[i].set); + bset2 = isl_basic_set_read_from_str(ctx, coef_tests[i].dual); + bset1 = isl_basic_set_coefficients(bset1); + equal = isl_basic_set_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect dual", return -1); + } + + for (i = 0; i < ARRAY_SIZE(sol_tests); ++i) { + int equal; + isl_basic_set *bset1, *bset2; + + bset1 = isl_basic_set_read_from_str(ctx, sol_tests[i].set); + bset2 = isl_basic_set_read_from_str(ctx, sol_tests[i].dual); + bset1 = isl_basic_set_solutions(bset1); + equal = isl_basic_set_is_equal(bset1, bset2); + isl_basic_set_free(bset1); + isl_basic_set_free(bset2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "incorrect dual", return -1); + } + + return 0; +} + +struct { + int scale_tile; + int shift_point; + const char *domain; + const char *schedule; + const char *sizes; + const char *tile; + const char *point; +} tile_tests[] = { + { 0, 0, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + }, + { 1, 0, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + }, + { 0, 1, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]", + "[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]", + }, + { 1, 1, "[n] -> { S[i,j] : 0 <= i,j < n }", + "[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]", + "{ [32,32] }", + "[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]", + "[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]", + }, +}; + +/* Basic tiling tests. Create a schedule tree with a domain and a band node, + * tile the band and then check if the tile and point bands have the + * expected partial schedule. + */ +static int test_tile(isl_ctx *ctx) +{ + int i; + int scale; + int shift; + + scale = isl_options_get_tile_scale_tile_loops(ctx); + shift = isl_options_get_tile_shift_point_loops(ctx); + + for (i = 0; i < ARRAY_SIZE(tile_tests); ++i) { + int opt; + int equal; + const char *str; + isl_union_set *domain; + isl_multi_union_pw_aff *mupa, *mupa2; + isl_schedule_node *node; + isl_multi_val *sizes; + + opt = tile_tests[i].scale_tile; + isl_options_set_tile_scale_tile_loops(ctx, opt); + opt = tile_tests[i].shift_point; + isl_options_set_tile_shift_point_loops(ctx, opt); + + str = tile_tests[i].domain; + domain = isl_union_set_read_from_str(ctx, str); + node = isl_schedule_node_from_domain(domain); + node = isl_schedule_node_child(node, 0); + str = tile_tests[i].schedule; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + node = isl_schedule_node_insert_partial_schedule(node, mupa); + str = tile_tests[i].sizes; + sizes = isl_multi_val_read_from_str(ctx, str); + node = isl_schedule_node_band_tile(node, sizes); + + str = tile_tests[i].tile; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + mupa2 = isl_schedule_node_band_get_partial_schedule(node); + equal = isl_multi_union_pw_aff_plain_is_equal(mupa, mupa2); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(mupa2); + + node = isl_schedule_node_child(node, 0); + + str = tile_tests[i].point; + mupa = isl_multi_union_pw_aff_read_from_str(ctx, str); + mupa2 = isl_schedule_node_band_get_partial_schedule(node); + if (equal >= 0 && equal) + equal = isl_multi_union_pw_aff_plain_is_equal(mupa, + mupa2); + isl_multi_union_pw_aff_free(mupa); + isl_multi_union_pw_aff_free(mupa2); + + isl_schedule_node_free(node); + + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, + "unexpected result", return -1); + } + + isl_options_set_tile_scale_tile_loops(ctx, scale); + isl_options_set_tile_shift_point_loops(ctx, shift); + + return 0; +} + struct { const char *name; int (*fn)(isl_ctx *ctx); } tests [] = { + { "dual", &test_dual }, + { "dependence analysis", &test_flow }, { "val", &test_val }, { "compute divs", &test_compute_divs }, { "partial lexmin", &test_partial_lexmin }, { "simplify", &test_simplify }, { "curry", &test_curry }, { "piecewise multi affine expressions", &test_pw_multi_aff }, + { "multi piecewise affine expressions", &test_multi_pw_aff }, { "conversion", &test_conversion }, { "list", &test_list }, { "align parameters", &test_align_parameters }, { "preimage", &test_preimage }, { "pullback", &test_pullback }, { "AST", &test_ast }, + { "AST build", &test_ast_build }, { "AST generation", &test_ast_gen }, { "eliminate", &test_eliminate }, { "residue class", &test_residue_class }, @@ -4494,6 +5925,8 @@ { "affine", &test_aff }, { "injective", &test_injective }, { "schedule", &test_schedule }, + { "schedule tree grouping", &test_schedule_tree_group }, + { "tile", &test_tile }, { "union_pw", &test_union_pw }, { "parse", &test_parse }, { "single-valued", &test_sv }, @@ -4506,36 +5939,41 @@ { "min", &test_min }, { "gist", &test_gist }, { "piecewise quasi-polynomials", &test_pwqp }, + { "lift", &test_lift }, + { "bound", &test_bound }, + { "union", &test_union }, + { "split periods", &test_split_periods }, + { "lexicographic order", &test_lex }, + { "bijectivity", &test_bijective }, + { "dataflow analysis", &test_dep }, + { "reading", &test_read }, + { "bounded", &test_bounded }, + { "construction", &test_construction }, + { "dimension manipulation", &test_dim }, + { "map application", &test_application }, + { "convex hull", &test_convex_hull }, + { "transitive closure", &test_closure }, }; -int main() +int main(int argc, char **argv) { int i; struct isl_ctx *ctx; + struct isl_options *options; srcdir = getenv("srcdir"); assert(srcdir); - ctx = isl_ctx_alloc(); + options = isl_options_new_with_defaults(); + assert(options); + argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); + + ctx = isl_ctx_alloc_with_options(&isl_options_args, options); for (i = 0; i < ARRAY_SIZE(tests); ++i) { printf("%s\n", tests[i].name); if (tests[i].fn(ctx) < 0) goto error; } - test_lift(ctx); - test_bound(ctx); - test_union(ctx); - test_split_periods(ctx); - test_lex(ctx); - test_bijective(ctx); - test_dep(ctx); - test_read(ctx); - test_bounded(ctx); - test_construction(ctx); - test_dim(ctx); - test_application(ctx); - test_convex_hull(ctx); - test_closure(ctx); isl_ctx_free(ctx); return 0; error: diff -Nru isl-0.12.2/isl_transitive_closure.c isl-0.15/isl_transitive_closure.c --- isl-0.12.2/isl_transitive_closure.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_transitive_closure.c 2015-06-02 09:28:10.000000000 +0000 @@ -11,11 +11,12 @@ #include #include #include -#include +#include #include -#include +#include #include #include +#include #include #include @@ -69,13 +70,15 @@ bmap = isl_basic_map_alloc_space(dim, 0, 1, 1); if (exactly) { k = isl_basic_map_alloc_equality(bmap); + if (k < 0) + goto error; c = bmap->eq[k]; } else { k = isl_basic_map_alloc_inequality(bmap); + if (k < 0) + goto error; c = bmap->ineq[k]; } - if (k < 0) - goto error; isl_seq_clr(c, 1 + isl_basic_map_total_dim(bmap)); isl_int_set_si(c[0], -length); isl_int_set_si(c[1 + nparam + d - 1], -1); @@ -473,13 +476,15 @@ continue; if (eq && p != MIXED) { k = isl_basic_map_alloc_equality(path); + if (k < 0) + goto error; path_c = path->eq[k]; } else { k = isl_basic_map_alloc_inequality(path); + if (k < 0) + goto error; path_c = path->ineq[k]; } - if (k < 0) - goto error; isl_seq_clr(path_c, 1 + isl_basic_map_total_dim(path)); if (p == PURE_VAR) { isl_seq_cpy(path_c + off, @@ -753,6 +758,9 @@ unsigned d; int i, j, n; + if (!map) + goto error; + d = isl_map_dim(map, isl_dim_in); path = isl_map_identity(isl_space_copy(dim)); @@ -818,7 +826,11 @@ isl_set *i; int no_overlap; - if (!isl_space_tuple_match(set1->dim, isl_dim_set, set2->dim, isl_dim_set)) + if (!set1 || !set2) + return -1; + + if (!isl_space_tuple_is_equal(set1->dim, isl_dim_set, + set2->dim, isl_dim_set)) return 0; i = isl_set_intersect(isl_set_copy(set1), isl_set_copy(set2)); @@ -854,16 +866,20 @@ struct isl_set *range = NULL; struct isl_map *app = NULL; struct isl_map *path = NULL; + int overlaps; domain = isl_map_domain(isl_map_copy(map)); domain = isl_set_coalesce(domain); range = isl_map_range(isl_map_copy(map)); range = isl_set_coalesce(range); - if (!isl_set_overlaps(domain, range)) { + overlaps = isl_set_overlaps(domain, range); + if (overlaps < 0 || !overlaps) { isl_set_free(domain); isl_set_free(range); isl_space_free(dim); + if (overlaps < 0) + map = NULL; map = isl_map_copy(map); map = isl_map_add_dims(map, isl_dim_in, 1); map = isl_map_add_dims(map, isl_dim_out, 1); @@ -1750,16 +1766,16 @@ * *check_closed is set if the subset relation holds while * R_1 \circ R_2 is not empty. */ -static int basic_map_follows(int i, int j, void *user) +static isl_bool basic_map_follows(int i, int j, void *user) { struct isl_tc_follows_data *data = user; struct isl_map *map12 = NULL; struct isl_map *map21 = NULL; - int subset; + isl_bool subset; - if (!isl_space_tuple_match(data->list[i]->dim, isl_dim_in, + if (!isl_space_tuple_is_equal(data->list[i]->dim, isl_dim_in, data->list[j]->dim, isl_dim_out)) - return 0; + return isl_bool_false; map21 = isl_map_from_basic_map( isl_basic_map_apply_range( @@ -1770,15 +1786,15 @@ goto error; if (subset) { isl_map_free(map21); - return 0; + return isl_bool_false; } - if (!isl_space_tuple_match(data->list[i]->dim, isl_dim_in, + if (!isl_space_tuple_is_equal(data->list[i]->dim, isl_dim_in, data->list[i]->dim, isl_dim_out) || - !isl_space_tuple_match(data->list[j]->dim, isl_dim_in, + !isl_space_tuple_is_equal(data->list[j]->dim, isl_dim_in, data->list[j]->dim, isl_dim_out)) { isl_map_free(map21); - return 1; + return isl_bool_true; } map12 = isl_map_from_basic_map( @@ -1794,10 +1810,10 @@ if (subset) data->check_closed = 1; - return subset < 0 ? -1 : !subset; + return subset < 0 ? isl_bool_error : !subset; error: isl_map_free(map21); - return -1; + return isl_bool_error; } /* Given a union of basic maps R = \cup_i R_i \subseteq D \times D @@ -1946,14 +1962,12 @@ { struct isl_map *app = NULL; isl_space *dim = NULL; - unsigned d; if (!map) return NULL; dim = isl_map_get_space(map); - d = isl_space_dim(dim, isl_dim_in); dim = isl_space_add_dims(dim, isl_dim_in, 1); dim = isl_space_add_dims(dim, isl_dim_out, 1); @@ -2596,7 +2610,7 @@ return NULL; } -static int inc_count(__isl_take isl_map *map, void *user) +static isl_stat inc_count(__isl_take isl_map *map, void *user) { int *n = user; @@ -2604,10 +2618,10 @@ isl_map_free(map); - return 0; + return isl_stat_ok; } -static int collect_basic_map(__isl_take isl_map *map, void *user) +static isl_stat collect_basic_map(__isl_take isl_map *map, void *user) { int i; isl_basic_map ***next = user; @@ -2620,10 +2634,10 @@ } isl_map_free(map); - return 0; + return isl_stat_ok; error: isl_map_free(map); - return -1; + return isl_stat_error; } /* Perform Floyd-Warshall on the given list of basic relations. @@ -2891,14 +2905,14 @@ int *exact; }; -static int power(__isl_take isl_map *map, void *user) +static isl_stat power(__isl_take isl_map *map, void *user) { struct isl_union_power *up = user; map = isl_map_power(map, up->exact); up->pow = isl_union_map_from_map(map); - return -1; + return isl_stat_error; } /* Construct a map [x] -> [x+1], with parameters prescribed by "dim". diff -Nru isl-0.12.2/isl_union_map.c isl-0.15/isl_union_map.c --- isl-0.12.2/isl_union_map.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_union_map.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,35 +1,80 @@ /* * Copyright 2010-2011 INRIA Saclay + * Copyright 2013-2014 Ecole Normale Superieure + * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France + * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, + * B.P. 105 - 78153 Le Chesnay, France */ #define ISL_DIM_H #include +#include #include #include #include #include #include #include -#include #include +#include + +/* Return the number of parameters of "umap", where "type" + * is required to be set to isl_dim_param. + */ +unsigned isl_union_map_dim(__isl_keep isl_union_map *umap, + enum isl_dim_type type) +{ + if (!umap) + return 0; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only reference parameters", return 0); + + return isl_space_dim(umap->dim, type); +} + +/* Return the number of parameters of "uset", where "type" + * is required to be set to isl_dim_param. + */ +unsigned isl_union_set_dim(__isl_keep isl_union_set *uset, + enum isl_dim_type type) +{ + return isl_union_map_dim(uset, type); +} + +/* Return the id of the specified dimension. + */ +__isl_give isl_id *isl_union_map_get_dim_id(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned pos) +{ + if (!umap) + return NULL; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only reference parameters", return NULL); + + return isl_space_get_dim_id(umap->dim, type, pos); +} /* Is this union set a parameter domain? */ -int isl_union_set_is_params(__isl_keep isl_union_set *uset) +isl_bool isl_union_set_is_params(__isl_keep isl_union_set *uset) { isl_set *set; - int params; + isl_bool params; if (!uset) - return -1; + return isl_bool_error; if (uset->table.n != 1) - return 0; + return isl_bool_false; set = isl_set_from_union_set(isl_union_set_copy(uset)); params = isl_set_is_params(set); @@ -37,22 +82,24 @@ return params; } -static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_space *dim, - int size) +static __isl_give isl_union_map *isl_union_map_alloc( + __isl_take isl_space *space, int size) { isl_union_map *umap; - dim = isl_space_params(dim); - if (!dim) + space = isl_space_params(space); + if (!space) return NULL; - umap = isl_calloc_type(dim->ctx, isl_union_map); - if (!umap) + umap = isl_calloc_type(space->ctx, isl_union_map); + if (!umap) { + isl_space_free(space); return NULL; + } umap->ref = 1; - umap->dim = dim; - if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0) + umap->dim = space; + if (isl_hash_table_init(space->ctx, &umap->table, size) < 0) return isl_union_map_free(umap); return umap; @@ -85,25 +132,37 @@ return isl_space_copy(umap->dim); } +/* Return the position of the parameter with the given name + * in "umap". + * Return -1 if no such dimension can be found. + */ +int isl_union_map_find_dim_by_name(__isl_keep isl_union_map *umap, + enum isl_dim_type type, const char *name) +{ + if (!umap) + return -1; + return isl_space_find_dim_by_name(umap->dim, type, name); +} + __isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset) { return isl_union_map_get_space(uset); } -static int free_umap_entry(void **entry, void *user) +static isl_stat free_umap_entry(void **entry, void *user) { isl_map *map = *entry; isl_map_free(map); - return 0; + return isl_stat_ok; } -static int add_map(__isl_take isl_map *map, void *user) +static isl_stat add_map(__isl_take isl_map *map, void *user) { isl_union_map **umap = (isl_union_map **)user; *umap = isl_union_map_add_map(*umap, map); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap) @@ -138,7 +197,7 @@ isl_union_map *res; }; -static int align_entry(void **entry, void *user) +static isl_stat align_entry(void **entry, void *user) { isl_map *map = *entry; isl_reordering *exp; @@ -150,7 +209,7 @@ data->res = isl_union_map_add_map(data->res, isl_map_realign(isl_map_copy(map), exp)); - return 0; + return isl_stat_ok; } /* Align the parameters of umap along those of model. @@ -243,7 +302,7 @@ return isl_union_map_copy(uset); } -void *isl_union_map_free(__isl_take isl_union_map *umap) +__isl_null isl_union_map *isl_union_map_free(__isl_take isl_union_map *umap) { if (!umap) return NULL; @@ -259,7 +318,7 @@ return NULL; } -void *isl_union_set_free(__isl_take isl_union_set *uset) +__isl_null isl_union_set *isl_union_set_free(__isl_take isl_union_set *uset) { return isl_union_map_free(uset); } @@ -359,11 +418,11 @@ struct isl_union_map_foreach_data { - int (*fn)(__isl_take isl_map *map, void *user); + isl_stat (*fn)(__isl_take isl_map *map, void *user); void *user; }; -static int call_on_copy(void **entry, void *user) +static isl_stat call_on_copy(void **entry, void *user) { isl_map *map = *entry; struct isl_union_map_foreach_data *data; @@ -382,26 +441,26 @@ return uset ? uset->table.n : 0; } -int isl_union_map_foreach_map(__isl_keep isl_union_map *umap, - int (*fn)(__isl_take isl_map *map, void *user), void *user) +isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap, + isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user) { struct isl_union_map_foreach_data data = { fn, user }; if (!umap) - return -1; + return isl_stat_error; return isl_hash_table_foreach(umap->dim->ctx, &umap->table, &call_on_copy, &data); } -static int copy_map(void **entry, void *user) +static isl_stat copy_map(void **entry, void *user) { isl_map *map = *entry; isl_map **map_p = user; *map_p = isl_map_copy(map); - return -1; + return isl_stat_error; } __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap) @@ -415,13 +474,16 @@ if (umap->table.n != 1) isl_die(ctx, isl_error_invalid, "union map needs to contain elements in exactly " - "one space", return isl_union_map_free(umap)); + "one space", goto error); isl_hash_table_foreach(ctx, &umap->table, ©_map, &map); isl_union_map_free(umap); return map; +error: + isl_union_map_free(umap); + return NULL; } __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset) @@ -485,22 +547,22 @@ return isl_union_map_contains(uset, dim); } -int isl_union_set_foreach_set(__isl_keep isl_union_set *uset, - int (*fn)(__isl_take isl_set *set, void *user), void *user) +isl_stat isl_union_set_foreach_set(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_set *set, void *user), void *user) { return isl_union_map_foreach_map(uset, - (int(*)(__isl_take isl_map *, void*))fn, user); + (isl_stat(*)(__isl_take isl_map *, void*))fn, user); } struct isl_union_set_foreach_point_data { - int (*fn)(__isl_take isl_point *pnt, void *user); + isl_stat (*fn)(__isl_take isl_point *pnt, void *user); void *user; }; -static int foreach_point(__isl_take isl_set *set, void *user) +static isl_stat foreach_point(__isl_take isl_set *set, void *user) { struct isl_union_set_foreach_point_data *data = user; - int r; + isl_stat r; r = isl_set_foreach_point(set, data->fn, data->user); isl_set_free(set); @@ -508,8 +570,8 @@ return r; } -int isl_union_set_foreach_point(__isl_keep isl_union_set *uset, - int (*fn)(__isl_take isl_point *pnt, void *user), void *user) +isl_stat isl_union_set_foreach_point(__isl_keep isl_union_set *uset, + isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user) { struct isl_union_set_foreach_point_data data = { fn, user }; return isl_union_set_foreach_set(uset, &foreach_point, &data); @@ -520,7 +582,7 @@ isl_union_map *res; }; -static int subtract_entry(void **entry, void *user) +static isl_stat subtract_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; @@ -538,20 +600,20 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map); - return 0; + return isl_stat_ok; } } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2, int (*fn)(void **, void *)) + __isl_take isl_union_map *umap2, isl_stat (*fn)(void **, void *)) { struct isl_union_map_gen_bin_data data = { NULL, NULL }; @@ -595,7 +657,7 @@ isl_union_map *res; }; -static int intersect_params_entry(void **entry, void *user) +static isl_stat intersect_params_entry(void **entry, void *user) { struct isl_union_map_gen_bin_set_data *data = user; isl_map *map = *entry; @@ -607,16 +669,16 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } static __isl_give isl_union_map *gen_bin_set_op(__isl_take isl_union_map *umap, - __isl_take isl_set *set, int (*fn)(void **, void *)) + __isl_take isl_set *set, isl_stat (*fn)(void **, void *)) { struct isl_union_map_gen_bin_set_data data = { NULL, NULL }; @@ -643,10 +705,28 @@ return NULL; } +/* Intersect "umap" with the parameter domain "set". + * + * If "set" does not have any constraints, then we can return immediately. + */ __isl_give isl_union_map *isl_union_map_intersect_params( __isl_take isl_union_map *umap, __isl_take isl_set *set) { + int is_universe; + + is_universe = isl_set_plain_is_universe(set); + if (is_universe < 0) + goto error; + if (is_universe) { + isl_set_free(set); + return umap; + } + return gen_bin_set_op(umap, set, &intersect_params_entry); +error: + isl_union_map_free(umap); + isl_set_free(set); + return NULL; } __isl_give isl_union_set *isl_union_set_intersect_params( @@ -674,7 +754,7 @@ __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*); }; -static int match_bin_entry(void **entry, void *user) +static isl_stat match_bin_entry(void **entry, void *user) { struct isl_union_map_match_bin_data *data = user; uint32_t hash; @@ -686,7 +766,7 @@ entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table, hash, &has_dim, map->dim, 0); if (!entry2) - return 0; + return isl_stat_ok; map = isl_map_copy(map); map = data->fn(map, isl_map_copy(entry2->data)); @@ -694,16 +774,16 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map); - return 0; + return isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1, @@ -766,7 +846,7 @@ return NULL; } -static int gist_params_entry(void **entry, void *user) +static isl_stat gist_params_entry(void **entry, void *user) { struct isl_union_map_gen_bin_set_data *data = user; isl_map *map = *entry; @@ -778,12 +858,12 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_gist_params( @@ -860,14 +940,14 @@ return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1)); } -static int intersect_domain_entry(void **entry, void *user) +static isl_stat intersect_domain_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *dim; isl_map *map = *entry; - int empty; + isl_bool empty; dim = isl_map_get_space(map); dim = isl_space_domain(dim); @@ -876,7 +956,7 @@ hash, &has_dim, dim, 0); isl_space_free(dim); if (!entry2) - return 0; + return isl_stat_ok; map = isl_map_copy(map); map = isl_map_intersect_domain(map, isl_set_copy(entry2->data)); @@ -884,16 +964,16 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map); - return 0; + return isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } /* Intersect the domain of "umap" with "uset". @@ -911,14 +991,14 @@ /* Remove the elements of data->umap2 from the domain of *entry * and add the result to data->res. */ -static int subtract_domain_entry(void **entry, void *user) +static isl_stat subtract_domain_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *dim; isl_map *map = *entry; - int empty; + isl_bool empty; dim = isl_map_get_space(map); dim = isl_space_domain(dim); @@ -931,7 +1011,7 @@ if (!entry2) { data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } map = isl_map_subtract_domain(map, isl_set_copy(entry2->data)); @@ -939,16 +1019,16 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map); - return 0; + return isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } /* Remove the elements of "uset" from the domain of "umap". @@ -962,14 +1042,14 @@ /* Remove the elements of data->umap2 from the range of *entry * and add the result to data->res. */ -static int subtract_range_entry(void **entry, void *user) +static isl_stat subtract_range_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *space; isl_map *map = *entry; - int empty; + isl_bool empty; space = isl_map_get_space(map); space = isl_space_range(space); @@ -982,7 +1062,7 @@ if (!entry2) { data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } map = isl_map_subtract_range(map, isl_set_copy(entry2->data)); @@ -990,16 +1070,16 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map); - return 0; + return isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } /* Remove the elements of "uset" from the range of "umap". @@ -1010,14 +1090,14 @@ return gen_bin_op(umap, dom, &subtract_range_entry); } -static int gist_domain_entry(void **entry, void *user) +static isl_stat gist_domain_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *dim; isl_map *map = *entry; - int empty; + isl_bool empty; dim = isl_map_get_space(map); dim = isl_space_domain(dim); @@ -1026,7 +1106,7 @@ hash, &has_dim, dim, 0); isl_space_free(dim); if (!entry2) - return 0; + return isl_stat_ok; map = isl_map_copy(map); map = isl_map_gist_domain(map, isl_set_copy(entry2->data)); @@ -1034,12 +1114,12 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } /* Compute the gist of "umap" with respect to the domain "uset". @@ -1054,14 +1134,14 @@ return gen_bin_op(umap, uset, &gist_domain_entry); } -static int gist_range_entry(void **entry, void *user) +static isl_stat gist_range_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *space; isl_map *map = *entry; - int empty; + isl_bool empty; space = isl_map_get_space(map); space = isl_space_range(space); @@ -1070,7 +1150,7 @@ hash, &has_dim, space, 0); isl_space_free(space); if (!entry2) - return 0; + return isl_stat_ok; map = isl_map_copy(map); map = isl_map_gist_range(map, isl_set_copy(entry2->data)); @@ -1078,12 +1158,12 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } /* Compute the gist of "umap" with respect to the range "uset". @@ -1094,14 +1174,14 @@ return gen_bin_op(umap, uset, &gist_range_entry); } -static int intersect_range_entry(void **entry, void *user) +static isl_stat intersect_range_entry(void **entry, void *user) { struct isl_union_map_gen_bin_data *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *dim; isl_map *map = *entry; - int empty; + isl_bool empty; dim = isl_map_get_space(map); dim = isl_space_range(dim); @@ -1110,7 +1190,7 @@ hash, &has_dim, dim, 0); isl_space_free(dim); if (!entry2) - return 0; + return isl_stat_ok; map = isl_map_copy(map); map = isl_map_intersect_range(map, isl_set_copy(entry2->data)); @@ -1118,16 +1198,16 @@ empty = isl_map_is_empty(map); if (empty < 0) { isl_map_free(map); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map); - return 0; + return isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_intersect_range( @@ -1140,37 +1220,37 @@ isl_union_map *umap2; isl_union_map *res; isl_map *map; - int (*fn)(void **entry, void *user); + isl_stat (*fn)(void **entry, void *user); }; -static int apply_range_entry(void **entry, void *user) +static isl_stat apply_range_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; - int empty; + isl_bool empty; - if (!isl_space_tuple_match(data->map->dim, isl_dim_out, + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_out, map2->dim, isl_dim_in)) - return 0; + return isl_stat_ok; map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2)); empty = isl_map_is_empty(map2); if (empty < 0) { isl_map_free(map2); - return -1; + return isl_stat_error; } if (empty) { isl_map_free(map2); - return 0; + return isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } -static int bin_entry(void **entry, void *user) +static isl_stat bin_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map = *entry; @@ -1178,13 +1258,14 @@ data->map = map; if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table, data->fn, data) < 0) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1, - __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user)) + __isl_take isl_union_map *umap2, + isl_stat (*fn)(void **entry, void *user)) { struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn }; @@ -1231,20 +1312,20 @@ return isl_union_map_apply_range(uset, umap); } -static int map_lex_lt_entry(void **entry, void *user) +static isl_stat map_lex_lt_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; - if (!isl_space_tuple_match(data->map->dim, isl_dim_out, + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_out, map2->dim, isl_dim_out)) - return 0; + return isl_stat_ok; map2 = isl_map_lex_lt_map(isl_map_copy(data->map), isl_map_copy(map2)); data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_lex_lt_union_map( @@ -1253,20 +1334,20 @@ return bin_op(umap1, umap2, &map_lex_lt_entry); } -static int map_lex_le_entry(void **entry, void *user) +static isl_stat map_lex_le_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; - if (!isl_space_tuple_match(data->map->dim, isl_dim_out, + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_out, map2->dim, isl_dim_out)) - return 0; + return isl_stat_ok; map2 = isl_map_lex_le_map(isl_map_copy(data->map), isl_map_copy(map2)); data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_lex_le_union_map( @@ -1275,7 +1356,7 @@ return bin_op(umap1, umap2, &map_lex_le_entry); } -static int product_entry(void **entry, void *user) +static isl_stat product_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; @@ -1284,7 +1365,7 @@ data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1, @@ -1293,7 +1374,7 @@ return bin_op(umap1, umap2, &product_entry); } -static int set_product_entry(void **entry, void *user) +static isl_stat set_product_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_set *set2 = *entry; @@ -1302,7 +1383,7 @@ data->res = isl_union_set_add_set(data->res, set2); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1, @@ -1311,21 +1392,21 @@ return bin_op(uset1, uset2, &set_product_entry); } -static int domain_product_entry(void **entry, void *user) +static isl_stat domain_product_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; - if (!isl_space_tuple_match(data->map->dim, isl_dim_out, + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_out, map2->dim, isl_dim_out)) - return 0; + return isl_stat_ok; map2 = isl_map_domain_product(isl_map_copy(data->map), isl_map_copy(map2)); data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D) @@ -1336,21 +1417,21 @@ return bin_op(umap1, umap2, &domain_product_entry); } -static int range_product_entry(void **entry, void *user) +static isl_stat range_product_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; - if (!isl_space_tuple_match(data->map->dim, isl_dim_in, + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_in, map2->dim, isl_dim_in)) - return 0; + return isl_stat_ok; map2 = isl_map_range_product(isl_map_copy(data->map), isl_map_copy(map2)); data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_range_product( @@ -1359,21 +1440,49 @@ return bin_op(umap1, umap2, &range_product_entry); } -static int flat_range_product_entry(void **entry, void *user) +/* If data->map A -> B and "map2" C -> D have the same range space, + * then add (A, C) -> (B * D) to data->res. + */ +static isl_stat flat_domain_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_out, + map2->dim, isl_dim_out)) + return isl_stat_ok; + + map2 = isl_map_flat_domain_product(isl_map_copy(data->map), + isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return isl_stat_ok; +} + +/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D). + */ +__isl_give isl_union_map *isl_union_map_flat_domain_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &flat_domain_product_entry); +} + +static isl_stat flat_range_product_entry(void **entry, void *user) { struct isl_union_map_bin_data *data = user; isl_map *map2 = *entry; - if (!isl_space_tuple_match(data->map->dim, isl_dim_in, + if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_in, map2->dim, isl_dim_in)) - return 0; + return isl_stat_ok; map2 = isl_map_flat_range_product(isl_map_copy(data->map), isl_map_copy(map2)); data->res = isl_union_map_add_map(data->res, map2); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_flat_range_product( @@ -1383,7 +1492,7 @@ } static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap, - int (*fn)(void **, void *)) + isl_stat (*fn)(void **, void *)) { isl_union_set *res; @@ -1402,7 +1511,7 @@ return NULL; } -static int from_range_entry(void **entry, void *user) +static isl_stat from_range_entry(void **entry, void *user) { isl_map *set = *entry; isl_union_set **res = user; @@ -1410,7 +1519,7 @@ *res = isl_union_map_add_map(*res, isl_map_from_range(isl_set_copy(set))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_from_range( @@ -1433,7 +1542,7 @@ } static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap, - int (*fn)(void **, void *)) + isl_stat (*fn)(void **, void *)) { umap = isl_union_map_cow(umap); if (!umap) @@ -1448,13 +1557,13 @@ return NULL; } -static int affine_entry(void **entry, void *user) +static isl_stat affine_entry(void **entry, void *user) { isl_map **map = (isl_map **)entry; *map = isl_map_from_basic_map(isl_map_affine_hull(*map)); - return *map ? 0 : -1; + return *map ? isl_stat_ok : isl_stat_error; } __isl_give isl_union_map *isl_union_map_affine_hull( @@ -1469,13 +1578,13 @@ return isl_union_map_affine_hull(uset); } -static int polyhedral_entry(void **entry, void *user) +static isl_stat polyhedral_entry(void **entry, void *user) { isl_map **map = (isl_map **)entry; *map = isl_map_from_basic_map(isl_map_polyhedral_hull(*map)); - return *map ? 0 : -1; + return *map ? isl_stat_ok : isl_stat_error; } __isl_give isl_union_map *isl_union_map_polyhedral_hull( @@ -1490,13 +1599,13 @@ return isl_union_map_polyhedral_hull(uset); } -static int simple_entry(void **entry, void *user) +static isl_stat simple_entry(void **entry, void *user) { isl_map **map = (isl_map **)entry; *map = isl_map_from_basic_map(isl_map_simple_hull(*map)); - return *map ? 0 : -1; + return *map ? isl_stat_ok : isl_stat_error; } __isl_give isl_union_map *isl_union_map_simple_hull( @@ -1511,7 +1620,7 @@ return isl_union_map_simple_hull(uset); } -static int inplace_entry(void **entry, void *user) +static isl_stat inplace_entry(void **entry, void *user) { __isl_give isl_map *(*fn)(__isl_take isl_map *); isl_map **map = (isl_map **)entry; @@ -1520,12 +1629,12 @@ fn = *(__isl_give isl_map *(**)(__isl_take isl_map *)) user; copy = fn(isl_map_copy(*map)); if (!copy) - return -1; + return isl_stat_error; isl_map_free(*map); *map = copy; - return 0; + return isl_stat_ok; } static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap, @@ -1544,6 +1653,24 @@ return NULL; } +/* Remove redundant constraints in each of the basic maps of "umap". + * Since removing redundant constraints does not change the meaning + * or the space, the operation can be performed in-place. + */ +__isl_give isl_union_map *isl_union_map_remove_redundancies( + __isl_take isl_union_map *umap) +{ + return inplace(umap, &isl_map_remove_redundancies); +} + +/* Remove redundant constraints in each of the basic sets of "uset". + */ +__isl_give isl_union_set *isl_union_set_remove_redundancies( + __isl_take isl_union_set *uset) +{ + return isl_union_map_remove_redundancies(uset); +} + __isl_give isl_union_map *isl_union_map_coalesce( __isl_take isl_union_map *umap) { @@ -1580,13 +1707,13 @@ return isl_union_map_compute_divs(uset); } -static int lexmin_entry(void **entry, void *user) +static isl_stat lexmin_entry(void **entry, void *user) { isl_map **map = (isl_map **)entry; *map = isl_map_lexmin(*map); - return *map ? 0 : -1; + return *map ? isl_stat_ok : isl_stat_error; } __isl_give isl_union_map *isl_union_map_lexmin( @@ -1601,13 +1728,13 @@ return isl_union_map_lexmin(uset); } -static int lexmax_entry(void **entry, void *user) +static isl_stat lexmax_entry(void **entry, void *user) { isl_map **map = (isl_map **)entry; *map = isl_map_lexmax(*map); - return *map ? 0 : -1; + return *map ? isl_stat_ok : isl_stat_error; } __isl_give isl_union_map *isl_union_map_lexmax( @@ -1622,7 +1749,7 @@ return isl_union_map_lexmax(uset); } -static int universe_entry(void **entry, void *user) +static isl_stat universe_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_map **res = user; @@ -1630,7 +1757,7 @@ map = isl_map_universe(isl_map_get_space(map)); *res = isl_union_map_add_map(*res, map); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_universe(__isl_take isl_union_map *umap) @@ -1643,14 +1770,14 @@ return isl_union_map_universe(uset); } -static int reverse_entry(void **entry, void *user) +static isl_stat reverse_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_map **res = user; *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap) @@ -1658,14 +1785,14 @@ return cond_un_op(umap, &reverse_entry); } -static int params_entry(void **entry, void *user) +static isl_stat params_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; *res = isl_union_set_add_set(*res, isl_map_params(isl_map_copy(map))); - return 0; + return isl_stat_ok; } /* Compute the parameter domain of the given union map. @@ -1676,7 +1803,7 @@ empty = isl_union_map_is_empty(umap); if (empty < 0) - return isl_union_map_free(umap); + goto error; if (empty) { isl_space *space; space = isl_union_map_get_space(umap); @@ -1684,6 +1811,9 @@ return isl_set_empty(space); } return isl_set_from_union_set(cond_un_op(umap, ¶ms_entry)); +error: + isl_union_map_free(umap); + return NULL; } /* Compute the parameter domain of the given union set. @@ -1693,14 +1823,14 @@ return isl_union_map_params(uset); } -static int domain_entry(void **entry, void *user) +static isl_stat domain_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap) @@ -1708,14 +1838,14 @@ return cond_un_op(umap, &domain_entry); } -static int range_entry(void **entry, void *user) +static isl_stat range_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap) @@ -1723,7 +1853,7 @@ return cond_un_op(umap, &range_entry); } -static int domain_map_entry(void **entry, void *user) +static isl_stat domain_map_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; @@ -1731,7 +1861,7 @@ *res = isl_union_map_add_map(*res, isl_map_domain_map(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_domain_map( @@ -1740,7 +1870,40 @@ return cond_un_op(umap, &domain_map_entry); } -static int range_map_entry(void **entry, void *user) +/* Construct an isl_pw_multi_aff that maps "map" to its domain and + * add the result to "res". + */ +static isl_stat domain_map_upma(__isl_take isl_map *map, void *user) +{ + isl_union_pw_multi_aff **res = user; + isl_multi_aff *ma; + isl_pw_multi_aff *pma; + + ma = isl_multi_aff_domain_map(isl_map_get_space(map)); + pma = isl_pw_multi_aff_alloc(isl_map_wrap(map), ma); + *res = isl_union_pw_multi_aff_add_pw_multi_aff(*res, pma); + + return *res ? isl_stat_ok : isl_stat_error; + +} + +/* Return an isl_union_pw_multi_aff that maps a wrapped copy of "umap" + * to its domain. + */ +__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff( + __isl_take isl_union_map *umap) +{ + isl_union_pw_multi_aff *res; + + res = isl_union_pw_multi_aff_empty(isl_union_map_get_space(umap)); + if (isl_union_map_foreach_map(umap, &domain_map_upma, &res) < 0) + res = isl_union_pw_multi_aff_free(res); + + isl_union_map_free(umap); + return res; +} + +static isl_stat range_map_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; @@ -1748,7 +1911,7 @@ *res = isl_union_map_add_map(*res, isl_map_range_map(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_range_map( @@ -1757,17 +1920,48 @@ return cond_un_op(umap, &range_map_entry); } -static int deltas_entry(void **entry, void *user) +/* Check if "set" is of the form A[B -> C]. + * If so, add A[B -> C] -> B to "res". + */ +static isl_stat wrapped_domain_map_entry(void **entry, void *user) +{ + isl_set *set = *entry; + isl_union_set **res = user; + int wrapping; + + wrapping = isl_set_is_wrapping(set); + if (wrapping < 0) + return isl_stat_error; + if (!wrapping) + return isl_stat_ok; + + *res = isl_union_map_add_map(*res, + isl_set_wrapped_domain_map(isl_set_copy(set))); + + return isl_stat_ok; +} + +/* Given a collection of wrapped maps of the form A[B -> C], + * return the collection of maps A[B -> C] -> B. + */ +__isl_give isl_union_map *isl_union_set_wrapped_domain_map( + __isl_take isl_union_set *uset) +{ + return cond_un_op(uset, &wrapped_domain_map_entry); +} + +static isl_stat deltas_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; - if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out)) - return 0; + if (!isl_space_tuple_is_equal(map->dim, isl_dim_in, + map->dim, isl_dim_out)) + return isl_stat_ok; *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap) @@ -1775,18 +1969,19 @@ return cond_un_op(umap, &deltas_entry); } -static int deltas_map_entry(void **entry, void *user) +static isl_stat deltas_map_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_map **res = user; - if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out)) - return 0; + if (!isl_space_tuple_is_equal(map->dim, isl_dim_in, + map->dim, isl_dim_out)) + return isl_stat_ok; *res = isl_union_map_add_map(*res, isl_map_deltas_map(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_deltas_map( @@ -1795,14 +1990,14 @@ return cond_un_op(umap, &deltas_map_entry); } -static int identity_entry(void **entry, void *user) +static isl_stat identity_entry(void **entry, void *user) { isl_set *set = *entry; isl_union_map **res = user; *res = isl_union_map_add_map(*res, isl_set_identity(isl_set_copy(set))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset) @@ -1810,17 +2005,174 @@ return cond_un_op(uset, &identity_entry); } -static int unwrap_entry(void **entry, void *user) +/* Construct an identity isl_pw_multi_aff on "set" and add it to *res. + */ +static isl_stat identity_upma(__isl_take isl_set *set, void *user) +{ + isl_union_pw_multi_aff **res = user; + isl_space *space; + isl_pw_multi_aff *pma; + + space = isl_space_map_from_set(isl_set_get_space(set)); + pma = isl_pw_multi_aff_identity(space); + pma = isl_pw_multi_aff_intersect_domain(pma, set); + *res = isl_union_pw_multi_aff_add_pw_multi_aff(*res, pma); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* Return an identity function on "uset" in the form + * of an isl_union_pw_multi_aff. + */ +__isl_give isl_union_pw_multi_aff *isl_union_set_identity_union_pw_multi_aff( + __isl_take isl_union_set *uset) +{ + isl_union_pw_multi_aff *res; + + res = isl_union_pw_multi_aff_empty(isl_union_set_get_space(uset)); + if (isl_union_set_foreach_set(uset, &identity_upma, &res) < 0) + res = isl_union_pw_multi_aff_free(res); + + isl_union_set_free(uset); + return res; +} + +/* If "map" is of the form [A -> B] -> C, then add A -> C to "res". + */ +static isl_stat domain_factor_domain_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_union_map **res = user; + + if (!isl_map_domain_is_wrapping(map)) + return isl_stat_ok; + + *res = isl_union_map_add_map(*res, + isl_map_domain_factor_domain(isl_map_copy(map))); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* For each map in "umap" of the form [A -> B] -> C, + * construct the map A -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_domain_factor_domain( + __isl_take isl_union_map *umap) +{ + return cond_un_op(umap, &domain_factor_domain_entry); +} + +/* If "map" is of the form [A -> B] -> C, then add B -> C to "res". + */ +static isl_stat domain_factor_range_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_union_map **res = user; + + if (!isl_map_domain_is_wrapping(map)) + return isl_stat_ok; + + *res = isl_union_map_add_map(*res, + isl_map_domain_factor_range(isl_map_copy(map))); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* For each map in "umap" of the form [A -> B] -> C, + * construct the map B -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_domain_factor_range( + __isl_take isl_union_map *umap) +{ + return cond_un_op(umap, &domain_factor_range_entry); +} + +/* If "map" is of the form A -> [B -> C], then add A -> C to "res". + */ +static isl_stat range_factor_range_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_union_map **res = user; + + if (!isl_map_range_is_wrapping(map)) + return isl_stat_ok; + + *res = isl_union_map_add_map(*res, + isl_map_range_factor_range(isl_map_copy(map))); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* For each map in "umap" of the form A -> [B -> C], + * construct the map A -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_range_factor_range( + __isl_take isl_union_map *umap) +{ + return cond_un_op(umap, &range_factor_range_entry); +} + +/* If "map" is of the form [A -> B] -> [C -> D], then add A -> C to "res". + */ +static isl_stat factor_domain_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_union_map **res = user; + + if (!isl_map_domain_is_wrapping(map) || !isl_map_range_is_wrapping(map)) + return isl_stat_ok; + + *res = isl_union_map_add_map(*res, + isl_map_factor_domain(isl_map_copy(map))); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* For each map in "umap" of the form [A -> B] -> [C -> D], + * construct the map A -> C and collect the results. + */ +__isl_give isl_union_map *isl_union_map_factor_domain( + __isl_take isl_union_map *umap) +{ + return cond_un_op(umap, &factor_domain_entry); +} + +/* If "map" is of the form [A -> B] -> [C -> D], then add B -> D to "res". + */ +static isl_stat factor_range_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_union_map **res = user; + + if (!isl_map_domain_is_wrapping(map) || !isl_map_range_is_wrapping(map)) + return isl_stat_ok; + + *res = isl_union_map_add_map(*res, + isl_map_factor_range(isl_map_copy(map))); + + return *res ? isl_stat_ok : isl_stat_error; +} + +/* For each map in "umap" of the form [A -> B] -> [C -> D], + * construct the map B -> D and collect the results. + */ +__isl_give isl_union_map *isl_union_map_factor_range( + __isl_take isl_union_map *umap) +{ + return cond_un_op(umap, &factor_range_entry); +} + +static isl_stat unwrap_entry(void **entry, void *user) { isl_set *set = *entry; isl_union_set **res = user; if (!isl_set_is_wrapping(set)) - return 0; + return isl_stat_ok; *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset) @@ -1828,14 +2180,14 @@ return cond_un_op(uset, &unwrap_entry); } -static int wrap_entry(void **entry, void *user) +static isl_stat wrap_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_set **res = user; *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap) @@ -1845,10 +2197,10 @@ struct isl_union_map_is_subset_data { isl_union_map *umap2; - int is_subset; + isl_bool is_subset; }; -static int is_subset_entry(void **entry, void *user) +static isl_stat is_subset_entry(void **entry, void *user) { struct isl_union_map_is_subset_data *data = user; uint32_t hash; @@ -1861,24 +2213,24 @@ if (!entry2) { int empty = isl_map_is_empty(map); if (empty < 0) - return -1; + return isl_stat_error; if (empty) - return 0; + return isl_stat_ok; data->is_subset = 0; - return -1; + return isl_stat_error; } data->is_subset = isl_map_is_subset(map, entry2->data); if (data->is_subset < 0 || !data->is_subset) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } -int isl_union_map_is_subset(__isl_keep isl_union_map *umap1, +isl_bool isl_union_map_is_subset(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2) { - struct isl_union_map_is_subset_data data = { NULL, 1 }; + struct isl_union_map_is_subset_data data = { NULL, isl_bool_true }; umap1 = isl_union_map_copy(umap1); umap2 = isl_union_map_copy(umap2); @@ -1901,68 +2253,142 @@ error: isl_union_map_free(umap1); isl_union_map_free(umap2); - return -1; + return isl_bool_error; } -int isl_union_set_is_subset(__isl_keep isl_union_set *uset1, +isl_bool isl_union_set_is_subset(__isl_keep isl_union_set *uset1, __isl_keep isl_union_set *uset2) { return isl_union_map_is_subset(uset1, uset2); } -int isl_union_map_is_equal(__isl_keep isl_union_map *umap1, +isl_bool isl_union_map_is_equal(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2) { - int is_subset; + isl_bool is_subset; if (!umap1 || !umap2) - return -1; + return isl_bool_error; is_subset = isl_union_map_is_subset(umap1, umap2); - if (is_subset != 1) + if (is_subset != isl_bool_true) return is_subset; is_subset = isl_union_map_is_subset(umap2, umap1); return is_subset; } -int isl_union_set_is_equal(__isl_keep isl_union_set *uset1, +isl_bool isl_union_set_is_equal(__isl_keep isl_union_set *uset1, __isl_keep isl_union_set *uset2) { return isl_union_map_is_equal(uset1, uset2); } -int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1, +isl_bool isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2) { - int is_subset; + isl_bool is_subset; if (!umap1 || !umap2) - return -1; + return isl_bool_error; is_subset = isl_union_map_is_subset(umap1, umap2); - if (is_subset != 1) + if (is_subset != isl_bool_true) return is_subset; is_subset = isl_union_map_is_subset(umap2, umap1); - if (is_subset == -1) + if (is_subset == isl_bool_error) return is_subset; return !is_subset; } -int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1, +isl_bool isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1, __isl_keep isl_union_set *uset2) { return isl_union_map_is_strict_subset(uset1, uset2); } -static int sample_entry(void **entry, void *user) -{ - isl_basic_map **sample = (isl_basic_map **)user; - isl_map *map = *entry; - +/* Internal data structure for isl_union_map_is_disjoint. + * umap2 is the union map with which we are comparing. + * is_disjoint is initialized to 1 and is set to 0 as soon + * as the union maps turn out not to be disjoint. + */ +struct isl_union_map_is_disjoint_data { + isl_union_map *umap2; + isl_bool is_disjoint; +}; + +/* Check if "map" is disjoint from data->umap2 and abort + * the search if it is not. + */ +static isl_stat is_disjoint_entry(void **entry, void *user) +{ + struct isl_union_map_is_disjoint_data *data = user; + uint32_t hash; + struct isl_hash_table_entry *entry2; + isl_map *map = *entry; + + hash = isl_space_get_hash(map->dim); + entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table, + hash, &has_dim, map->dim, 0); + if (!entry2) + return isl_stat_ok; + + data->is_disjoint = isl_map_is_disjoint(map, entry2->data); + if (data->is_disjoint < 0 || !data->is_disjoint) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Are "umap1" and "umap2" disjoint? + */ +isl_bool isl_union_map_is_disjoint(__isl_keep isl_union_map *umap1, + __isl_keep isl_union_map *umap2) +{ + struct isl_union_map_is_disjoint_data data = { NULL, isl_bool_true }; + + umap1 = isl_union_map_copy(umap1); + umap2 = isl_union_map_copy(umap2); + umap1 = isl_union_map_align_params(umap1, + isl_union_map_get_space(umap2)); + umap2 = isl_union_map_align_params(umap2, + isl_union_map_get_space(umap1)); + + if (!umap1 || !umap2) + goto error; + + data.umap2 = umap2; + if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, + &is_disjoint_entry, &data) < 0 && + data.is_disjoint) + goto error; + + isl_union_map_free(umap1); + isl_union_map_free(umap2); + + return data.is_disjoint; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return isl_bool_error; +} + +/* Are "uset1" and "uset2" disjoint? + */ +isl_bool isl_union_set_is_disjoint(__isl_keep isl_union_set *uset1, + __isl_keep isl_union_set *uset2) +{ + return isl_union_map_is_disjoint(uset1, uset2); +} + +static isl_stat sample_entry(void **entry, void *user) +{ + isl_basic_map **sample = (isl_basic_map **)user; + isl_map *map = *entry; + *sample = isl_map_sample(isl_map_copy(map)); if (!*sample) - return -1; + return isl_stat_error; if (!isl_basic_map_plain_is_empty(*sample)) - return -1; - return 0; + return isl_stat_error; + return isl_stat_ok; } __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap) @@ -1994,99 +2420,100 @@ } struct isl_forall_data { - int res; - int (*fn)(__isl_keep isl_map *map); + isl_bool res; + isl_bool (*fn)(__isl_keep isl_map *map); }; -static int forall_entry(void **entry, void *user) +static isl_stat forall_entry(void **entry, void *user) { struct isl_forall_data *data = user; isl_map *map = *entry; data->res = data->fn(map); if (data->res < 0) - return -1; + return isl_stat_error; if (!data->res) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } -static int union_map_forall(__isl_keep isl_union_map *umap, - int (*fn)(__isl_keep isl_map *map)) +static isl_bool union_map_forall(__isl_keep isl_union_map *umap, + isl_bool (*fn)(__isl_keep isl_map *map)) { - struct isl_forall_data data = { 1, fn }; + struct isl_forall_data data = { isl_bool_true, fn }; if (!umap) - return -1; + return isl_bool_error; if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, &forall_entry, &data) < 0 && data.res) - return -1; + return isl_bool_error; return data.res; } struct isl_forall_user_data { - int res; - int (*fn)(__isl_keep isl_map *map, void *user); + isl_bool res; + isl_bool (*fn)(__isl_keep isl_map *map, void *user); void *user; }; -static int forall_user_entry(void **entry, void *user) +static isl_stat forall_user_entry(void **entry, void *user) { struct isl_forall_user_data *data = user; isl_map *map = *entry; data->res = data->fn(map, data->user); if (data->res < 0) - return -1; + return isl_stat_error; if (!data->res) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Check if fn(map, user) returns true for all maps "map" in umap. */ -static int union_map_forall_user(__isl_keep isl_union_map *umap, - int (*fn)(__isl_keep isl_map *map, void *user), void *user) +static isl_bool union_map_forall_user(__isl_keep isl_union_map *umap, + isl_bool (*fn)(__isl_keep isl_map *map, void *user), void *user) { - struct isl_forall_user_data data = { 1, fn, user }; + struct isl_forall_user_data data = { isl_bool_true, fn, user }; if (!umap) - return -1; + return isl_bool_error; if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, &forall_user_entry, &data) < 0 && data.res) - return -1; + return isl_bool_error; return data.res; } -int isl_union_map_is_empty(__isl_keep isl_union_map *umap) +isl_bool isl_union_map_is_empty(__isl_keep isl_union_map *umap) { return union_map_forall(umap, &isl_map_is_empty); } -int isl_union_set_is_empty(__isl_keep isl_union_set *uset) +isl_bool isl_union_set_is_empty(__isl_keep isl_union_set *uset) { return isl_union_map_is_empty(uset); } -static int is_subset_of_identity(__isl_keep isl_map *map) +static isl_bool is_subset_of_identity(__isl_keep isl_map *map) { - int is_subset; + isl_bool is_subset; isl_space *dim; isl_map *id; if (!map) - return -1; + return isl_bool_error; - if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out)) - return 0; + if (!isl_space_tuple_is_equal(map->dim, isl_dim_in, + map->dim, isl_dim_out)) + return isl_bool_false; dim = isl_map_get_space(map); id = isl_map_identity(dim); @@ -2098,40 +2525,104 @@ return is_subset; } -/* Check if the given map is single-valued. - * We simply compute +/* Given an isl_union_map that consists of a single map, check + * if it is single-valued. + */ +static isl_bool single_map_is_single_valued(__isl_keep isl_union_map *umap) +{ + isl_map *map; + isl_bool sv; + + umap = isl_union_map_copy(umap); + map = isl_map_from_union_map(umap); + sv = isl_map_is_single_valued(map); + isl_map_free(map); + + return sv; +} + +/* Internal data structure for single_valued_on_domain. + * + * "umap" is the union map to be tested. + * "sv" is set to 1 as long as "umap" may still be single-valued. + */ +struct isl_union_map_is_sv_data { + isl_union_map *umap; + isl_bool sv; +}; + +/* Check if the data->umap is single-valued on "set". + * + * If data->umap consists of a single map on "set", then test it + * as an isl_map. + * + * Otherwise, compute * * M \circ M^-1 * - * and check if the result is a subset of the identity mapping. + * check if the result is a subset of the identity mapping and + * store the result in data->sv. + * + * Terminate as soon as data->umap has been determined not to + * be single-valued. */ -int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap) +static isl_stat single_valued_on_domain(__isl_take isl_set *set, void *user) { - isl_union_map *test; - int sv; + struct isl_union_map_is_sv_data *data = user; + isl_union_map *umap, *test; + + umap = isl_union_map_copy(data->umap); + umap = isl_union_map_intersect_domain(umap, + isl_union_set_from_set(set)); if (isl_union_map_n_map(umap) == 1) { - isl_map *map; - umap = isl_union_map_copy(umap); - map = isl_map_from_union_map(umap); - sv = isl_map_is_single_valued(map); - isl_map_free(map); - return sv; + data->sv = single_map_is_single_valued(umap); + isl_union_map_free(umap); + } else { + test = isl_union_map_reverse(isl_union_map_copy(umap)); + test = isl_union_map_apply_range(test, umap); + + data->sv = union_map_forall(test, &is_subset_of_identity); + + isl_union_map_free(test); } - test = isl_union_map_reverse(isl_union_map_copy(umap)); - test = isl_union_map_apply_range(test, isl_union_map_copy(umap)); + if (data->sv < 0 || !data->sv) + return isl_stat_error; + return isl_stat_ok; +} - sv = union_map_forall(test, &is_subset_of_identity); +/* Check if the given map is single-valued. + * + * If the union map consists of a single map, then test it as an isl_map. + * Otherwise, check if the union map is single-valued on each of its + * domain spaces. + */ +isl_bool isl_union_map_is_single_valued(__isl_keep isl_union_map *umap) +{ + isl_union_map *universe; + isl_union_set *domain; + struct isl_union_map_is_sv_data data; - isl_union_map_free(test); + if (isl_union_map_n_map(umap) == 1) + return single_map_is_single_valued(umap); - return sv; + universe = isl_union_map_universe(isl_union_map_copy(umap)); + domain = isl_union_map_domain(universe); + + data.sv = isl_bool_true; + data.umap = umap; + if (isl_union_set_foreach_set(domain, + &single_valued_on_domain, &data) < 0 && data.sv) + data.sv = isl_bool_error; + isl_union_set_free(domain); + + return data.sv; } -int isl_union_map_is_injective(__isl_keep isl_union_map *umap) +isl_bool isl_union_map_is_injective(__isl_keep isl_union_map *umap) { - int in; + isl_bool in; umap = isl_union_map_copy(umap); umap = isl_union_map_reverse(umap); @@ -2199,7 +2690,7 @@ int pos; }; -static int fixed_at_pos(__isl_keep isl_map *map, void *user) +static isl_bool fixed_at_pos(__isl_keep isl_map *map, void *user) { struct isl_fixed_dim_data *data = user; @@ -2208,7 +2699,7 @@ &data->v[data->n++].v); } -static int plain_injective_on_range(__isl_take isl_union_map *umap, +static isl_bool plain_injective_on_range(__isl_take isl_union_map *umap, int first, int n_range); /* Given a list of the maps, with their fixed values at output dimension "pos", @@ -2272,7 +2763,7 @@ * and then check if these values, possibly along with fixed values * at later dimensions, entail distinct ranges. */ -static int plain_injective_on_range(__isl_take isl_union_map *umap, +static isl_bool plain_injective_on_range(__isl_take isl_union_map *umap, int first, int n_range) { isl_ctx *ctx; @@ -2287,12 +2778,12 @@ if (n <= 1) { isl_union_map_free(umap); - return 1; + return isl_bool_true; } if (first >= n_range) { isl_union_map_free(umap); - return 0; + return isl_bool_false; } data.v = alloc_isl_fixed_map_array(ctx, n); @@ -2300,7 +2791,7 @@ goto error; for (data.pos = first; data.pos < n_range; ++data.pos) { - int fixed; + isl_bool fixed; int injective; isl_space *dim; @@ -2319,17 +2810,18 @@ free_isl_fixed_map_array(data.v, n); isl_union_map_free(umap); - return 0; + return isl_bool_false; error: free_isl_fixed_map_array(data.v, n); isl_union_map_free(umap); - return -1; + return isl_bool_error; } /* Check whether the maps in umap that map to subsets of "ran" * have obviously distinct ranges. */ -static int plain_injective_on_range_wrap(__isl_keep isl_set *ran, void *user) +static isl_bool plain_injective_on_range_wrap(__isl_keep isl_set *ran, + void *user) { isl_union_map *umap = user; @@ -2345,17 +2837,17 @@ * injective and then check if all the ranges of these maps are * obviously disjoint. */ -int isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap) +isl_bool isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap) { - int in; + isl_bool in; isl_union_map *univ; isl_union_set *ran; in = union_map_forall(umap, &isl_map_plain_is_injective); if (in < 0) - return -1; + return isl_bool_error; if (!in) - return 0; + return isl_bool_false; univ = isl_union_map_universe(isl_union_map_copy(umap)); ran = isl_union_map_range(univ); @@ -2367,9 +2859,9 @@ return in; } -int isl_union_map_is_bijective(__isl_keep isl_union_map *umap) +isl_bool isl_union_map_is_bijective(__isl_keep isl_union_map *umap) { - int sv; + isl_bool sv; sv = isl_union_map_is_single_valued(umap); if (sv < 0 || !sv) @@ -2378,17 +2870,17 @@ return isl_union_map_is_injective(umap); } -static int zip_entry(void **entry, void *user) +static isl_stat zip_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_map **res = user; if (!isl_map_can_zip(map)) - return 0; + return isl_stat_ok; *res = isl_union_map_add_map(*res, isl_map_zip(isl_map_copy(map))); - return 0; + return isl_stat_ok; } __isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap) @@ -2396,17 +2888,17 @@ return cond_un_op(umap, &zip_entry); } -static int uncurry_entry(void **entry, void *user) +static isl_stat uncurry_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_map **res = user; if (!isl_map_can_uncurry(map)) - return 0; + return isl_stat_ok; *res = isl_union_map_add_map(*res, isl_map_uncurry(isl_map_copy(map))); - return 0; + return isl_stat_ok; } /* Given a union map, take the maps of the form A -> (B -> C) and @@ -2417,17 +2909,17 @@ return cond_un_op(umap, &uncurry_entry); } -static int curry_entry(void **entry, void *user) +static isl_stat curry_entry(void **entry, void *user) { isl_map *map = *entry; isl_union_map **res = user; if (!isl_map_can_curry(map)) - return 0; + return isl_stat_ok; *res = isl_union_map_add_map(*res, isl_map_curry(isl_map_copy(map))); - return 0; + return isl_stat_ok; } /* Given a union map, take the maps of the form (A -> B) -> C and @@ -2438,14 +2930,14 @@ return cond_un_op(umap, &curry_entry); } -static int lift_entry(void **entry, void *user) +static isl_stat lift_entry(void **entry, void *user) { isl_set *set = *entry; isl_union_set **res = user; *res = isl_union_set_add_set(*res, isl_set_lift(isl_set_copy(set))); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset) @@ -2453,7 +2945,7 @@ return cond_un_op(uset, &lift_entry); } -static int coefficients_entry(void **entry, void *user) +static isl_stat coefficients_entry(void **entry, void *user) { isl_set *set = *entry; isl_union_set **res = user; @@ -2462,7 +2954,7 @@ set = isl_set_from_basic_set(isl_set_coefficients(set)); *res = isl_union_set_add_set(*res, set); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_set_coefficients( @@ -2490,7 +2982,7 @@ return NULL; } -static int solutions_entry(void **entry, void *user) +static isl_stat solutions_entry(void **entry, void *user) { isl_set *set = *entry; isl_union_set **res = user; @@ -2503,9 +2995,9 @@ *res = isl_union_set_add_set(*res, set); if (!*res) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } __isl_give isl_union_set *isl_union_set_solutions( @@ -2534,49 +3026,162 @@ return NULL; } -/* Internal data structure for isl_union_map_preimage_domain_multi_aff. +/* Is the domain space of "map" equal to "space"? + */ +static int domain_match(__isl_keep isl_map *map, __isl_keep isl_space *space) +{ + return isl_space_tuple_is_equal(map->dim, isl_dim_in, + space, isl_dim_out); +} + +/* Is the range space of "map" equal to "space"? + */ +static int range_match(__isl_keep isl_map *map, __isl_keep isl_space *space) +{ + return isl_space_tuple_is_equal(map->dim, isl_dim_out, + space, isl_dim_out); +} + +/* Is the set space of "map" equal to "space"? + */ +static int set_match(__isl_keep isl_map *map, __isl_keep isl_space *space) +{ + return isl_space_tuple_is_equal(map->dim, isl_dim_set, + space, isl_dim_out); +} + +/* Internal data structure for preimage_pw_multi_aff. * - * "ma" is the function under which the preimage should be taken. - * "space" is the space of "ma". + * "pma" is the function under which the preimage should be taken. + * "space" is the space of "pma". * "res" collects the results. + * "fn" computes the preimage for a given map. + * "match" returns true if "fn" can be called. */ -struct isl_union_map_preimage_domain_data { +struct isl_union_map_preimage_data { isl_space *space; - isl_multi_aff *ma; + isl_pw_multi_aff *pma; isl_union_map *res; + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space); + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma); }; -/* Compute the preimage of the domain of *entry under the function - * represented by data->ma, provided the domain space of *entry - * match the target space of data->ma, and add the result to data->res. +/* Call data->fn to compute the preimage of the domain or range of *entry + * under the function represented by data->pma, provided the domain/range + * space of *entry matches the target space of data->pma + * (as given by data->match), and add the result to data->res. */ -static int preimage_domain_entry(void **entry, void *user) +static isl_stat preimage_entry(void **entry, void *user) { int m; isl_map *map = *entry; - struct isl_union_map_preimage_domain_data *data = user; - int empty; + struct isl_union_map_preimage_data *data = user; + isl_bool empty; - m = isl_space_tuple_match(map->dim, isl_dim_in, - data->space, isl_dim_out); + m = data->match(map, data->space); if (m < 0) - return -1; + return isl_stat_error; if (!m) - return 0; + return isl_stat_ok; map = isl_map_copy(map); - map = isl_map_preimage_domain_multi_aff(map, - isl_multi_aff_copy(data->ma)); + map = data->fn(map, isl_pw_multi_aff_copy(data->pma)); empty = isl_map_is_empty(map); if (empty < 0 || empty) { isl_map_free(map); - return empty < 0 ? -1 : 0; + return empty < 0 ? isl_stat_error : isl_stat_ok; } data->res = isl_union_map_add_map(data->res, map); - return 0; + return isl_stat_ok; +} + +/* Compute the preimage of the domain or range of "umap" under the function + * represented by "pma". + * In other words, plug in "pma" in the domain or range of "umap". + * The function "fn" performs the actual preimage computation on a map, + * while "match" determines to which maps the function should be applied. + */ +static __isl_give isl_union_map *preimage_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma, + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space), + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_pw_multi_aff *pma)) +{ + isl_ctx *ctx; + isl_space *space; + struct isl_union_map_preimage_data data; + + umap = isl_union_map_align_params(umap, + isl_pw_multi_aff_get_space(pma)); + pma = isl_pw_multi_aff_align_params(pma, isl_union_map_get_space(umap)); + + if (!umap || !pma) + goto error; + + ctx = isl_union_map_get_ctx(umap); + space = isl_union_map_get_space(umap); + data.space = isl_pw_multi_aff_get_space(pma); + data.pma = pma; + data.res = isl_union_map_alloc(space, umap->table.n); + data.match = match; + data.fn = fn; + if (isl_hash_table_foreach(ctx, &umap->table, &preimage_entry, + &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_space_free(data.space); + isl_union_map_free(umap); + isl_pw_multi_aff_free(pma); + return data.res; +error: + isl_union_map_free(umap); + isl_pw_multi_aff_free(pma); + return NULL; +} + +/* Compute the preimage of the domain of "umap" under the function + * represented by "pma". + * In other words, plug in "pma" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to the target space of "pma", + * except that the domain has been replaced by the domain space of "pma". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma) +{ + return preimage_pw_multi_aff(umap, pma, &domain_match, + &isl_map_preimage_domain_pw_multi_aff); +} + +/* Compute the preimage of the range of "umap" under the function + * represented by "pma". + * In other words, plug in "pma" in the range of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with range space equal to the target space of "pma", + * except that the range has been replaced by the domain space of "pma". + */ +__isl_give isl_union_map *isl_union_map_preimage_range_pw_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma) +{ + return preimage_pw_multi_aff(umap, pma, &range_match, + &isl_map_preimage_range_pw_multi_aff); +} + +/* Compute the preimage of "uset" under the function represented by "pma". + * In other words, plug in "pma" in "uset". + * The result contains sets that live in the same spaces as the sets of "uset" + * with space equal to the target space of "pma", + * except that the space has been replaced by the domain space of "pma". + */ +__isl_give isl_union_set *isl_union_set_preimage_pw_multi_aff( + __isl_take isl_union_set *uset, __isl_take isl_pw_multi_aff *pma) +{ + return preimage_pw_multi_aff(uset, pma, &set_match, + &isl_set_preimage_pw_multi_aff); } /* Compute the preimage of the domain of "umap" under the function @@ -2589,28 +3194,570 @@ __isl_give isl_union_map *isl_union_map_preimage_domain_multi_aff( __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma) { + return isl_union_map_preimage_domain_pw_multi_aff(umap, + isl_pw_multi_aff_from_multi_aff(ma)); +} + +/* Compute the preimage of the range of "umap" under the function + * represented by "ma". + * In other words, plug in "ma" in the range of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with range space equal to the target space of "ma", + * except that the range has been replaced by the domain space of "ma". + */ +__isl_give isl_union_map *isl_union_map_preimage_range_multi_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma) +{ + return isl_union_map_preimage_range_pw_multi_aff(umap, + isl_pw_multi_aff_from_multi_aff(ma)); +} + +/* Compute the preimage of "uset" under the function represented by "ma". + * In other words, plug in "ma" in "uset". + * The result contains sets that live in the same spaces as the sets of "uset" + * with space equal to the target space of "ma", + * except that the space has been replaced by the domain space of "ma". + */ +__isl_give isl_union_map *isl_union_set_preimage_multi_aff( + __isl_take isl_union_set *uset, __isl_take isl_multi_aff *ma) +{ + return isl_union_set_preimage_pw_multi_aff(uset, + isl_pw_multi_aff_from_multi_aff(ma)); +} + +/* Internal data structure for preimage_multi_pw_aff. + * + * "mpa" is the function under which the preimage should be taken. + * "space" is the space of "mpa". + * "res" collects the results. + * "fn" computes the preimage for a given map. + * "match" returns true if "fn" can be called. + */ +struct isl_union_map_preimage_mpa_data { + isl_space *space; + isl_multi_pw_aff *mpa; + isl_union_map *res; + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space); + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa); +}; + +/* Call data->fn to compute the preimage of the domain or range of *entry + * under the function represented by data->mpa, provided the domain/range + * space of *entry matches the target space of data->mpa + * (as given by data->match), and add the result to data->res. + */ +static isl_stat preimage_mpa_entry(void **entry, void *user) +{ + int m; + isl_map *map = *entry; + struct isl_union_map_preimage_mpa_data *data = user; + isl_bool empty; + + m = data->match(map, data->space); + if (m < 0) + return isl_stat_error; + if (!m) + return isl_stat_ok; + + map = isl_map_copy(map); + map = data->fn(map, isl_multi_pw_aff_copy(data->mpa)); + + empty = isl_map_is_empty(map); + if (empty < 0 || empty) { + isl_map_free(map); + return empty < 0 ? isl_stat_error : isl_stat_ok; + } + + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +/* Compute the preimage of the domain or range of "umap" under the function + * represented by "mpa". + * In other words, plug in "mpa" in the domain or range of "umap". + * The function "fn" performs the actual preimage computation on a map, + * while "match" determines to which maps the function should be applied. + */ +static __isl_give isl_union_map *preimage_multi_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_pw_aff *mpa, + int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space), + __isl_give isl_map *(*fn)(__isl_take isl_map *map, + __isl_take isl_multi_pw_aff *mpa)) +{ isl_ctx *ctx; isl_space *space; - struct isl_union_map_preimage_domain_data data; + struct isl_union_map_preimage_mpa_data data; + + umap = isl_union_map_align_params(umap, + isl_multi_pw_aff_get_space(mpa)); + mpa = isl_multi_pw_aff_align_params(mpa, isl_union_map_get_space(umap)); - if (!umap || !ma) + if (!umap || !mpa) goto error; ctx = isl_union_map_get_ctx(umap); space = isl_union_map_get_space(umap); - data.space = isl_multi_aff_get_space(ma); - data.ma = ma; + data.space = isl_multi_pw_aff_get_space(mpa); + data.mpa = mpa; data.res = isl_union_map_alloc(space, umap->table.n); - if (isl_hash_table_foreach(ctx, &umap->table, &preimage_domain_entry, + data.match = match; + data.fn = fn; + if (isl_hash_table_foreach(ctx, &umap->table, &preimage_mpa_entry, &data) < 0) data.res = isl_union_map_free(data.res); isl_space_free(data.space); isl_union_map_free(umap); - isl_multi_aff_free(ma); + isl_multi_pw_aff_free(mpa); return data.res; error: isl_union_map_free(umap); - isl_multi_aff_free(ma); + isl_multi_pw_aff_free(mpa); return NULL; } + +/* Compute the preimage of the domain of "umap" under the function + * represented by "mpa". + * In other words, plug in "mpa" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to the target space of "mpa", + * except that the domain has been replaced by the domain space of "mpa". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_multi_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_pw_aff *mpa) +{ + return preimage_multi_pw_aff(umap, mpa, &domain_match, + &isl_map_preimage_domain_multi_pw_aff); +} + +/* Internal data structure for preimage_upma. + * + * "umap" is the map of which the preimage should be computed. + * "res" collects the results. + * "fn" computes the preimage for a given piecewise multi-affine function. + */ +struct isl_union_map_preimage_upma_data { + isl_union_map *umap; + isl_union_map *res; + __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma); +}; + +/* Call data->fn to compute the preimage of the domain or range of data->umap + * under the function represented by pma and add the result to data->res. + */ +static isl_stat preimage_upma(__isl_take isl_pw_multi_aff *pma, void *user) +{ + struct isl_union_map_preimage_upma_data *data = user; + isl_union_map *umap; + + umap = isl_union_map_copy(data->umap); + umap = data->fn(umap, pma); + data->res = isl_union_map_union(data->res, umap); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Compute the preimage of the domain or range of "umap" under the function + * represented by "upma". + * In other words, plug in "upma" in the domain or range of "umap". + * The function "fn" performs the actual preimage computation + * on a piecewise multi-affine function. + */ +static __isl_give isl_union_map *preimage_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma, + __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap, + __isl_take isl_pw_multi_aff *pma)) +{ + struct isl_union_map_preimage_upma_data data; + + data.umap = umap; + data.res = isl_union_map_empty(isl_union_map_get_space(umap)); + data.fn = fn; + if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, + &preimage_upma, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_union_map_free(umap); + isl_union_pw_multi_aff_free(upma); + + return data.res; +} + +/* Compute the preimage of the domain of "umap" under the function + * represented by "upma". + * In other words, plug in "upma" in the domain of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with domain space equal to one of the target spaces of "upma", + * except that the domain has been replaced by one of the the domain spaces that + * corresponds to that target space of "upma". + */ +__isl_give isl_union_map *isl_union_map_preimage_domain_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma) +{ + return preimage_union_pw_multi_aff(umap, upma, + &isl_union_map_preimage_domain_pw_multi_aff); +} + +/* Compute the preimage of the range of "umap" under the function + * represented by "upma". + * In other words, plug in "upma" in the range of "umap". + * The result contains maps that live in the same spaces as the maps of "umap" + * with range space equal to one of the target spaces of "upma", + * except that the range has been replaced by one of the the domain spaces that + * corresponds to that target space of "upma". + */ +__isl_give isl_union_map *isl_union_map_preimage_range_union_pw_multi_aff( + __isl_take isl_union_map *umap, + __isl_take isl_union_pw_multi_aff *upma) +{ + return preimage_union_pw_multi_aff(umap, upma, + &isl_union_map_preimage_range_pw_multi_aff); +} + +/* Compute the preimage of "uset" under the function represented by "upma". + * In other words, plug in "upma" in the range of "uset". + * The result contains sets that live in the same spaces as the sets of "uset" + * with space equal to one of the target spaces of "upma", + * except that the space has been replaced by one of the the domain spaces that + * corresponds to that target space of "upma". + */ +__isl_give isl_union_set *isl_union_set_preimage_union_pw_multi_aff( + __isl_take isl_union_set *uset, + __isl_take isl_union_pw_multi_aff *upma) +{ + return preimage_union_pw_multi_aff(uset, upma, + &isl_union_set_preimage_pw_multi_aff); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of *entry. + */ +static isl_stat reset_user(void **entry, void *user) +{ + isl_map **map = (isl_map **)entry; + + *map = isl_map_reset_user(*map); + + return *map ? isl_stat_ok : isl_stat_error; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the spaces of "umap". + */ +__isl_give isl_union_map *isl_union_map_reset_user( + __isl_take isl_union_map *umap) +{ + umap = isl_union_map_cow(umap); + if (!umap) + return NULL; + umap->dim = isl_space_reset_user(umap->dim); + if (!umap->dim) + return isl_union_map_free(umap); + umap = un_op(umap, &reset_user); + + return umap; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the spaces of "uset". + */ +__isl_give isl_union_set *isl_union_set_reset_user( + __isl_take isl_union_set *uset) +{ + return isl_union_map_reset_user(uset); +} + +/* Internal data structure for isl_union_map_project_out. + * "type", "first" and "n" are the arguments for the isl_map_project_out + * call. + * "res" collects the results. + */ +struct isl_union_map_project_out_data { + enum isl_dim_type type; + unsigned first; + unsigned n; + + isl_union_map *res; +}; + +/* Turn the data->n dimensions of type data->type, starting at data->first + * into existentially quantified variables and add the result to data->res. + */ +static isl_stat project_out(__isl_take isl_map *map, void *user) +{ + struct isl_union_map_project_out_data *data = user; + + map = isl_map_project_out(map, data->type, data->first, data->n); + data->res = isl_union_map_add_map(data->res, map); + + return isl_stat_ok; +} + +/* Turn the "n" dimensions of type "type", starting at "first" + * into existentially quantified variables. + * Since the space of an isl_union_map only contains parameters, + * type is required to be equal to isl_dim_param. + */ +__isl_give isl_union_map *isl_union_map_project_out( + __isl_take isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + struct isl_union_map_project_out_data data = { type, first, n }; + + if (!umap) + return NULL; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only project out parameters", + return isl_union_map_free(umap)); + + space = isl_union_map_get_space(umap); + space = isl_space_drop_dims(space, type, first, n); + data.res = isl_union_map_empty(space); + if (isl_union_map_foreach_map(umap, &project_out, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_union_map_free(umap); + + return data.res; +} + +/* Turn the "n" dimensions of type "type", starting at "first" + * into existentially quantified variables. + * Since the space of an isl_union_set only contains parameters, + * "type" is required to be equal to isl_dim_param. + */ +__isl_give isl_union_set *isl_union_set_project_out( + __isl_take isl_union_set *uset, + enum isl_dim_type type, unsigned first, unsigned n) +{ + return isl_union_map_project_out(uset, type, first, n); +} + +/* Internal data structure for isl_union_map_involves_dims. + * "first" and "n" are the arguments for the isl_map_involves_dims calls. + */ +struct isl_union_map_involves_dims_data { + unsigned first; + unsigned n; +}; + +/* Does "map" _not_ involve the data->n parameters starting at data->first? + */ +static isl_bool map_excludes(__isl_keep isl_map *map, void *user) +{ + struct isl_union_map_involves_dims_data *data = user; + isl_bool involves; + + involves = isl_map_involves_dims(map, + isl_dim_param, data->first, data->n); + if (involves < 0) + return isl_bool_error; + return !involves; +} + +/* Does "umap" involve any of the n parameters starting at first? + * "type" is required to be set to isl_dim_param. + * + * "umap" involves any of those parameters if any of its maps + * involve the parameters. In other words, "umap" does not + * involve any of the parameters if all its maps to not + * involve the parameters. + */ +isl_bool isl_union_map_involves_dims(__isl_keep isl_union_map *umap, + enum isl_dim_type type, unsigned first, unsigned n) +{ + struct isl_union_map_involves_dims_data data = { first, n }; + isl_bool excludes; + + if (type != isl_dim_param) + isl_die(isl_union_map_get_ctx(umap), isl_error_invalid, + "can only reference parameters", return isl_bool_error); + + excludes = union_map_forall_user(umap, &map_excludes, &data); + + if (excludes < 0) + return isl_bool_error; + + return !excludes; +} + +/* Internal data structure for isl_union_map_reset_range_space. + * "range" is the space from which to set the range space. + * "res" collects the results. + */ +struct isl_union_map_reset_range_space_data { + isl_space *range; + isl_union_map *res; +}; + +/* Replace the range space of "map" by the range space of data->range and + * add the result to data->res. + */ +static isl_stat reset_range_space(__isl_take isl_map *map, void *user) +{ + struct isl_union_map_reset_range_space_data *data = user; + isl_space *space; + + space = isl_map_get_space(map); + space = isl_space_domain(space); + space = isl_space_extend_domain_with_range(space, + isl_space_copy(data->range)); + map = isl_map_reset_space(map, space); + data->res = isl_union_map_add_map(data->res, map); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Replace the range space of all the maps in "umap" by + * the range space of "space". + * + * This assumes that all maps have the same output dimension. + * This function should therefore not be made publicly available. + * + * Since the spaces of the maps change, so do their hash value. + * We therefore need to create a new isl_union_map. + */ +__isl_give isl_union_map *isl_union_map_reset_range_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space) +{ + struct isl_union_map_reset_range_space_data data = { space }; + + data.res = isl_union_map_empty(isl_union_map_get_space(umap)); + if (isl_union_map_foreach_map(umap, &reset_range_space, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_space_free(space); + isl_union_map_free(umap); + return data.res; +} + +/* Internal data structure for isl_union_map_order_at_multi_union_pw_aff. + * "mupa" is the function from which the isl_multi_pw_affs are extracted. + * "order" is applied to the extracted isl_multi_pw_affs that correspond + * to the domain and the range of each map. + * "res" collects the results. + */ +struct isl_union_order_at_data { + isl_multi_union_pw_aff *mupa; + __isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2); + isl_union_map *res; +}; + +/* Intersect "map" with the result of applying data->order to + * the functions in data->mupa that apply to the domain and the range + * of "map" and add the result to data->res. + */ +static isl_stat order_at(__isl_take isl_map *map, void *user) +{ + struct isl_union_order_at_data *data = user; + isl_space *space; + isl_multi_pw_aff *mpa1, *mpa2; + isl_map *order; + + space = isl_space_domain(isl_map_get_space(map)); + mpa1 = isl_multi_union_pw_aff_extract_multi_pw_aff(data->mupa, space); + space = isl_space_range(isl_map_get_space(map)); + mpa2 = isl_multi_union_pw_aff_extract_multi_pw_aff(data->mupa, space); + order = data->order(mpa1, mpa2); + map = isl_map_intersect(map, order); + data->res = isl_union_map_add_map(data->res, map); + + return data->res ? isl_stat_ok : isl_stat_error; +} + +/* Intersect each map in "umap" with the result of calling "order" + * on the functions is "mupa" that apply to the domain and the range + * of the map. + */ +static __isl_give isl_union_map *isl_union_map_order_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, __isl_take isl_multi_union_pw_aff *mupa, + __isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1, + __isl_take isl_multi_pw_aff *mpa2)) +{ + struct isl_union_order_at_data data; + + umap = isl_union_map_align_params(umap, + isl_multi_union_pw_aff_get_space(mupa)); + mupa = isl_multi_union_pw_aff_align_params(mupa, + isl_union_map_get_space(umap)); + data.mupa = mupa; + data.order = order; + data.res = isl_union_map_empty(isl_union_map_get_space(umap)); + if (isl_union_map_foreach_map(umap, &order_at, &data) < 0) + data.res = isl_union_map_free(data.res); + + isl_multi_union_pw_aff_free(mupa); + isl_union_map_free(umap); + return data.res; +} + +/* Return the subset of "umap" where the domain and the range + * have equal "mupa" values. + */ +__isl_give isl_union_map *isl_union_map_eq_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa) +{ + return isl_union_map_order_at_multi_union_pw_aff(umap, mupa, + &isl_multi_pw_aff_eq_map); +} + +/* Return the subset of "umap" where the domain has a lexicographically + * smaller "mupa" value than the range. + */ +__isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa) +{ + return isl_union_map_order_at_multi_union_pw_aff(umap, mupa, + &isl_multi_pw_aff_lex_lt_map); +} + +/* Return the subset of "umap" where the domain has a lexicographically + * greater "mupa" value than the range. + */ +__isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff( + __isl_take isl_union_map *umap, + __isl_take isl_multi_union_pw_aff *mupa) +{ + return isl_union_map_order_at_multi_union_pw_aff(umap, mupa, + &isl_multi_pw_aff_lex_gt_map); +} + +/* Return the union of the elements in the list "list". + */ +__isl_give isl_union_set *isl_union_set_list_union( + __isl_take isl_union_set_list *list) +{ + int i, n; + isl_ctx *ctx; + isl_space *space; + isl_union_set *res; + + if (!list) + return NULL; + + ctx = isl_union_set_list_get_ctx(list); + space = isl_space_params_alloc(ctx, 0); + res = isl_union_set_empty(space); + + n = isl_union_set_list_n_union_set(list); + for (i = 0; i < n; ++i) { + isl_union_set *uset_i; + + uset_i = isl_union_set_list_get_union_set(list, i); + res = isl_union_set_union(res, uset_i); + } + + isl_union_set_list_free(list); + return res; +} diff -Nru isl-0.12.2/isl_union_map_private.h isl-0.15/isl_union_map_private.h --- isl-0.12.2/isl_union_map_private.h 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/isl_union_map_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,4 @@ +#define isl_union_set_list isl_union_map_list #define isl_union_set isl_union_map #include #include @@ -8,3 +9,6 @@ struct isl_hash_table table; }; + +__isl_give isl_union_map *isl_union_map_reset_range_space( + __isl_take isl_union_map *umap, __isl_take isl_space *space); diff -Nru isl-0.12.2/isl_union_templ.c isl-0.15/isl_union_templ.c --- isl-0.12.2/isl_union_templ.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_union_templ.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,11 +1,13 @@ /* * Copyright 2010 INRIA Saclay + * Copyright 2013 Ecole Normale Superieure * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France */ #define xFN(TYPE,NAME) TYPE ## _ ## NAME @@ -18,7 +20,7 @@ #ifdef HAS_TYPE enum isl_fold type; #endif - isl_space *dim; + isl_space *space; struct isl_hash_table table; }; @@ -27,14 +29,41 @@ isl_ctx *FN(UNION,get_ctx)(__isl_keep UNION *u) { - return u ? u->dim->ctx : NULL; + return u ? u->space->ctx : NULL; } __isl_give isl_space *FN(UNION,get_space)(__isl_keep UNION *u) { if (!u) return NULL; - return isl_space_copy(u->dim); + return isl_space_copy(u->space); +} + +/* Return the number of parameters of "u", where "type" + * is required to be set to isl_dim_param. + */ +unsigned FN(UNION,dim)(__isl_keep UNION *u, enum isl_dim_type type) +{ + if (!u) + return 0; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "can only reference parameters", return 0); + + return isl_space_dim(u->space, type); +} + +/* Return the position of the parameter with the given name + * in "u". + * Return -1 if no such dimension can be found. + */ +int FN(UNION,find_dim_by_name)(__isl_keep UNION *u, enum isl_dim_type type, + const char *name) +{ + if (!u) + return -1; + return isl_space_find_dim_by_name(u->space, type, name); } #ifdef HAS_TYPE @@ -52,20 +81,19 @@ u = isl_calloc_type(dim->ctx, UNION); if (!u) - return NULL; + goto error; u->ref = 1; #ifdef HAS_TYPE u->type = type; #endif - u->dim = dim; + u->space = dim; if (isl_hash_table_init(dim->ctx, &u->table, size) < 0) - goto error; + return FN(UNION,free)(u); return u; error: isl_space_free(dim); - FN(UNION,free)(u); return NULL; } @@ -90,13 +118,20 @@ return u; } +/* Return the number of base expressions in "u". + */ +int FN(FN(UNION,n),PARTS)(__isl_keep UNION *u) +{ + return u ? u->table.n : 0; +} + S(UNION,foreach_data) { - int (*fn)(__isl_take PART *part, void *user); + isl_stat (*fn)(__isl_take PART *part, void *user); void *user; }; -static int call_on_copy(void **entry, void *user) +static isl_stat FN(UNION,call_on_copy)(void **entry, void *user) { PART *part = *entry; S(UNION,foreach_data) *data = (S(UNION,foreach_data) *)user; @@ -104,90 +139,163 @@ return data->fn(FN(PART,copy)(part), data->user); } -int FN(FN(UNION,foreach),PARTS)(__isl_keep UNION *u, - int (*fn)(__isl_take PART *part, void *user), void *user) +isl_stat FN(FN(UNION,foreach),PARTS)(__isl_keep UNION *u, + isl_stat (*fn)(__isl_take PART *part, void *user), void *user) { S(UNION,foreach_data) data = { fn, user }; if (!u) - return -1; + return isl_stat_error; - return isl_hash_table_foreach(u->dim->ctx, &u->table, - &call_on_copy, &data); + return isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,call_on_copy), &data); } -static int has_dim(const void *entry, const void *val) +/* Is the space of "entry" equal to "space"? + */ +static int FN(UNION,has_space)(const void *entry, const void *val) { PART *part = (PART *)entry; - isl_space *dim = (isl_space *)val; + isl_space *space = (isl_space *) val; + + return isl_space_is_equal(part->dim, space); +} + +/* This function is not currently used by isl_aff.c. + */ +static int FN(UNION,has_domain_space)(const void *entry, const void *val) + __attribute__ ((unused)); + +/* Is the domain space of "entry" equal to "space"? + */ +static int FN(UNION,has_domain_space)(const void *entry, const void *val) +{ + PART *part = (PART *)entry; + isl_space *space = (isl_space *) val; + + if (isl_space_is_params(space)) + return isl_space_is_set(part->dim); + + return isl_space_tuple_is_equal(part->dim, isl_dim_in, + space, isl_dim_set); +} + +/* Is the domain space of "entry" equal to the domain of "space"? + */ +static int FN(UNION,has_same_domain_space)(const void *entry, const void *val) +{ + PART *part = (PART *)entry; + isl_space *space = (isl_space *) val; + + if (isl_space_is_set(space)) + return isl_space_is_set(part->dim); - return isl_space_is_equal(part->dim, dim); + return isl_space_tuple_is_equal(part->dim, isl_dim_in, + space, isl_dim_in); } +/* Extract the element of "u" living in "space" (ignoring parameters). + * + * Return the ZERO element if "u" does not contain any element + * living in "space". + */ __isl_give PART *FN(FN(UNION,extract),PARTS)(__isl_keep UNION *u, - __isl_take isl_space *dim) + __isl_take isl_space *space) { uint32_t hash; struct isl_hash_table_entry *entry; - if (!u || !dim) + if (!u || !space) goto error; + if (!isl_space_match(u->space, isl_dim_param, space, isl_dim_param)) { + space = isl_space_drop_dims(space, isl_dim_param, + 0, isl_space_dim(space, isl_dim_param)); + space = isl_space_align_params(space, + FN(UNION,get_space)(u)); + if (!space) + goto error; + } - hash = isl_space_get_hash(dim); - entry = isl_hash_table_find(u->dim->ctx, &u->table, hash, - &has_dim, dim, 0); + hash = isl_space_get_hash(space); + entry = isl_hash_table_find(u->space->ctx, &u->table, hash, + &FN(UNION,has_space), space, 0); if (!entry) #ifdef HAS_TYPE - return FN(PART,ZERO)(dim, u->type); + return FN(PART,ZERO)(space, u->type); #else - return FN(PART,ZERO)(dim); + return FN(PART,ZERO)(space); #endif - isl_space_free(dim); + isl_space_free(space); return FN(PART,copy)(entry->data); error: - isl_space_free(dim); + isl_space_free(space); return NULL; } -__isl_give UNION *FN(FN(UNION,add),PARTS)(__isl_take UNION *u, - __isl_take PART *part) +/* Add "part" to "u". + * If "disjoint" is set, then "u" is not allowed to already have + * a part that is defined on the same space as "part". + * Otherwise, compute the union sum of "part" and the part in "u" + * defined on the same space. + */ +static __isl_give UNION *FN(UNION,add_part_generic)(__isl_take UNION *u, + __isl_take PART *part, int disjoint) { + int empty; uint32_t hash; struct isl_hash_table_entry *entry; if (!part) goto error; - if (DEFAULT_IS_ZERO && FN(PART,IS_ZERO)(part)) { + empty = FN(PART,IS_ZERO)(part); + if (empty < 0) + goto error; + if (empty) { FN(PART,free)(part); return u; } + u = FN(UNION,align_params)(u, FN(PART,get_space)(part)); + part = FN(PART,align_params)(part, FN(UNION,get_space)(u)); + u = FN(UNION,cow)(u); if (!u) goto error; - isl_assert(u->dim->ctx, isl_space_match(part->dim, isl_dim_param, u->dim, - isl_dim_param), goto error); - hash = isl_space_get_hash(part->dim); - entry = isl_hash_table_find(u->dim->ctx, &u->table, hash, - &has_dim, part->dim, 1); + entry = isl_hash_table_find(u->space->ctx, &u->table, hash, + &FN(UNION,has_same_domain_space), + part->dim, 1); if (!entry) goto error; if (!entry->data) entry->data = part; else { - entry->data = FN(PART,add)(entry->data, FN(PART,copy)(part)); + PART *entry_part = entry->data; + if (disjoint) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "additional part should live on separate " + "space", goto error); + if (!isl_space_tuple_is_equal(entry_part->dim, isl_dim_out, + part->dim, isl_dim_out)) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "union expression can only contain a single " + "expression over a given domain", goto error); + entry->data = FN(PART,union_add_)(entry->data, + FN(PART,copy)(part)); if (!entry->data) goto error; - FN(PART,free)(part); - if (DEFAULT_IS_ZERO && FN(PART,IS_ZERO)(entry->data)) { + empty = FN(PART,IS_ZERO)(part); + if (empty < 0) + goto error; + if (empty) { FN(PART,free)(entry->data); - isl_hash_table_remove(u->dim->ctx, &u->table, entry); + isl_hash_table_remove(u->space->ctx, &u->table, entry); } + FN(PART,free)(part); } return u; @@ -197,13 +305,22 @@ return NULL; } -static int add_part(__isl_take PART *part, void *user) +/* Add "part" to "u", where "u" is assumed not to already have + * a part that is defined on the same space as "part". + */ +__isl_give UNION *FN(FN(UNION,add),PARTS)(__isl_take UNION *u, + __isl_take PART *part) +{ + return FN(UNION,add_part_generic)(u, part, 1); +} + +static isl_stat FN(UNION,add_part)(__isl_take PART *part, void *user) { UNION **u = (UNION **)user; *u = FN(FN(UNION,add),PARTS)(*u, part); - return 0; + return isl_stat_ok; } __isl_give UNION *FN(UNION,dup)(__isl_keep UNION *u) @@ -214,11 +331,11 @@ return NULL; #ifdef HAS_TYPE - dup = FN(UNION,ZERO)(isl_space_copy(u->dim), u->type); + dup = FN(UNION,ZERO)(isl_space_copy(u->space), u->type); #else - dup = FN(UNION,ZERO)(isl_space_copy(u->dim)); + dup = FN(UNION,ZERO)(isl_space_copy(u->space)); #endif - if (FN(FN(UNION,foreach),PARTS)(u, &add_part, &dup) < 0) + if (FN(FN(UNION,foreach),PARTS)(u, &FN(UNION,add_part), &dup) < 0) goto error; return dup; error: @@ -237,14 +354,14 @@ return FN(UNION,dup)(u); } -static int free_u_entry(void **entry, void *user) +static isl_stat FN(UNION,free_u_entry)(void **entry, void *user) { PART *part = *entry; FN(PART,free)(part); - return 0; + return isl_stat_ok; } -void *FN(UNION,free)(__isl_take UNION *u) +__isl_null UNION *FN(UNION,free)(__isl_take UNION *u) { if (!u) return NULL; @@ -252,9 +369,10 @@ if (--u->ref > 0) return NULL; - isl_hash_table_foreach(u->dim->ctx, &u->table, &free_u_entry, NULL); + isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,free_u_entry), NULL); isl_hash_table_clear(&u->table); - isl_space_free(u->dim); + isl_space_free(u->space); free(u); return NULL; } @@ -264,8 +382,7 @@ UNION *res; }; -#ifdef ALIGN_DOMAIN -static int align_entry(__isl_take PART *part, void *user) +static isl_stat FN(UNION,align_entry)(__isl_take PART *part, void *user) { isl_reordering *exp; S(UNION,align) *data = user; @@ -276,64 +393,87 @@ data->res = FN(FN(UNION,add),PARTS)(data->res, FN(PART,realign_domain)(part, exp)); - return 0; + return isl_stat_ok; } -#else -static int align_entry(__isl_take PART *part, void *user) + +/* Reorder the parameters of "u" according to the given reordering. + */ +static __isl_give UNION *FN(UNION,realign_domain)(__isl_take UNION *u, + __isl_take isl_reordering *r) { - isl_reordering *exp; - S(UNION,align) *data = user; + S(UNION,align) data = { NULL, NULL }; - exp = isl_reordering_extend_space(isl_reordering_copy(data->exp), - FN(PART,get_space)(part)); + if (!u || !r) + goto error; - data->res = FN(FN(UNION,add),PARTS)(data->res, - FN(PART,realign)(part, exp)); +#ifdef HAS_TYPE + data.res = FN(UNION,alloc)(isl_space_copy(r->dim), u->type, u->table.n); +#else + data.res = FN(UNION,alloc)(isl_space_copy(r->dim), u->table.n); +#endif + data.exp = r; + if (FN(FN(UNION,foreach),PARTS)(u, &FN(UNION,align_entry), &data) < 0) + data.res = FN(UNION,free)(data.res); - return 0; + isl_reordering_free(data.exp); + FN(UNION,free)(u); + return data.res; +error: + FN(UNION,free)(u); + isl_reordering_free(r); + return NULL; } -#endif +/* Align the parameters of "u" to those of "model". + */ __isl_give UNION *FN(UNION,align_params)(__isl_take UNION *u, __isl_take isl_space *model) { - S(UNION,align) data = { NULL, NULL }; + isl_reordering *r; if (!u || !model) goto error; - if (isl_space_match(u->dim, isl_dim_param, model, isl_dim_param)) { + if (isl_space_match(u->space, isl_dim_param, model, isl_dim_param)) { isl_space_free(model); return u; } model = isl_space_params(model); - data.exp = isl_parameter_alignment_reordering(u->dim, model); - if (!data.exp) - goto error; - -#ifdef HAS_TYPE - data.res = FN(UNION,alloc)(isl_space_copy(data.exp->dim), - u->type, u->table.n); -#else - data.res = FN(UNION,alloc)(isl_space_copy(data.exp->dim), u->table.n); -#endif - if (FN(FN(UNION,foreach),PARTS)(u, &align_entry, &data) < 0) - goto error; - - isl_reordering_free(data.exp); - FN(UNION,free)(u); + r = isl_parameter_alignment_reordering(u->space, model); isl_space_free(model); - return data.res; + + return FN(UNION,realign_domain)(u, r); error: - isl_reordering_free(data.exp); - FN(UNION,free)(u); - FN(UNION,free)(data.res); isl_space_free(model); + FN(UNION,free)(u); return NULL; } -__isl_give UNION *FN(UNION,add)(__isl_take UNION *u1, __isl_take UNION *u2) +/* Add "part" to *u, taking the union sum if "u" already has + * a part defined on the same space as "part". + */ +static isl_stat FN(UNION,union_add_part)(__isl_take PART *part, void *user) +{ + UNION **u = (UNION **)user; + + *u = FN(UNION,add_part_generic)(*u, part, 0); + + return isl_stat_ok; +} + +/* Compute the sum of "u1" and "u2" on the union of their domains, + * with the actual sum on the shared domain and + * the defined expression on the symmetric difference of the domains. + * + * This is an internal function that is exposed under different + * names depending on whether the base expressions have a zero default + * value. + * If they do, then this function is called "add". + * Otherwise, it is called "union_add". + */ +static __isl_give UNION *FN(UNION,union_add_)(__isl_take UNION *u1, + __isl_take UNION *u2) { u1 = FN(UNION,align_params)(u1, FN(UNION,get_space)(u2)); u2 = FN(UNION,align_params)(u2, FN(UNION,get_space)(u1)); @@ -343,7 +483,7 @@ if (!u1 || !u2) goto error; - if (FN(FN(UNION,foreach),PARTS)(u2, &add_part, &u1) < 0) + if (FN(FN(UNION,foreach),PARTS)(u2, &FN(UNION,union_add_part), &u1) < 0) goto error; FN(UNION,free)(u2); @@ -386,55 +526,52 @@ * If so, call data->fn on the two elements and add the result to * data->res. */ -static int match_bin_entry(void **entry, void *user) +static isl_stat FN(UNION,match_bin_entry)(void **entry, void *user) { S(UNION,match_bin_data) *data = user; uint32_t hash; struct isl_hash_table_entry *entry2; isl_space *space; PART *part = *entry; + PART *part2; space = FN(PART,get_space)(part); hash = isl_space_get_hash(space); - entry2 = isl_hash_table_find(data->u2->dim->ctx, &data->u2->table, - hash, &has_dim, space, 0); + entry2 = isl_hash_table_find(data->u2->space->ctx, &data->u2->table, + hash, &FN(UNION,has_same_domain_space), + space, 0); isl_space_free(space); if (!entry2) - return 0; + return isl_stat_ok; + + part2 = entry2->data; + if (!isl_space_tuple_is_equal(part->dim, isl_dim_out, + part2->dim, isl_dim_out)) + isl_die(FN(UNION,get_ctx)(data->u2), isl_error_invalid, + "entries should have the same range space", + return isl_stat_error); part = FN(PART, copy)(part); part = data->fn(part, FN(PART, copy)(entry2->data)); - if (DEFAULT_IS_ZERO) { - int empty; - - empty = FN(PART,IS_ZERO)(part); - if (empty < 0) { - FN(PART,free)(part); - return -1; - } - if (empty) { - FN(PART,free)(part); - return 0; - } - } - data->res = FN(FN(UNION,add),PARTS)(data->res, part); + if (!data->res) + return isl_stat_error; - return 0; + return isl_stat_ok; } /* This function is currently only used from isl_polynomial.c * and not from isl_fold.c. */ -static __isl_give UNION *match_bin_op(__isl_take UNION *u1, +static __isl_give UNION *FN(UNION,match_bin_op)(__isl_take UNION *u1, __isl_take UNION *u2, __isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *)) __attribute__ ((unused)); /* For each pair of elements in "u1" and "u2" living in the same space, * call "fn" and collect the results. */ -static __isl_give UNION *match_bin_op(__isl_take UNION *u1, +static __isl_give UNION *FN(UNION,match_bin_op)(__isl_take UNION *u1, __isl_take UNION *u2, __isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *)) { @@ -448,12 +585,13 @@ data.u2 = u2; #ifdef HAS_TYPE - data.res = FN(UNION,alloc)(isl_space_copy(u1->dim), u1->type, u1->table.n); + data.res = FN(UNION,alloc)(isl_space_copy(u1->space), u1->type, + u1->table.n); #else - data.res = FN(UNION,alloc)(isl_space_copy(u1->dim), u1->table.n); + data.res = FN(UNION,alloc)(isl_space_copy(u1->space), u1->table.n); #endif - if (isl_hash_table_foreach(u1->dim->ctx, &u1->table, - &match_bin_entry, &data) < 0) + if (isl_hash_table_foreach(u1->space->ctx, &u1->table, + &FN(UNION,match_bin_entry), &data) < 0) goto error; FN(UNION,free)(u1); @@ -466,12 +604,27 @@ return NULL; } +/* Compute the sum of "u1" and "u2". + * + * If the base expressions have a default zero value, then the sum + * is computed on the union of the domains of "u1" and "u2". + * Otherwise, it is computed on their shared domains. + */ +__isl_give UNION *FN(UNION,add)(__isl_take UNION *u1, __isl_take UNION *u2) +{ +#if DEFAULT_IS_ZERO + return FN(UNION,union_add_)(u1, u2); +#else + return FN(UNION,match_bin_op)(u1, u2, &FN(PART,add)); +#endif +} + #ifndef NO_SUB /* Subtract "u2" from "u1" and return the result. */ __isl_give UNION *FN(UNION,sub)(__isl_take UNION *u1, __isl_take UNION *u2) { - return match_bin_op(u1, u2, &FN(PART,sub)); + return FN(UNION,match_bin_op)(u1, u2, &FN(PART,sub)); } #endif @@ -481,7 +634,7 @@ __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*); }; -static int any_set_entry(void **entry, void *user) +static isl_stat FN(UNION,any_set_entry)(void **entry, void *user) { S(UNION,any_set_data) *data = user; PW *pw = *entry; @@ -489,28 +642,16 @@ pw = FN(PW,copy)(pw); pw = data->fn(pw, isl_set_copy(data->set)); - if (DEFAULT_IS_ZERO) { - int empty; - - empty = FN(PW,IS_ZERO)(pw); - if (empty < 0) { - FN(PW,free)(pw); - return -1; - } - if (empty) { - FN(PW,free)(pw); - return 0; - } - } - data->res = FN(FN(UNION,add),PARTS)(data->res, pw); + if (!data->res) + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Update each element of "u" by calling "fn" on the element and "set". */ -static __isl_give UNION *any_set_op(__isl_take UNION *u, +static __isl_give UNION *FN(UNION,any_set_op)(__isl_take UNION *u, __isl_take isl_set *set, __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*)) { @@ -524,12 +665,13 @@ data.set = set; #ifdef HAS_TYPE - data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->type, u->table.n); + data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->type, + u->table.n); #else - data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->table.n); + data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->table.n); #endif - if (isl_hash_table_foreach(u->dim->ctx, &u->table, - &any_set_entry, &data) < 0) + if (isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,any_set_entry), &data) < 0) goto error; FN(UNION,free)(u); @@ -547,7 +689,7 @@ __isl_give UNION *FN(UNION,intersect_params)(__isl_take UNION *u, __isl_take isl_set *set) { - return any_set_op(u, set, &FN(PW,intersect_params)); + return FN(UNION,any_set_op)(u, set, &FN(PW,intersect_params)); } /* Compute the gist of the domain of "u" with respect to @@ -556,7 +698,7 @@ __isl_give UNION *FN(UNION,gist_params)(__isl_take UNION *u, __isl_take isl_set *set) { - return any_set_op(u, set, &FN(PW,gist_params)); + return FN(UNION,any_set_op)(u, set, &FN(PW,gist_params)); } S(UNION,match_domain_data) { @@ -565,7 +707,7 @@ __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*); }; -static int set_has_dim(const void *entry, const void *val) +static int FN(UNION,set_has_dim)(const void *entry, const void *val) { isl_set *set = (isl_set *)entry; isl_space *dim = (isl_space *)val; @@ -573,11 +715,11 @@ return isl_space_is_equal(set->dim, dim); } -/* Find the set in data->uset that live in the same space as the domain +/* Find the set in data->uset that lives in the same space as the domain * of *entry, apply data->fn to *entry and this set (if any), and add * the result to data->res. */ -static int match_domain_entry(void **entry, void *user) +static isl_stat FN(UNION,match_domain_entry)(void **entry, void *user) { S(UNION,match_domain_data) *data = user; uint32_t hash; @@ -588,38 +730,26 @@ space = FN(PW,get_domain_space)(pw); hash = isl_space_get_hash(space); entry2 = isl_hash_table_find(data->uset->dim->ctx, &data->uset->table, - hash, &set_has_dim, space, 0); + hash, &FN(UNION,set_has_dim), space, 0); isl_space_free(space); if (!entry2) - return 0; + return isl_stat_ok; pw = FN(PW,copy)(pw); pw = data->fn(pw, isl_set_copy(entry2->data)); - if (DEFAULT_IS_ZERO) { - int empty; - - empty = FN(PW,IS_ZERO)(pw); - if (empty < 0) { - FN(PW,free)(pw); - return -1; - } - if (empty) { - FN(PW,free)(pw); - return 0; - } - } - data->res = FN(FN(UNION,add),PARTS)(data->res, pw); + if (!data->res) + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Apply fn to each pair of PW in u and set in uset such that * the set lives in the same space as the domain of PW * and collect the results. */ -static __isl_give UNION *match_domain_op(__isl_take UNION *u, +static __isl_give UNION *FN(UNION,match_domain_op)(__isl_take UNION *u, __isl_take isl_union_set *uset, __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*)) { @@ -633,12 +763,13 @@ data.uset = uset; #ifdef HAS_TYPE - data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->type, u->table.n); + data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->type, + u->table.n); #else - data.res = FN(UNION,alloc)(isl_space_copy(u->dim), u->table.n); + data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->table.n); #endif - if (isl_hash_table_foreach(u->dim->ctx, &u->table, - &match_domain_entry, &data) < 0) + if (isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,match_domain_entry), &data) < 0) goto error; FN(UNION,free)(u); @@ -661,7 +792,64 @@ if (isl_union_set_is_params(uset)) return FN(UNION,intersect_params)(u, isl_set_from_union_set(uset)); - return match_domain_op(u, uset, &FN(PW,intersect_domain)); + return FN(UNION,match_domain_op)(u, uset, &FN(PW,intersect_domain)); +} + +/* Internal data structure for isl_union_*_subtract_domain. + * uset is the set that needs to be removed from the domain. + * res collects the results. + */ +S(UNION,subtract_domain_data) { + isl_union_set *uset; + UNION *res; +}; + +/* Take the set (which may be empty) in data->uset that lives + * in the same space as the domain of "pw", subtract it from the domain + * of "pw" and add the result to data->res. + */ +static isl_stat FN(UNION,subtract_domain_entry)(__isl_take PW *pw, void *user) +{ + S(UNION,subtract_domain_data) *data = user; + isl_space *space; + isl_set *set; + + space = FN(PW,get_domain_space)(pw); + set = isl_union_set_extract_set(data->uset, space); + pw = FN(PW,subtract_domain)(pw, set); + data->res = FN(FN(UNION,add),PARTS)(data->res, pw); + + return isl_stat_ok; +} + +/* Subtract "uset' from the domain of "u". + */ +__isl_give UNION *FN(UNION,subtract_domain)(__isl_take UNION *u, + __isl_take isl_union_set *uset) +{ + S(UNION,subtract_domain_data) data; + + if (!u || !uset) + goto error; + + data.uset = uset; +#ifdef HAS_TYPE + data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->type, + u->table.n); +#else + data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->table.n); +#endif + if (FN(FN(UNION,foreach),PARTS)(u, + &FN(UNION,subtract_domain_entry), &data) < 0) + data.res = FN(UNION,free)(data.res); + + FN(UNION,free)(u); + isl_union_set_free(uset); + return data.res; +error: + FN(UNION,free)(u); + isl_union_set_free(uset); + return NULL; } __isl_give UNION *FN(UNION,gist)(__isl_take UNION *u, @@ -669,38 +857,37 @@ { if (isl_union_set_is_params(uset)) return FN(UNION,gist_params)(u, isl_set_from_union_set(uset)); - return match_domain_op(u, uset, &FN(PW,gist)); + return FN(UNION,match_domain_op)(u, uset, &FN(PW,gist)); } #ifndef NO_EVAL -__isl_give isl_qpolynomial *FN(UNION,eval)(__isl_take UNION *u, +__isl_give isl_val *FN(UNION,eval)(__isl_take UNION *u, __isl_take isl_point *pnt) { uint32_t hash; struct isl_hash_table_entry *entry; isl_space *space; - isl_qpolynomial *qp; + isl_val *v; if (!u || !pnt) goto error; space = isl_space_copy(pnt->dim); - space = isl_space_from_domain(space); - space = isl_space_add_dims(space, isl_dim_out, 1); if (!space) goto error; hash = isl_space_get_hash(space); - entry = isl_hash_table_find(u->dim->ctx, &u->table, - hash, &has_dim, space, 0); + entry = isl_hash_table_find(u->space->ctx, &u->table, + hash, &FN(UNION,has_domain_space), + space, 0); isl_space_free(space); if (!entry) { - qp = isl_qpolynomial_zero_on_domain(isl_space_copy(pnt->dim)); + v = isl_val_zero(isl_point_get_ctx(pnt)); isl_point_free(pnt); } else { - qp = FN(PART,eval)(FN(PART,copy)(entry->data), pnt); + v = FN(PART,eval)(FN(PART,copy)(entry->data), pnt); } FN(UNION,free)(u); - return qp; + return v; error: FN(UNION,free)(u); isl_point_free(pnt); @@ -708,15 +895,15 @@ } #endif -static int coalesce_entry(void **entry, void *user) +static isl_stat FN(UNION,coalesce_entry)(void **entry, void *user) { PW **pw = (PW **)entry; *pw = FN(PW,coalesce)(*pw); if (!*pw) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } __isl_give UNION *FN(UNION,coalesce)(__isl_take UNION *u) @@ -724,8 +911,8 @@ if (!u) return NULL; - if (isl_hash_table_foreach(u->dim->ctx, &u->table, - &coalesce_entry, NULL) < 0) + if (isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,coalesce_entry), NULL) < 0) goto error; return u; @@ -734,13 +921,13 @@ return NULL; } -static int domain(__isl_take PART *part, void *user) +static isl_stat FN(UNION,domain_entry)(__isl_take PART *part, void *user) { isl_union_set **uset = (isl_union_set **)user; *uset = isl_union_set_add_set(*uset, FN(PART,domain)(part)); - return 0; + return isl_stat_ok; } __isl_give isl_union_set *FN(UNION,domain)(__isl_take UNION *u) @@ -748,7 +935,7 @@ isl_union_set *uset; uset = isl_union_set_empty(FN(UNION,get_space)(u)); - if (FN(FN(UNION,foreach),PARTS)(u, &domain, &uset) < 0) + if (FN(FN(UNION,foreach),PARTS)(u, &FN(UNION,domain_entry), &uset) < 0) goto error; FN(UNION,free)(u); @@ -760,16 +947,16 @@ return NULL; } -static int mul_isl_int(void **entry, void *user) +static isl_stat FN(UNION,mul_isl_int_entry)(void **entry, void *user) { PW **pw = (PW **)entry; isl_int *v = user; *pw = FN(PW,mul_isl_int)(*pw, *v); if (!*pw) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } __isl_give UNION *FN(UNION,mul_isl_int)(__isl_take UNION *u, isl_int v) @@ -797,8 +984,8 @@ if (isl_int_is_neg(v)) u->type = isl_fold_type_negate(u->type); #endif - if (isl_hash_table_foreach(u->dim->ctx, &u->table, - &mul_isl_int, &v) < 0) + if (isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,mul_isl_int_entry), &v) < 0) goto error; return u; @@ -811,16 +998,16 @@ * * Return 0 on success and -1 on error. */ -static int scale_val(void **entry, void *user) +static isl_stat FN(UNION,scale_val_entry)(void **entry, void *user) { PW **pw = (PW **)entry; isl_val *v = user; *pw = FN(PW,scale_val)(*pw, isl_val_copy(v)); if (!*pw) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } /* Multiply "u" by "v" and return the result. @@ -860,7 +1047,63 @@ if (isl_val_is_neg(v)) u->type = isl_fold_type_negate(u->type); #endif - if (isl_hash_table_foreach(u->dim->ctx, &u->table, &scale_val, v) < 0) + if (isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,scale_val_entry), v) < 0) + goto error; + + isl_val_free(v); + return u; +error: + isl_val_free(v); + FN(UNION,free)(u); + return NULL; +} + +/* Divide *entry by the isl_val "user". + * + * Return 0 on success and -1 on error. + */ +static isl_stat FN(UNION,scale_down_val_entry)(void **entry, void *user) +{ + PW **pw = (PW **)entry; + isl_val *v = user; + + *pw = FN(PW,scale_down_val)(*pw, isl_val_copy(v)); + if (!*pw) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Divide "u" by "v" and return the result. + */ +__isl_give UNION *FN(UNION,scale_down_val)(__isl_take UNION *u, + __isl_take isl_val *v) +{ + if (!u || !v) + goto error; + if (isl_val_is_one(v)) { + isl_val_free(v); + return u; + } + + if (!isl_val_is_rat(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "expecting rational factor", goto error); + if (isl_val_is_zero(v)) + isl_die(isl_val_get_ctx(v), isl_error_invalid, + "cannot scale down by zero", goto error); + + u = FN(UNION,cow)(u); + if (!u) + return NULL; + +#ifdef HAS_TYPE + if (isl_val_is_neg(v)) + u->type = isl_fold_type_negate(u->type); +#endif + if (isl_hash_table_foreach(FN(UNION,get_ctx)(u), &u->table, + &FN(UNION,scale_down_val_entry), v) < 0) goto error; isl_val_free(v); @@ -874,10 +1117,10 @@ S(UNION,plain_is_equal_data) { UNION *u2; - int is_equal; + isl_bool is_equal; }; -static int plain_is_equal_entry(void **entry, void *user) +static isl_stat FN(UNION,plain_is_equal_entry)(void **entry, void *user) { S(UNION,plain_is_equal_data) *data = user; uint32_t hash; @@ -885,30 +1128,31 @@ PW *pw = *entry; hash = isl_space_get_hash(pw->dim); - entry2 = isl_hash_table_find(data->u2->dim->ctx, &data->u2->table, - hash, &has_dim, pw->dim, 0); + entry2 = isl_hash_table_find(data->u2->space->ctx, &data->u2->table, + hash, &FN(UNION,has_same_domain_space), + pw->dim, 0); if (!entry2) { - data->is_equal = 0; - return -1; + data->is_equal = isl_bool_false; + return isl_stat_error; } data->is_equal = FN(PW,plain_is_equal)(pw, entry2->data); if (data->is_equal < 0 || !data->is_equal) - return -1; + return isl_stat_error; - return 0; + return isl_stat_ok; } -int FN(UNION,plain_is_equal)(__isl_keep UNION *u1, __isl_keep UNION *u2) +isl_bool FN(UNION,plain_is_equal)(__isl_keep UNION *u1, __isl_keep UNION *u2) { - S(UNION,plain_is_equal_data) data = { NULL, 1 }; + S(UNION,plain_is_equal_data) data = { NULL, isl_bool_true }; if (!u1 || !u2) - return -1; + return isl_bool_error; if (u1 == u2) - return 1; + return isl_bool_true; if (u1->table.n != u2->table.n) - return 0; + return isl_bool_false; u1 = FN(UNION,copy)(u1); u2 = FN(UNION,copy)(u2); @@ -918,8 +1162,8 @@ goto error; data.u2 = u2; - if (isl_hash_table_foreach(u1->dim->ctx, &u1->table, - &plain_is_equal_entry, &data) < 0 && + if (isl_hash_table_foreach(u1->space->ctx, &u1->table, + &FN(UNION,plain_is_equal_entry), &data) < 0 && data.is_equal) goto error; @@ -930,5 +1174,198 @@ error: FN(UNION,free)(u1); FN(UNION,free)(u2); - return -1; + return isl_bool_error; +} + +#ifndef NO_NEG +/* Replace *entry by its opposite. + * + * Return 0 on success and -1 on error. + */ +static isl_stat FN(UNION,neg_entry)(void **entry, void *user) +{ + PW **pw = (PW **) entry; + + *pw = FN(PW,neg)(*pw); + + return *pw ? isl_stat_ok : isl_stat_error; +} + +/* Return the opposite of "u". + */ +__isl_give UNION *FN(UNION,neg)(__isl_take UNION *u) +{ + u = FN(UNION,cow)(u); + if (!u) + return NULL; + + if (isl_hash_table_foreach(u->space->ctx, &u->table, + &FN(UNION,neg_entry), NULL) < 0) + return FN(UNION,free)(u); + + return u; +} +#endif + +/* Internal data structure for isl_union_*_drop_dims. + * type, first and n are passed to isl_*_drop_dims. + * res collects the results. + */ +S(UNION,drop_dims_data) { + enum isl_dim_type type; + unsigned first; + unsigned n; + + UNION *res; +}; + +/* Drop the parameters specified by "data" from "part" and + * add the results to data->res. + */ +static isl_stat FN(UNION,drop_dims_entry)(__isl_take PART *part, void *user) +{ + S(UNION,drop_dims_data) *data = user; + + part = FN(PART,drop_dims)(part, data->type, data->first, data->n); + data->res = FN(FN(UNION,add),PARTS)(data->res, part); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Drop the specified parameters from "u". + * That is, type is required to be isl_dim_param. + */ +__isl_give UNION *FN(UNION,drop_dims)( __isl_take UNION *u, + enum isl_dim_type type, unsigned first, unsigned n) +{ + isl_space *space; + S(UNION,drop_dims_data) data = { type, first, n }; + + if (!u) + return NULL; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "can only project out parameters", + return FN(UNION,free)(u)); + + space = FN(UNION,get_space)(u); + space = isl_space_drop_dims(space, type, first, n); +#ifdef HAS_TYPE + data.res = FN(UNION,alloc)(space, u->type, u->table.n); +#else + data.res = FN(UNION,alloc)(space, u->table.n); +#endif + if (FN(FN(UNION,foreach),PARTS)(u, + &FN(UNION,drop_dims_entry), &data) < 0) + data.res = FN(UNION,free)(data.res); + + FN(UNION,free)(u); + + return data.res; +} + +/* Internal data structure for isl_union_*_set_dim_name. + * pos is the position of the parameter that needs to be renamed. + * s is the new name. + * res collects the results. + */ +S(UNION,set_dim_name_data) { + unsigned pos; + const char *s; + + UNION *res; +}; + +/* Change the name of the parameter at position data->pos of "part" to data->s + * and add the result to data->res. + */ +static isl_stat FN(UNION,set_dim_name_entry)(__isl_take PART *part, void *user) +{ + S(UNION,set_dim_name_data) *data = user; + + part = FN(PART,set_dim_name)(part, isl_dim_param, data->pos, data->s); + data->res = FN(FN(UNION,add),PARTS)(data->res, part); + if (!data->res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Change the name of the parameter at position "pos" to "s". + * That is, type is required to be isl_dim_param. + */ +__isl_give UNION *FN(UNION,set_dim_name)(__isl_take UNION *u, + enum isl_dim_type type, unsigned pos, const char *s) +{ + S(UNION,set_dim_name_data) data = { pos, s }; + isl_space *space; + + if (!u) + return NULL; + + if (type != isl_dim_param) + isl_die(FN(UNION,get_ctx)(u), isl_error_invalid, + "can only set parameter names", + return FN(UNION,free)(u)); + + space = FN(UNION,get_space)(u); + space = isl_space_set_dim_name(space, type, pos, s); +#ifdef HAS_TYPE + data.res = FN(UNION,alloc)(space, u->type, u->table.n); +#else + data.res = FN(UNION,alloc)(space, u->table.n); +#endif + + if (FN(FN(UNION,foreach),PARTS)(u, + &FN(UNION,set_dim_name_entry), &data) < 0) + data.res = FN(UNION,free)(data.res); + + FN(UNION,free)(u); + + return data.res; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "part" and add the result to *res. + */ +static isl_stat FN(UNION,reset_user_entry)(__isl_take PART *part, void *user) +{ + UNION **res = user; + + part = FN(PART,reset_user)(part); + *res = FN(FN(UNION,add),PARTS)(*res, part); + if (!*res) + return isl_stat_error; + + return isl_stat_ok; +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the spaces of "u". + */ +__isl_give UNION *FN(UNION,reset_user)(__isl_take UNION *u) +{ + isl_space *space; + UNION *res; + + if (!u) + return NULL; + + space = FN(UNION,get_space)(u); + space = isl_space_reset_user(space); +#ifdef HAS_TYPE + res = FN(UNION,alloc)(space, u->type, u->table.n); +#else + res = FN(UNION,alloc)(space, u->table.n); +#endif + if (FN(FN(UNION,foreach),PARTS)(u, + &FN(UNION,reset_user_entry), &res) < 0) + res = FN(UNION,free)(res); + + FN(UNION,free)(u); + + return res; } diff -Nru isl-0.12.2/isl_val.c isl-0.15/isl_val.c --- isl-0.12.2/isl_val.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_val.c 2015-06-11 10:46:17.000000000 +0000 @@ -49,6 +49,13 @@ return isl_val_int_from_si(ctx, 1); } +/* Return a reference to an isl_val representing negative one. + */ +__isl_give isl_val *isl_val_negone(isl_ctx *ctx) +{ + return isl_val_int_from_si(ctx, -1); +} + /* Return a reference to an isl_val representing NaN. */ __isl_give isl_val *isl_val_nan(isl_ctx *ctx) @@ -252,7 +259,7 @@ /* Free "v" and return NULL. */ -void *isl_val_free(__isl_take isl_val *v) +__isl_null isl_val *isl_val_free(__isl_take isl_val *v) { if (!v) return NULL; @@ -386,6 +393,33 @@ return v; } +/* Return the inverse of "v". + */ +__isl_give isl_val *isl_val_inv(__isl_take isl_val *v) +{ + if (!v) + return NULL; + if (isl_val_is_nan(v)) + return v; + if (isl_val_is_zero(v)) { + isl_ctx *ctx = isl_val_get_ctx(v); + isl_val_free(v); + return isl_val_nan(ctx); + } + if (isl_val_is_infty(v) || isl_val_is_neginfty(v)) { + isl_ctx *ctx = isl_val_get_ctx(v); + isl_val_free(v); + return isl_val_zero(ctx); + } + + v = isl_val_cow(v); + if (!v) + return NULL; + isl_int_swap(v->n, v->d); + + return isl_val_normalize(v); +} + /* Return the absolute value of "v". */ __isl_give isl_val *isl_val_abs(__isl_take isl_val *v) @@ -851,16 +885,27 @@ return NULL; } +/* Divide "v1" by "v2". + * + * This is a private copy of isl_val_div for use in the generic + * isl_multi_*_scale_down_val instantiated for isl_val. + */ +__isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1, + __isl_take isl_val *v2) +{ + return isl_val_div(v1, v2); +} + /* Given two integer values "v1" and "v2", check if "v1" is divisible by "v2". */ -int isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { if (!v1 || !v2) - return -1; + return isl_bool_error; if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) isl_die(isl_val_get_ctx(v1), isl_error_invalid, - "expecting two integers", return -1); + "expecting two integers", return isl_bool_error); return isl_int_is_divisible_by(v1->n, v2->n); } @@ -891,6 +936,18 @@ return NULL; } +/* Given two integer values "v1" and "v2", return the residue of "v1" + * modulo "v2". + * + * This is a private copy of isl_val_mod for use in the generic + * isl_multi_*_mod_multi_val instantiated for isl_val. + */ +__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1, + __isl_take isl_val *v2) +{ + return isl_val_mod(v1, v2); +} + /* Given two integer values, return their greatest common divisor. */ __isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2) @@ -924,6 +981,48 @@ return NULL; } +/* Compute x, y and g such that g = gcd(a,b) and a*x+b*y = g. + */ +static void isl_int_gcdext(isl_int g, isl_int x, isl_int y, + isl_int a, isl_int b) +{ + isl_int d, tmp; + isl_int a_copy, b_copy; + + isl_int_init(a_copy); + isl_int_init(b_copy); + isl_int_init(d); + isl_int_init(tmp); + isl_int_set(a_copy, a); + isl_int_set(b_copy, b); + isl_int_abs(g, a_copy); + isl_int_abs(d, b_copy); + isl_int_set_si(x, 1); + isl_int_set_si(y, 0); + while (isl_int_is_pos(d)) { + isl_int_fdiv_q(tmp, g, d); + isl_int_submul(x, tmp, y); + isl_int_submul(g, tmp, d); + isl_int_swap(g, d); + isl_int_swap(x, y); + } + if (isl_int_is_zero(a_copy)) + isl_int_set_si(x, 0); + else if (isl_int_is_neg(a_copy)) + isl_int_neg(x, x); + if (isl_int_is_zero(b_copy)) + isl_int_set_si(y, 0); + else { + isl_int_mul(tmp, a_copy, x); + isl_int_sub(tmp, g, tmp); + isl_int_divexact(y, tmp, b_copy); + } + isl_int_clear(d); + isl_int_clear(tmp); + isl_int_clear(a_copy); + isl_int_clear(b_copy); +} + /* Given two integer values v1 and v2, return their greatest common divisor g, * as well as two integers x and y such that x * v1 + y * v2 = g. */ @@ -976,126 +1075,126 @@ /* Does "v" represent an integer value? */ -int isl_val_is_int(__isl_keep isl_val *v) +isl_bool isl_val_is_int(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_one(v->d); } /* Does "v" represent a rational value? */ -int isl_val_is_rat(__isl_keep isl_val *v) +isl_bool isl_val_is_rat(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return !isl_int_is_zero(v->d); } /* Does "v" represent NaN? */ -int isl_val_is_nan(__isl_keep isl_val *v) +isl_bool isl_val_is_nan(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_zero(v->n) && isl_int_is_zero(v->d); } /* Does "v" represent +infinity? */ -int isl_val_is_infty(__isl_keep isl_val *v) +isl_bool isl_val_is_infty(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_pos(v->n) && isl_int_is_zero(v->d); } /* Does "v" represent -infinity? */ -int isl_val_is_neginfty(__isl_keep isl_val *v) +isl_bool isl_val_is_neginfty(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_neg(v->n) && isl_int_is_zero(v->d); } /* Does "v" represent the integer zero? */ -int isl_val_is_zero(__isl_keep isl_val *v) +isl_bool isl_val_is_zero(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_zero(v->n) && !isl_int_is_zero(v->d); } /* Does "v" represent the integer one? */ -int isl_val_is_one(__isl_keep isl_val *v) +isl_bool isl_val_is_one(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_eq(v->n, v->d); } /* Does "v" represent the integer negative one? */ -int isl_val_is_negone(__isl_keep isl_val *v) +isl_bool isl_val_is_negone(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_neg(v->n) && isl_int_abs_eq(v->n, v->d); } /* Is "v" (strictly) positive? */ -int isl_val_is_pos(__isl_keep isl_val *v) +isl_bool isl_val_is_pos(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_pos(v->n); } /* Is "v" (strictly) negative? */ -int isl_val_is_neg(__isl_keep isl_val *v) +isl_bool isl_val_is_neg(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; return isl_int_is_neg(v->n); } /* Is "v" non-negative? */ -int isl_val_is_nonneg(__isl_keep isl_val *v) +isl_bool isl_val_is_nonneg(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; if (isl_val_is_nan(v)) - return 0; + return isl_bool_false; return isl_int_is_nonneg(v->n); } /* Is "v" non-positive? */ -int isl_val_is_nonpos(__isl_keep isl_val *v) +isl_bool isl_val_is_nonpos(__isl_keep isl_val *v) { if (!v) - return -1; + return isl_bool_error; if (isl_val_is_nan(v)) - return 0; + return isl_bool_false; return isl_int_is_nonpos(v->n); } @@ -1117,27 +1216,27 @@ /* Is "v1" (strictly) less than "v2"? */ -int isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { isl_int t; - int lt; + isl_bool lt; if (!v1 || !v2) - return -1; + return isl_bool_error; if (isl_val_is_int(v1) && isl_val_is_int(v2)) return isl_int_lt(v1->n, v2->n); if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) - return 0; + return isl_bool_false; if (isl_val_eq(v1, v2)) - return 0; + return isl_bool_false; if (isl_val_is_infty(v2)) - return 1; + return isl_bool_true; if (isl_val_is_infty(v1)) - return 0; + return isl_bool_false; if (isl_val_is_neginfty(v1)) - return 1; + return isl_bool_true; if (isl_val_is_neginfty(v2)) - return 0; + return isl_bool_false; isl_int_init(t); isl_int_mul(t, v1->n, v2->d); @@ -1150,34 +1249,34 @@ /* Is "v1" (strictly) greater than "v2"? */ -int isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { return isl_val_lt(v2, v1); } /* Is "v1" less than or equal to "v2"? */ -int isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { isl_int t; - int le; + isl_bool le; if (!v1 || !v2) - return -1; + return isl_bool_error; if (isl_val_is_int(v1) && isl_val_is_int(v2)) return isl_int_le(v1->n, v2->n); if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) - return 0; + return isl_bool_false; if (isl_val_eq(v1, v2)) - return 1; + return isl_bool_true; if (isl_val_is_infty(v2)) - return 1; + return isl_bool_true; if (isl_val_is_infty(v1)) - return 0; + return isl_bool_false; if (isl_val_is_neginfty(v1)) - return 1; + return isl_bool_true; if (isl_val_is_neginfty(v2)) - return 0; + return isl_bool_false; isl_int_init(t); isl_int_mul(t, v1->n, v2->d); @@ -1190,7 +1289,7 @@ /* Is "v1" greater than or equal to "v2"? */ -int isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { return isl_val_le(v2, v1); } @@ -1228,24 +1327,36 @@ /* Is "v1" equal to "v2"? */ -int isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { if (!v1 || !v2) - return -1; + return isl_bool_error; if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) - return 0; + return isl_bool_false; return isl_int_eq(v1->n, v2->n) && isl_int_eq(v1->d, v2->d); } +/* Is "v1" equal to "v2" in absolute value? + */ +isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +{ + if (!v1 || !v2) + return isl_bool_error; + if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) + return isl_bool_false; + + return isl_int_abs_eq(v1->n, v2->n) && isl_int_eq(v1->d, v2->d); +} + /* Is "v1" different from "v2"? */ -int isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2) +isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2) { if (!v1 || !v2) - return -1; + return isl_bool_error; if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) - return 0; + return isl_bool_false; return isl_int_ne(v1->n, v2->n) || isl_int_ne(v1->d, v2->d); } @@ -1281,6 +1392,33 @@ return p; } +/* Is "val1" (obviously) equal to "val2"? + * + * This is a private copy of isl_val_eq for use in the generic + * isl_multi_*_plain_is_equal instantiated for isl_val. + */ +int isl_val_plain_is_equal(__isl_keep isl_val *val1, __isl_keep isl_val *val2) +{ + return isl_val_eq(val1, val2); +} + +/* Does "v" have any non-zero coefficients + * for any dimension in the given range? + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have any coefficients, this function + * always return 0. + */ +int isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type, + unsigned first, unsigned n) +{ + if (!v) + return -1; + + return 0; +} + /* Insert "n" dimensions of type "type" at position "first". * * This function is only meant to be used in the generic isl_multi_* @@ -1320,6 +1458,22 @@ return v; } +/* Return the space of "v". + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. The conditions surrounding the call to this function make sure + * that this function will never actually get called. We return a valid + * space anyway, just in case. + */ +__isl_give isl_space *isl_val_get_space(__isl_keep isl_val *v) +{ + if (!v) + return NULL; + + return isl_space_params_alloc(isl_val_get_ctx(v), 0); +} + /* Reset the domain space of "v" to "space". * * This function is only meant to be used in the generic isl_multi_* @@ -1336,6 +1490,24 @@ return v; } +/* Align the parameters of "v" to those of "space". + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have an associated space, this function + * does not do anything, apart from error handling and cleaning up memory. + * Note that the conditions surrounding the call to this function make sure + * that this function will never actually get called. + */ +__isl_give isl_val *isl_val_align_params(__isl_take isl_val *v, + __isl_take isl_space *space) +{ + if (!space) + return isl_val_free(v); + isl_space_free(space); + return v; +} + /* Reorder the dimensions of the domain of "v" according * to the given reordering. * @@ -1371,6 +1543,20 @@ return isl_val_zero(ctx); } +/* Do the parameters of "v" match those of "space"? + * + * This function is only meant to be used in the generic isl_multi_* + * functions which have to deal with base objects that have an associated + * space. Since an isl_val does not have an associated space, this function + * simply returns 1, except if "v" or "space" are NULL. + */ +int isl_val_matching_params(__isl_keep isl_val *v, __isl_keep isl_space *space) +{ + if (!v || !space) + return -1; + return 1; +} + /* Check that the domain space of "v" matches "space". * * Return 0 on success and -1 on error. @@ -1391,9 +1577,10 @@ #undef BASE #define BASE val -#define NO_GIST +#define NO_DOMAIN #define NO_IDENTITY #define NO_FROM_BASE +#define NO_MOVE_DIMS #include /* Apply "fn" to each of the elements of "mv" with as second argument "v". diff -Nru isl-0.12.2/isl_val_imath.c isl-0.15/isl_val_imath.c --- isl-0.12.2/isl_val_imath.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_val_imath.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,64 @@ +#include + +/* 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; +} diff -Nru isl-0.12.2/isl_val_private.h isl-0.15/isl_val_private.h --- isl-0.12.2/isl_val_private.h 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_val_private.h 2015-06-02 09:28:10.000000000 +0000 @@ -1,7 +1,7 @@ #ifndef ISL_VAL_PRIVATE_H #define ISL_VAL_PRIVATE_H -#include +#include #include #include #include @@ -34,21 +34,33 @@ isl_int n, isl_int d); __isl_give isl_val *isl_val_cow(__isl_take isl_val *val); +int isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type, + unsigned first, unsigned n); __isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_val *isl_val_drop_dims(__isl_take isl_val *v, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v, enum isl_dim_type type, unsigned pos, const char *s); +__isl_give isl_space *isl_val_get_space(__isl_keep isl_val *v); __isl_give isl_val *isl_val_reset_domain_space(__isl_take isl_val *v, __isl_take isl_space *space); +__isl_give isl_val *isl_val_align_params(__isl_take isl_val *v, + __isl_take isl_space *space); __isl_give isl_val *isl_val_realign_domain(__isl_take isl_val *v, __isl_take isl_reordering *r); __isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls); __isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1, __isl_take isl_val *v2); +__isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1, + __isl_take isl_val *v2); +__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1, + __isl_take isl_val *v2); + +int isl_val_plain_is_equal(__isl_keep isl_val *val1, __isl_keep isl_val *val2); +int isl_val_matching_params(__isl_keep isl_val *v, __isl_keep isl_space *space); int isl_val_check_match_domain_space(__isl_keep isl_val *v, __isl_keep isl_space *space); diff -Nru isl-0.12.2/isl_vec.c isl-0.15/isl_vec.c --- isl-0.12.2/isl_vec.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/isl_vec.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,16 +1,19 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven + * Copyright 2013 Ecole Normale Superieure * * 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 + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France */ #include -#include -#include +#include #include +#include +#include isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec) { @@ -157,7 +160,7 @@ return vec2; } -void *isl_vec_free(__isl_take isl_vec *vec) +__isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec) { if (!vec) return NULL; @@ -267,13 +270,13 @@ return isl_int_cmp(vec1->el[pos], vec2->el[pos]); } -int isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2) +isl_bool isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2) { if (!vec1 || !vec2) - return -1; + return isl_bool_error; if (vec1->size != vec2->size) - return 0; + return isl_bool_false; return isl_seq_eq(vec1->el, vec2->el, vec1->size); } @@ -526,3 +529,51 @@ return vec; } + +/* Move the "n" elements starting as "src_pos" of "vec" + * to "dst_pos". The elements originally at "dst_pos" are moved + * up or down depending on whether "dst_pos" is smaller or greater + * than "src_pos". + */ +__isl_give isl_vec *isl_vec_move_els(__isl_take isl_vec *vec, + unsigned dst_pos, unsigned src_pos, unsigned n) +{ + isl_vec *res; + + if (!vec) + return NULL; + + if (src_pos + n > vec->size) + isl_die(vec->ctx, isl_error_invalid, + "source range out of bounds", return isl_vec_free(vec)); + if (dst_pos + n > vec->size) + isl_die(vec->ctx, isl_error_invalid, + "destination range out of bounds", + return isl_vec_free(vec)); + + if (n == 0 || dst_pos == src_pos) + return vec; + + res = isl_vec_alloc(vec->ctx, vec->size); + if (!res) + return isl_vec_free(vec); + + if (dst_pos < src_pos) { + isl_seq_cpy(res->el, vec->el, dst_pos); + isl_seq_cpy(res->el + dst_pos, vec->el + src_pos, n); + isl_seq_cpy(res->el + dst_pos + n, + vec->el + dst_pos, src_pos - dst_pos); + isl_seq_cpy(res->el + src_pos + n, + vec->el + src_pos + n, res->size - src_pos - n); + } else { + isl_seq_cpy(res->el, vec->el, src_pos); + isl_seq_cpy(res->el + src_pos, + vec->el + src_pos + n, dst_pos - src_pos); + isl_seq_cpy(res->el + dst_pos, vec->el + src_pos, n); + isl_seq_cpy(res->el + dst_pos + n, + vec->el + dst_pos + n, res->size - dst_pos - n); + } + + isl_vec_free(vec); + return res; +} diff -Nru isl-0.12.2/isl_vec_private.h isl-0.15/isl_vec_private.h --- isl-0.12.2/isl_vec_private.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_vec_private.h 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,24 @@ +#ifndef ISL_VEC_PRIVATE_H +#define ISL_VEC_PRIVATE_H + +#include +#include + +struct isl_vec { + int ref; + + struct isl_ctx *ctx; + + unsigned size; + isl_int *el; + + struct isl_blk block; +}; + +__isl_give isl_vec *isl_vec_cow(__isl_take isl_vec *vec); + +void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm); +int isl_vec_get_element(__isl_keep isl_vec *vec, int pos, isl_int *v); +__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v); + +#endif diff -Nru isl-0.12.2/isl_version.c isl-0.15/isl_version.c --- isl-0.12.2/isl_version.c 2012-09-15 11:27:10.000000000 +0000 +++ isl-0.15/isl_version.c 2015-06-11 10:46:17.000000000 +0000 @@ -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"; } diff -Nru isl-0.12.2/isl_vertices.c isl-0.15/isl_vertices.c --- isl-0.12.2/isl_vertices.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/isl_vertices.c 2015-06-02 09:28:10.000000000 +0000 @@ -9,13 +9,15 @@ */ #include +#include #include -#include +#include #include #include #include #include #include +#include #define SELECTED 1 #define DESELECTED -1 @@ -112,14 +114,12 @@ __isl_keep isl_basic_set *bset, struct isl_tab *tab) { unsigned nvar; - unsigned nparam; struct isl_vertex_list *v = NULL; if (isl_tab_detect_implicit_equalities(tab) < 0) return -1; nvar = isl_basic_set_dim(bset, isl_dim_set); - nparam = isl_basic_set_dim(bset, isl_dim_param); v = isl_calloc_type(tab->mat->ctx, struct isl_vertex_list); if (!v) @@ -153,13 +153,10 @@ static __isl_give isl_vertices *vertices_empty(__isl_keep isl_basic_set *bset) { isl_vertices *vertices; - unsigned nparam; if (!bset) return NULL; - nparam = isl_basic_set_dim(bset, isl_dim_param); - vertices = isl_calloc_type(bset->ctx, isl_vertices); if (!vertices) return NULL; @@ -181,13 +178,10 @@ static __isl_give isl_vertices *vertices_0D(__isl_keep isl_basic_set *bset) { isl_vertices *vertices; - unsigned nparam; if (!bset) return NULL; - nparam = isl_basic_set_dim(bset, isl_dim_param); - vertices = isl_calloc_type(bset->ctx, isl_vertices); if (!vertices) return NULL; @@ -629,7 +623,7 @@ c->c.vertices = isl_alloc_array(tab->mat->ctx, int, n_vertices); if (n_vertices && !c->c.vertices) goto error; - c->c.dom = isl_basic_set_from_basic_map(isl_basic_map_copy(tab->bmap)); + c->c.dom = isl_basic_set_copy(isl_tab_peek_bset(tab)); c->c.dom = isl_basic_set_set_rational(c->c.dom); c->c.dom = isl_basic_set_cow(c->c.dom); c->c.dom = isl_basic_set_update_from_tab(c->c.dom, tab); @@ -706,7 +700,7 @@ if (!todo->constraint) goto error; isl_seq_neg(todo->constraint->el, tab->bmap->ineq[con], 1 + tab->n_var); - todo->bset = isl_basic_set_from_basic_map(isl_basic_map_copy(tab->bmap)); + todo->bset = isl_basic_set_copy(isl_tab_peek_bset(tab)); todo->bset = isl_basic_set_set_rational(todo->bset); todo->bset = isl_basic_set_cow(todo->bset); todo->bset = isl_basic_set_update_from_tab(todo->bset, tab); @@ -985,6 +979,25 @@ return vertex ? vertex->id : -1; } +__isl_give isl_basic_set *isl_basic_set_set_integral(__isl_take isl_basic_set *bset) +{ + if (!bset) + return NULL; + + if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)) + return bset; + + bset = isl_basic_set_cow(bset); + if (!bset) + return NULL; + + ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL); + + return isl_basic_set_finalize(bset); +} + +/* Return the activity domain of the vertex "vertex". + */ __isl_give isl_basic_set *isl_vertex_get_domain(__isl_keep isl_vertex *vertex) { struct isl_vertex *v; @@ -996,21 +1009,27 @@ if (!v->dom) { v->dom = isl_basic_set_copy(v->vertex); v->dom = isl_basic_set_params(v->dom); + v->dom = isl_basic_set_set_integral(v->dom); } return isl_basic_set_copy(v->dom); } -__isl_give isl_basic_set *isl_vertex_get_expr(__isl_keep isl_vertex *vertex) +/* Return a multiple quasi-affine expression describing the vertex "vertex" + * in terms of the parameters, + */ +__isl_give isl_multi_aff *isl_vertex_get_expr(__isl_keep isl_vertex *vertex) { struct isl_vertex *v; + isl_basic_set *bset; if (!vertex) return NULL; v = &vertex->vertices->v[vertex->id]; - return isl_basic_set_copy(v->vertex); + bset = isl_basic_set_copy(v->vertex); + return isl_multi_aff_from_basic_set_equalities(bset); } static __isl_give isl_vertex *isl_vertex_alloc(__isl_take isl_vertices *vertices, @@ -1044,23 +1063,6 @@ free(vertex); } -__isl_give isl_basic_set *isl_basic_set_set_integral(__isl_take isl_basic_set *bset) -{ - if (!bset) - return NULL; - - if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL)) - return bset; - - bset = isl_basic_set_cow(bset); - if (!bset) - return NULL; - - ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL); - - return isl_basic_set_finalize(bset); -} - isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell) { return cell ? cell->dom->ctx : NULL; @@ -1258,87 +1260,87 @@ return -1; } -int isl_vertices_foreach_cell(__isl_keep isl_vertices *vertices, - int (*fn)(__isl_take isl_cell *cell, void *user), void *user) +isl_stat isl_vertices_foreach_cell(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_cell *cell, void *user), void *user) { int i; isl_cell *cell; if (!vertices) - return -1; + return isl_stat_error; if (vertices->n_chambers == 0) - return 0; + return isl_stat_ok; for (i = 0; i < vertices->n_chambers; ++i) { - int r; + isl_stat r; isl_basic_set *dom = isl_basic_set_copy(vertices->c[i].dom); cell = isl_cell_alloc(isl_vertices_copy(vertices), dom, i); if (!cell) - return -1; + return isl_stat_error; r = fn(cell, user); if (r < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } -int isl_vertices_foreach_vertex(__isl_keep isl_vertices *vertices, - int (*fn)(__isl_take isl_vertex *vertex, void *user), void *user) +isl_stat isl_vertices_foreach_vertex(__isl_keep isl_vertices *vertices, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user) { int i; isl_vertex *vertex; if (!vertices) - return -1; + return isl_stat_error; if (vertices->n_vertices == 0) - return 0; + return isl_stat_ok; for (i = 0; i < vertices->n_vertices; ++i) { - int r; + isl_stat r; vertex = isl_vertex_alloc(isl_vertices_copy(vertices), i); if (!vertex) - return -1; + return isl_stat_error; r = fn(vertex, user); if (r < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } -int isl_cell_foreach_vertex(__isl_keep isl_cell *cell, - int (*fn)(__isl_take isl_vertex *vertex, void *user), void *user) +isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, + isl_stat (*fn)(__isl_take isl_vertex *vertex, void *user), void *user) { int i; isl_vertex *vertex; if (!cell) - return -1; + return isl_stat_error; if (cell->n_vertices == 0) - return 0; + return isl_stat_ok; for (i = 0; i < cell->n_vertices; ++i) { - int r; + isl_stat r; vertex = isl_vertex_alloc(isl_vertices_copy(cell->vertices), cell->ids[i]); if (!vertex) - return -1; + return isl_stat_error; r = fn(vertex, user); if (r < 0) - return -1; + return isl_stat_error; } - return 0; + return isl_stat_ok; } isl_ctx *isl_vertices_get_ctx(__isl_keep isl_vertices *vertices) diff -Nru isl-0.12.2/isl_yaml.h isl-0.15/isl_yaml.h --- isl-0.12.2/isl_yaml.h 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/isl_yaml.h 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,18 @@ +#ifndef ISL_YAML_H +#define ISL_YAML_H + +#define ISL_YAML_INDENT_FLOW -1 + +enum isl_yaml_state { + isl_yaml_none, + isl_yaml_mapping_first_key_start, + isl_yaml_mapping_key_start, + isl_yaml_mapping_key, + isl_yaml_mapping_val_start, + isl_yaml_mapping_val, + isl_yaml_sequence_first_start, + isl_yaml_sequence_start, + isl_yaml_sequence +}; + +#endif diff -Nru isl-0.12.2/m4/ax_detect_git_head.m4 isl-0.15/m4/ax_detect_git_head.m4 --- isl-0.12.2/m4/ax_detect_git_head.m4 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/m4/ax_detect_git_head.m4 2015-04-19 12:02:52.000000000 +0000 @@ -2,10 +2,15 @@ AC_SUBST(GIT_HEAD_ID) AC_SUBST(GIT_HEAD) AC_SUBST(GIT_HEAD_VERSION) - if test -f $srcdir/.git/HEAD; then + if test -f $srcdir/.git; then + gitdir=`GIT_DIR=$srcdir/.git git rev-parse --git-dir` + GIT_HEAD="$gitdir/index" + GIT_REPO="$gitdir" + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` + elif test -f $srcdir/.git/HEAD; then GIT_HEAD="$srcdir/.git/index" GIT_REPO="$srcdir/.git" - GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe` + GIT_HEAD_ID=`GIT_DIR=$GIT_REPO git describe --always` elif test -f $srcdir/GIT_HEAD_ID; then GIT_HEAD_ID=`cat $srcdir/GIT_HEAD_ID` else @@ -22,6 +27,6 @@ if test -z "$GIT_REPO" ; then GIT_HEAD_VERSION="$GIT_HEAD_ID" else - GIT_HEAD_VERSION="\`GIT_DIR=$GIT_REPO git describe\`" + GIT_HEAD_VERSION="\`GIT_DIR=$GIT_REPO git describe --always\`" fi ]) diff -Nru isl-0.12.2/m4/ax_detect_gmp.m4 isl-0.15/m4/ax_detect_gmp.m4 --- isl-0.12.2/m4/ax_detect_gmp.m4 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/m4/ax_detect_gmp.m4 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,48 @@ +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" + MP_CPPFLAGS="-I$with_gmp_prefix/include" + MP_LDFLAGS="-L$with_gmp_prefix/lib" + fi + MP_LIBS=-lgmp + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_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 ]], [[ + mpz_t n, d; + if (mpz_divisible_p(n, d)) + mpz_divexact_ui(n, n, 4); + ]])], [], [AC_ERROR([gmp library too old])]) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" + ;; +build) + 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="$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 +],[#include ]) +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" +LIBS="$SAVE_LIBS" +AM_CONDITIONAL(NEED_GET_MEMORY_FUNCTIONS, test x$need_get_memory_functions = xtrue) +]) diff -Nru isl-0.12.2/m4/ax_detect_imath.m4 isl-0.15/m4/ax_detect_imath.m4 --- isl-0.12.2/m4/ax_detect_imath.m4 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/m4/ax_detect_imath.m4 2015-04-19 12:02:52.000000000 +0000 @@ -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) +]) diff -Nru isl-0.12.2/Makefile.am isl-0.15/Makefile.am --- isl-0.12.2/Makefile.am 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/Makefile.am 2015-06-11 10:46:17.000000000 +0000 @@ -5,7 +5,7 @@ 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,30 +14,47 @@ isl_closure isl_bound isl_codegen TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh -if HAVE_PIPLIB -ISL_PIPLIB = \ - isl_lp_piplib.c \ - isl_map_piplib.c \ - isl_sample_piplib.c \ - isl_sample_piplib.h \ - isl_piplib.c -else -ISL_PIPLIB = \ - isl_lp_no_piplib.c \ - isl_map_no_piplib.c \ - isl_sample_no_piplib.c +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 -INCLUDES = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ +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 = \ - $(ISL_PIPLIB) \ - $(GET_MEMORY_FUNCTIONS) \ + $(MP_SRC) \ + $(DEPRECATED_SRC) \ isl_aff.c \ isl_aff_private.h \ isl_affine_hull.c \ @@ -58,6 +75,7 @@ isl_bernstein.c \ isl_bernstein.h \ isl_blk.c \ + isl_blk.h \ isl_bound.c \ isl_bound.h \ isl_coalesce.c \ @@ -67,7 +85,6 @@ isl_ctx.c \ isl_ctx_private.h \ isl_deprecated.c \ - isl_dim.c \ isl_dim_map.h \ isl_dim_map.c \ isl_equalities.c \ @@ -77,22 +94,23 @@ isl_farkas.c \ isl_flow.c \ isl_fold.c \ - isl_gmp.c \ isl_hash.c \ - isl_hmap_map_basic_set.c \ - isl_hmap_map_basic_set.h \ + isl_id_to_ast_expr.c \ + isl_id_to_pw_aff.c \ isl_ilp.c \ + isl_ilp_private.h \ isl_input.c \ isl_int.h \ isl_local_space_private.h \ isl_local_space.c \ isl_lp.c \ - isl_lp_piplib.h \ + isl_lp_private.h \ isl_map.c \ + isl_map_list.c \ isl_map_simplify.c \ isl_map_subtract.c \ isl_map_private.h \ - isl_map_piplib.h \ + isl_map_to_basic_set.c \ isl_mat.c \ isl_mat_private.h \ isl_morph.c \ @@ -103,7 +121,6 @@ isl_options.c \ isl_options_private.h \ isl_output.c \ - isl_piplib.h \ isl_point_private.h \ isl_point.c \ isl_polynomial_private.h \ @@ -120,7 +137,15 @@ isl_scan.c \ isl_scan.h \ isl_schedule.c \ + isl_schedule_band.c \ + isl_schedule_band.h \ + isl_schedule_node.c \ + isl_schedule_node_private.h \ + isl_schedule_read.c \ + isl_schedule_tree.c \ + isl_schedule_tree.h \ isl_schedule_private.h \ + isl_scheduler.c \ isl_set_list.c \ isl_sort.c \ isl_sort.h \ @@ -129,6 +154,7 @@ isl_stream.c \ isl_stream_private.h \ isl_seq.c \ + isl_seq.h \ isl_tab.c \ isl_tab.h \ isl_tab_pip.c \ @@ -138,103 +164,86 @@ 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 -EXTRA_libisl_la_SOURCES = \ - isl_lp_piplib.c \ - isl_lp_no_piplib.c \ - isl_map_piplib.c \ - isl_map_no_piplib.c \ - isl_sample_no_piplib.c \ - isl_sample_piplib.c \ - isl_sample_piplib.h \ - isl_piplib.c -libisl_la_LIBADD = @PIPLIB_LIBS@ @GMP_LIBS@ + isl_vertices.c \ + isl_yaml.h +libisl_la_LIBADD = @MP_LIBS@ libisl_la_LDFLAGS = -version-info @versioninfo@ \ - @PIPLIB_LDFLAGS@ @GMP_LDFLAGS@ -libisl_la_CPPFLAGS = $(INCLUDES) @PIPLIB_CPPFLAGS@ @GMP_CPPFLAGS@ + @MP_LDFLAGS@ -isl_test_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_polyhedron_sample_LDADD = libisl.la isl_polyhedron_sample_SOURCES = \ polyhedron_sample.c -isl_pip_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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 -isl_polytope_scan_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_polytope_scan_LDADD = libisl.la isl_polytope_scan_SOURCES = \ polytope_scan.c -isl_polyhedron_detect_equalities_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_polyhedron_detect_equalities_LDADD = libisl.la isl_polyhedron_detect_equalities_SOURCES = \ polyhedron_detect_equalities.c -isl_cat_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_cat_LDADD = libisl.la isl_cat_SOURCES = \ cat.c -isl_closure_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_closure_LDADD = libisl.la isl_closure_SOURCES = \ closure.c nodist_pkginclude_HEADERS = \ - include/isl/config.h \ include/isl/stdint.h pkginclude_HEADERS = \ + $(MP_INCLUDE_H) \ include/isl/aff.h \ include/isl/aff_type.h \ include/isl/arg.h \ include/isl/ast.h \ + include/isl/ast_type.h \ include/isl/ast_build.h \ include/isl/band.h \ - include/isl/blk.h \ include/isl/constraint.h \ include/isl/ctx.h \ - include/isl/dim.h \ include/isl/flow.h \ include/isl/id.h \ + include/isl/id_to_ast_expr.h \ + include/isl/id_to_pw_aff.h \ include/isl/ilp.h \ - include/isl/int.h \ include/isl/hash.h \ + include/isl/hmap.h \ include/isl/list.h \ include/isl/local_space.h \ include/isl/lp.h \ include/isl/mat.h \ include/isl/map.h \ + include/isl/map_to_basic_set.h \ include/isl/map_type.h \ include/isl/multi.h \ include/isl/obj.h \ @@ -244,7 +253,8 @@ include/isl/polynomial_type.h \ include/isl/printer.h \ include/isl/schedule.h \ - include/isl/seq.h \ + include/isl/schedule_node.h \ + include/isl/schedule_type.h \ include/isl/set.h \ include/isl/set_type.h \ include/isl/space.h \ @@ -254,26 +264,48 @@ include/isl/union_set.h \ include/isl/union_set_type.h \ include/isl/val.h \ - include/isl/val_gmp.h \ - include/isl/val_int.h \ include/isl/vec.h \ include/isl/version.h \ include/isl/vertices.h +deprecateddir = $(pkgincludedir)/deprecated +deprecated_HEADERS = \ + include/isl/deprecated/int.h \ + include/isl/deprecated/aff_int.h \ + include/isl/deprecated/ast_int.h \ + include/isl/deprecated/constraint_int.h \ + include/isl/deprecated/ilp_int.h \ + include/isl/deprecated/map_int.h \ + include/isl/deprecated/mat_int.h \ + include/isl/deprecated/point_int.h \ + include/isl/deprecated/polynomial_int.h \ + include/isl/deprecated/set_int.h \ + include/isl/deprecated/union_map_int.h \ + include/isl/deprecated/val_int.h \ + include/isl/deprecated/vec_int.h EXTRA_DIST = \ LICENSE \ isl_config_post.h \ basis_reduction_templ.c \ + isl_hmap_templ.c \ isl_list_templ.c \ isl_list_templ.h \ isl_map_lexopt_templ.c \ + isl_multi_macro.h \ isl_multi_templ.c \ isl_multi_templ.h \ + isl_multi_apply_templ.c \ + isl_multi_apply_set.c \ + isl_multi_apply_union_set.c \ + isl_multi_floor.c \ + isl_multi_gist.c \ + isl_multi_intersect.c \ print_templ.c \ isl_power_templ.c \ isl_pw_templ.c \ isl_union_templ.c \ isl.py \ + doc/CodingStyle \ doc/SubmittingPatches \ doc/chicago.bst \ doc/chicago.sty \ @@ -282,6 +314,12 @@ 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 diff -Nru isl-0.12.2/Makefile.in isl-0.15/Makefile.in --- isl-0.12.2/Makefile.in 2014-01-12 11:45:17.000000000 +0000 +++ isl-0.15/Makefile.in 2015-06-11 10:47:03.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -19,23 +18,51 @@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -61,13 +88,13 @@ isl_closure$(EXEEXT) isl_bound$(EXEEXT) isl_codegen$(EXEEXT) TESTS = isl_test$(EXEEXT) codegen_test.sh pip_test.sh bound_test.sh subdir = . -DIST_COMMON = README $(am__configure_deps) $(pkginclude_HEADERS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/bound_test.sh.in $(srcdir)/codegen_test.sh.in \ - $(srcdir)/isl_config.h.in $(srcdir)/pip_test.sh.in \ - $(top_srcdir)/configure $(top_srcdir)/include/isl/config.h.in \ - AUTHORS ChangeLog compile config.guess config.sub depcomp \ - install-sh ltmain.sh missing +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/isl_config.h.in $(srcdir)/bound_test.sh.in \ + $(srcdir)/codegen_test.sh.in $(srcdir)/pip_test.sh.in depcomp \ + $(deprecated_HEADERS) $(am__pkginclude_HEADERS_DIST) \ + test-driver AUTHORS ChangeLog README compile config.guess \ + config.sub install-sh missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \ $(top_srcdir)/m4/ax_cc_maxopt.m4 \ @@ -76,6 +103,8 @@ $(top_srcdir)/m4/ax_create_pkgconfig_info.m4 \ $(top_srcdir)/m4/ax_create_stdint_h.m4 \ $(top_srcdir)/m4/ax_detect_git_head.m4 \ + $(top_srcdir)/m4/ax_detect_gmp.m4 \ + $(top_srcdir)/m4/ax_detect_imath.m4 \ $(top_srcdir)/m4/ax_gcc_archflag.m4 \ $(top_srcdir)/m4/ax_gcc_warn_unused_result.m4 \ $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ @@ -89,7 +118,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = isl_config.h $(top_builddir)/include/isl/config.h +CONFIG_HEADER = isl_config.h CONFIG_CLEAN_FILES = bound_test.sh codegen_test.sh pip_test.sh CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -120,123 +149,118 @@ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)" + "$(DESTDIR)$(deprecateddir)" "$(DESTDIR)$(pkgincludedir)" \ + "$(DESTDIR)$(pkgincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libisl_la_DEPENDENCIES = -am__libisl_la_SOURCES_DIST = isl_lp_no_piplib.c isl_map_no_piplib.c \ - isl_sample_no_piplib.c isl_lp_piplib.c isl_map_piplib.c \ - isl_sample_piplib.c isl_sample_piplib.h isl_piplib.c \ - mp_get_memory_functions.c isl_aff.c isl_aff_private.h \ +am__libisl_la_SOURCES_DIST = mp_get_memory_functions.c isl_int_gmp.h \ + isl_gmp.c isl_val_gmp.c 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 isl_ast_int.c isl_aff.c isl_aff_private.h \ isl_affine_hull.c isl_arg.c isl_ast.c isl_ast_private.h \ isl_ast_build.c isl_ast_build_private.h isl_ast_build_expr.c \ isl_ast_build_expr.h isl_ast_codegen.c isl_ast_graft.c \ isl_ast_graft_private.h isl_band.c isl_band_private.h \ isl_basis_reduction.h basis_reduction_tab.c isl_bernstein.c \ - isl_bernstein.h isl_blk.c isl_bound.c isl_bound.h \ + isl_bernstein.h isl_blk.c isl_blk.h isl_bound.c isl_bound.h \ isl_coalesce.c isl_constraint.c isl_constraint_private.h \ isl_convex_hull.c isl_ctx.c isl_ctx_private.h isl_deprecated.c \ - isl_dim.c isl_dim_map.h isl_dim_map.c isl_equalities.c \ - isl_equalities.h isl_factorization.c isl_factorization.h \ - isl_farkas.c isl_flow.c isl_fold.c isl_gmp.c isl_hash.c \ - isl_hmap_map_basic_set.c isl_hmap_map_basic_set.h isl_ilp.c \ - isl_input.c isl_int.h isl_local_space_private.h \ - isl_local_space.c isl_lp.c isl_lp_piplib.h isl_map.c \ - isl_map_simplify.c isl_map_subtract.c isl_map_private.h \ - isl_map_piplib.h isl_mat.c isl_mat_private.h isl_morph.c \ - isl_morph.h isl_id.c isl_id_private.h isl_obj.c isl_options.c \ - isl_options_private.h isl_output.c isl_piplib.h \ - isl_point_private.h isl_point.c isl_polynomial_private.h \ - isl_polynomial.c isl_printer_private.h isl_printer.c print.c \ - isl_range.c isl_range.h isl_reordering.c isl_reordering.h \ - isl_sample.h isl_sample.c isl_scan.c isl_scan.h isl_schedule.c \ - isl_schedule_private.h isl_set_list.c isl_sort.c isl_sort.h \ + isl_dim_map.h isl_dim_map.c isl_equalities.c isl_equalities.h \ + isl_factorization.c isl_factorization.h isl_farkas.c \ + isl_flow.c isl_fold.c isl_hash.c isl_id_to_ast_expr.c \ + isl_id_to_pw_aff.c isl_ilp.c isl_ilp_private.h isl_input.c \ + isl_int.h isl_local_space_private.h isl_local_space.c isl_lp.c \ + isl_lp_private.h isl_map.c isl_map_list.c isl_map_simplify.c \ + isl_map_subtract.c isl_map_private.h isl_map_to_basic_set.c \ + isl_mat.c isl_mat_private.h isl_morph.c isl_morph.h isl_id.c \ + isl_id_private.h isl_obj.c isl_options.c isl_options_private.h \ + isl_output.c isl_point_private.h isl_point.c \ + isl_polynomial_private.h isl_polynomial.c \ + isl_printer_private.h isl_printer.c print.c isl_range.c \ + isl_range.h isl_reordering.c isl_reordering.h isl_sample.h \ + isl_sample.c isl_scan.c isl_scan.h isl_schedule.c \ + isl_schedule_band.c isl_schedule_band.h isl_schedule_node.c \ + isl_schedule_node_private.h isl_schedule_read.c \ + isl_schedule_tree.c isl_schedule_tree.h isl_schedule_private.h \ + isl_scheduler.c isl_set_list.c isl_sort.c isl_sort.h \ isl_space.c isl_space_private.h isl_stream.c \ - isl_stream_private.h isl_seq.c isl_tab.c isl_tab.h \ + isl_stream_private.h isl_seq.c isl_seq.h isl_tab.c isl_tab.h \ isl_tab_pip.c isl_tarjan.c isl_tarjan.h \ isl_transitive_closure.c isl_union_map.c \ - isl_union_map_private.h isl_val.c isl_val_gmp.c \ - isl_val_private.h isl_vec.c isl_version.c \ - isl_vertices_private.h isl_vertices.c -@HAVE_PIPLIB_FALSE@am__objects_1 = libisl_la-isl_lp_no_piplib.lo \ -@HAVE_PIPLIB_FALSE@ libisl_la-isl_map_no_piplib.lo \ -@HAVE_PIPLIB_FALSE@ libisl_la-isl_sample_no_piplib.lo -@HAVE_PIPLIB_TRUE@am__objects_1 = libisl_la-isl_lp_piplib.lo \ -@HAVE_PIPLIB_TRUE@ libisl_la-isl_map_piplib.lo \ -@HAVE_PIPLIB_TRUE@ libisl_la-isl_sample_piplib.lo \ -@HAVE_PIPLIB_TRUE@ libisl_la-isl_piplib.lo -@NEED_GET_MEMORY_FUNCTIONS_TRUE@am__objects_2 = libisl_la-mp_get_memory_functions.lo -am_libisl_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ - libisl_la-isl_aff.lo libisl_la-isl_affine_hull.lo \ - libisl_la-isl_arg.lo libisl_la-isl_ast.lo \ - libisl_la-isl_ast_build.lo libisl_la-isl_ast_build_expr.lo \ - libisl_la-isl_ast_codegen.lo libisl_la-isl_ast_graft.lo \ - libisl_la-isl_band.lo libisl_la-basis_reduction_tab.lo \ - libisl_la-isl_bernstein.lo libisl_la-isl_blk.lo \ - libisl_la-isl_bound.lo libisl_la-isl_coalesce.lo \ - libisl_la-isl_constraint.lo libisl_la-isl_convex_hull.lo \ - libisl_la-isl_ctx.lo libisl_la-isl_deprecated.lo \ - libisl_la-isl_dim.lo libisl_la-isl_dim_map.lo \ - libisl_la-isl_equalities.lo libisl_la-isl_factorization.lo \ - libisl_la-isl_farkas.lo libisl_la-isl_flow.lo \ - libisl_la-isl_fold.lo libisl_la-isl_gmp.lo \ - libisl_la-isl_hash.lo libisl_la-isl_hmap_map_basic_set.lo \ - libisl_la-isl_ilp.lo libisl_la-isl_input.lo \ - libisl_la-isl_local_space.lo libisl_la-isl_lp.lo \ - libisl_la-isl_map.lo libisl_la-isl_map_simplify.lo \ - libisl_la-isl_map_subtract.lo libisl_la-isl_mat.lo \ - libisl_la-isl_morph.lo libisl_la-isl_id.lo \ - libisl_la-isl_obj.lo libisl_la-isl_options.lo \ - libisl_la-isl_output.lo libisl_la-isl_point.lo \ - libisl_la-isl_polynomial.lo libisl_la-isl_printer.lo \ - libisl_la-print.lo libisl_la-isl_range.lo \ - libisl_la-isl_reordering.lo libisl_la-isl_sample.lo \ - libisl_la-isl_scan.lo libisl_la-isl_schedule.lo \ - libisl_la-isl_set_list.lo libisl_la-isl_sort.lo \ - libisl_la-isl_space.lo libisl_la-isl_stream.lo \ - libisl_la-isl_seq.lo libisl_la-isl_tab.lo \ - libisl_la-isl_tab_pip.lo libisl_la-isl_tarjan.lo \ - libisl_la-isl_transitive_closure.lo libisl_la-isl_union_map.lo \ - libisl_la-isl_val.lo libisl_la-isl_val_gmp.lo \ - libisl_la-isl_vec.lo libisl_la-isl_version.lo \ - libisl_la-isl_vertices.lo + isl_union_map_private.h isl_val.c isl_val_private.h \ + isl_vec_private.h isl_vec.c isl_version.c \ + isl_vertices_private.h isl_vertices.c isl_yaml.h +@GMP_FOR_MP_TRUE@@NEED_GET_MEMORY_FUNCTIONS_TRUE@am__objects_1 = mp_get_memory_functions.lo +am__dirstamp = $(am__leading_dot)dirstamp +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@am__objects_2 = isl_imath.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ isl_val_imath.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ imath_wrap/gmp_compat.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ imath_wrap/imath.lo \ +@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ imath_wrap/imrat.lo +@GMP_FOR_MP_TRUE@am__objects_2 = $(am__objects_1) isl_gmp.lo \ +@GMP_FOR_MP_TRUE@ isl_val_gmp.lo +@GMP_FOR_MP_TRUE@am__objects_3 = isl_ast_int.lo +am_libisl_la_OBJECTS = $(am__objects_2) $(am__objects_3) isl_aff.lo \ + isl_affine_hull.lo isl_arg.lo isl_ast.lo isl_ast_build.lo \ + isl_ast_build_expr.lo isl_ast_codegen.lo isl_ast_graft.lo \ + isl_band.lo basis_reduction_tab.lo isl_bernstein.lo isl_blk.lo \ + isl_bound.lo isl_coalesce.lo isl_constraint.lo \ + isl_convex_hull.lo isl_ctx.lo isl_deprecated.lo isl_dim_map.lo \ + isl_equalities.lo isl_factorization.lo isl_farkas.lo \ + isl_flow.lo isl_fold.lo isl_hash.lo isl_id_to_ast_expr.lo \ + isl_id_to_pw_aff.lo isl_ilp.lo isl_input.lo isl_local_space.lo \ + isl_lp.lo isl_map.lo isl_map_list.lo isl_map_simplify.lo \ + isl_map_subtract.lo isl_map_to_basic_set.lo isl_mat.lo \ + isl_morph.lo isl_id.lo isl_obj.lo isl_options.lo isl_output.lo \ + isl_point.lo isl_polynomial.lo isl_printer.lo print.lo \ + isl_range.lo isl_reordering.lo isl_sample.lo isl_scan.lo \ + isl_schedule.lo isl_schedule_band.lo isl_schedule_node.lo \ + isl_schedule_read.lo isl_schedule_tree.lo isl_scheduler.lo \ + isl_set_list.lo isl_sort.lo isl_space.lo isl_stream.lo \ + isl_seq.lo isl_tab.lo isl_tab_pip.lo isl_tarjan.lo \ + isl_transitive_closure.lo isl_union_map.lo isl_val.lo \ + isl_vec.lo isl_version.lo isl_vertices.lo libisl_la_OBJECTS = $(am_libisl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent +am__v_lt_1 = libisl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libisl_la_LDFLAGS) $(LDFLAGS) -o $@ PROGRAMS = $(noinst_PROGRAMS) -am_isl_bound_OBJECTS = isl_bound-bound.$(OBJEXT) +am_isl_bound_OBJECTS = bound.$(OBJEXT) isl_bound_OBJECTS = $(am_isl_bound_OBJECTS) isl_bound_DEPENDENCIES = libisl.la isl_bound_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(isl_bound_LDFLAGS) $(LDFLAGS) -o $@ -am_isl_cat_OBJECTS = isl_cat-cat.$(OBJEXT) +am_isl_cat_OBJECTS = cat.$(OBJEXT) isl_cat_OBJECTS = $(am_isl_cat_OBJECTS) isl_cat_DEPENDENCIES = libisl.la -am_isl_closure_OBJECTS = isl_closure-closure.$(OBJEXT) +am_isl_closure_OBJECTS = closure.$(OBJEXT) isl_closure_OBJECTS = $(am_isl_closure_OBJECTS) isl_closure_DEPENDENCIES = libisl.la -am_isl_codegen_OBJECTS = isl_codegen-codegen.$(OBJEXT) +am_isl_codegen_OBJECTS = codegen.$(OBJEXT) isl_codegen_OBJECTS = $(am_isl_codegen_OBJECTS) isl_codegen_DEPENDENCIES = libisl.la isl_codegen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(isl_codegen_LDFLAGS) $(LDFLAGS) -o $@ -am_isl_pip_OBJECTS = isl_pip-pip.$(OBJEXT) +am_isl_pip_OBJECTS = pip.$(OBJEXT) isl_pip_OBJECTS = $(am_isl_pip_OBJECTS) isl_pip_DEPENDENCIES = libisl.la isl_pip_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(isl_pip_LDFLAGS) $(LDFLAGS) -o $@ -am_isl_polyhedron_detect_equalities_OBJECTS = isl_polyhedron_detect_equalities-polyhedron_detect_equalities.$(OBJEXT) +am_isl_polyhedron_detect_equalities_OBJECTS = \ + polyhedron_detect_equalities.$(OBJEXT) isl_polyhedron_detect_equalities_OBJECTS = \ $(am_isl_polyhedron_detect_equalities_OBJECTS) isl_polyhedron_detect_equalities_DEPENDENCIES = libisl.la -am_isl_polyhedron_minimize_OBJECTS = \ - isl_polyhedron_minimize-polyhedron_minimize.$(OBJEXT) +am_isl_polyhedron_minimize_OBJECTS = polyhedron_minimize.$(OBJEXT) isl_polyhedron_minimize_OBJECTS = \ $(am_isl_polyhedron_minimize_OBJECTS) isl_polyhedron_minimize_DEPENDENCIES = libisl.la @@ -244,20 +268,30 @@ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(isl_polyhedron_minimize_LDFLAGS) \ $(LDFLAGS) -o $@ -am_isl_polyhedron_sample_OBJECTS = \ - isl_polyhedron_sample-polyhedron_sample.$(OBJEXT) +am_isl_polyhedron_sample_OBJECTS = polyhedron_sample.$(OBJEXT) isl_polyhedron_sample_OBJECTS = $(am_isl_polyhedron_sample_OBJECTS) isl_polyhedron_sample_DEPENDENCIES = libisl.la -am_isl_polytope_scan_OBJECTS = \ - isl_polytope_scan-polytope_scan.$(OBJEXT) +am_isl_polytope_scan_OBJECTS = polytope_scan.$(OBJEXT) isl_polytope_scan_OBJECTS = $(am_isl_polytope_scan_OBJECTS) isl_polytope_scan_DEPENDENCIES = libisl.la isl_test_SOURCES = isl_test.c -isl_test_OBJECTS = isl_test-isl_test.$(OBJEXT) +isl_test_OBJECTS = isl_test.$(OBJEXT) isl_test_DEPENDENCIES = libisl.la isl_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(isl_test_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -270,58 +304,270 @@ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libisl_la_SOURCES) $(EXTRA_libisl_la_SOURCES) \ - $(isl_bound_SOURCES) $(isl_cat_SOURCES) $(isl_closure_SOURCES) \ - $(isl_codegen_SOURCES) $(isl_pip_SOURCES) \ - $(isl_polyhedron_detect_equalities_SOURCES) \ +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libisl_la_SOURCES) $(isl_bound_SOURCES) $(isl_cat_SOURCES) \ + $(isl_closure_SOURCES) $(isl_codegen_SOURCES) \ + $(isl_pip_SOURCES) $(isl_polyhedron_detect_equalities_SOURCES) \ $(isl_polyhedron_minimize_SOURCES) \ $(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \ isl_test.c -DIST_SOURCES = $(am__libisl_la_SOURCES_DIST) \ - $(EXTRA_libisl_la_SOURCES) $(isl_bound_SOURCES) \ +DIST_SOURCES = $(am__libisl_la_SOURCES_DIST) $(isl_bound_SOURCES) \ $(isl_cat_SOURCES) $(isl_closure_SOURCES) \ $(isl_codegen_SOURCES) $(isl_pip_SOURCES) \ $(isl_polyhedron_detect_equalities_SOURCES) \ $(isl_polyhedron_minimize_SOURCES) \ $(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \ isl_test.c -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(pkgconfig_DATA) -HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS) +am__pkginclude_HEADERS_DIST = include/isl/val_gmp.h include/isl/aff.h \ + include/isl/aff_type.h include/isl/arg.h include/isl/ast.h \ + include/isl/ast_type.h include/isl/ast_build.h \ + include/isl/band.h include/isl/constraint.h include/isl/ctx.h \ + include/isl/flow.h include/isl/id.h \ + include/isl/id_to_ast_expr.h include/isl/id_to_pw_aff.h \ + include/isl/ilp.h include/isl/hash.h include/isl/hmap.h \ + include/isl/list.h include/isl/local_space.h include/isl/lp.h \ + include/isl/mat.h include/isl/map.h \ + include/isl/map_to_basic_set.h include/isl/map_type.h \ + include/isl/multi.h include/isl/obj.h include/isl/options.h \ + include/isl/point.h include/isl/polynomial.h \ + include/isl/polynomial_type.h include/isl/printer.h \ + include/isl/schedule.h include/isl/schedule_node.h \ + include/isl/schedule_type.h include/isl/set.h \ + include/isl/set_type.h include/isl/space.h \ + include/isl/stream.h include/isl/union_map.h \ + include/isl/union_map_type.h include/isl/union_set.h \ + include/isl/union_set_type.h include/isl/val.h \ + include/isl/vec.h include/isl/version.h include/isl/vertices.h +HEADERS = $(deprecated_HEADERS) $(nodist_pkginclude_HEADERS) \ + $(pkginclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir dist dist-all distcheck +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope check recheck distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)isl_config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= +CSCOPE = cscope +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -331,6 +577,7 @@ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi +am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -358,6 +605,7 @@ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best +DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -397,9 +645,6 @@ GIT_HEAD = @GIT_HEAD@ GIT_HEAD_ID = @GIT_HEAD_ID@ GIT_HEAD_VERSION = @GIT_HEAD_VERSION@ -GMP_CPPFLAGS = @GMP_CPPFLAGS@ -GMP_LDFLAGS = @GMP_LDFLAGS@ -GMP_LIBS = @GMP_LIBS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -418,6 +663,9 @@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MP_CPPFLAGS = @MP_CPPFLAGS@ +MP_LDFLAGS = @MP_LDFLAGS@ +MP_LIBS = @MP_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ @@ -434,9 +682,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ -PIPLIB_CPPFLAGS = @PIPLIB_CPPFLAGS@ -PIPLIB_LDFLAGS = @PIPLIB_LDFLAGS@ -PIPLIB_LIBS = @PIPLIB_LIBS@ POD2HTML = @POD2HTML@ PRTDIAG = @PRTDIAG@ RANLIB = @RANLIB@ @@ -507,26 +752,38 @@ 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 -@HAVE_PIPLIB_FALSE@ISL_PIPLIB = \ -@HAVE_PIPLIB_FALSE@ isl_lp_no_piplib.c \ -@HAVE_PIPLIB_FALSE@ isl_map_no_piplib.c \ -@HAVE_PIPLIB_FALSE@ isl_sample_no_piplib.c - -@HAVE_PIPLIB_TRUE@ISL_PIPLIB = \ -@HAVE_PIPLIB_TRUE@ isl_lp_piplib.c \ -@HAVE_PIPLIB_TRUE@ isl_map_piplib.c \ -@HAVE_PIPLIB_TRUE@ isl_sample_piplib.c \ -@HAVE_PIPLIB_TRUE@ isl_sample_piplib.h \ -@HAVE_PIPLIB_TRUE@ isl_piplib.c - -@NEED_GET_MEMORY_FUNCTIONS_TRUE@GET_MEMORY_FUNCTIONS = mp_get_memory_functions.c -INCLUDES = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ +@GMP_FOR_MP_TRUE@MP_SRC = \ +@GMP_FOR_MP_TRUE@ $(GET_MEMORY_FUNCTIONS) \ +@GMP_FOR_MP_TRUE@ isl_int_gmp.h \ +@GMP_FOR_MP_TRUE@ isl_gmp.c \ +@GMP_FOR_MP_TRUE@ isl_val_gmp.c + +@IMATH_FOR_MP_TRUE@MP_SRC = \ +@IMATH_FOR_MP_TRUE@ isl_hide_deprecated.h \ +@IMATH_FOR_MP_TRUE@ isl_imath.c \ +@IMATH_FOR_MP_TRUE@ isl_imath.h \ +@IMATH_FOR_MP_TRUE@ isl_int_imath.h \ +@IMATH_FOR_MP_TRUE@ isl_val_imath.c \ +@IMATH_FOR_MP_TRUE@ imath_wrap/gmp_compat.h \ +@IMATH_FOR_MP_TRUE@ imath_wrap/imath.h \ +@IMATH_FOR_MP_TRUE@ imath_wrap/imrat.h \ +@IMATH_FOR_MP_TRUE@ imath_wrap/wrap.h \ +@IMATH_FOR_MP_TRUE@ imath_wrap/gmp_compat.c \ +@IMATH_FOR_MP_TRUE@ imath_wrap/imath.c \ +@IMATH_FOR_MP_TRUE@ imath_wrap/imrat.c + +@GMP_FOR_MP_TRUE@DEPRECATED_SRC = isl_ast_int.c +@IMATH_FOR_MP_TRUE@DEPRECATED_SRC = +@GMP_FOR_MP_TRUE@MP_INCLUDE_H = include/isl/val_gmp.h +@IMATH_FOR_MP_TRUE@MP_INCLUDE_H = +@GMP_FOR_MP_TRUE@@NEED_GET_MEMORY_FUNCTIONS_TRUE@GET_MEMORY_FUNCTIONS = mp_get_memory_functions.c +AM_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ @MP_CPPFLAGS@ AM_CFLAGS = @WARNING_FLAGS@ libisl_la_SOURCES = \ - $(ISL_PIPLIB) \ - $(GET_MEMORY_FUNCTIONS) \ + $(MP_SRC) \ + $(DEPRECATED_SRC) \ isl_aff.c \ isl_aff_private.h \ isl_affine_hull.c \ @@ -547,6 +804,7 @@ isl_bernstein.c \ isl_bernstein.h \ isl_blk.c \ + isl_blk.h \ isl_bound.c \ isl_bound.h \ isl_coalesce.c \ @@ -556,7 +814,6 @@ isl_ctx.c \ isl_ctx_private.h \ isl_deprecated.c \ - isl_dim.c \ isl_dim_map.h \ isl_dim_map.c \ isl_equalities.c \ @@ -566,22 +823,23 @@ isl_farkas.c \ isl_flow.c \ isl_fold.c \ - isl_gmp.c \ isl_hash.c \ - isl_hmap_map_basic_set.c \ - isl_hmap_map_basic_set.h \ + isl_id_to_ast_expr.c \ + isl_id_to_pw_aff.c \ isl_ilp.c \ + isl_ilp_private.h \ isl_input.c \ isl_int.h \ isl_local_space_private.h \ isl_local_space.c \ isl_lp.c \ - isl_lp_piplib.h \ + isl_lp_private.h \ isl_map.c \ + isl_map_list.c \ isl_map_simplify.c \ isl_map_subtract.c \ isl_map_private.h \ - isl_map_piplib.h \ + isl_map_to_basic_set.c \ isl_mat.c \ isl_mat_private.h \ isl_morph.c \ @@ -592,7 +850,6 @@ isl_options.c \ isl_options_private.h \ isl_output.c \ - isl_piplib.h \ isl_point_private.h \ isl_point.c \ isl_polynomial_private.h \ @@ -609,7 +866,15 @@ isl_scan.c \ isl_scan.h \ isl_schedule.c \ + isl_schedule_band.c \ + isl_schedule_band.h \ + isl_schedule_node.c \ + isl_schedule_node_private.h \ + isl_schedule_read.c \ + isl_schedule_tree.c \ + isl_schedule_tree.h \ isl_schedule_private.h \ + isl_scheduler.c \ isl_set_list.c \ isl_sort.c \ isl_sort.h \ @@ -618,6 +883,7 @@ isl_stream.c \ isl_stream_private.h \ isl_seq.c \ + isl_seq.h \ isl_tab.c \ isl_tab.h \ isl_tab_pip.c \ @@ -627,105 +893,87 @@ 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 - -EXTRA_libisl_la_SOURCES = \ - isl_lp_piplib.c \ - isl_lp_no_piplib.c \ - isl_map_piplib.c \ - isl_map_no_piplib.c \ - isl_sample_no_piplib.c \ - isl_sample_piplib.c \ - isl_sample_piplib.h \ - isl_piplib.c + isl_vertices.c \ + isl_yaml.h -libisl_la_LIBADD = @PIPLIB_LIBS@ @GMP_LIBS@ +libisl_la_LIBADD = @MP_LIBS@ libisl_la_LDFLAGS = -version-info @versioninfo@ \ - @PIPLIB_LDFLAGS@ @GMP_LDFLAGS@ + @MP_LDFLAGS@ -libisl_la_CPPFLAGS = $(INCLUDES) @PIPLIB_CPPFLAGS@ @GMP_CPPFLAGS@ -isl_test_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -isl_test_LDFLAGS = @GMP_LDFLAGS@ -isl_test_LDADD = libisl.la @GMP_LIBS@ -isl_polyhedron_sample_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ +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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ -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 -isl_polytope_scan_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_polytope_scan_LDADD = libisl.la isl_polytope_scan_SOURCES = \ polytope_scan.c -isl_polyhedron_detect_equalities_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_polyhedron_detect_equalities_LDADD = libisl.la isl_polyhedron_detect_equalities_SOURCES = \ polyhedron_detect_equalities.c -isl_cat_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_cat_LDADD = libisl.la isl_cat_SOURCES = \ cat.c -isl_closure_CPPFLAGS = $(INCLUDES) @GMP_CPPFLAGS@ isl_closure_LDADD = libisl.la isl_closure_SOURCES = \ closure.c nodist_pkginclude_HEADERS = \ - include/isl/config.h \ include/isl/stdint.h pkginclude_HEADERS = \ + $(MP_INCLUDE_H) \ include/isl/aff.h \ include/isl/aff_type.h \ include/isl/arg.h \ include/isl/ast.h \ + include/isl/ast_type.h \ include/isl/ast_build.h \ include/isl/band.h \ - include/isl/blk.h \ include/isl/constraint.h \ include/isl/ctx.h \ - include/isl/dim.h \ include/isl/flow.h \ include/isl/id.h \ + include/isl/id_to_ast_expr.h \ + include/isl/id_to_pw_aff.h \ include/isl/ilp.h \ - include/isl/int.h \ include/isl/hash.h \ + include/isl/hmap.h \ include/isl/list.h \ include/isl/local_space.h \ include/isl/lp.h \ include/isl/mat.h \ include/isl/map.h \ + include/isl/map_to_basic_set.h \ include/isl/map_type.h \ include/isl/multi.h \ include/isl/obj.h \ @@ -735,7 +983,8 @@ include/isl/polynomial_type.h \ include/isl/printer.h \ include/isl/schedule.h \ - include/isl/seq.h \ + include/isl/schedule_node.h \ + include/isl/schedule_type.h \ include/isl/set.h \ include/isl/set_type.h \ include/isl/space.h \ @@ -745,26 +994,49 @@ include/isl/union_set.h \ include/isl/union_set_type.h \ include/isl/val.h \ - include/isl/val_gmp.h \ - include/isl/val_int.h \ include/isl/vec.h \ include/isl/version.h \ include/isl/vertices.h +deprecateddir = $(pkgincludedir)/deprecated +deprecated_HEADERS = \ + include/isl/deprecated/int.h \ + include/isl/deprecated/aff_int.h \ + include/isl/deprecated/ast_int.h \ + include/isl/deprecated/constraint_int.h \ + include/isl/deprecated/ilp_int.h \ + include/isl/deprecated/map_int.h \ + include/isl/deprecated/mat_int.h \ + include/isl/deprecated/point_int.h \ + include/isl/deprecated/polynomial_int.h \ + include/isl/deprecated/set_int.h \ + include/isl/deprecated/union_map_int.h \ + include/isl/deprecated/val_int.h \ + include/isl/deprecated/vec_int.h + EXTRA_DIST = \ LICENSE \ isl_config_post.h \ basis_reduction_templ.c \ + isl_hmap_templ.c \ isl_list_templ.c \ isl_list_templ.h \ isl_map_lexopt_templ.c \ + isl_multi_macro.h \ isl_multi_templ.c \ isl_multi_templ.h \ + isl_multi_apply_templ.c \ + isl_multi_apply_set.c \ + isl_multi_apply_union_set.c \ + isl_multi_floor.c \ + isl_multi_gist.c \ + isl_multi_intersect.c \ print_templ.c \ isl_power_templ.c \ isl_pw_templ.c \ isl_union_templ.c \ isl.py \ + doc/CodingStyle \ doc/SubmittingPatches \ doc/chicago.bst \ doc/chicago.sty \ @@ -773,6 +1045,12 @@ 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 @@ -783,7 +1061,7 @@ $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -.SUFFIXES: .c .lo .o .obj +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @@ -820,8 +1098,8 @@ $(am__aclocal_m4_deps): isl_config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/isl_config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -831,22 +1109,15 @@ rm -f stamp-h1 touch $@ -include/isl/config.h: include/isl/stamp-h2 - @if test ! -f $@; then rm -f include/isl/stamp-h2; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) include/isl/stamp-h2; else :; fi - -include/isl/stamp-h2: $(top_srcdir)/include/isl/config.h.in $(top_builddir)/config.status - @rm -f include/isl/stamp-h2 - cd $(top_builddir) && $(SHELL) ./config.status include/isl/config.h - distclean-hdr: - -rm -f isl_config.h stamp-h1 include/isl/config.h include/isl/stamp-h2 + -rm -f isl_config.h stamp-h1 bound_test.sh: $(top_builddir)/config.status $(srcdir)/bound_test.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ codegen_test.sh: $(top_builddir)/config.status $(srcdir)/codegen_test.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ pip_test.sh: $(top_builddir)/config.status $(srcdir)/pip_test.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ + install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ @@ -873,12 +1144,27 @@ clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +imath_wrap/$(am__dirstamp): + @$(MKDIR_P) imath_wrap + @: > imath_wrap/$(am__dirstamp) +imath_wrap/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) imath_wrap/$(DEPDIR) + @: > imath_wrap/$(DEPDIR)/$(am__dirstamp) +imath_wrap/gmp_compat.lo: imath_wrap/$(am__dirstamp) \ + imath_wrap/$(DEPDIR)/$(am__dirstamp) +imath_wrap/imath.lo: imath_wrap/$(am__dirstamp) \ + imath_wrap/$(DEPDIR)/$(am__dirstamp) +imath_wrap/imrat.lo: imath_wrap/$(am__dirstamp) \ + imath_wrap/$(DEPDIR)/$(am__dirstamp) + libisl.la: $(libisl_la_OBJECTS) $(libisl_la_DEPENDENCIES) $(EXTRA_libisl_la_DEPENDENCIES) $(AM_V_CCLD)$(libisl_la_LINK) -rpath $(libdir) $(libisl_la_OBJECTS) $(libisl_la_LIBADD) $(LIBS) @@ -890,804 +1176,175 @@ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + isl_bound$(EXEEXT): $(isl_bound_OBJECTS) $(isl_bound_DEPENDENCIES) $(EXTRA_isl_bound_DEPENDENCIES) @rm -f isl_bound$(EXEEXT) $(AM_V_CCLD)$(isl_bound_LINK) $(isl_bound_OBJECTS) $(isl_bound_LDADD) $(LIBS) + isl_cat$(EXEEXT): $(isl_cat_OBJECTS) $(isl_cat_DEPENDENCIES) $(EXTRA_isl_cat_DEPENDENCIES) @rm -f isl_cat$(EXEEXT) $(AM_V_CCLD)$(LINK) $(isl_cat_OBJECTS) $(isl_cat_LDADD) $(LIBS) + isl_closure$(EXEEXT): $(isl_closure_OBJECTS) $(isl_closure_DEPENDENCIES) $(EXTRA_isl_closure_DEPENDENCIES) @rm -f isl_closure$(EXEEXT) $(AM_V_CCLD)$(LINK) $(isl_closure_OBJECTS) $(isl_closure_LDADD) $(LIBS) + isl_codegen$(EXEEXT): $(isl_codegen_OBJECTS) $(isl_codegen_DEPENDENCIES) $(EXTRA_isl_codegen_DEPENDENCIES) @rm -f isl_codegen$(EXEEXT) $(AM_V_CCLD)$(isl_codegen_LINK) $(isl_codegen_OBJECTS) $(isl_codegen_LDADD) $(LIBS) + isl_pip$(EXEEXT): $(isl_pip_OBJECTS) $(isl_pip_DEPENDENCIES) $(EXTRA_isl_pip_DEPENDENCIES) @rm -f isl_pip$(EXEEXT) $(AM_V_CCLD)$(isl_pip_LINK) $(isl_pip_OBJECTS) $(isl_pip_LDADD) $(LIBS) + isl_polyhedron_detect_equalities$(EXEEXT): $(isl_polyhedron_detect_equalities_OBJECTS) $(isl_polyhedron_detect_equalities_DEPENDENCIES) $(EXTRA_isl_polyhedron_detect_equalities_DEPENDENCIES) @rm -f isl_polyhedron_detect_equalities$(EXEEXT) $(AM_V_CCLD)$(LINK) $(isl_polyhedron_detect_equalities_OBJECTS) $(isl_polyhedron_detect_equalities_LDADD) $(LIBS) + isl_polyhedron_minimize$(EXEEXT): $(isl_polyhedron_minimize_OBJECTS) $(isl_polyhedron_minimize_DEPENDENCIES) $(EXTRA_isl_polyhedron_minimize_DEPENDENCIES) @rm -f isl_polyhedron_minimize$(EXEEXT) $(AM_V_CCLD)$(isl_polyhedron_minimize_LINK) $(isl_polyhedron_minimize_OBJECTS) $(isl_polyhedron_minimize_LDADD) $(LIBS) + isl_polyhedron_sample$(EXEEXT): $(isl_polyhedron_sample_OBJECTS) $(isl_polyhedron_sample_DEPENDENCIES) $(EXTRA_isl_polyhedron_sample_DEPENDENCIES) @rm -f isl_polyhedron_sample$(EXEEXT) $(AM_V_CCLD)$(LINK) $(isl_polyhedron_sample_OBJECTS) $(isl_polyhedron_sample_LDADD) $(LIBS) + isl_polytope_scan$(EXEEXT): $(isl_polytope_scan_OBJECTS) $(isl_polytope_scan_DEPENDENCIES) $(EXTRA_isl_polytope_scan_DEPENDENCIES) @rm -f isl_polytope_scan$(EXEEXT) $(AM_V_CCLD)$(LINK) $(isl_polytope_scan_OBJECTS) $(isl_polytope_scan_LDADD) $(LIBS) + isl_test$(EXEEXT): $(isl_test_OBJECTS) $(isl_test_DEPENDENCIES) $(EXTRA_isl_test_DEPENDENCIES) @rm -f isl_test$(EXEEXT) $(AM_V_CCLD)$(isl_test_LINK) $(isl_test_OBJECTS) $(isl_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f imath_wrap/*.$(OBJEXT) + -rm -f imath_wrap/*.lo distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bound-bound.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_cat-cat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_closure-closure.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_codegen-codegen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_pip-pip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polytope_scan-polytope_scan.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test-isl_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-basis_reduction_tab.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_aff.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_affine_hull.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_arg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ast.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ast_build.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ast_build_expr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ast_codegen.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ast_graft.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_band.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_bernstein.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_blk.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_bound.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_coalesce.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_constraint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_convex_hull.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ctx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_deprecated.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_dim.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_dim_map.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_equalities.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_factorization.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_farkas.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_flow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_fold.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_gmp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_hash.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_hmap_map_basic_set.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_id.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_ilp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_input.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_local_space.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_lp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_lp_no_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_lp_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_map.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_map_no_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_map_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_map_simplify.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_map_subtract.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_mat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_morph.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_obj.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_options.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_output.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_point.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_polynomial.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_printer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_range.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_reordering.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_sample.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_sample_no_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_sample_piplib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_scan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_schedule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_seq.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_set_list.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_sort.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_space.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_stream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_tab.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_tab_pip.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_tarjan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_transitive_closure.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_union_map.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_val.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_val_gmp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_vec.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_version.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-isl_vertices.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-mp_get_memory_functions.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisl_la-print.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basis_reduction_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bound.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codegen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_aff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_affine_hull.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_arg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build_expr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_codegen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_graft.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_int.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_band.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bernstein.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_blk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bound.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_coalesce.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_constraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_convex_hull.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ctx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_deprecated.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_dim_map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_equalities.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_factorization.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_farkas.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_flow.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_fold.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_gmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_ast_expr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_id_to_pw_aff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ilp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_imath.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_input.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_local_space.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_lp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_list.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_simplify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_subtract.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_map_to_basic_set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_mat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_morph.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_obj.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_options.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_output.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_point.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_polynomial.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_printer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_range.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_reordering.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sample.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_band.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_node.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_read.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_schedule_tree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_scheduler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_seq.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_set_list.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sort.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_space.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab_pip.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tarjan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_transitive_closure.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_union_map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_gmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_val_imath.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_vertices.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp_get_memory_functions.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_detect_equalities.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_minimize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_sample.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope_scan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/gmp_compat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imath.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@imath_wrap/$(DEPDIR)/imrat.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libisl_la-isl_lp_no_piplib.lo: isl_lp_no_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_lp_no_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_lp_no_piplib.Tpo -c -o libisl_la-isl_lp_no_piplib.lo `test -f 'isl_lp_no_piplib.c' || echo '$(srcdir)/'`isl_lp_no_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_lp_no_piplib.Tpo $(DEPDIR)/libisl_la-isl_lp_no_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_lp_no_piplib.c' object='libisl_la-isl_lp_no_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_lp_no_piplib.lo `test -f 'isl_lp_no_piplib.c' || echo '$(srcdir)/'`isl_lp_no_piplib.c - -libisl_la-isl_map_no_piplib.lo: isl_map_no_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_map_no_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_map_no_piplib.Tpo -c -o libisl_la-isl_map_no_piplib.lo `test -f 'isl_map_no_piplib.c' || echo '$(srcdir)/'`isl_map_no_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_map_no_piplib.Tpo $(DEPDIR)/libisl_la-isl_map_no_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_map_no_piplib.c' object='libisl_la-isl_map_no_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_map_no_piplib.lo `test -f 'isl_map_no_piplib.c' || echo '$(srcdir)/'`isl_map_no_piplib.c - -libisl_la-isl_sample_no_piplib.lo: isl_sample_no_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_sample_no_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_sample_no_piplib.Tpo -c -o libisl_la-isl_sample_no_piplib.lo `test -f 'isl_sample_no_piplib.c' || echo '$(srcdir)/'`isl_sample_no_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_sample_no_piplib.Tpo $(DEPDIR)/libisl_la-isl_sample_no_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_sample_no_piplib.c' object='libisl_la-isl_sample_no_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_sample_no_piplib.lo `test -f 'isl_sample_no_piplib.c' || echo '$(srcdir)/'`isl_sample_no_piplib.c - -libisl_la-isl_lp_piplib.lo: isl_lp_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_lp_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_lp_piplib.Tpo -c -o libisl_la-isl_lp_piplib.lo `test -f 'isl_lp_piplib.c' || echo '$(srcdir)/'`isl_lp_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_lp_piplib.Tpo $(DEPDIR)/libisl_la-isl_lp_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_lp_piplib.c' object='libisl_la-isl_lp_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_lp_piplib.lo `test -f 'isl_lp_piplib.c' || echo '$(srcdir)/'`isl_lp_piplib.c - -libisl_la-isl_map_piplib.lo: isl_map_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_map_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_map_piplib.Tpo -c -o libisl_la-isl_map_piplib.lo `test -f 'isl_map_piplib.c' || echo '$(srcdir)/'`isl_map_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_map_piplib.Tpo $(DEPDIR)/libisl_la-isl_map_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_map_piplib.c' object='libisl_la-isl_map_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_map_piplib.lo `test -f 'isl_map_piplib.c' || echo '$(srcdir)/'`isl_map_piplib.c - -libisl_la-isl_sample_piplib.lo: isl_sample_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_sample_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_sample_piplib.Tpo -c -o libisl_la-isl_sample_piplib.lo `test -f 'isl_sample_piplib.c' || echo '$(srcdir)/'`isl_sample_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_sample_piplib.Tpo $(DEPDIR)/libisl_la-isl_sample_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_sample_piplib.c' object='libisl_la-isl_sample_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_sample_piplib.lo `test -f 'isl_sample_piplib.c' || echo '$(srcdir)/'`isl_sample_piplib.c - -libisl_la-isl_piplib.lo: isl_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_piplib.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_piplib.Tpo -c -o libisl_la-isl_piplib.lo `test -f 'isl_piplib.c' || echo '$(srcdir)/'`isl_piplib.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_piplib.Tpo $(DEPDIR)/libisl_la-isl_piplib.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_piplib.c' object='libisl_la-isl_piplib.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_piplib.lo `test -f 'isl_piplib.c' || echo '$(srcdir)/'`isl_piplib.c - -libisl_la-mp_get_memory_functions.lo: mp_get_memory_functions.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-mp_get_memory_functions.lo -MD -MP -MF $(DEPDIR)/libisl_la-mp_get_memory_functions.Tpo -c -o libisl_la-mp_get_memory_functions.lo `test -f 'mp_get_memory_functions.c' || echo '$(srcdir)/'`mp_get_memory_functions.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-mp_get_memory_functions.Tpo $(DEPDIR)/libisl_la-mp_get_memory_functions.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mp_get_memory_functions.c' object='libisl_la-mp_get_memory_functions.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-mp_get_memory_functions.lo `test -f 'mp_get_memory_functions.c' || echo '$(srcdir)/'`mp_get_memory_functions.c - -libisl_la-isl_aff.lo: isl_aff.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_aff.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_aff.Tpo -c -o libisl_la-isl_aff.lo `test -f 'isl_aff.c' || echo '$(srcdir)/'`isl_aff.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_aff.Tpo $(DEPDIR)/libisl_la-isl_aff.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_aff.c' object='libisl_la-isl_aff.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_aff.lo `test -f 'isl_aff.c' || echo '$(srcdir)/'`isl_aff.c - -libisl_la-isl_affine_hull.lo: isl_affine_hull.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_affine_hull.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_affine_hull.Tpo -c -o libisl_la-isl_affine_hull.lo `test -f 'isl_affine_hull.c' || echo '$(srcdir)/'`isl_affine_hull.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_affine_hull.Tpo $(DEPDIR)/libisl_la-isl_affine_hull.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_affine_hull.c' object='libisl_la-isl_affine_hull.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_affine_hull.lo `test -f 'isl_affine_hull.c' || echo '$(srcdir)/'`isl_affine_hull.c - -libisl_la-isl_arg.lo: isl_arg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_arg.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_arg.Tpo -c -o libisl_la-isl_arg.lo `test -f 'isl_arg.c' || echo '$(srcdir)/'`isl_arg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_arg.Tpo $(DEPDIR)/libisl_la-isl_arg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_arg.c' object='libisl_la-isl_arg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_arg.lo `test -f 'isl_arg.c' || echo '$(srcdir)/'`isl_arg.c - -libisl_la-isl_ast.lo: isl_ast.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ast.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ast.Tpo -c -o libisl_la-isl_ast.lo `test -f 'isl_ast.c' || echo '$(srcdir)/'`isl_ast.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ast.Tpo $(DEPDIR)/libisl_la-isl_ast.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ast.c' object='libisl_la-isl_ast.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ast.lo `test -f 'isl_ast.c' || echo '$(srcdir)/'`isl_ast.c - -libisl_la-isl_ast_build.lo: isl_ast_build.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ast_build.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ast_build.Tpo -c -o libisl_la-isl_ast_build.lo `test -f 'isl_ast_build.c' || echo '$(srcdir)/'`isl_ast_build.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ast_build.Tpo $(DEPDIR)/libisl_la-isl_ast_build.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ast_build.c' object='libisl_la-isl_ast_build.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ast_build.lo `test -f 'isl_ast_build.c' || echo '$(srcdir)/'`isl_ast_build.c - -libisl_la-isl_ast_build_expr.lo: isl_ast_build_expr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ast_build_expr.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ast_build_expr.Tpo -c -o libisl_la-isl_ast_build_expr.lo `test -f 'isl_ast_build_expr.c' || echo '$(srcdir)/'`isl_ast_build_expr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ast_build_expr.Tpo $(DEPDIR)/libisl_la-isl_ast_build_expr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ast_build_expr.c' object='libisl_la-isl_ast_build_expr.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ast_build_expr.lo `test -f 'isl_ast_build_expr.c' || echo '$(srcdir)/'`isl_ast_build_expr.c - -libisl_la-isl_ast_codegen.lo: isl_ast_codegen.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ast_codegen.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ast_codegen.Tpo -c -o libisl_la-isl_ast_codegen.lo `test -f 'isl_ast_codegen.c' || echo '$(srcdir)/'`isl_ast_codegen.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ast_codegen.Tpo $(DEPDIR)/libisl_la-isl_ast_codegen.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ast_codegen.c' object='libisl_la-isl_ast_codegen.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ast_codegen.lo `test -f 'isl_ast_codegen.c' || echo '$(srcdir)/'`isl_ast_codegen.c - -libisl_la-isl_ast_graft.lo: isl_ast_graft.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ast_graft.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ast_graft.Tpo -c -o libisl_la-isl_ast_graft.lo `test -f 'isl_ast_graft.c' || echo '$(srcdir)/'`isl_ast_graft.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ast_graft.Tpo $(DEPDIR)/libisl_la-isl_ast_graft.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ast_graft.c' object='libisl_la-isl_ast_graft.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ast_graft.lo `test -f 'isl_ast_graft.c' || echo '$(srcdir)/'`isl_ast_graft.c - -libisl_la-isl_band.lo: isl_band.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_band.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_band.Tpo -c -o libisl_la-isl_band.lo `test -f 'isl_band.c' || echo '$(srcdir)/'`isl_band.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_band.Tpo $(DEPDIR)/libisl_la-isl_band.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_band.c' object='libisl_la-isl_band.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_band.lo `test -f 'isl_band.c' || echo '$(srcdir)/'`isl_band.c - -libisl_la-basis_reduction_tab.lo: basis_reduction_tab.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-basis_reduction_tab.lo -MD -MP -MF $(DEPDIR)/libisl_la-basis_reduction_tab.Tpo -c -o libisl_la-basis_reduction_tab.lo `test -f 'basis_reduction_tab.c' || echo '$(srcdir)/'`basis_reduction_tab.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-basis_reduction_tab.Tpo $(DEPDIR)/libisl_la-basis_reduction_tab.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='basis_reduction_tab.c' object='libisl_la-basis_reduction_tab.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-basis_reduction_tab.lo `test -f 'basis_reduction_tab.c' || echo '$(srcdir)/'`basis_reduction_tab.c - -libisl_la-isl_bernstein.lo: isl_bernstein.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_bernstein.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_bernstein.Tpo -c -o libisl_la-isl_bernstein.lo `test -f 'isl_bernstein.c' || echo '$(srcdir)/'`isl_bernstein.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_bernstein.Tpo $(DEPDIR)/libisl_la-isl_bernstein.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_bernstein.c' object='libisl_la-isl_bernstein.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_bernstein.lo `test -f 'isl_bernstein.c' || echo '$(srcdir)/'`isl_bernstein.c - -libisl_la-isl_blk.lo: isl_blk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_blk.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_blk.Tpo -c -o libisl_la-isl_blk.lo `test -f 'isl_blk.c' || echo '$(srcdir)/'`isl_blk.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_blk.Tpo $(DEPDIR)/libisl_la-isl_blk.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_blk.c' object='libisl_la-isl_blk.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_blk.lo `test -f 'isl_blk.c' || echo '$(srcdir)/'`isl_blk.c - -libisl_la-isl_bound.lo: isl_bound.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_bound.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_bound.Tpo -c -o libisl_la-isl_bound.lo `test -f 'isl_bound.c' || echo '$(srcdir)/'`isl_bound.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_bound.Tpo $(DEPDIR)/libisl_la-isl_bound.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_bound.c' object='libisl_la-isl_bound.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_bound.lo `test -f 'isl_bound.c' || echo '$(srcdir)/'`isl_bound.c - -libisl_la-isl_coalesce.lo: isl_coalesce.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_coalesce.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_coalesce.Tpo -c -o libisl_la-isl_coalesce.lo `test -f 'isl_coalesce.c' || echo '$(srcdir)/'`isl_coalesce.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_coalesce.Tpo $(DEPDIR)/libisl_la-isl_coalesce.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_coalesce.c' object='libisl_la-isl_coalesce.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_coalesce.lo `test -f 'isl_coalesce.c' || echo '$(srcdir)/'`isl_coalesce.c - -libisl_la-isl_constraint.lo: isl_constraint.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_constraint.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_constraint.Tpo -c -o libisl_la-isl_constraint.lo `test -f 'isl_constraint.c' || echo '$(srcdir)/'`isl_constraint.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_constraint.Tpo $(DEPDIR)/libisl_la-isl_constraint.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_constraint.c' object='libisl_la-isl_constraint.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_constraint.lo `test -f 'isl_constraint.c' || echo '$(srcdir)/'`isl_constraint.c - -libisl_la-isl_convex_hull.lo: isl_convex_hull.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_convex_hull.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_convex_hull.Tpo -c -o libisl_la-isl_convex_hull.lo `test -f 'isl_convex_hull.c' || echo '$(srcdir)/'`isl_convex_hull.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_convex_hull.Tpo $(DEPDIR)/libisl_la-isl_convex_hull.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_convex_hull.c' object='libisl_la-isl_convex_hull.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_convex_hull.lo `test -f 'isl_convex_hull.c' || echo '$(srcdir)/'`isl_convex_hull.c - -libisl_la-isl_ctx.lo: isl_ctx.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ctx.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ctx.Tpo -c -o libisl_la-isl_ctx.lo `test -f 'isl_ctx.c' || echo '$(srcdir)/'`isl_ctx.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ctx.Tpo $(DEPDIR)/libisl_la-isl_ctx.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ctx.c' object='libisl_la-isl_ctx.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ctx.lo `test -f 'isl_ctx.c' || echo '$(srcdir)/'`isl_ctx.c - -libisl_la-isl_deprecated.lo: isl_deprecated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_deprecated.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_deprecated.Tpo -c -o libisl_la-isl_deprecated.lo `test -f 'isl_deprecated.c' || echo '$(srcdir)/'`isl_deprecated.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_deprecated.Tpo $(DEPDIR)/libisl_la-isl_deprecated.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_deprecated.c' object='libisl_la-isl_deprecated.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_deprecated.lo `test -f 'isl_deprecated.c' || echo '$(srcdir)/'`isl_deprecated.c - -libisl_la-isl_dim.lo: isl_dim.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_dim.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_dim.Tpo -c -o libisl_la-isl_dim.lo `test -f 'isl_dim.c' || echo '$(srcdir)/'`isl_dim.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_dim.Tpo $(DEPDIR)/libisl_la-isl_dim.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_dim.c' object='libisl_la-isl_dim.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_dim.lo `test -f 'isl_dim.c' || echo '$(srcdir)/'`isl_dim.c - -libisl_la-isl_dim_map.lo: isl_dim_map.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_dim_map.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_dim_map.Tpo -c -o libisl_la-isl_dim_map.lo `test -f 'isl_dim_map.c' || echo '$(srcdir)/'`isl_dim_map.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_dim_map.Tpo $(DEPDIR)/libisl_la-isl_dim_map.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_dim_map.c' object='libisl_la-isl_dim_map.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_dim_map.lo `test -f 'isl_dim_map.c' || echo '$(srcdir)/'`isl_dim_map.c - -libisl_la-isl_equalities.lo: isl_equalities.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_equalities.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_equalities.Tpo -c -o libisl_la-isl_equalities.lo `test -f 'isl_equalities.c' || echo '$(srcdir)/'`isl_equalities.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_equalities.Tpo $(DEPDIR)/libisl_la-isl_equalities.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_equalities.c' object='libisl_la-isl_equalities.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_equalities.lo `test -f 'isl_equalities.c' || echo '$(srcdir)/'`isl_equalities.c - -libisl_la-isl_factorization.lo: isl_factorization.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_factorization.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_factorization.Tpo -c -o libisl_la-isl_factorization.lo `test -f 'isl_factorization.c' || echo '$(srcdir)/'`isl_factorization.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_factorization.Tpo $(DEPDIR)/libisl_la-isl_factorization.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_factorization.c' object='libisl_la-isl_factorization.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_factorization.lo `test -f 'isl_factorization.c' || echo '$(srcdir)/'`isl_factorization.c - -libisl_la-isl_farkas.lo: isl_farkas.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_farkas.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_farkas.Tpo -c -o libisl_la-isl_farkas.lo `test -f 'isl_farkas.c' || echo '$(srcdir)/'`isl_farkas.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_farkas.Tpo $(DEPDIR)/libisl_la-isl_farkas.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_farkas.c' object='libisl_la-isl_farkas.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_farkas.lo `test -f 'isl_farkas.c' || echo '$(srcdir)/'`isl_farkas.c - -libisl_la-isl_flow.lo: isl_flow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_flow.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_flow.Tpo -c -o libisl_la-isl_flow.lo `test -f 'isl_flow.c' || echo '$(srcdir)/'`isl_flow.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_flow.Tpo $(DEPDIR)/libisl_la-isl_flow.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_flow.c' object='libisl_la-isl_flow.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_flow.lo `test -f 'isl_flow.c' || echo '$(srcdir)/'`isl_flow.c - -libisl_la-isl_fold.lo: isl_fold.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_fold.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_fold.Tpo -c -o libisl_la-isl_fold.lo `test -f 'isl_fold.c' || echo '$(srcdir)/'`isl_fold.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_fold.Tpo $(DEPDIR)/libisl_la-isl_fold.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_fold.c' object='libisl_la-isl_fold.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_fold.lo `test -f 'isl_fold.c' || echo '$(srcdir)/'`isl_fold.c - -libisl_la-isl_gmp.lo: isl_gmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_gmp.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_gmp.Tpo -c -o libisl_la-isl_gmp.lo `test -f 'isl_gmp.c' || echo '$(srcdir)/'`isl_gmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_gmp.Tpo $(DEPDIR)/libisl_la-isl_gmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_gmp.c' object='libisl_la-isl_gmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_gmp.lo `test -f 'isl_gmp.c' || echo '$(srcdir)/'`isl_gmp.c - -libisl_la-isl_hash.lo: isl_hash.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_hash.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_hash.Tpo -c -o libisl_la-isl_hash.lo `test -f 'isl_hash.c' || echo '$(srcdir)/'`isl_hash.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_hash.Tpo $(DEPDIR)/libisl_la-isl_hash.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_hash.c' object='libisl_la-isl_hash.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_hash.lo `test -f 'isl_hash.c' || echo '$(srcdir)/'`isl_hash.c - -libisl_la-isl_hmap_map_basic_set.lo: isl_hmap_map_basic_set.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_hmap_map_basic_set.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_hmap_map_basic_set.Tpo -c -o libisl_la-isl_hmap_map_basic_set.lo `test -f 'isl_hmap_map_basic_set.c' || echo '$(srcdir)/'`isl_hmap_map_basic_set.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_hmap_map_basic_set.Tpo $(DEPDIR)/libisl_la-isl_hmap_map_basic_set.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_hmap_map_basic_set.c' object='libisl_la-isl_hmap_map_basic_set.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_hmap_map_basic_set.lo `test -f 'isl_hmap_map_basic_set.c' || echo '$(srcdir)/'`isl_hmap_map_basic_set.c - -libisl_la-isl_ilp.lo: isl_ilp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_ilp.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_ilp.Tpo -c -o libisl_la-isl_ilp.lo `test -f 'isl_ilp.c' || echo '$(srcdir)/'`isl_ilp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_ilp.Tpo $(DEPDIR)/libisl_la-isl_ilp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_ilp.c' object='libisl_la-isl_ilp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_ilp.lo `test -f 'isl_ilp.c' || echo '$(srcdir)/'`isl_ilp.c - -libisl_la-isl_input.lo: isl_input.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_input.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_input.Tpo -c -o libisl_la-isl_input.lo `test -f 'isl_input.c' || echo '$(srcdir)/'`isl_input.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_input.Tpo $(DEPDIR)/libisl_la-isl_input.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_input.c' object='libisl_la-isl_input.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_input.lo `test -f 'isl_input.c' || echo '$(srcdir)/'`isl_input.c - -libisl_la-isl_local_space.lo: isl_local_space.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_local_space.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_local_space.Tpo -c -o libisl_la-isl_local_space.lo `test -f 'isl_local_space.c' || echo '$(srcdir)/'`isl_local_space.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_local_space.Tpo $(DEPDIR)/libisl_la-isl_local_space.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_local_space.c' object='libisl_la-isl_local_space.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_local_space.lo `test -f 'isl_local_space.c' || echo '$(srcdir)/'`isl_local_space.c - -libisl_la-isl_lp.lo: isl_lp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_lp.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_lp.Tpo -c -o libisl_la-isl_lp.lo `test -f 'isl_lp.c' || echo '$(srcdir)/'`isl_lp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_lp.Tpo $(DEPDIR)/libisl_la-isl_lp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_lp.c' object='libisl_la-isl_lp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_lp.lo `test -f 'isl_lp.c' || echo '$(srcdir)/'`isl_lp.c - -libisl_la-isl_map.lo: isl_map.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_map.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_map.Tpo -c -o libisl_la-isl_map.lo `test -f 'isl_map.c' || echo '$(srcdir)/'`isl_map.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_map.Tpo $(DEPDIR)/libisl_la-isl_map.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_map.c' object='libisl_la-isl_map.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_map.lo `test -f 'isl_map.c' || echo '$(srcdir)/'`isl_map.c - -libisl_la-isl_map_simplify.lo: isl_map_simplify.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_map_simplify.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_map_simplify.Tpo -c -o libisl_la-isl_map_simplify.lo `test -f 'isl_map_simplify.c' || echo '$(srcdir)/'`isl_map_simplify.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_map_simplify.Tpo $(DEPDIR)/libisl_la-isl_map_simplify.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_map_simplify.c' object='libisl_la-isl_map_simplify.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_map_simplify.lo `test -f 'isl_map_simplify.c' || echo '$(srcdir)/'`isl_map_simplify.c - -libisl_la-isl_map_subtract.lo: isl_map_subtract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_map_subtract.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_map_subtract.Tpo -c -o libisl_la-isl_map_subtract.lo `test -f 'isl_map_subtract.c' || echo '$(srcdir)/'`isl_map_subtract.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_map_subtract.Tpo $(DEPDIR)/libisl_la-isl_map_subtract.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_map_subtract.c' object='libisl_la-isl_map_subtract.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_map_subtract.lo `test -f 'isl_map_subtract.c' || echo '$(srcdir)/'`isl_map_subtract.c - -libisl_la-isl_mat.lo: isl_mat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_mat.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_mat.Tpo -c -o libisl_la-isl_mat.lo `test -f 'isl_mat.c' || echo '$(srcdir)/'`isl_mat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_mat.Tpo $(DEPDIR)/libisl_la-isl_mat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_mat.c' object='libisl_la-isl_mat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_mat.lo `test -f 'isl_mat.c' || echo '$(srcdir)/'`isl_mat.c - -libisl_la-isl_morph.lo: isl_morph.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_morph.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_morph.Tpo -c -o libisl_la-isl_morph.lo `test -f 'isl_morph.c' || echo '$(srcdir)/'`isl_morph.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_morph.Tpo $(DEPDIR)/libisl_la-isl_morph.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_morph.c' object='libisl_la-isl_morph.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_morph.lo `test -f 'isl_morph.c' || echo '$(srcdir)/'`isl_morph.c - -libisl_la-isl_id.lo: isl_id.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_id.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_id.Tpo -c -o libisl_la-isl_id.lo `test -f 'isl_id.c' || echo '$(srcdir)/'`isl_id.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_id.Tpo $(DEPDIR)/libisl_la-isl_id.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_id.c' object='libisl_la-isl_id.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_id.lo `test -f 'isl_id.c' || echo '$(srcdir)/'`isl_id.c - -libisl_la-isl_obj.lo: isl_obj.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_obj.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_obj.Tpo -c -o libisl_la-isl_obj.lo `test -f 'isl_obj.c' || echo '$(srcdir)/'`isl_obj.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_obj.Tpo $(DEPDIR)/libisl_la-isl_obj.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_obj.c' object='libisl_la-isl_obj.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_obj.lo `test -f 'isl_obj.c' || echo '$(srcdir)/'`isl_obj.c - -libisl_la-isl_options.lo: isl_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_options.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_options.Tpo -c -o libisl_la-isl_options.lo `test -f 'isl_options.c' || echo '$(srcdir)/'`isl_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_options.Tpo $(DEPDIR)/libisl_la-isl_options.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_options.c' object='libisl_la-isl_options.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_options.lo `test -f 'isl_options.c' || echo '$(srcdir)/'`isl_options.c - -libisl_la-isl_output.lo: isl_output.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_output.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_output.Tpo -c -o libisl_la-isl_output.lo `test -f 'isl_output.c' || echo '$(srcdir)/'`isl_output.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_output.Tpo $(DEPDIR)/libisl_la-isl_output.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_output.c' object='libisl_la-isl_output.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_output.lo `test -f 'isl_output.c' || echo '$(srcdir)/'`isl_output.c - -libisl_la-isl_point.lo: isl_point.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_point.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_point.Tpo -c -o libisl_la-isl_point.lo `test -f 'isl_point.c' || echo '$(srcdir)/'`isl_point.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_point.Tpo $(DEPDIR)/libisl_la-isl_point.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_point.c' object='libisl_la-isl_point.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_point.lo `test -f 'isl_point.c' || echo '$(srcdir)/'`isl_point.c - -libisl_la-isl_polynomial.lo: isl_polynomial.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_polynomial.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_polynomial.Tpo -c -o libisl_la-isl_polynomial.lo `test -f 'isl_polynomial.c' || echo '$(srcdir)/'`isl_polynomial.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_polynomial.Tpo $(DEPDIR)/libisl_la-isl_polynomial.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_polynomial.c' object='libisl_la-isl_polynomial.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_polynomial.lo `test -f 'isl_polynomial.c' || echo '$(srcdir)/'`isl_polynomial.c - -libisl_la-isl_printer.lo: isl_printer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_printer.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_printer.Tpo -c -o libisl_la-isl_printer.lo `test -f 'isl_printer.c' || echo '$(srcdir)/'`isl_printer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_printer.Tpo $(DEPDIR)/libisl_la-isl_printer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_printer.c' object='libisl_la-isl_printer.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_printer.lo `test -f 'isl_printer.c' || echo '$(srcdir)/'`isl_printer.c - -libisl_la-print.lo: print.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-print.lo -MD -MP -MF $(DEPDIR)/libisl_la-print.Tpo -c -o libisl_la-print.lo `test -f 'print.c' || echo '$(srcdir)/'`print.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-print.Tpo $(DEPDIR)/libisl_la-print.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print.c' object='libisl_la-print.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-print.lo `test -f 'print.c' || echo '$(srcdir)/'`print.c - -libisl_la-isl_range.lo: isl_range.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_range.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_range.Tpo -c -o libisl_la-isl_range.lo `test -f 'isl_range.c' || echo '$(srcdir)/'`isl_range.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_range.Tpo $(DEPDIR)/libisl_la-isl_range.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_range.c' object='libisl_la-isl_range.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_range.lo `test -f 'isl_range.c' || echo '$(srcdir)/'`isl_range.c - -libisl_la-isl_reordering.lo: isl_reordering.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_reordering.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_reordering.Tpo -c -o libisl_la-isl_reordering.lo `test -f 'isl_reordering.c' || echo '$(srcdir)/'`isl_reordering.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_reordering.Tpo $(DEPDIR)/libisl_la-isl_reordering.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_reordering.c' object='libisl_la-isl_reordering.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_reordering.lo `test -f 'isl_reordering.c' || echo '$(srcdir)/'`isl_reordering.c - -libisl_la-isl_sample.lo: isl_sample.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_sample.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_sample.Tpo -c -o libisl_la-isl_sample.lo `test -f 'isl_sample.c' || echo '$(srcdir)/'`isl_sample.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_sample.Tpo $(DEPDIR)/libisl_la-isl_sample.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_sample.c' object='libisl_la-isl_sample.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_sample.lo `test -f 'isl_sample.c' || echo '$(srcdir)/'`isl_sample.c - -libisl_la-isl_scan.lo: isl_scan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_scan.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_scan.Tpo -c -o libisl_la-isl_scan.lo `test -f 'isl_scan.c' || echo '$(srcdir)/'`isl_scan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_scan.Tpo $(DEPDIR)/libisl_la-isl_scan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_scan.c' object='libisl_la-isl_scan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_scan.lo `test -f 'isl_scan.c' || echo '$(srcdir)/'`isl_scan.c - -libisl_la-isl_schedule.lo: isl_schedule.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_schedule.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_schedule.Tpo -c -o libisl_la-isl_schedule.lo `test -f 'isl_schedule.c' || echo '$(srcdir)/'`isl_schedule.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_schedule.Tpo $(DEPDIR)/libisl_la-isl_schedule.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_schedule.c' object='libisl_la-isl_schedule.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_schedule.lo `test -f 'isl_schedule.c' || echo '$(srcdir)/'`isl_schedule.c - -libisl_la-isl_set_list.lo: isl_set_list.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_set_list.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_set_list.Tpo -c -o libisl_la-isl_set_list.lo `test -f 'isl_set_list.c' || echo '$(srcdir)/'`isl_set_list.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_set_list.Tpo $(DEPDIR)/libisl_la-isl_set_list.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_set_list.c' object='libisl_la-isl_set_list.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_set_list.lo `test -f 'isl_set_list.c' || echo '$(srcdir)/'`isl_set_list.c - -libisl_la-isl_sort.lo: isl_sort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_sort.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_sort.Tpo -c -o libisl_la-isl_sort.lo `test -f 'isl_sort.c' || echo '$(srcdir)/'`isl_sort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_sort.Tpo $(DEPDIR)/libisl_la-isl_sort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_sort.c' object='libisl_la-isl_sort.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_sort.lo `test -f 'isl_sort.c' || echo '$(srcdir)/'`isl_sort.c - -libisl_la-isl_space.lo: isl_space.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_space.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_space.Tpo -c -o libisl_la-isl_space.lo `test -f 'isl_space.c' || echo '$(srcdir)/'`isl_space.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_space.Tpo $(DEPDIR)/libisl_la-isl_space.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_space.c' object='libisl_la-isl_space.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_space.lo `test -f 'isl_space.c' || echo '$(srcdir)/'`isl_space.c - -libisl_la-isl_stream.lo: isl_stream.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_stream.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_stream.Tpo -c -o libisl_la-isl_stream.lo `test -f 'isl_stream.c' || echo '$(srcdir)/'`isl_stream.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_stream.Tpo $(DEPDIR)/libisl_la-isl_stream.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_stream.c' object='libisl_la-isl_stream.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_stream.lo `test -f 'isl_stream.c' || echo '$(srcdir)/'`isl_stream.c - -libisl_la-isl_seq.lo: isl_seq.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_seq.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_seq.Tpo -c -o libisl_la-isl_seq.lo `test -f 'isl_seq.c' || echo '$(srcdir)/'`isl_seq.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_seq.Tpo $(DEPDIR)/libisl_la-isl_seq.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_seq.c' object='libisl_la-isl_seq.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_seq.lo `test -f 'isl_seq.c' || echo '$(srcdir)/'`isl_seq.c - -libisl_la-isl_tab.lo: isl_tab.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_tab.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_tab.Tpo -c -o libisl_la-isl_tab.lo `test -f 'isl_tab.c' || echo '$(srcdir)/'`isl_tab.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_tab.Tpo $(DEPDIR)/libisl_la-isl_tab.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_tab.c' object='libisl_la-isl_tab.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_tab.lo `test -f 'isl_tab.c' || echo '$(srcdir)/'`isl_tab.c - -libisl_la-isl_tab_pip.lo: isl_tab_pip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_tab_pip.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_tab_pip.Tpo -c -o libisl_la-isl_tab_pip.lo `test -f 'isl_tab_pip.c' || echo '$(srcdir)/'`isl_tab_pip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_tab_pip.Tpo $(DEPDIR)/libisl_la-isl_tab_pip.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_tab_pip.c' object='libisl_la-isl_tab_pip.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_tab_pip.lo `test -f 'isl_tab_pip.c' || echo '$(srcdir)/'`isl_tab_pip.c - -libisl_la-isl_tarjan.lo: isl_tarjan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_tarjan.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_tarjan.Tpo -c -o libisl_la-isl_tarjan.lo `test -f 'isl_tarjan.c' || echo '$(srcdir)/'`isl_tarjan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_tarjan.Tpo $(DEPDIR)/libisl_la-isl_tarjan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_tarjan.c' object='libisl_la-isl_tarjan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_tarjan.lo `test -f 'isl_tarjan.c' || echo '$(srcdir)/'`isl_tarjan.c - -libisl_la-isl_transitive_closure.lo: isl_transitive_closure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_transitive_closure.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_transitive_closure.Tpo -c -o libisl_la-isl_transitive_closure.lo `test -f 'isl_transitive_closure.c' || echo '$(srcdir)/'`isl_transitive_closure.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_transitive_closure.Tpo $(DEPDIR)/libisl_la-isl_transitive_closure.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_transitive_closure.c' object='libisl_la-isl_transitive_closure.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_transitive_closure.lo `test -f 'isl_transitive_closure.c' || echo '$(srcdir)/'`isl_transitive_closure.c - -libisl_la-isl_union_map.lo: isl_union_map.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_union_map.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_union_map.Tpo -c -o libisl_la-isl_union_map.lo `test -f 'isl_union_map.c' || echo '$(srcdir)/'`isl_union_map.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_union_map.Tpo $(DEPDIR)/libisl_la-isl_union_map.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_union_map.c' object='libisl_la-isl_union_map.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_union_map.lo `test -f 'isl_union_map.c' || echo '$(srcdir)/'`isl_union_map.c - -libisl_la-isl_val.lo: isl_val.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_val.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_val.Tpo -c -o libisl_la-isl_val.lo `test -f 'isl_val.c' || echo '$(srcdir)/'`isl_val.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_val.Tpo $(DEPDIR)/libisl_la-isl_val.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_val.c' object='libisl_la-isl_val.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_val.lo `test -f 'isl_val.c' || echo '$(srcdir)/'`isl_val.c - -libisl_la-isl_val_gmp.lo: isl_val_gmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_val_gmp.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_val_gmp.Tpo -c -o libisl_la-isl_val_gmp.lo `test -f 'isl_val_gmp.c' || echo '$(srcdir)/'`isl_val_gmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_val_gmp.Tpo $(DEPDIR)/libisl_la-isl_val_gmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_val_gmp.c' object='libisl_la-isl_val_gmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_val_gmp.lo `test -f 'isl_val_gmp.c' || echo '$(srcdir)/'`isl_val_gmp.c - -libisl_la-isl_vec.lo: isl_vec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_vec.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_vec.Tpo -c -o libisl_la-isl_vec.lo `test -f 'isl_vec.c' || echo '$(srcdir)/'`isl_vec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_vec.Tpo $(DEPDIR)/libisl_la-isl_vec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_vec.c' object='libisl_la-isl_vec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_vec.lo `test -f 'isl_vec.c' || echo '$(srcdir)/'`isl_vec.c - -libisl_la-isl_version.lo: isl_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_version.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_version.Tpo -c -o libisl_la-isl_version.lo `test -f 'isl_version.c' || echo '$(srcdir)/'`isl_version.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_version.Tpo $(DEPDIR)/libisl_la-isl_version.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_version.c' object='libisl_la-isl_version.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_version.lo `test -f 'isl_version.c' || echo '$(srcdir)/'`isl_version.c - -libisl_la-isl_vertices.lo: isl_vertices.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisl_la-isl_vertices.lo -MD -MP -MF $(DEPDIR)/libisl_la-isl_vertices.Tpo -c -o libisl_la-isl_vertices.lo `test -f 'isl_vertices.c' || echo '$(srcdir)/'`isl_vertices.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisl_la-isl_vertices.Tpo $(DEPDIR)/libisl_la-isl_vertices.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_vertices.c' object='libisl_la-isl_vertices.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisl_la-isl_vertices.lo `test -f 'isl_vertices.c' || echo '$(srcdir)/'`isl_vertices.c - -isl_bound-bound.o: bound.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_bound_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_bound-bound.o -MD -MP -MF $(DEPDIR)/isl_bound-bound.Tpo -c -o isl_bound-bound.o `test -f 'bound.c' || echo '$(srcdir)/'`bound.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_bound-bound.Tpo $(DEPDIR)/isl_bound-bound.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bound.c' object='isl_bound-bound.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_bound_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_bound-bound.o `test -f 'bound.c' || echo '$(srcdir)/'`bound.c - -isl_bound-bound.obj: bound.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_bound_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_bound-bound.obj -MD -MP -MF $(DEPDIR)/isl_bound-bound.Tpo -c -o isl_bound-bound.obj `if test -f 'bound.c'; then $(CYGPATH_W) 'bound.c'; else $(CYGPATH_W) '$(srcdir)/bound.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_bound-bound.Tpo $(DEPDIR)/isl_bound-bound.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bound.c' object='isl_bound-bound.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_bound_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_bound-bound.obj `if test -f 'bound.c'; then $(CYGPATH_W) 'bound.c'; else $(CYGPATH_W) '$(srcdir)/bound.c'; fi` - -isl_cat-cat.o: cat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_cat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_cat-cat.o -MD -MP -MF $(DEPDIR)/isl_cat-cat.Tpo -c -o isl_cat-cat.o `test -f 'cat.c' || echo '$(srcdir)/'`cat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_cat-cat.Tpo $(DEPDIR)/isl_cat-cat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat.c' object='isl_cat-cat.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_cat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_cat-cat.o `test -f 'cat.c' || echo '$(srcdir)/'`cat.c - -isl_cat-cat.obj: cat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_cat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_cat-cat.obj -MD -MP -MF $(DEPDIR)/isl_cat-cat.Tpo -c -o isl_cat-cat.obj `if test -f 'cat.c'; then $(CYGPATH_W) 'cat.c'; else $(CYGPATH_W) '$(srcdir)/cat.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_cat-cat.Tpo $(DEPDIR)/isl_cat-cat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat.c' object='isl_cat-cat.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_cat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_cat-cat.obj `if test -f 'cat.c'; then $(CYGPATH_W) 'cat.c'; else $(CYGPATH_W) '$(srcdir)/cat.c'; fi` - -isl_closure-closure.o: closure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_closure_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_closure-closure.o -MD -MP -MF $(DEPDIR)/isl_closure-closure.Tpo -c -o isl_closure-closure.o `test -f 'closure.c' || echo '$(srcdir)/'`closure.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_closure-closure.Tpo $(DEPDIR)/isl_closure-closure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='closure.c' object='isl_closure-closure.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_closure_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_closure-closure.o `test -f 'closure.c' || echo '$(srcdir)/'`closure.c - -isl_closure-closure.obj: closure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_closure_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_closure-closure.obj -MD -MP -MF $(DEPDIR)/isl_closure-closure.Tpo -c -o isl_closure-closure.obj `if test -f 'closure.c'; then $(CYGPATH_W) 'closure.c'; else $(CYGPATH_W) '$(srcdir)/closure.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_closure-closure.Tpo $(DEPDIR)/isl_closure-closure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='closure.c' object='isl_closure-closure.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_closure_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_closure-closure.obj `if test -f 'closure.c'; then $(CYGPATH_W) 'closure.c'; else $(CYGPATH_W) '$(srcdir)/closure.c'; fi` - -isl_codegen-codegen.o: codegen.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_codegen_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_codegen-codegen.o -MD -MP -MF $(DEPDIR)/isl_codegen-codegen.Tpo -c -o isl_codegen-codegen.o `test -f 'codegen.c' || echo '$(srcdir)/'`codegen.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_codegen-codegen.Tpo $(DEPDIR)/isl_codegen-codegen.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen.c' object='isl_codegen-codegen.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_codegen_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_codegen-codegen.o `test -f 'codegen.c' || echo '$(srcdir)/'`codegen.c - -isl_codegen-codegen.obj: codegen.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_codegen_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_codegen-codegen.obj -MD -MP -MF $(DEPDIR)/isl_codegen-codegen.Tpo -c -o isl_codegen-codegen.obj `if test -f 'codegen.c'; then $(CYGPATH_W) 'codegen.c'; else $(CYGPATH_W) '$(srcdir)/codegen.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_codegen-codegen.Tpo $(DEPDIR)/isl_codegen-codegen.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen.c' object='isl_codegen-codegen.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_codegen_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_codegen-codegen.obj `if test -f 'codegen.c'; then $(CYGPATH_W) 'codegen.c'; else $(CYGPATH_W) '$(srcdir)/codegen.c'; fi` - -isl_pip-pip.o: pip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_pip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_pip-pip.o -MD -MP -MF $(DEPDIR)/isl_pip-pip.Tpo -c -o isl_pip-pip.o `test -f 'pip.c' || echo '$(srcdir)/'`pip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_pip-pip.Tpo $(DEPDIR)/isl_pip-pip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pip.c' object='isl_pip-pip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_pip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_pip-pip.o `test -f 'pip.c' || echo '$(srcdir)/'`pip.c - -isl_pip-pip.obj: pip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_pip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_pip-pip.obj -MD -MP -MF $(DEPDIR)/isl_pip-pip.Tpo -c -o isl_pip-pip.obj `if test -f 'pip.c'; then $(CYGPATH_W) 'pip.c'; else $(CYGPATH_W) '$(srcdir)/pip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_pip-pip.Tpo $(DEPDIR)/isl_pip-pip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pip.c' object='isl_pip-pip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_pip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_pip-pip.obj `if test -f 'pip.c'; then $(CYGPATH_W) 'pip.c'; else $(CYGPATH_W) '$(srcdir)/pip.c'; fi` - -isl_polyhedron_detect_equalities-polyhedron_detect_equalities.o: polyhedron_detect_equalities.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_detect_equalities_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polyhedron_detect_equalities-polyhedron_detect_equalities.o -MD -MP -MF $(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Tpo -c -o isl_polyhedron_detect_equalities-polyhedron_detect_equalities.o `test -f 'polyhedron_detect_equalities.c' || echo '$(srcdir)/'`polyhedron_detect_equalities.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Tpo $(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polyhedron_detect_equalities.c' object='isl_polyhedron_detect_equalities-polyhedron_detect_equalities.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_detect_equalities_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polyhedron_detect_equalities-polyhedron_detect_equalities.o `test -f 'polyhedron_detect_equalities.c' || echo '$(srcdir)/'`polyhedron_detect_equalities.c - -isl_polyhedron_detect_equalities-polyhedron_detect_equalities.obj: polyhedron_detect_equalities.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_detect_equalities_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polyhedron_detect_equalities-polyhedron_detect_equalities.obj -MD -MP -MF $(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Tpo -c -o isl_polyhedron_detect_equalities-polyhedron_detect_equalities.obj `if test -f 'polyhedron_detect_equalities.c'; then $(CYGPATH_W) 'polyhedron_detect_equalities.c'; else $(CYGPATH_W) '$(srcdir)/polyhedron_detect_equalities.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Tpo $(DEPDIR)/isl_polyhedron_detect_equalities-polyhedron_detect_equalities.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polyhedron_detect_equalities.c' object='isl_polyhedron_detect_equalities-polyhedron_detect_equalities.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_detect_equalities_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polyhedron_detect_equalities-polyhedron_detect_equalities.obj `if test -f 'polyhedron_detect_equalities.c'; then $(CYGPATH_W) 'polyhedron_detect_equalities.c'; else $(CYGPATH_W) '$(srcdir)/polyhedron_detect_equalities.c'; fi` - -isl_polyhedron_minimize-polyhedron_minimize.o: polyhedron_minimize.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_minimize_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polyhedron_minimize-polyhedron_minimize.o -MD -MP -MF $(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Tpo -c -o isl_polyhedron_minimize-polyhedron_minimize.o `test -f 'polyhedron_minimize.c' || echo '$(srcdir)/'`polyhedron_minimize.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Tpo $(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polyhedron_minimize.c' object='isl_polyhedron_minimize-polyhedron_minimize.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_minimize_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polyhedron_minimize-polyhedron_minimize.o `test -f 'polyhedron_minimize.c' || echo '$(srcdir)/'`polyhedron_minimize.c - -isl_polyhedron_minimize-polyhedron_minimize.obj: polyhedron_minimize.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_minimize_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polyhedron_minimize-polyhedron_minimize.obj -MD -MP -MF $(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Tpo -c -o isl_polyhedron_minimize-polyhedron_minimize.obj `if test -f 'polyhedron_minimize.c'; then $(CYGPATH_W) 'polyhedron_minimize.c'; else $(CYGPATH_W) '$(srcdir)/polyhedron_minimize.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Tpo $(DEPDIR)/isl_polyhedron_minimize-polyhedron_minimize.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polyhedron_minimize.c' object='isl_polyhedron_minimize-polyhedron_minimize.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_minimize_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polyhedron_minimize-polyhedron_minimize.obj `if test -f 'polyhedron_minimize.c'; then $(CYGPATH_W) 'polyhedron_minimize.c'; else $(CYGPATH_W) '$(srcdir)/polyhedron_minimize.c'; fi` - -isl_polyhedron_sample-polyhedron_sample.o: polyhedron_sample.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_sample_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polyhedron_sample-polyhedron_sample.o -MD -MP -MF $(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Tpo -c -o isl_polyhedron_sample-polyhedron_sample.o `test -f 'polyhedron_sample.c' || echo '$(srcdir)/'`polyhedron_sample.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Tpo $(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polyhedron_sample.c' object='isl_polyhedron_sample-polyhedron_sample.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_sample_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polyhedron_sample-polyhedron_sample.o `test -f 'polyhedron_sample.c' || echo '$(srcdir)/'`polyhedron_sample.c - -isl_polyhedron_sample-polyhedron_sample.obj: polyhedron_sample.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_sample_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polyhedron_sample-polyhedron_sample.obj -MD -MP -MF $(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Tpo -c -o isl_polyhedron_sample-polyhedron_sample.obj `if test -f 'polyhedron_sample.c'; then $(CYGPATH_W) 'polyhedron_sample.c'; else $(CYGPATH_W) '$(srcdir)/polyhedron_sample.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Tpo $(DEPDIR)/isl_polyhedron_sample-polyhedron_sample.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polyhedron_sample.c' object='isl_polyhedron_sample-polyhedron_sample.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polyhedron_sample_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polyhedron_sample-polyhedron_sample.obj `if test -f 'polyhedron_sample.c'; then $(CYGPATH_W) 'polyhedron_sample.c'; else $(CYGPATH_W) '$(srcdir)/polyhedron_sample.c'; fi` - -isl_polytope_scan-polytope_scan.o: polytope_scan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polytope_scan_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polytope_scan-polytope_scan.o -MD -MP -MF $(DEPDIR)/isl_polytope_scan-polytope_scan.Tpo -c -o isl_polytope_scan-polytope_scan.o `test -f 'polytope_scan.c' || echo '$(srcdir)/'`polytope_scan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polytope_scan-polytope_scan.Tpo $(DEPDIR)/isl_polytope_scan-polytope_scan.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polytope_scan.c' object='isl_polytope_scan-polytope_scan.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polytope_scan_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polytope_scan-polytope_scan.o `test -f 'polytope_scan.c' || echo '$(srcdir)/'`polytope_scan.c - -isl_polytope_scan-polytope_scan.obj: polytope_scan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polytope_scan_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_polytope_scan-polytope_scan.obj -MD -MP -MF $(DEPDIR)/isl_polytope_scan-polytope_scan.Tpo -c -o isl_polytope_scan-polytope_scan.obj `if test -f 'polytope_scan.c'; then $(CYGPATH_W) 'polytope_scan.c'; else $(CYGPATH_W) '$(srcdir)/polytope_scan.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_polytope_scan-polytope_scan.Tpo $(DEPDIR)/isl_polytope_scan-polytope_scan.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='polytope_scan.c' object='isl_polytope_scan-polytope_scan.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_polytope_scan_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_polytope_scan-polytope_scan.obj `if test -f 'polytope_scan.c'; then $(CYGPATH_W) 'polytope_scan.c'; else $(CYGPATH_W) '$(srcdir)/polytope_scan.c'; fi` - -isl_test-isl_test.o: isl_test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_test-isl_test.o -MD -MP -MF $(DEPDIR)/isl_test-isl_test.Tpo -c -o isl_test-isl_test.o `test -f 'isl_test.c' || echo '$(srcdir)/'`isl_test.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_test-isl_test.Tpo $(DEPDIR)/isl_test-isl_test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_test.c' object='isl_test-isl_test.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_test-isl_test.o `test -f 'isl_test.c' || echo '$(srcdir)/'`isl_test.c - -isl_test-isl_test.obj: isl_test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT isl_test-isl_test.obj -MD -MP -MF $(DEPDIR)/isl_test-isl_test.Tpo -c -o isl_test-isl_test.obj `if test -f 'isl_test.c'; then $(CYGPATH_W) 'isl_test.c'; else $(CYGPATH_W) '$(srcdir)/isl_test.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/isl_test-isl_test.Tpo $(DEPDIR)/isl_test-isl_test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isl_test.c' object='isl_test-isl_test.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o isl_test-isl_test.obj `if test -f 'isl_test.c'; then $(CYGPATH_W) 'isl_test.c'; else $(CYGPATH_W) '$(srcdir)/isl_test.c'; fi` - mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs + -rm -rf imath_wrap/.libs imath_wrap/_libs distclean-libtool: -rm -f libtool config.lt @@ -1712,6 +1369,27 @@ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-deprecatedHEADERS: $(deprecated_HEADERS) + @$(NORMAL_INSTALL) + @list='$(deprecated_HEADERS)'; test -n "$(deprecateddir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(deprecateddir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(deprecateddir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(deprecateddir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(deprecateddir)" || exit $$?; \ + done + +uninstall-deprecatedHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(deprecated_HEADERS)'; test -n "$(deprecateddir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(deprecateddir)'; $(am__uninstall_files_from_dir) install-nodist_pkgincludeHEADERS: $(nodist_pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ @@ -1756,22 +1434,25 @@ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -1786,57 +1467,12 @@ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -TAGS: tags-recursive $(HEADERS) $(SOURCES) isl_config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -1852,12 +1488,7 @@ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) isl_config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -1869,15 +1500,11 @@ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) isl_config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) isl_config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -1886,102 +1513,215 @@ here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ else \ - skipped="($$skip tests were not run)"; \ + color_start= color_end=; \ fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +isl_test.log: isl_test$(EXEEXT) + @p='isl_test$(EXEEXT)'; \ + b='isl_test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +codegen_test.sh.log: codegen_test.sh + @p='codegen_test.sh'; \ + b='codegen_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +pip_test.sh.log: pip_test.sh + @p='pip_test.sh'; \ + b='pip_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +bound_test.sh.log: bound_test.sh + @p='bound_test.sh'; \ + b='bound_test.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) $(am__remove_distdir) @@ -2052,40 +1792,42 @@ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__remove_distdir) - -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) + $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -2096,8 +1838,6 @@ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ @@ -2109,18 +1849,19 @@ *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -2143,7 +1884,7 @@ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' @@ -2180,7 +1921,7 @@ isl_config.h installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(deprecateddir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -2203,12 +1944,17 @@ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f imath_wrap/$(DEPDIR)/$(am__dirstamp) + -rm -f imath_wrap/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -2220,7 +1966,7 @@ distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) imath_wrap/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -2237,8 +1983,9 @@ info-am: -install-data-am: install-data-local install-nodist_pkgincludeHEADERS \ - install-pkgconfigDATA install-pkgincludeHEADERS +install-data-am: install-data-local install-deprecatedHEADERS \ + install-nodist_pkgincludeHEADERS install-pkgconfigDATA \ + install-pkgincludeHEADERS install-dvi: install-dvi-recursive @@ -2269,7 +2016,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) imath_wrap/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -2286,35 +2033,36 @@ ps-am: -uninstall-am: uninstall-libLTLIBRARIES \ +uninstall-am: uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \ uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ - ctags-recursive install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) all check-am install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-TESTS check-am clean \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-TESTS check-am clean clean-cscope \ clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstPROGRAMS ctags ctags-recursive dist dist-all \ - dist-bzip2 dist-gzip dist-hook dist-lzip dist-lzma dist-shar \ + clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-compile distclean-generic distclean-hdr \ distclean-libtool distclean-tags distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ - install-data-local install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES install-man \ + install-data-local install-deprecatedHEADERS install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man \ install-nodist_pkgincludeHEADERS install-pdf install-pdf-am \ install-pkgconfigDATA install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-recursive uninstall uninstall-am \ - uninstall-libLTLIBRARIES uninstall-nodist_pkgincludeHEADERS \ - uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS + recheck tags tags-am uninstall uninstall-am \ + uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \ + uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \ + uninstall-pkgincludeHEADERS dist-hook: diff -Nru isl-0.12.2/missing isl-0.15/missing --- isl-0.12.2/missing 2014-01-12 11:45:02.000000000 +0000 +++ isl-0.15/missing 2014-10-26 07:36:32.000000000 +0000 @@ -1,7 +1,7 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-06-26.16; # UTC +scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. @@ -160,7 +160,7 @@ ;; autom4te*) echo "You might have modified some maintainer files that require" - echo "the 'automa4te' program to be rebuilt." + echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) diff -Nru isl-0.12.2/pip.c isl-0.15/pip.c --- isl-0.12.2/pip.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/pip.c 2015-06-02 09:28:10.000000000 +0000 @@ -16,10 +16,11 @@ #include "isl_tab.h" #include "isl_sample.h" #include "isl_scan.h" -#include -#include +#include +#include #include #include +#include #include /* The input of this program is the same as that of the "example" program @@ -198,7 +199,7 @@ * Otherwise, the optimal solution, should be equal to the result of * plugging in the value of the parameters in "sol". */ -static int scan_one(struct isl_scan_callback *callback, +static isl_stat scan_one(struct isl_scan_callback *callback, __isl_take isl_vec *sample) { struct isl_scan_pip *sp = (struct isl_scan_pip *)callback; @@ -230,7 +231,7 @@ fflush(stdout); } - return sp->n >= 1 ? 0 : -1; + return sp->n >= 1 ? isl_stat_ok : isl_stat_error; } static void check_solution(isl_basic_set *bset, isl_basic_set *context, diff -Nru isl-0.12.2/polyhedron_detect_equalities.c isl-0.15/polyhedron_detect_equalities.c --- isl-0.12.2/polyhedron_detect_equalities.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/polyhedron_detect_equalities.c 2015-06-02 09:28:10.000000000 +0000 @@ -13,10 +13,16 @@ { struct isl_ctx *ctx = isl_ctx_alloc(); struct isl_basic_set *bset; + isl_printer *p; bset = isl_basic_set_read_from_file(ctx, stdin); bset = isl_basic_set_detect_equalities(bset); - isl_basic_set_print(bset, stdout, 0, "", "", ISL_FORMAT_POLYLIB); + + p = isl_printer_to_file(ctx, stdout); + p = isl_printer_set_output_format(p, ISL_FORMAT_POLYLIB); + p = isl_printer_print_basic_set(p, bset); + isl_printer_free(p); + isl_basic_set_free(bset); isl_ctx_free(ctx); diff -Nru isl-0.12.2/polyhedron_minimize.c isl-0.15/polyhedron_minimize.c --- isl-0.12.2/polyhedron_minimize.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/polyhedron_minimize.c 2015-04-19 12:02:52.000000000 +0000 @@ -10,8 +10,9 @@ #include #include #include -#include -#include +#include +#include +#include /* The input of this program is the same as that of the "polytope_minimize" * program from the barvinok distribution. diff -Nru isl-0.12.2/polyhedron_sample.c isl-0.15/polyhedron_sample.c --- isl-0.12.2/polyhedron_sample.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/polyhedron_sample.c 2015-04-19 12:02:52.000000000 +0000 @@ -26,7 +26,7 @@ p = isl_printer_end_line(p); isl_printer_free(p); assert(sample); - if (sample->size > 0) + if (isl_vec_size(sample) > 0) assert(isl_basic_set_contains(bset, sample)); isl_basic_set_free(bset); isl_vec_free(sample); diff -Nru isl-0.12.2/polytope_scan.c isl-0.15/polytope_scan.c --- isl-0.12.2/polytope_scan.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/polytope_scan.c 2015-06-02 09:28:10.000000000 +0000 @@ -10,9 +10,10 @@ #include #include #include "isl_equalities.h" -#include +#include #include "isl_scan.h" #include +#include /* The input of this program is the same as that of the "polytope_scan" * program from the barvinok distribution. @@ -27,7 +28,7 @@ struct isl_mat *samples; }; -static int scan_samples_add_sample(struct isl_scan_callback *cb, +static isl_stat scan_samples_add_sample(struct isl_scan_callback *cb, __isl_take isl_vec *sample) { struct scan_samples *ss = (struct scan_samples *)cb; @@ -41,10 +42,10 @@ sample->el, sample->size); isl_vec_free(sample); - return 0; + return isl_stat_ok; error: isl_vec_free(sample); - return -1; + return isl_stat_error; } static struct isl_mat *isl_basic_set_scan_samples(struct isl_basic_set *bset) diff -Nru isl-0.12.2/print.c isl-0.15/print.c --- isl-0.12.2/print.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/print.c 2015-06-02 09:28:10.000000000 +0000 @@ -21,6 +21,9 @@ #define BASE val #include #undef BASE +#define BASE multi_val +#include +#undef BASE #define BASE space #include #undef BASE @@ -87,6 +90,12 @@ #define BASE multi_pw_aff #include #undef BASE +#define BASE union_pw_aff +#include +#undef BASE +#define BASE multi_union_pw_aff +#include +#undef BASE #define BASE point #include #undef BASE diff -Nru isl-0.12.2/README isl-0.15/README --- isl-0.12.2/README 2013-05-28 07:39:07.000000000 +0000 +++ isl-0.15/README 2015-04-19 12:02:52.000000000 +0000 @@ -29,6 +29,11 @@ For bug reports, feature requests and questions, contact http://groups.google.com/group/isl-development +Whenever you report a bug, please mention the exact version of isl +that you are using (output of "./isl_cat --version"). If you are unable +to compile isl, then report the git version (output of "git describe") +or the version included in the name of the tarball. + If you use isl for your research, you are invited do cite the following paper and/or the paper(s) describing the specific operations you use. diff -Nru isl-0.12.2/test-driver isl-0.15/test-driver --- isl-0.12.2/test-driver 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test-driver 2014-03-27 14:32:45.000000000 +0000 @@ -0,0 +1,127 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2012-06-27.10; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff -Nru isl-0.12.2/test_inputs/codegen/atomic3.c isl-0.15/test_inputs/codegen/atomic3.c --- isl-0.12.2/test_inputs/codegen/atomic3.c 2014-01-12 11:34:13.000000000 +0000 +++ isl-0.15/test_inputs/codegen/atomic3.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,8 @@ -for (int c0 = 0; c0 <= 64; c0 += 1) +for (int c0 = 0; c0 <= 64; c0 += 1) { if (c0 >= 63) { sync(); } else if (c0 >= 1) { sync(); } else sync(); +} diff -Nru isl-0.12.2/test_inputs/codegen/atomic.st isl-0.15/test_inputs/codegen/atomic.st --- isl-0.12.2/test_inputs/codegen/atomic.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/atomic.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,4 @@ +domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" +child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ atomic[x] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/0D-1.in isl-0.15/test_inputs/codegen/cloog/0D-1.in --- isl-0.12.2/test_inputs/codegen/cloog/0D-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/0D-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[] -> [0] } -{ : } -{ [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/0D-1.st isl-0.15/test_inputs/codegen/cloog/0D-1.st --- isl-0.12.2/test_inputs/codegen/cloog/0D-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/0D-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,3 @@ +domain: "{ S1[] }" +child: + context: "{ [] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/0D-2.in isl-0.15/test_inputs/codegen/cloog/0D-2.in --- isl-0.12.2/test_inputs/codegen/cloog/0D-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/0D-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[] -> [0] : M >= 0 } -[M] -> { : } -[M] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/0D-2.st isl-0.15/test_inputs/codegen/cloog/0D-2.st --- isl-0.12.2/test_inputs/codegen/cloog/0D-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/0D-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,3 @@ +domain: "[M] -> { S1[] : M >= 0 }" +child: + context: "[M] -> { [] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/0D-3.in isl-0.15/test_inputs/codegen/cloog/0D-3.in --- isl-0.12.2/test_inputs/codegen/cloog/0D-3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/0D-3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[] -> [0] : M >= 0 } -[M] -> { : M >= 0 } -[M] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/0D-3.st isl-0.15/test_inputs/codegen/cloog/0D-3.st --- isl-0.12.2/test_inputs/codegen/cloog/0D-3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/0D-3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,3 @@ +domain: "[M] -> { S1[] : M >= 0 }" +child: + context: "[M] -> { [] : M >= 0 }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/1point-1.in isl-0.15/test_inputs/codegen/cloog/1point-1.in --- isl-0.12.2/test_inputs/codegen/cloog/1point-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/1point-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[2M, M] -> [2M, M, 0] } -[M] -> { : } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/1point-1.st isl-0.15/test_inputs/codegen/cloog/1point-1.st --- isl-0.12.2/test_inputs/codegen/cloog/1point-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/1point-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[2M, M] }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/1point-2.in isl-0.15/test_inputs/codegen/cloog/1point-2.in --- isl-0.12.2/test_inputs/codegen/cloog/1point-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/1point-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[2M, 2 + N] -> [2M, 2 + N, 0] } -[M, N] -> { : } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/1point-2.st isl-0.15/test_inputs/codegen/cloog/1point-2.st --- isl-0.12.2/test_inputs/codegen/cloog/1point-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/1point-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[2M, 2 + N] }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/4-param.c isl-0.15/test_inputs/codegen/cloog/4-param.c --- isl-0.12.2/test_inputs/codegen/cloog/4-param.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/4-param.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,9 +1,9 @@ { - for (int c0 = m; c0 <= min(p - 1, n); c0 += 1) + for (int c0 = m; c0 <= min(n, p - 1); c0 += 1) S1(c0); - for (int c0 = p; c0 <= min(q, m - 1); c0 += 1) + for (int c0 = p; c0 <= min(m - 1, q); c0 += 1) S2(c0); - for (int c0 = max(m, p); c0 <= min(q, n); c0 += 1) { + for (int c0 = max(m, p); c0 <= min(n, q); c0 += 1) { S1(c0); S2(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/4-param.in isl-0.15/test_inputs/codegen/cloog/4-param.in --- isl-0.12.2/test_inputs/codegen/cloog/4-param.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/4-param.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m, n, p, q] -> { S1[i0] -> [i0, 0] : i0 >= m and i0 <= n; S2[i0] -> [i0, 1] : i0 >= p and i0 <= q } -[m, n, p, q] -> { : } -[m, n, p, q] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/4-param.st isl-0.15/test_inputs/codegen/cloog/4-param.st --- isl-0.12.2/test_inputs/codegen/cloog/4-param.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/4-param.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[m, n, p, q] -> { S1[i0] : i0 >= m and i0 <= n; S2[i0] : i0 >= p and i0 <= q }" +child: + context: "[m, n, p, q] -> { [] }" + child: + schedule: "[m, n, p, q] -> [{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "[m, n, p, q] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n, p, q] -> { S1[i0] }" + - filter: "[m, n, p, q] -> { S2[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/backtrack.in isl-0.15/test_inputs/codegen/cloog/backtrack.in --- isl-0.12.2/test_inputs/codegen/cloog/backtrack.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/backtrack.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[0] -> [0, 0] } -{ : } -{ [i, j] -> atomic[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/backtrack.st isl-0.15/test_inputs/codegen/cloog/backtrack.st --- isl-0.12.2/test_inputs/codegen/cloog/backtrack.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/backtrack.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[0] }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-1.in isl-0.15/test_inputs/codegen/cloog/basic-bounds-1.in --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0] -> [i0, 0] : i0 >= 0 and i0 <= 2 } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-1.st isl-0.15/test_inputs/codegen/cloog/basic-bounds-1.st --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i0] : i0 >= 0 and i0 <= 2 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-2.in isl-0.15/test_inputs/codegen/cloog/basic-bounds-2.in --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[0] -> [0, 0] } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-2.st isl-0.15/test_inputs/codegen/cloog/basic-bounds-2.st --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[0] }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-3.in isl-0.15/test_inputs/codegen/cloog/basic-bounds-3.in --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0] -> [i0, 0] : i0 >= 0 and i0 <= M } -[M] -> { : M >= 0 } -[M] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-3.st isl-0.15/test_inputs/codegen/cloog/basic-bounds-3.st --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0] : i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-4.in isl-0.15/test_inputs/codegen/cloog/basic-bounds-4.in --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-4.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-4.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0] -> [i0, 0] : i0 >= 0 and i0 <= 1 + M } -[M] -> { : M >= 0 } -[M] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-4.st isl-0.15/test_inputs/codegen/cloog/basic-bounds-4.st --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0] : i0 >= 0 and i0 <= 1 + M }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-5.in isl-0.15/test_inputs/codegen/cloog/basic-bounds-5.in --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-5.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-5.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[1, i1] -> [1, i1, 0] : 2i1 >= M and 2i1 <= 1 + M } -[M] -> { : } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-5.st isl-0.15/test_inputs/codegen/cloog/basic-bounds-5.st --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-5.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-5.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[1, i1] : 2i1 >= M and 2i1 <= 1 + M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-6.c isl-0.15/test_inputs/codegen/cloog/basic-bounds-6.c --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-6.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-6.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1 @@ +S1(-1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-6.st isl-0.15/test_inputs/codegen/cloog/basic-bounds-6.st --- isl-0.12.2/test_inputs/codegen/cloog/basic-bounds-6.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/basic-bounds-6.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[-1] }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/block2.in isl-0.15/test_inputs/codegen/cloog/block2.in --- isl-0.12.2/test_inputs/codegen/cloog/block2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/block2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, 1] -> [i0, 1, 6] : i0 >= 0 and i0 <= 9; S2[i0, 1] -> [i0, 1, 11] : i0 >= 0 and i0 <= 9; S3[i0, 1] -> [i0, 1, 8] : i0 >= 0 and i0 <= 9 } -{ : } -{ [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/block2.st isl-0.15/test_inputs/codegen/cloog/block2.st --- isl-0.12.2/test_inputs/codegen/cloog/block2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/block2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +domain: "{ S2[i0, 1] : i0 >= 0 and i0 <= 9; S1[i0, 1] : i0 >= 0 and i0 <= 9; S3[i0, 1] : i0 >= 0 and i0 <= 9 }" +child: + context: "{ [] }" + child: + schedule: "[{ S3[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S3[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S3[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/block3.in isl-0.15/test_inputs/codegen/cloog/block3.in --- isl-0.12.2/test_inputs/codegen/cloog/block3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/block3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[] -> [1]; S3[i0] -> [i0] : i0 >= 0 and i0 <= 1; S1[] -> [0] } -{ : } -{ [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/block3.st isl-0.15/test_inputs/codegen/cloog/block3.st --- isl-0.12.2/test_inputs/codegen/cloog/block3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/block3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[]; S3[i0] : i0 >= 0 and i0 <= 1; S2[] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[] -> [(1)]; S3[i0] -> [(i0)]; S1[] -> [(0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/block.in isl-0.15/test_inputs/codegen/cloog/block.in --- isl-0.12.2/test_inputs/codegen/cloog/block.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/block.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S3[i0] -> [i0, 1] : i0 >= 0 and i0 <= 1; S1[] -> [0, 0]; S2[] -> [1, 0] } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/block.st isl-0.15/test_inputs/codegen/cloog/block.st --- isl-0.12.2/test_inputs/codegen/cloog/block.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/block.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S1[]; S3[i0] : i0 >= 0 and i0 <= 1; S2[] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[] -> [(1)]; S3[i0] -> [(i0)]; S1[] -> [(0)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[]; S2[] }" + - filter: "{ S3[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/byu98-1-2-3.in isl-0.15/test_inputs/codegen/cloog/byu98-1-2-3.in --- isl-0.12.2/test_inputs/codegen/cloog/byu98-1-2-3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/byu98-1-2-3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1] -> [i0, i1, 0] : i1 >= 6 - i0 and i0 >= 2 and i1 >= 3 and i1 <= 6 and i1 >= -1 + i0; S2[i0, 9 - i0] -> [i0, 9 - i0, 1] : i0 <= 8 and i0 >= 4 } -{ : } -{ [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/byu98-1-2-3.st isl-0.15/test_inputs/codegen/cloog/byu98-1-2-3.st --- isl-0.12.2/test_inputs/codegen/cloog/byu98-1-2-3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/byu98-1-2-3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S2[i0, 9 - i0] : i0 <= 8 and i0 >= 4; S1[i0, i1] : i1 >= 6 - i0 and i0 >= 2 and i1 >= 3 and i1 <= 6 and i1 >= -1 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/cholesky2.c isl-0.15/test_inputs/codegen/cloog/cholesky2.c --- isl-0.12.2/test_inputs/codegen/cloog/cholesky2.c 2013-08-20 14:50:16.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/cholesky2.c 2015-06-02 09:28:10.000000000 +0000 @@ -6,14 +6,11 @@ } for (int c0 = 1; c0 < 3 * M - 1; c0 += 3) { S3((c0 + 2) / 3); - if (3 * M >= c0 + 8) { - for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) { - S6((c0 + 2) / 3, c1); - for (int c4 = (c0 + 5) / 3; c4 < c1; c4 += 1) - S5(c4, c1, (c0 + 2) / 3); - } - } else if (c0 + 5 == 3 * M) - S6(M - 1, M); + for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) { + S6((c0 + 2) / 3, c1); + for (int c4 = (c0 + 5) / 3; c4 < c1; c4 += 1) + S5(c4, c1, (c0 + 2) / 3); + } for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) S2(c1, (c0 + 2) / 3); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/cholesky2.in isl-0.15/test_inputs/codegen/cloog/cholesky2.in --- isl-0.12.2/test_inputs/codegen/cloog/cholesky2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/cholesky2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [3i1, i0, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0; S4[i0, i1] -> [0, i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S1[i0] -> [0, i0, 0] : i0 >= 1 and i0 <= M; S6[i0, i1] -> [-1 + 3i0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S3[i0] -> [-2 + 3i0, 0, 0] : i0 >= 1 and i0 <= M; S5[i0, i1, i2] -> [-1 + 3i2, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 and i2 <= -1 + i0 } -[M] -> { : } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/cholesky2.st isl-0.15/test_inputs/codegen/cloog/cholesky2.st --- isl-0.12.2/test_inputs/codegen/cloog/cholesky2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/cholesky2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S4[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S5[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 and i2 <= -1 + i0; S6[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S3[i0] : i0 >= 1 and i0 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0; S1[i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0] -> [(0)]; S3[i0] -> [(-2 + 3i0)]; S4[i0, i1] -> [(0)]; S5[i0, i1, i2] -> [(-1 + 3i2)]; S2[i0, i1] -> [(3i1)]; S6[i0, i1] -> [(-1 + 3i0)] }, { S1[i0] -> [(i0)]; S3[i0] -> [(0)]; S4[i0, i1] -> [(i0)]; S5[i0, i1, i2] -> [(i1)]; S2[i0, i1] -> [(i0)]; S6[i0, i1] -> [(i1)] }, { S1[i0] -> [(0)]; S3[i0] -> [(0)]; S4[i0, i1] -> [(i1)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1] -> [(0)]; S6[i0, i1] -> [(0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/cholesky.c isl-0.15/test_inputs/codegen/cloog/cholesky.c --- isl-0.12.2/test_inputs/codegen/cloog/cholesky.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/cholesky.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,12 +1,12 @@ for (int c0 = 1; c0 <= n; c0 += 1) { S1(c0); - for (int c2 = 1; c2 < c0; c2 += 1) - S2(c0, c2); + for (int c1 = 1; c1 < c0; c1 += 1) + S2(c0, c1); S3(c0); - for (int c2 = c0 + 1; c2 <= n; c2 += 1) { - S4(c0, c2); - for (int c4 = 1; c4 < c0; c4 += 1) - S5(c0, c2, c4); - S6(c0, c2); + for (int c1 = c0 + 1; c1 <= n; c1 += 1) { + S4(c0, c1); + for (int c2 = 1; c2 < c0; c2 += 1) + S5(c0, c1, c2); + S6(c0, c1); } } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/cholesky.in isl-0.15/test_inputs/codegen/cloog/cholesky.in --- isl-0.12.2/test_inputs/codegen/cloog/cholesky.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/cholesky.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i0] -> [i0, 1, 0, 0, 0, 0] : i0 >= 1 and i0 <= n; S2[i0, i1] -> [i0, 2, i1, 1, 0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= -1 + i0; S6[i0, i1] -> [i0, 4, i1, 3, 0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S3[i0] -> [i0, 3, 0, 0, 0, 0] : i0 >= 1 and i0 <= n; S4[i0, i1] -> [i0, 4, i1, 1, 0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S5[i0, i1, i2] -> [i0, 4, i1, 2, i2, 1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 and i2 <= -1 + i0 } -[n] -> { : } -[n] -> { [i, j, k, l, m, n'] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/cholesky.st isl-0.15/test_inputs/codegen/cloog/cholesky.st --- isl-0.12.2/test_inputs/codegen/cloog/cholesky.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/cholesky.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,26 @@ +domain: "[n] -> { S2[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= -1 + i0; S1[i0] : i0 >= 1 and i0 <= n; S4[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S5[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 and i2 <= -1 + i0; S6[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S3[i0] : i0 >= 1 and i0 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0] -> [(i0)]; S4[i0, i1] -> [(i0)]; S6[i0, i1] -> [(i0)]; S3[i0] -> [(i0)]; S5[i0, i1, i2] -> [(i0)]; S2[i0, i1] -> [(i0)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0] }" + - filter: "[n] -> { S2[i0, i1] }" + child: + schedule: "[n] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + - filter: "[n] -> { S3[i0] }" + - filter: "[n] -> { S4[i0, i1]; S5[i0, i1, i2]; S6[i0, i1] }" + child: + schedule: "[n] -> [{ S4[i0, i1] -> [(i1)]; S6[i0, i1] -> [(i1)]; S5[i0, i1, i2] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S4[i0, i1] }" + - filter: "[n] -> { S5[i0, i1, i2] }" + child: + schedule: "[n] -> [{ S5[i0, i1, i2] -> [(i2)] }]" + options: "[n] -> { separate[i0] }" + - filter: "[n] -> { S6[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/christian.c isl-0.15/test_inputs/codegen/cloog/christian.c --- isl-0.12.2/test_inputs/codegen/cloog/christian.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/christian.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,6 @@ for (int c0 = -N + 1; c0 <= N; c0 += 1) { - for (int c1 = max(c0 - 1, 0); c1 < min(N + c0 - 1, N); c1 += 1) - S2(c1, -c0 + c1 + 1); - for (int c1 = max(c0, 0); c1 < min(N + c0, N); c1 += 1) + for (int c1 = max(0, c0); c1 < min(N, N + c0); c1 += 1) S1(c1, -c0 + c1); + for (int c1 = max(0, c0 - 1); c1 < min(N, N + c0 - 1); c1 += 1) + S2(c1, -c0 + c1 + 1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/christian.in isl-0.15/test_inputs/codegen/cloog/christian.in --- isl-0.12.2/test_inputs/codegen/cloog/christian.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/christian.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[N] -> { S1[i0, i1] -> [i0 - i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S2[i0, i1] -> [1 + i0 - i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N } -[N] -> { : } -[N] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/christian.st isl-0.15/test_inputs/codegen/cloog/christian.st --- isl-0.12.2/test_inputs/codegen/cloog/christian.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/christian.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[N] -> { S1[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S2[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N }" +child: + context: "[N] -> { [] }" + child: + schedule: "[N] -> [{ S1[i0, i1] -> [(i0 - i1)]; S2[i0, i1] -> [(1 + i0 - i1)] }]" + options: "[N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/classen2.c isl-0.15/test_inputs/codegen/cloog/classen2.c --- isl-0.12.2/test_inputs/codegen/cloog/classen2.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/classen2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = max(max(max(max(max(max(5 * outerTimeTileScatter, 10 * outerProcTileScatter1 - 2 * N + 2), 5 * outerProcTileScatter1 + 5 * outerProcTileScatter2 - N), 5 * outerProcTileScatter1), 10 * outerProcTileScatter2 - N + 1), 5 * outerProcTileScatter2 + 1), 4); c0 <= min(min(min(min(min(min(2 * M + 2 * N - 6, 5 * outerProcTileScatter2 + M + N), 10 * outerProcTileScatter2 + N + 3), 5 * outerProcTileScatter1 + M + 2), 5 * outerProcTileScatter1 + 5 * outerProcTileScatter2 + 5), 10 * outerProcTileScatter1 + 4), 5 * outerTimeTileScatter + 4); c0 += 1) - for (int c1 = max(max(max(max(-5 * outerProcTileScatter2 + c0 - 1, -M + c0 + 2), (c0 + 1) / 2 + 2), 5 * outerProcTileScatter2 + 1), 5 * outerProcTileScatter1); c1 <= min(min(min(min(5 * outerProcTileScatter1 + 4, 5 * outerProcTileScatter2 + N + 2), N + c0 / 2 - 1), c0), -5 * outerProcTileScatter2 + N + c0); c1 += 1) - for (int c2 = max(max(-N + c1 + 2, c0 - c1 + 3), 5 * outerProcTileScatter2); c2 <= min(min(5 * outerProcTileScatter2 + 4, N + c0 - c1), c1 - 1); c2 += 1) +for (int c0 = max(max(max(max(max(max(4, 5 * outerTimeTileScatter), 5 * outerProcTileScatter1), 5 * outerProcTileScatter2 + 1), 5 * outerProcTileScatter1 + 5 * outerProcTileScatter2 - N), 10 * outerProcTileScatter2 - N + 1), 10 * outerProcTileScatter1 - 2 * N + 2); c0 <= min(min(min(min(min(min(5 * outerTimeTileScatter + 4, 10 * outerProcTileScatter1 + 4), 5 * outerProcTileScatter1 + 5 * outerProcTileScatter2 + 5), 5 * outerProcTileScatter1 + M + 2), 2 * M + 2 * N - 6), 5 * outerProcTileScatter2 + M + N), 10 * outerProcTileScatter2 + N + 3); c0 += 1) + for (int c1 = max(max(max(max(5 * outerProcTileScatter1, 5 * outerProcTileScatter2 + 1), -5 * outerProcTileScatter2 + c0 - 1), -M + c0 + 2), (c0 + 1) / 2 + 2); c1 <= min(min(min(min(5 * outerProcTileScatter1 + 4, 5 * outerProcTileScatter2 + N + 2), -5 * outerProcTileScatter2 + N + c0), c0), N + c0 / 2 - 1); c1 += 1) + for (int c2 = max(max(5 * outerProcTileScatter2, -N + c1 + 2), c0 - c1 + 3); c2 <= min(min(5 * outerProcTileScatter2 + 4, c1 - 1), N + c0 - c1); c2 += 1) S1(c0 - c1 + 1, -c0 + c1 + c2 - 2, c1 - c2, c0, c1, c2); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/classen2.in isl-0.15/test_inputs/codegen/cloog/classen2.in --- isl-0.12.2/test_inputs/codegen/cloog/classen2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/classen2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { S1[i0, i1, i2, 2i0 + i1 + i2, 1 + i0 + i1 + i2, 1 + i0 + i1] -> [2i0 + i1 + i2, 1 + i0 + i1 + i2, 1 + i0 + i1] : N >= 3 and i2 <= 3 + 5outerProcTileScatter1 - i0 - i1 and i1 >= -1 + 5outerProcTileScatter2 - i0 and M >= 2 and i2 <= 4 + 5outerTimeTileScatter - 2i0 - i1 and i1 <= 3 + 5outerProcTileScatter2 - i0 and i2 >= 1 and i2 <= -2 + N and i1 >= 1 and i1 <= -2 + N and i0 >= 1 and i0 <= -1 + M and i2 >= 5outerTimeTileScatter - 2i0 - i1 and i2 >= -1 + 5outerProcTileScatter1 - i0 - i1 } -[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { : } -[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/classen2.st isl-0.15/test_inputs/codegen/cloog/classen2.st --- isl-0.12.2/test_inputs/codegen/cloog/classen2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/classen2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { S1[compIter1, compIter2, compIter3, 2compIter1 + compIter2 + compIter3, 1 + compIter1 + compIter2 + compIter3, 1 + compIter1 + compIter2] : N >= 3 and compIter3 <= 3 + 5outerProcTileScatter1 - compIter1 - compIter2 and compIter2 >= -1 + 5outerProcTileScatter2 - compIter1 and M >= 2 and compIter3 <= 4 + 5outerTimeTileScatter - 2compIter1 - compIter2 and compIter2 <= 3 + 5outerProcTileScatter2 - compIter1 and compIter3 >= 1 and compIter3 <= -2 + N and compIter2 >= 1 and compIter2 <= -2 + N and compIter1 >= 1 and compIter1 <= -1 + M and compIter3 >= 5outerTimeTileScatter - 2compIter1 - compIter2 and compIter3 >= -1 + 5outerProcTileScatter1 - compIter1 - compIter2 }" +child: + context: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { [] }" + child: + schedule: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> [{ S1[i0, i1, i2, i3, i4, i5] -> [(i3)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i4)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i5)] }]" + options: "[outerTimeTileScatter, outerProcTileScatter1, outerProcTileScatter2, M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/classen.c isl-0.15/test_inputs/codegen/cloog/classen.c --- isl-0.12.2/test_inputs/codegen/cloog/classen.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/classen.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,11 +1,11 @@ -{ +if (m >= 1) { if (m == 1) { S1(0, 1, 1, 1); S8(0, 1); - } else if (m >= 2) { + } else { S1(0, 1, 1, 1); - S3(0, 1, 1, 2, 1, 1, 1, 2); S4(0, 1, 2, 2, 1, 1, 2, 2); + S3(0, 1, 1, 2, 1, 1, 1, 2); S2(0, 1, 1, 1, 1, 1, 2, 1); S8(0, 1); } @@ -14,48 +14,48 @@ S5(m - 2, 1, m - 1, 1, m - 1, 1, m, 1); S1(m - 1, 1, m, 1); S3(m - 1, 1, m, 2, m, 1, m, 2); - } else if (c0 >= m) { - S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2); - S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2); - S1(c0, -m + c0 + 2, m, -m + c0 + 2); - S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3); - } else { + } else if (m >= c0 + 2) { S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1); S1(c0, 1, c0 + 1, 1); - S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2); S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2); S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1); + S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2); + } else { + S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2); + S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2); + S1(c0, -m + c0 + 2, m, -m + c0 + 2); + S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3); } - for (int c2 = max(2, -m + c0 + 3); c2 <= min(c0, m - 1); c2 += 1) { - S5(c0 - 1, c2, c0, c2, c0 - c2 + 1, c2, c0 - c2 + 2, c2); - S7(c0 - 1, c2 - 1, c0 + 1, c2, c0 - c2 + 2, c2 - 1, c0 - c2 + 3, c2); - S6(c0 - 1, c2 - 1, c0, c2, c0 - c2 + 2, c2 - 1, c0 - c2 + 2, c2); - S1(c0, c2, c0 - c2 + 2, c2); - S3(c0, c2, c0 + 1, c2 + 1, c0 - c2 + 2, c2, c0 - c2 + 2, c2 + 1); - S4(c0, c2, c0 + 2, c2 + 1, c0 - c2 + 2, c2, c0 - c2 + 3, c2 + 1); - S2(c0, c2, c0 + 1, c2, c0 - c2 + 2, c2, c0 - c2 + 3, c2); + for (int c1 = max(2, -m + c0 + 3); c1 <= min(m - 1, c0); c1 += 1) { + S5(c0 - 1, c1, c0, c1, c0 - c1 + 1, c1, c0 - c1 + 2, c1); + S6(c0 - 1, c1 - 1, c0, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 2, c1); + S7(c0 - 1, c1 - 1, c0 + 1, c1, c0 - c1 + 2, c1 - 1, c0 - c1 + 3, c1); + S1(c0, c1, c0 - c1 + 2, c1); + S4(c0, c1, c0 + 2, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 3, c1 + 1); + S2(c0, c1, c0 + 1, c1, c0 - c1 + 2, c1, c0 - c1 + 3, c1); + S3(c0, c1, c0 + 1, c1 + 1, c0 - c1 + 2, c1, c0 - c1 + 2, c1 + 1); } if (c0 + 1 == m) { S7(m - 2, m - 1, m, m, 1, m - 1, 2, m); S6(m - 2, m - 1, m - 1, m, 1, m - 1, 1, m); S1(m - 1, m, 1, m); S2(m - 1, m, m, m, 1, m, 2, m); - } else if (c0 >= m) { - S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m); - S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m); - S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m); - S1(c0, m, -m + c0 + 2, m); - S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m); - } else { + } else if (m >= c0 + 2) { S7(c0 - 1, c0, c0 + 1, c0 + 1, 1, c0, 2, c0 + 1); S6(c0 - 1, c0, c0, c0 + 1, 1, c0, 1, c0 + 1); S1(c0, c0 + 1, 1, c0 + 1); - S3(c0, c0 + 1, c0 + 1, c0 + 2, 1, c0 + 1, 1, c0 + 2); S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2); S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1); + S3(c0, c0 + 1, c0 + 1, c0 + 2, 1, c0 + 1, 1, c0 + 2); + } else { + S5(c0 - 1, m, c0, m, -m + c0 + 1, m, -m + c0 + 2, m); + S7(c0 - 1, m - 1, c0 + 1, m, -m + c0 + 2, m - 1, -m + c0 + 3, m); + S6(c0 - 1, m - 1, c0, m, -m + c0 + 2, m - 1, -m + c0 + 2, m); + S1(c0, m, -m + c0 + 2, m); + S2(c0, m, c0 + 1, m, -m + c0 + 2, m, -m + c0 + 3, m); } - for (int c8 = max(1, -m + c0 + 2); c8 <= min(c0 + 1, m); c8 += 1) - S8(c0, c8); + for (int c2 = max(1, -m + c0 + 2); c2 <= min(m, c0 + 1); c2 += 1) + S8(c0, c2); } if (m >= 2) { if (m >= 3) { @@ -76,8 +76,8 @@ S1(1, 2, 1, 2); } S2(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m); - for (int c8 = m - 1; c8 <= m; c8 += 1) - S8(2 * m - 3, c8); + for (int c2 = m - 1; c2 <= m; c2 += 1) + S8(2 * m - 3, c2); S5(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m); S6(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m); S1(2 * m - 2, m, m, m); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/classen.in isl-0.15/test_inputs/codegen/cloog/classen.in --- isl-0.12.2/test_inputs/codegen/cloog/classen.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/classen.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m] -> { S2[i0, i1, 1 + i0, i1, 2 + i0 - i1, i1, 3 + i0 - i1, i1] -> [i0, 0, i1, 2, 2 + i0 - i1, i1, 1] : m >= 1 and i0 <= -3 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= m and i1 >= 3 - m + i0 and i1 >= 1; S4[i0, i1, 2 + i0, 1 + i1, 2 + i0 - i1, i1, 3 + i0 - i1, 1 + i1] -> [i0, 0, i1, 2, 2 + i0 - i1, i1, 1] : m >= 1 and i0 <= -4 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= -1 + m and i1 >= 3 - m + i0 and i1 >= 1; S5[i0, i1, 1 + i0, i1, 2 + i0 - i1, i1, 3 + i0 - i1, i1] -> [1 + i0, 0, i1, 0, 2 + i0 - i1, i1, 1] : m >= 1 and i0 <= -3 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= m and i1 >= 3 - m + i0 and i1 >= 1; S7[i0, i1, 2 + i0, 1 + i1, 2 + i0 - i1, i1, 3 + i0 - i1, 1 + i1] -> [1 + i0, 0, 1 + i1, 0, 2 + i0 - i1, i1, 1] : m >= 1 and i0 <= -4 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= -1 + m and i1 >= 3 - m + i0 and i1 >= 1; S6[i0, i1, 1 + i0, 1 + i1, 2 + i0 - i1, i1, 2 + i0 - i1, 1 + i1] -> [1 + i0, 0, 1 + i1, 0, 2 + i0 - i1, i1, 1] : m >= 1 and i0 <= -3 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= -1 + m and i1 >= 2 - m + i0 and i1 >= 1; S3[i0, i1, 1 + i0, 1 + i1, 2 + i0 - i1, i1, 2 + i0 - i1, 1 + i1] -> [i0, 0, i1, 2, 2 + i0 - i1, i1, 1] : m >= 1 and i0 <= -3 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= -1 + m and i1 >= 2 - m + i0 and i1 >= 1; S8[i0, i1] -> [i0, 1, 0, 0, 0, 0, 0] : i0 <= -2 + 2m and i0 >= 0 and i1 <= 1 + i0 and i1 <= m and i1 >= 2 - m + i0 and i1 >= 1; S1[i0, i1, 2 + i0 - i1, i1] -> [i0, 0, i1, 1, 0, 0, 0] : m >= 1 and i1 >= 2 - m + i0 and i1 <= 1 + i0 and i1 <= m and i1 >= 1 } -[m] -> { : m >= 0 } -[m] -> { [i, j, k, l, m', n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/classen.st isl-0.15/test_inputs/codegen/cloog/classen.st --- isl-0.12.2/test_inputs/codegen/cloog/classen.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/classen.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,24 @@ +domain: "[m] -> { S2[coordT1, coordP1, 1 + coordT1, coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S4[coordT1, coordP1, 2 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -4 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S6[coordT1, coordP1, 1 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 2 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 2 - m + coordT1 and coordP1 >= 1; S1[coordT1, coordP1, 2 + coordT1 - coordP1, coordP1] : m >= 1 and coordP1 >= 2 - m + coordT1 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 1; S8[coordT1, coordP1] : coordT1 <= -2 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 2 - m + coordT1 and coordP1 >= 1; S5[coordT1, coordP1, 1 + coordT1, coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S7[coordT1, coordP1, 2 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 3 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -4 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 3 - m + coordT1 and coordP1 >= 1; S3[coordT1, coordP1, 1 + coordT1, 1 + coordP1, 2 + coordT1 - coordP1, coordP1, 2 + coordT1 - coordP1, 1 + coordP1] : m >= 1 and coordT1 <= -3 + 2m and coordT1 >= 0 and coordP1 <= 1 + coordT1 and coordP1 <= -1 + m and coordP1 >= 2 - m + coordT1 and coordP1 >= 1 }" +child: + context: "[m] -> { [] : m >= 0 }" + child: + schedule: "[m] -> [{ S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(1 + i0)]; S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i0)]; S8[i0, i1] -> [(i0)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i0)]; S1[i0, i1, i2, i3] -> [(i0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i0)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(1 + i0)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(1 + i0)] }]" + options: "[m] -> { separate[i0] }" + child: + sequence: + - filter: "[m] -> { S2[i0, i1, i2, i3, i4, i5, i6, i7]; S6[i0, i1, i2, i3, i4, i5, i6, i7]; S4[i0, i1, i2, i3, i4, i5, i6, i7]; S1[i0, i1, i2, i3]; S7[i0, i1, i2, i3, i4, i5, i6, i7]; S5[i0, i1, i2, i3, i4, i5, i6, i7]; S3[i0, i1, i2, i3, i4, i5, i6, i7] }" + child: + schedule: "[m] -> [{ S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i3)]; S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i1)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i1)]; S1[i0, i1, i2, i3] -> [(i1)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i1)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i3)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i3)] }]" + options: "[m] -> { separate[i0] }" + child: + sequence: + - filter: "[m] -> { S6[i0, i1, i2, i3, i4, i5, i6, i7]; S5[i0, i1, i2, i3, i4, i5, i6, i7]; S7[i0, i1, i2, i3, i4, i5, i6, i7] }" + child: + schedule: "[m] -> [{ S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)] }, { S7[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S5[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S6[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)] }]" + options: "[m] -> { separate[i0] }" + - filter: "[m] -> { S1[i0, i1, i2, i3] }" + - filter: "[m] -> { S2[i0, i1, i2, i3, i4, i5, i6, i7]; S4[i0, i1, i2, i3, i4, i5, i6, i7]; S3[i0, i1, i2, i3, i4, i5, i6, i7] }" + child: + schedule: "[m] -> [{ S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i4)] }, { S4[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S3[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)]; S2[i0, i1, i2, i3, i4, i5, i6, i7] -> [(i5)] }]" + options: "[m] -> { separate[i0] }" + - filter: "[m] -> { S8[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/constant.c isl-0.15/test_inputs/codegen/cloog/constant.c --- isl-0.12.2/test_inputs/codegen/cloog/constant.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/constant.c 2015-04-19 12:02:52.000000000 +0000 @@ -3,7 +3,7 @@ S1(c1); S3(c1); } - for (int c1 = max(M + 1025, 0); c1 <= 1023; c1 += 1) { + for (int c1 = max(0, M + 1025); c1 <= 1023; c1 += 1) { S2(c1); S3(c1); } @@ -11,7 +11,7 @@ S4(c0); S6(c0); } - for (int c0 = max(M + 1025, 0); c0 <= 1023; c0 += 1) { + for (int c0 = max(0, M + 1025); c0 <= 1023; c0 += 1) { S5(c0); S6(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/constant.in isl-0.15/test_inputs/codegen/cloog/constant.in --- isl-0.12.2/test_inputs/codegen/cloog/constant.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/constant.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S5[i0] -> [i0, 0, 1] : i0 >= 0 and i0 <= 1023 and i0 >= 1025 + M; S1[i0] -> [-1, i0, 0] : i0 >= 0 and i0 <= 1023 and i0 <= 1024 + M; S3[i0] -> [-1, i0, 2] : i0 >= 0 and i0 <= 1023; S2[i0] -> [-1, i0, 1] : i0 >= 0 and i0 <= 1023 and i0 >= 1025 + M; S4[i0] -> [i0, 0, 0] : i0 >= 0 and i0 <= 1023 and i0 <= 1024 + M; S6[i0] -> [i0, 0, 2] : i0 >= 0 and i0 <= 1023 } -[M] -> { : } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/constant.st isl-0.15/test_inputs/codegen/cloog/constant.st --- isl-0.12.2/test_inputs/codegen/cloog/constant.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/constant.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +domain: "[M] -> { S4[i0] : i0 >= 0 and i0 <= 1023 and i0 <= 1024 + M; S5[i0] : i0 >= 0 and i0 <= 1023 and i0 >= 1025 + M; S3[i0] : i0 >= 0 and i0 <= 1023; S2[i0] : i0 >= 0 and i0 <= 1023 and i0 >= 1025 + M; S1[i0] : i0 >= 0 and i0 <= 1023 and i0 <= 1024 + M; S6[i0] : i0 >= 0 and i0 <= 1023 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S2[i0] -> [(-1)]; S4[i0] -> [(i0)]; S1[i0] -> [(-1)]; S3[i0] -> [(-1)]; S6[i0] -> [(i0)]; S5[i0] -> [(i0)] }, { S2[i0] -> [(i0)]; S4[i0] -> [(0)]; S1[i0] -> [(i0)]; S3[i0] -> [(i0)]; S6[i0] -> [(0)]; S5[i0] -> [(0)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S4[i0]; S1[i0] }" + - filter: "[M] -> { S5[i0]; S2[i0] }" + - filter: "[M] -> { S3[i0]; S6[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/constbound.c isl-0.15/test_inputs/codegen/cloog/constbound.c --- isl-0.12.2/test_inputs/codegen/cloog/constbound.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/constbound.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ for (int c0 = 0; c0 <= 199; c0 += 1) { - for (int c2 = 50 * c0; c2 <= 50 * c0 + 24; c2 += 1) - for (int c3 = 0; c3 <= c2; c3 += 1) - S1(c0, c2, c3); - for (int c2 = 50 * c0 + 25; c2 <= 50 * c0 + 49; c2 += 1) - for (int c3 = 0; c3 <= c2; c3 += 1) - S2(c0, c2, c3); + for (int c1 = 50 * c0; c1 <= 50 * c0 + 24; c1 += 1) + for (int c2 = 0; c2 <= c1; c2 += 1) + S1(c0, c1, c2); + for (int c1 = 50 * c0 + 25; c1 <= 50 * c0 + 49; c1 += 1) + for (int c2 = 0; c2 <= c1; c2 += 1) + S2(c0, c1, c2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/constbound.in isl-0.15/test_inputs/codegen/cloog/constbound.in --- isl-0.12.2/test_inputs/codegen/cloog/constbound.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/constbound.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[i0, i1, i2] -> [i0, 1, i1, i2] : i1 >= 0 and i1 <= 9999 and i2 >= 0 and i2 <= i1 and i1 >= 25 + 50i0 and i1 <= 49 + 50i0; S1[i0, i1, i2] -> [i0, 0, i1, i2] : i1 >= 0 and i1 <= 9999 and i2 >= 0 and i2 <= i1 and i1 >= 50i0 and i1 <= 24 + 50i0 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/constbound.st isl-0.15/test_inputs/codegen/cloog/constbound.st --- isl-0.12.2/test_inputs/codegen/cloog/constbound.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/constbound.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,16 @@ +domain: "{ S2[i0, i1, i2] : i1 >= 0 and i1 <= 9999 and i2 >= 0 and i2 <= i1 and i1 >= 25 + 50i0 and i1 <= 49 + 50i0; S1[i0, i1, i2] : i1 >= 0 and i1 <= 9999 and i2 >= 0 and i2 <= i1 and i1 >= 50i0 and i1 <= 24 + 50i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" + - filter: "{ S2[i0, i1, i2] }" + child: + schedule: "[{ S2[i0, i1, i2] -> [(i1)] }, { S2[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/darte.c isl-0.15/test_inputs/codegen/cloog/darte.c --- isl-0.12.2/test_inputs/codegen/cloog/darte.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/darte.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,12 +1,12 @@ for (int c0 = -n + 1; c0 <= n; c0 += 1) { if (c0 <= 0) for (int c2 = -c0 + 4; c2 <= 2 * n - c0 + 2; c2 += 2) - S1(1, -c0 + 1, (c0 + c2 - 2) / 2); - for (int c1 = max(c0 + 2, -c0 + 4); c1 <= min(2 * n + c0, 2 * n - c0); c1 += 2) { + S1(1, -c0 + 1, ((c0 + c2) / 2) - 1); + for (int c1 = max(c0 + 2, -c0 + 4); c1 <= min(2 * n - c0, 2 * n + c0); c1 += 2) { for (int c2 = c1 + 2; c2 <= 2 * n + c1; c2 += 2) S1((c0 + c1) / 2, (-c0 + c1) / 2, (-c1 + c2) / 2); for (int c2 = 1; c2 <= n; c2 += 1) - S2((c0 + c1 - 2) / 2, (-c0 + c1) / 2, c2); + S2(((c0 + c1) / 2) - 1, (-c0 + c1) / 2, c2); } if (c0 >= 1) for (int c2 = 1; c2 <= n; c2 += 1) diff -Nru isl-0.12.2/test_inputs/codegen/cloog/darte.in isl-0.15/test_inputs/codegen/cloog/darte.in --- isl-0.12.2/test_inputs/codegen/cloog/darte.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/darte.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S2[i0, i1, i2] -> [1 + i0 - i1, 2 + i0 + i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= n and i2 >= 1 and i2 <= n; S1[i0, i1, i2] -> [i0 - i1, i0 + i1, i0 + i1 + 2i2] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= n and i2 >= 1 and i2 <= n } -[n] -> { : } -[n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/darte.st isl-0.15/test_inputs/codegen/cloog/darte.st --- isl-0.12.2/test_inputs/codegen/cloog/darte.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/darte.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= n and i2 >= 1 and i2 <= n; S2[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= n and i2 >= 1 and i2 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0, i1, i2] -> [(i0 - i1)]; S2[i0, i1, i2] -> [(1 + i0 - i1)] }, { S1[i0, i1, i2] -> [(i0 + i1)]; S2[i0, i1, i2] -> [(2 + i0 + i1)] }, { S1[i0, i1, i2] -> [(i0 + i1 + 2i2)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dealII.c isl-0.15/test_inputs/codegen/cloog/dealII.c --- isl-0.12.2/test_inputs/codegen/cloog/dealII.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dealII.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,12 +1,32 @@ { - for (int c0 = 0; c0 <= min(T_66, T_2 - 1); c0 += 1) { + if (T_67 == 0 && T_66 <= -1) { + S1(0); + } else if (T_2 >= 1 && T_67 >= 1 && T_66 <= -1) { + S1(0); + } else if (T_2 >= 1 && T_67 >= 1 && T_66 >= 0) { + S1(0); + S2(0); + } + for (int c0 = 1; c0 <= min(min(T_2 - 1, T_67 - 1), T_66); c0 += 1) { S1(c0); S2(c0); } - for (int c0 = T_2; c0 <= min(T_67 - 1, T_66); c0 += 1) + for (int c0 = max(1, T_66 + 1); c0 < min(T_2, T_67); c0 += 1) + S1(c0); + if (T_2 >= 1 && T_67 == 0 && T_66 >= 0) { + S1(0); + S2(0); + } + for (int c0 = max(1, T_67); c0 <= min(T_2 - 1, T_66); c0 += 1) { + S1(c0); S2(c0); - for (int c0 = max(0, T_66 + 1); c0 < T_2; c0 += 1) + } + for (int c0 = max(max(1, T_67), T_66 + 1); c0 < T_2; c0 += 1) S1(c0); - if (T_67 == 0 && T_2 == 0) + if (T_2 == 0 && T_67 >= 1 && T_66 >= 0) + S2(0); + for (int c0 = max(1, T_2); c0 <= min(T_67 - 1, T_66); c0 += 1) + S2(c0); + if (T_2 == 0 && T_67 == 0 && T_66 >= 0) S1(0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dealII.in isl-0.15/test_inputs/codegen/cloog/dealII.in --- isl-0.12.2/test_inputs/codegen/cloog/dealII.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dealII.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[T_2, T_67, T_66] -> { S1[scat_0] -> [scat_0, 0] : (scat_0 <= -1 + T_2 and scat_0 >= 0) or (scat_0 <= -T_67 and scat_0 >= 0); S2[scat_0] -> [scat_0, 1] : (scat_0 <= -1 + T_2 and scat_0 >= 0 and scat_0 <= T_66) or (scat_0 <= -1 + T_67 and scat_0 >= 0 and scat_0 <= T_66) } -[T_2, T_67, T_66] -> { : T_2 <= 4 and T_2 >= 0 and T_67 <= 4 and T_67 >= 0 } -[T_2, T_67, T_66] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dealII.st isl-0.15/test_inputs/codegen/cloog/dealII.st --- isl-0.12.2/test_inputs/codegen/cloog/dealII.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dealII.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[T_2, T_67, T_66] -> { S1[scat_0] : (scat_0 >= 0 and scat_0 <= -1 + T_2) or (scat_0 <= -T_67 and scat_0 >= 0); S2[scat_0] : (scat_0 >= 0 and scat_0 <= T_66 and scat_0 <= -1 + T_2) or (scat_0 >= 0 and scat_0 <= T_66 and scat_0 <= -1 + T_67) }" +child: + context: "[T_2, T_67, T_66] -> { [] : T_2 <= 4 and T_2 >= 0 and T_67 <= 4 and T_67 >= 0 }" + child: + schedule: "[T_2, T_67, T_66] -> [{ S2[scat_0] -> [(scat_0)]; S1[scat_0] -> [(scat_0)] }]" + options: "[T_2, T_67, T_66] -> { separate[i0] }" + child: + sequence: + - filter: "[T_2, T_67, T_66] -> { S1[scat_0] }" + - filter: "[T_2, T_67, T_66] -> { S2[scat_0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/donotsimp.c isl-0.15/test_inputs/codegen/cloog/donotsimp.c --- isl-0.12.2/test_inputs/codegen/cloog/donotsimp.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/donotsimp.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,6 @@ -for (int c1 = 1; c1 <= 10; c1 += 1) { - for (int c3 = 1; c3 <= c1; c3 += 1) - S1(c1, c3); - for (int c3 = 11; c3 <= M; c3 += 1) - S2(c1, c3); +for (int c0 = 1; c0 <= 10; c0 += 1) { + for (int c1 = 1; c1 <= c0; c1 += 1) + S1(c0, c1); + for (int c1 = 11; c1 <= M; c1 += 1) + S2(c0, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/donotsimp.in isl-0.15/test_inputs/codegen/cloog/donotsimp.in --- isl-0.12.2/test_inputs/codegen/cloog/donotsimp.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/donotsimp.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 1 and i0 <= 10 and i1 >= 11 and i1 <= M; S1[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 1 and i0 <= 10 and i1 >= 1 and i1 <= i0 } -[M] -> { : M >= 20 } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/donotsimp.st isl-0.15/test_inputs/codegen/cloog/donotsimp.st --- isl-0.12.2/test_inputs/codegen/cloog/donotsimp.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/donotsimp.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,9 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= 10 and i1 >= 1 and i1 <= i0; S2[i0, i1] : i0 >= 1 and i0 <= 10 and i1 >= 11 and i1 <= M }" +child: + context: "[M] -> { [] : M >= 20 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dot2.c isl-0.15/test_inputs/codegen/cloog/dot2.c --- isl-0.12.2/test_inputs/codegen/cloog/dot2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dot2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ { - for (int c0 = 1; c0 <= min(N, M); c0 += 1) { + for (int c0 = 1; c0 <= min(M, N); c0 += 1) { S1(c0); for (int c1 = 1; c1 <= M; c1 += 1) S2(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dot2.in isl-0.15/test_inputs/codegen/cloog/dot2.in --- isl-0.12.2/test_inputs/codegen/cloog/dot2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dot2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0, i1] -> [i0, i1, 1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S1[i0] -> [i0, 0, 0] : i0 >= 1 and i0 <= M } -[M, N] -> { : M >= 1 and N >= 1 } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dot2.st isl-0.15/test_inputs/codegen/cloog/dot2.st --- isl-0.12.2/test_inputs/codegen/cloog/dot2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dot2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0] : i0 >= 1 and i0 <= M; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dot.in isl-0.15/test_inputs/codegen/cloog/dot.in --- isl-0.12.2/test_inputs/codegen/cloog/dot.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dot.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[0, i1] -> [0, i1, 0] : i1 <= M and N >= 0 and i1 >= 1; S2[i0, i1] -> [i0, i1, 1] : i0 >= 1 and i1 <= M and i0 <= N and i1 >= 1 } -[M, N] -> { : M >= 1 and N >= 1 } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/dot.st isl-0.15/test_inputs/codegen/cloog/dot.st --- isl-0.12.2/test_inputs/codegen/cloog/dot.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/dot.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[0, i1] : i1 <= M and N >= 0 and i1 >= 1; S2[i0, i1] : i0 >= 1 and i1 <= M and i0 <= N and i1 >= 1 }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/durbin_e_s.in isl-0.15/test_inputs/codegen/cloog/durbin_e_s.in --- isl-0.12.2/test_inputs/codegen/cloog/durbin_e_s.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/durbin_e_s.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S5[i0, i1, 3] -> [i0, i1, 3, 4] : i1 <= -1 + i0 and i0 <= 10 and i1 >= 1; S8[i0, 0, 3] -> [i0, 0, 3, 7] : i0 >= 1 and i0 <= 9; S2[i0, -7, 0] -> [i0, -7, 0, 1] : i0 >= 2 and i0 <= 10; S3[i0, i1, 1] -> [i0, i1, 1, 2] : i1 >= -7 and i0 <= 10 and i1 <= -9 + i0; S1[10, i1, 4] -> [10, i1, 4, 0] : i1 >= 1 and i1 <= 10; S7[1, 0, 0] -> [1, 0, 0, 6]; S4[1, 0, 0] -> [1, 0, 0, 3]; S6[i0, -9 + i0, 2] -> [i0, -9 + i0, 2, 5] : i0 >= 2 and i0 <= 10 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/durbin_e_s.st isl-0.15/test_inputs/codegen/cloog/durbin_e_s.st --- isl-0.12.2/test_inputs/codegen/cloog/durbin_e_s.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/durbin_e_s.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,16 @@ +domain: "{ S2[i0, -7, 0] : i0 >= 2 and i0 <= 10; S4[1, 0, 0]; S6[i0, -9 + i0, 2] : i0 >= 2 and i0 <= 10; S1[10, i1, 4] : i1 >= 1 and i1 <= 10; S5[i0, i1, 3] : i1 <= -1 + i0 and i0 <= 10 and i1 >= 1; S7[1, 0, 0]; S8[i0, 0, 3] : i0 >= 1 and i0 <= 9; S3[i0, i1, 1] : i1 >= -7 and i0 <= 10 and i1 <= -9 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S6[i0, i1, i2] -> [(i0)]; S8[i0, i1, i2] -> [(i0)]; S5[i0, i1, i2] -> [(i0)]; S4[i0, i1, i2] -> [(i0)]; S7[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }, { S6[i0, i1, i2] -> [(i1)]; S8[i0, i1, i2] -> [(i1)]; S5[i0, i1, i2] -> [(i1)]; S4[i0, i1, i2] -> [(i1)]; S7[i0, i1, i2] -> [(i1)]; S3[i0, i1, i2] -> [(i1)]; S1[i0, i1, i2] -> [(i1)]; S2[i0, i1, i2] -> [(i1)] }, { S6[i0, i1, i2] -> [(i2)]; S8[i0, i1, i2] -> [(i2)]; S5[i0, i1, i2] -> [(i2)]; S4[i0, i1, i2] -> [(i2)]; S7[i0, i1, i2] -> [(i2)]; S3[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2] }" + - filter: "{ S2[i0, i1, i2] }" + - filter: "{ S3[i0, i1, i2] }" + - filter: "{ S4[i0, i1, i2] }" + - filter: "{ S5[i0, i1, i2] }" + - filter: "{ S6[i0, i1, i2] }" + - filter: "{ S7[i0, i1, i2] }" + - filter: "{ S8[i0, i1, i2] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/emploi.in isl-0.15/test_inputs/codegen/cloog/emploi.in --- isl-0.12.2/test_inputs/codegen/cloog/emploi.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/emploi.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m, n] -> { S1[i0] -> [i0, 0, 0] : (i0 >= 1 and i0 <= n and i0 <= 2m) or (i0 >= 1 and i0 <= n and i0 >= m); S2[i0, i1] -> [i0, i1, 1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= m } -[m, n] -> { : } -[m, n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/emploi.st isl-0.15/test_inputs/codegen/cloog/emploi.st --- isl-0.12.2/test_inputs/codegen/cloog/emploi.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/emploi.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[m, n] -> { S1[i0] : (i0 >= 1 and i0 <= n and i0 <= 2m) or (i0 >= m and i0 >= 1 and i0 <= n); S2[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= m }" +child: + context: "[m, n] -> { [] }" + child: + schedule: "[m, n] -> [{ S1[i0] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0] -> [(0)]; S2[i0, i1] -> [(i1)] }]" + options: "[m, n] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n] -> { S1[i0] }" + - filter: "[m, n] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/equality2.c isl-0.15/test_inputs/codegen/cloog/equality2.c --- isl-0.12.2/test_inputs/codegen/cloog/equality2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/equality2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,8 +1,8 @@ for (int c0 = 1; c0 <= 10000; c0 += 1) for (int c1 = 1000; c1 <= 1016; c1 += 1) for (int c2 = 1; c2 < 2 * c1 - 1998; c2 += 1) { - if (c2 + 1999 == 2 * c1 && c1 <= 1008) + if (c1 <= 1008 && c2 + 1999 == 2 * c1) S2(c0, c1, 2 * c1 - 1999, 1, c0, 2 * c1 - 1000, 1, 2, c0, c1 - 499, 2 * c1 - 1999, c0, 2 * c1 - 1999, c1 - 999, c1 - 999); - if (c1 % 2 == 0 && c2 == 1) - S1(c0, c1, 1, 2, c0, (c1 + 2) / 2, c1 - 999, c0, c1 - 999, (c1 - 998) / 2, (c1 - 998) / 2); + if (c2 == 1 && c1 % 2 == 0) + S1(c0, c1, 1, 2, c0, (c1 / 2) + 1, c1 - 999, c0, c1 - 999, (c1 / 2) - 499, (c1 / 2) - 499); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/equality2.in isl-0.15/test_inputs/codegen/cloog/equality2.in --- isl-0.12.2/test_inputs/codegen/cloog/equality2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/equality2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1, 1, 2, i0, i5, -999 + i1, i0, -999 + i1, i9, i10] -> [i0, i1, 1, 2, i0, n, -999 + i1, i0, -999 + i1, r, s, 0, 0, 0, 0, 0] : 2s = -998 + i1 and 2n = 2 + i1 and 2i10 = -998 + i1 and 2i5 = 2 + i1 and 2i9 = -998 + i1 and 2r = -998 + i1 and i0 >= 1 and i0 <= 10000 and i1 >= 1000 and i1 <= 1016; S2[i0, i1, -1999 + 2i1, 1, i0, -1000 + 2i1, 1, 2, i0, -499 + i1, -1999 + 2i1, i0, -1999 + 2i1, -999 + i1, -999 + i1] -> [i0, i1, -1999 + 2i1, 1, i0, -1000 + 2i1, 1, 2, i0, -499 + i1, -1999 + 2i1, i0, -1999 + 2i1, -999 + i1, -999 + i1, 1] : i0 >= 1 and i0 <= 10000 and i1 >= 1000 and i1 <= 1008 } -{ : } -{ [i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x] -> atomic[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/equality2.st isl-0.15/test_inputs/codegen/cloog/equality2.st --- isl-0.12.2/test_inputs/codegen/cloog/equality2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/equality2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S1[i0, i1, 1, 2, i0, i5, -999 + i1, i0, -999 + i1, i9, i10] : 2i5 = 2 + i1 and 2i9 = -998 + i1 and 2i10 = -998 + i1 and i0 >= 1 and i0 <= 10000 and i1 >= 1000 and i1 <= 1016; S2[i0, i1, -1999 + 2i1, 1, i0, -1000 + 2i1, 1, 2, i0, -499 + i1, -1999 + 2i1, i0, -1999 + 2i1, -999 + i1, -999 + i1] : i0 >= 1 and i0 <= 10000 and i1 >= 1000 and i1 <= 1008 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i0)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i1)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i1)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i2)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i2)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i3)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i3)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i4)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i4)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i5)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i5)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i6)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i6)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i7)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i7)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i8)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i8)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i9)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i9)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(i10)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i10)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i11)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i12)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i13)] }, { S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] -> [(0)]; S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] -> [(i14)] }]" + options: "{ atomic[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10] }" + - filter: "{ S2[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/equality.in isl-0.15/test_inputs/codegen/cloog/equality.in --- isl-0.12.2/test_inputs/codegen/cloog/equality.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/equality.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, 2i0] -> [i0, 2i0, 0] : i0 >= 0 and i0 <= 5; S2[i0, 4] -> [i0, 4, 1] : i0 >= 0 and i0 <= 5 } -{ : } -{ [i, j, k] -> atomic[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/equality.st isl-0.15/test_inputs/codegen/cloog/equality.st --- isl-0.12.2/test_inputs/codegen/cloog/equality.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/equality.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S2[i0, 4] : i0 >= 0 and i0 <= 5; S1[i0, 2i0] : i0 >= 0 and i0 <= 5 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ atomic[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/esced.in isl-0.15/test_inputs/codegen/cloog/esced.in --- isl-0.12.2/test_inputs/codegen/cloog/esced.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/esced.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n, m] -> { S1[i0] -> [i0, 0, 0] : i0 >= 1 and i0 <= m; S2[i0, i1] -> [i0, i1, 1] : i0 >= 1 and i0 <= m and i1 >= 1 and i1 <= n } -[n, m] -> { : } -[n, m] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/esced.st isl-0.15/test_inputs/codegen/cloog/esced.st --- isl-0.12.2/test_inputs/codegen/cloog/esced.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/esced.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[n, m] -> { S1[i0] : i0 >= 1 and i0 <= m; S2[i0, i1] : i0 >= 1 and i0 <= m and i1 >= 1 and i1 <= n }" +child: + context: "[n, m] -> { [] }" + child: + schedule: "[n, m] -> [{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "[n, m] -> { separate[i0] }" + child: + sequence: + - filter: "[n, m] -> { S1[i0] }" + - filter: "[n, m] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/ex1.in isl-0.15/test_inputs/codegen/cloog/ex1.in --- isl-0.12.2/test_inputs/codegen/cloog/ex1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/ex1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S2[i0, i1] -> [i0, i1, 1] : i0 >= 15 and i0 <= n and i1 >= 10 and i1 <= n; S1[i0, i1] -> [i0, i1, 0] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= -15 + n } -[n] -> { : n >= 25 } -[n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/ex1.st isl-0.15/test_inputs/codegen/cloog/ex1.st --- isl-0.12.2/test_inputs/codegen/cloog/ex1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/ex1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= -15 + n; S2[i0, i1] : i0 >= 15 and i0 <= n and i1 >= 10 and i1 <= n }" +child: + context: "[n] -> { [] : n >= 25 }" + child: + schedule: "[n] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1] }" + - filter: "[n] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/faber.c isl-0.15/test_inputs/codegen/cloog/faber.c --- isl-0.12.2/test_inputs/codegen/cloog/faber.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/faber.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,156 @@ +{ + for (int c0 = 0; c0 <= 36; c0 += 1) { + for (int c1 = -6; c1 < c0 / 14 - 5; c1 += 1) { + for (int c2 = -((-2 * c1 + 3) / 5) + 9; c2 <= c1 + 12; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 + 24; c2 <= -2 * c1 + 24; c2 += 1) + S2(c0, c1, c2); + for (int c2 = -2 * c1 + 30; c2 <= c1 + 48; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = c0 / 14 - 5; c1 < 0; c1 += 1) { + if (c1 >= -3 && 2 * c0 >= 7 * c1 + 42) + S7(c0, c1, 6); + for (int c2 = max(c1 - (6 * c0 + 77) / 77 + 13, -((-2 * c1 + 3) / 5) + 9); c2 <= c1 + 12; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 + 48; c2 += 1) + S1(c0, c1, c2); + } + S3(c0, 0, 0); + S10(c0, 0, 0); + for (int c2 = 1; c2 <= 5; c2 += 1) + S3(c0, 0, c2); + for (int c2 = 6; c2 <= 2 * c0 / 21 + 4; c2 += 1) { + S3(c0, 0, c2); + S7(c0, 0, c2); + } + for (int c2 = max(6, 2 * c0 / 21 + 5); c2 <= -((6 * c0 + 77) / 77) + 12; c2 += 1) + S3(c0, 0, c2); + for (int c2 = -((6 * c0 + 77) / 77) + 13; c2 <= 12; c2 += 1) { + S3(c0, 0, c2); + S6(c0, 0, c2); + } + for (int c2 = 13; c2 <= 24; c2 += 1) + S3(c0, 0, c2); + for (int c2 = -((3 * c0 + 14) / 14) + 49; c2 <= 48; c2 += 1) + S1(c0, 0, c2); + for (int c1 = 1; c1 <= 18; c1 += 1) { + for (int c2 = -8 * c1; c2 <= min(6, -8 * c1 + 24); c2 += 1) + S3(c0, c1, c2); + if (c0 <= 34 && c1 == 1) { + S3(c0, 1, 7); + } else if (c1 == 2) { + S3(c0, 2, 7); + } else if (c0 >= 35 && c1 == 1) { + S3(c0, 1, 7); + S7(c0, 1, 7); + } + for (int c2 = 8; c2 <= min(-8 * c1 + 24, c1 - (6 * c0 + 77) / 77 + 12); c2 += 1) + S3(c0, c1, c2); + if (c1 == 1) { + for (int c2 = -((6 * c0 + 77) / 77) + 14; c2 <= 13; c2 += 1) { + S3(c0, 1, c2); + S6(c0, 1, c2); + } + for (int c2 = 14; c2 <= 16; c2 += 1) + S3(c0, 1, c2); + } + for (int c2 = max(-8 * c1 + 25, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 + 12; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 + 48; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = 19; c1 <= 24; c1 += 1) { + for (int c2 = -8 * c1; c2 <= -8 * c1 + 24; c2 += 1) + S3(c0, c1, c2); + for (int c2 = c1 - (6 * c0 + 77) / 77 + 13; c2 <= 30; c2 += 1) + S6(c0, c1, c2); + } + } + for (int c0 = 37; c0 <= 218; c0 += 1) { + for (int c1 = (c0 + 5) / 14 - 8; c1 < min(0, c0 / 14 - 5); c1 += 1) { + if (c0 <= 46 && c1 == -3) + S7(c0, -3, 6); + if (-77 * ((-3 * c1 + 1) / 5) + 447 >= 6 * c0) + S6(c0, c1, -((-2 * c1 + 3) / 5) + 9); + for (int c2 = c1 + 24; c2 <= -2 * c1 + 24; c2 += 1) + S2(c0, c1, c2); + for (int c2 = -2 * c1 + 30; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + if (c0 <= 148) + for (int c1 = max(0, (c0 + 5) / 14 - 8); c1 < c0 / 14 - 5; c1 += 1) { + if (c1 == 0) + S2(c0, 0, 24); + for (int c2 = max(c1 + 24, -2 * c1 + 30); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + if (c0 >= 79 && c0 % 14 >= 9) { + for (int c2 = max((c0 - 70) / 14 + 24, (c0 - 70) / 14 - (3 * c0 + 14) / 14 + 49); c2 <= (c0 - 70) / 14 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c0 / 14 - 5, c2); + } else if (c0 <= 69 && c0 % 14 >= 9) { + if (c0 <= 41) + S7(c0, -3, 6); + S6(c0, c0 / 14 - 5, 8); + for (int c2 = -((-c0 + 83) / 14) - (3 * c0 + 14) / 14 + 49; c2 <= -((-c0 + 83) / 14) - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c0 / 14 - 5, c2); + } + for (int c1 = (c0 + 5) / 14 - 5; c1 < 0; c1 += 1) { + if (7 * c1 + 114 >= 2 * c0) + S7(c0, c1, 6); + for (int c2 = max(8, c1 - (6 * c0 + 77) / 77 + 13); c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1) + S6(c0, c1, c2); + for (int c2 = c1 - (3 * c0 + 14) / 14 + 49; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = max(0, (c0 + 5) / 14 - 5); c1 < c0 / 14 - 2; c1 += 1) { + for (int c2 = max(c1, -2 * c1 + 6); c2 <= min(min(-2 * c1 + 24, c1 - (6 * c0 + 91) / 77 + 15), (2 * c0 - 7 * c1 - 10) / 21 + 1); c2 += 1) + S9(c0, c1, c2); + if (c1 >= 1 && c1 <= 5 && 14 * c1 + 46 >= c0) + S9(c0, c1, c1 + 5); + for (int c2 = max(c1 + 6, (2 * c0 - 7 * c1 - 10) / 21 + 2); c2 <= (2 * c1 + 1) / 5 + 7; c2 += 1) { + S7(c0, c1, c2); + S9(c0, c1, c2); + } + if (c1 <= 3 && 7 * c1 + 21 * ((2 * c1 + 41) / 5) >= 2 * c0 + 12) + S9(c0, c1, (2 * c1 + 1) / 5 + 8); + for (int c2 = (2 * c1 + 1) / 5 + 9; c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1) { + S6(c0, c1, c2); + S9(c0, c1, c2); + } + for (int c2 = c1 - (6 * c0 + 91) / 77 + 16; c2 <= -2 * c1 + 24; c2 += 1) + S9(c0, c1, c2); + for (int c2 = max(c1, -2 * c1 + 30); c2 <= min(c1 + 24, c1 - (3 * c0 + 17) / 14 + 47); c2 += 1) + S8(c0, c1, c2); + for (int c2 = max(c1 + 24, c1 - (3 * c0 + 14) / 14 + 49); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = c0 / 14 - 2; c1 <= 18; c1 += 1) { + for (int c2 = max(6, (c0 + 5) / 14 + 1); c2 <= min(min(c1, c0 / 14 + 3), -c1 + c1 / 2 + 18); c2 += 1) + S5(c0, c1, c2); + for (int c2 = c1 + 6; c2 <= min((2 * c1 + 1) / 5 + 7, (2 * c0 - 7 * c1 + 63) / 21 + 1); c2 += 1) + S7(c0, c1, c2); + for (int c2 = max(max(c1 + 6, c1 - (6 * c0 + 77) / 77 + 13), (2 * c1 + 1) / 5 + 9); c2 <= c1 - (6 * c0 + 91) / 77 + 15; c2 += 1) + S6(c0, c1, c2); + for (int c2 = max(c1 + (3 * c0 + 3) / 14 - 40, -c1 + (c1 + 1) / 2 + 21); c2 <= min(c1, c1 + 3 * c0 / 14 - 33); c2 += 1) + S4(c0, c1, c2); + for (int c2 = max(c1, c1 - (3 * c0 + 14) / 14 + 40); c2 <= min(c1 + 24, c1 - (3 * c0 + 17) / 14 + 47); c2 += 1) + S8(c0, c1, c2); + for (int c2 = max(c1 + 24, c1 - (3 * c0 + 14) / 14 + 49); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1) + S1(c0, c1, c2); + } + for (int c1 = 19; c1 <= 24; c1 += 1) { + for (int c2 = max(c1 - 12, (c0 + 5) / 14 + 1); c2 <= min(c0 / 14 + 3, -c1 + c1 / 2 + 18); c2 += 1) + S5(c0, c1, c2); + for (int c2 = max(max(c1 - 12, c1 + (3 * c0 + 3) / 14 - 40), -c1 + (c1 + 1) / 2 + 21); c2 <= min(c1, c1 + 3 * c0 / 14 - 33); c2 += 1) + S4(c0, c1, c2); + for (int c2 = max(c1 + 6, c1 - (6 * c0 + 77) / 77 + 13); c2 <= min(30, c1 - (6 * c0 + 91) / 77 + 15); c2 += 1) + S6(c0, c1, c2); + for (int c2 = max(c1, c1 - (3 * c0 + 14) / 14 + 40); c2 <= min(c1 + 24, c1 - (3 * c0 + 17) / 14 + 47); c2 += 1) + S8(c0, c1, c2); + } + for (int c1 = 25; c1 <= min(42, -((3 * c0 + 17) / 14) + 71); c1 += 1) + for (int c2 = max(c1 - 12, c1 + (3 * c0 + 3) / 14 - 40); c2 <= min(min(30, c1), c1 + 3 * c0 / 14 - 33); c2 += 1) + S4(c0, c1, c2); + } +} diff -Nru isl-0.12.2/test_inputs/codegen/cloog/faber.st isl-0.15/test_inputs/codegen/cloog/faber.st --- isl-0.12.2/test_inputs/codegen/cloog/faber.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/faber.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,18 @@ +domain: "{ S2[idx4, idx5, idx6] : 14idx5 <= -84 + idx4 and 14idx5 >= -120 + idx4 and idx6 >= 24 + idx5 and idx6 <= 48 + idx5 and idx5 >= -6 and idx5 <= 18 and idx6 <= 24 - 2idx5; S4[idx4, idx5, idx6] : 14idx6 <= -462 + 3idx4 + 14idx5 and 14idx6 >= -570 + 3idx4 + 14idx5 and idx6 <= idx5 and idx6 >= -12 + idx5 and idx6 >= 6 and idx6 <= 30 and 2idx6 >= 42 - idx5; S6[idx4, idx5, idx6] : 77idx6 >= 924 - 6idx4 + 77idx5 and 77idx6 <= 1140 - 6idx4 + 77idx5 and idx6 <= 12 + idx5 and idx6 >= 6 + idx5 and idx6 >= 6 and idx6 <= 30 and 5idx6 >= 42 + 2idx5; S1[idx4, idx5, idx6] : 14idx6 >= 672 - 3idx4 + 14idx5 and 14idx6 <= 780 - 3idx4 + 14idx5 and idx6 >= 24 + idx5 and idx6 <= 48 + idx5 and idx5 >= -6 and idx5 <= 18 and idx6 >= 30 - 2idx5; S5[idx4, idx5, idx6] : 14idx6 <= 42 + idx4 and 14idx6 >= 6 + idx4 and idx6 <= idx5 and idx6 >= -12 + idx5 and idx6 >= 6 and idx6 <= 30 and 2idx6 <= 36 - idx5; S7[idx4, idx5, idx6] : 21idx6 <= 84 + 2idx4 - 7idx5 and 21idx6 >= 12 + 2idx4 - 7idx5 and idx6 <= 12 + idx5 and idx6 >= 6 + idx5 and idx6 >= 6 and idx6 <= 30 and 5idx6 <= 36 + 2idx5; S8[idx4, idx5, idx6] : 14idx6 >= 546 - 3idx4 + 14idx5 and 14idx6 <= 654 - 3idx4 + 14idx5 and idx6 >= idx5 and idx6 <= 24 + idx5 and idx5 >= 0 and idx5 <= 24 and idx6 >= 30 - 2idx5; S3[idx4, idx5, idx6] : idx4 >= 0 and idx4 <= 36 and idx6 >= -8idx5 and idx6 <= 24 - 8idx5 and idx5 >= 0 and idx5 <= 24; S9[idx4, idx5, idx6] : 14idx5 <= -42 + idx4 and 14idx5 >= -78 + idx4 and idx6 >= idx5 and idx6 <= 24 + idx5 and idx5 >= 0 and idx5 <= 24 and idx6 <= 24 - 2idx5 and idx6 >= 6 - 2idx5; S10[idx4, idx5, idx6] : 7idx6 <= idx4 - 28idx5 and 7idx6 >= -36 + idx4 - 28idx5 and idx6 >= idx5 and idx6 <= 24 + idx5 and idx5 >= 0 and idx5 <= 24 and idx6 <= -2idx5 }" +child: + context: "{ [] }" + child: + schedule: "[{ S6[idx4, idx5, idx6] -> [(idx4)]; S8[idx4, idx5, idx6] -> [(idx4)]; S5[idx4, idx5, idx6] -> [(idx4)]; S9[idx4, idx5, idx6] -> [(idx4)]; S4[idx4, idx5, idx6] -> [(idx4)]; S10[idx4, idx5, idx6] -> [(idx4)]; S7[idx4, idx5, idx6] -> [(idx4)]; S3[idx4, idx5, idx6] -> [(idx4)]; S1[idx4, idx5, idx6] -> [(idx4)]; S2[idx4, idx5, idx6] -> [(idx4)] }, { S6[idx4, idx5, idx6] -> [(idx5)]; S8[idx4, idx5, idx6] -> [(idx5)]; S5[idx4, idx5, idx6] -> [(idx5)]; S9[idx4, idx5, idx6] -> [(idx5)]; S4[idx4, idx5, idx6] -> [(idx5)]; S10[idx4, idx5, idx6] -> [(idx5)]; S7[idx4, idx5, idx6] -> [(idx5)]; S3[idx4, idx5, idx6] -> [(idx5)]; S1[idx4, idx5, idx6] -> [(idx5)]; S2[idx4, idx5, idx6] -> [(idx5)] }, { S6[idx4, idx5, idx6] -> [(idx6)]; S8[idx4, idx5, idx6] -> [(idx6)]; S5[idx4, idx5, idx6] -> [(idx6)]; S9[idx4, idx5, idx6] -> [(idx6)]; S4[idx4, idx5, idx6] -> [(idx6)]; S10[idx4, idx5, idx6] -> [(idx6)]; S7[idx4, idx5, idx6] -> [(idx6)]; S3[idx4, idx5, idx6] -> [(idx6)]; S1[idx4, idx5, idx6] -> [(idx6)]; S2[idx4, idx5, idx6] -> [(idx6)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[idx4, idx5, idx6] }" + - filter: "{ S2[idx4, idx5, idx6] }" + - filter: "{ S3[idx4, idx5, idx6] }" + - filter: "{ S4[idx4, idx5, idx6] }" + - filter: "{ S5[idx4, idx5, idx6] }" + - filter: "{ S6[idx4, idx5, idx6] }" + - filter: "{ S7[idx4, idx5, idx6] }" + - filter: "{ S8[idx4, idx5, idx6] }" + - filter: "{ S9[idx4, idx5, idx6] }" + - filter: "{ S10[idx4, idx5, idx6] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/forwardsub-1-1-2.in isl-0.15/test_inputs/codegen/cloog/forwardsub-1-1-2.in --- isl-0.12.2/test_inputs/codegen/cloog/forwardsub-1-1-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/forwardsub-1-1-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [i0, i1, 1] : i1 <= -1 + i0 and i1 >= 2 and i0 <= M; S4[i0, i0] -> [i0, i0, 3] : M >= 3 and i0 <= M and i0 >= 2; S1[i0, 1] -> [i0, 1, 0] : M >= 3 and i0 <= M and i0 >= 2; S3[1, 1] -> [1, 1, 2] : M >= 3 } -[M] -> { : M >= 3 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/forwardsub-1-1-2.st isl-0.15/test_inputs/codegen/cloog/forwardsub-1-1-2.st --- isl-0.12.2/test_inputs/codegen/cloog/forwardsub-1-1-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/forwardsub-1-1-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,12 @@ +domain: "[M] -> { S4[i0, i0] : M >= 3 and i0 <= M and i0 >= 2; S1[i0, 1] : M >= 3 and i0 <= M and i0 >= 2; S3[1, 1] : M >= 3; S2[i0, i1] : i1 <= -1 + i0 and i1 >= 2 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 3 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" + - filter: "[M] -> { S3[i0, i1] }" + - filter: "[M] -> { S4[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/forwardsub-2-1-2-3.in isl-0.15/test_inputs/codegen/cloog/forwardsub-2-1-2-3.in --- isl-0.12.2/test_inputs/codegen/cloog/forwardsub-2-1-2-3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/forwardsub-2-1-2-3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[1, 1, i2] -> [1, 1, i2, 0] : M >= 3 and i2 <= M and i2 >= 2; S2[i0, 1, i2] -> [i0, 1, i2, 1] : i2 >= 1 + i0 and i0 >= 2 and i2 <= M; S4[i0, 0] -> [i0, 0, 0, 3] : i0 >= 2 and M >= 3 and i0 <= M; S3[1, 0] -> [1, 0, 0, 2] : M >= 3 } -[M] -> { : M >= 3 } -[M] -> { [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st isl-0.15/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st --- isl-0.12.2/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/forwardsub-2-1-2-3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,12 @@ +domain: "[M] -> { S4[i0, 0] : i0 >= 2 and M >= 3 and i0 <= M; S3[1, 0] : M >= 3; S2[i0, 1, i2] : i2 >= 1 + i0 and i0 >= 2 and i2 <= M; S1[1, 1, i2] : M >= 3 and i2 <= M and i2 >= 2 }" +child: + context: "[M] -> { [] : M >= 3 }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0)]; S4[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)]; S4[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)]; S4[i0, i1] -> [(0)]; S3[i0, i1] -> [(0)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + - filter: "[M] -> { S2[i0, i1, i2] }" + - filter: "[M] -> { S3[i0, i1] }" + - filter: "[M] -> { S4[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/forwardsub-3-1-2.in isl-0.15/test_inputs/codegen/cloog/forwardsub-3-1-2.in --- isl-0.12.2/test_inputs/codegen/cloog/forwardsub-3-1-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/forwardsub-3-1-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [i0, i1, 1] : 2i1 <= -1 + i0 and i1 >= 2 and i1 >= -M + i0; S4[i0, i1] -> [i0, j, 3] : 2j = i0 and 2i1 = i0 and M >= 3 and i0 <= 2M and i0 >= 4; S1[i0, 1] -> [i0, 1, 0] : M >= 3 and i0 <= 1 + M and i0 >= 3; S3[2, 1] -> [2, 1, 2] : M >= 3 } -[M] -> { : M >= 3 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/forwardsub-3-1-2.st isl-0.15/test_inputs/codegen/cloog/forwardsub-3-1-2.st --- isl-0.12.2/test_inputs/codegen/cloog/forwardsub-3-1-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/forwardsub-3-1-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,12 @@ +domain: "[M] -> { S4[i0, i1] : 2i1 = i0 and M >= 3 and i0 <= 2M and i0 >= 4; S1[i0, 1] : M >= 3 and i0 <= 1 + M and i0 >= 3; S3[2, 1] : M >= 3; S2[i0, i1] : 2i1 <= -1 + i0 and i1 >= 2 and i1 >= -M + i0 }" +child: + context: "[M] -> { [] : M >= 3 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" + - filter: "[M] -> { S3[i0, i1] }" + - filter: "[M] -> { S4[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gauss.c isl-0.15/test_inputs/codegen/cloog/gauss.c --- isl-0.12.2/test_inputs/codegen/cloog/gauss.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gauss.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,7 +1,7 @@ for (int c0 = 1; c0 < M; c0 += 1) for (int c1 = c0 + 1; c1 <= M; c1 += 1) { - for (int c3 = c0 + 1; c3 <= M; c3 += 1) - S2(c0, c3, c1); for (int c3 = 1; c3 < c0; c3 += 1) S1(c0, c3, c1); + for (int c3 = c0 + 1; c3 <= M; c3 += 1) + S2(c0, c3, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gauss.in isl-0.15/test_inputs/codegen/cloog/gauss.in --- isl-0.12.2/test_inputs/codegen/cloog/gauss.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gauss.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2] -> [i0, i2] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M; S2[i0, i1, i2] -> [i0, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 + i0 and i2 <= M } -[M] -> { : } -[M] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gauss.st isl-0.15/test_inputs/codegen/cloog/gauss.st --- isl-0.12.2/test_inputs/codegen/cloog/gauss.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gauss.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 + i0 and i2 <= M; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i2)]; S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gesced2.in isl-0.15/test_inputs/codegen/cloog/gesced2.in --- isl-0.12.2/test_inputs/codegen/cloog/gesced2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gesced2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [i0, i1] : i0 >= 1 and i0 <= M and i1 >= 5 and i1 <= -10 + M; S2[i0, i1] -> [i1, i0 - i1] : i0 >= 1 and i0 <= M and i1 >= 5 and i1 <= -10 + M } -[M] -> { : M >= 16 } -[M] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gesced2.st isl-0.15/test_inputs/codegen/cloog/gesced2.st --- isl-0.12.2/test_inputs/codegen/cloog/gesced2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gesced2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 5 and i1 <= -10 + M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 5 and i1 <= -10 + M }" +child: + context: "[M] -> { [] : M >= 16 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i1)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i0 - i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gesced3.in isl-0.15/test_inputs/codegen/cloog/gesced3.in --- isl-0.12.2/test_inputs/codegen/cloog/gesced3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gesced3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0] -> [2M + i0] : i0 >= 1 and i0 <= N; S1[i0] -> [M + i0] : i0 >= 1 and i0 <= N } -[M, N] -> { : N >= M and M >= 2 } -[M, N] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gesced3.st isl-0.15/test_inputs/codegen/cloog/gesced3.st --- isl-0.12.2/test_inputs/codegen/cloog/gesced3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gesced3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0] : i0 >= 1 and i0 <= N; S2[i0] : i0 >= 1 and i0 <= N }" +child: + context: "[M, N] -> { [] : N >= M and M >= 2 }" + child: + schedule: "[M, N] -> [{ S2[i0] -> [(2M + i0)]; S1[i0] -> [(M + i0)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gesced.in isl-0.15/test_inputs/codegen/cloog/gesced.in --- isl-0.12.2/test_inputs/codegen/cloog/gesced.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gesced.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S3[i0, i1] -> [2N + i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S2[i0, i1] -> [N + i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S1[i0] -> [i0] : i0 >= 1 and i0 <= N } -[M, N] -> { : N <= M and M >= 2 and N >= 2 } -[M, N] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/gesced.st isl-0.15/test_inputs/codegen/cloog/gesced.st --- isl-0.12.2/test_inputs/codegen/cloog/gesced.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/gesced.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S3[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S1[i0] : i0 >= 1 and i0 <= N; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] : N <= M and M >= 2 and N >= 2 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(N + i1)]; S3[i0, i1] -> [(2N + i1)]; S1[i0] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/guide.in isl-0.15/test_inputs/codegen/cloog/guide.in --- isl-0.12.2/test_inputs/codegen/cloog/guide.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/guide.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0] -> [i0, 0] : (i0 >= 1 and i0 <= N and i0 <= 2M) or (i0 >= 1 and i0 <= N and i0 >= M); S2[i0] -> [i0, 1] : i0 >= 1 + N and i0 <= 2N } -[M, N] -> { : } -[M, N] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/guide.st isl-0.15/test_inputs/codegen/cloog/guide.st --- isl-0.12.2/test_inputs/codegen/cloog/guide.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/guide.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0] : (i0 >= 1 and i0 <= N and i0 <= 2M) or (i0 >= M and i0 >= 1 and i0 <= N); S2[i0] : i0 >= 1 + N and i0 <= 2N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S2[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/iftest2.in isl-0.15/test_inputs/codegen/cloog/iftest2.in --- isl-0.12.2/test_inputs/codegen/cloog/iftest2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/iftest2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1] -> [i0, i1, 0] : (i0 >= 1 and i0 <= N and i0 >= M and i1 >= 1 and i1 <= M) or (i0 >= 1 and i0 <= N and i0 <= 2M and i1 >= 1 and i1 <= M) } -[M, N] -> { : } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/iftest2.st isl-0.15/test_inputs/codegen/cloog/iftest2.st --- isl-0.12.2/test_inputs/codegen/cloog/iftest2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/iftest2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0, i1] : (i0 >= M and i0 <= N and i1 >= 1 and i1 <= M) or (i0 >= 1 and i0 <= N and i0 <= 2M and i1 >= 1 and i1 <= M) }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/iftest.in isl-0.15/test_inputs/codegen/cloog/iftest.in --- isl-0.12.2/test_inputs/codegen/cloog/iftest.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/iftest.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m, n] -> { S1[i0] -> [i0, 0] : (i0 >= 1 and i0 <= n and i0 >= m) or (i0 >= 1 and i0 <= n and i0 <= 2m) } -[m, n] -> { : } -[m, n] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/iftest.st isl-0.15/test_inputs/codegen/cloog/iftest.st --- isl-0.12.2/test_inputs/codegen/cloog/iftest.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/iftest.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[m, n] -> { S1[i0] : (i0 >= m and i0 >= 1 and i0 <= n) or (i0 >= 1 and i0 <= n and i0 <= 2m) }" +child: + context: "[m, n] -> { [] }" + child: + schedule: "[m, n] -> [{ S1[i0] -> [(i0)] }]" + options: "[m, n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/infinite2.in isl-0.15/test_inputs/codegen/cloog/infinite2.in --- isl-0.12.2/test_inputs/codegen/cloog/infinite2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/infinite2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0, i1] -> [i0, i1, 1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S1[i0] -> [i0, 0, 0] : i0 >= 1 } -[M, N] -> { : M >= 1 and N >= 1 } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/infinite2.st isl-0.15/test_inputs/codegen/cloog/infinite2.st --- isl-0.12.2/test_inputs/codegen/cloog/infinite2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/infinite2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0] : i0 >= 1; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/jacobi-shared.c isl-0.15/test_inputs/codegen/cloog/jacobi-shared.c --- isl-0.12.2/test_inputs/codegen/cloog/jacobi-shared.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/jacobi-shared.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,3 @@ -if (2 * floord(h0 - 1, 2) + 1 == h0 && g2 + 29 >= (g2 - t1 + 32) % 32 && ((g2 - t1 + 32) % 32) + N >= g2 + 33) - for (int c0 = max(((g1 + t0 + 13) % 16) - g1 + 3, ((t0 + 15) % 16) + 1); c0 <= min(32, N - g1 - 1); c0 += 16) +if (((t1 + 31) % 32) + g2 >= 2 && N >= ((t1 + 31) % 32) + g2 + 2 && (h0 - 1) % 2 == 0) + for (int c0 = max(((t0 + 15) % 16) + 1, ((g1 + t0 + 13) % 16) - g1 + 3); c0 <= min(32, N - g1 - 1); c0 += 16) S1(g1 + c0 - 1, ((t1 + 31) % 32) + g2); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/jacobi-shared.in isl-0.15/test_inputs/codegen/cloog/jacobi-shared.in --- isl-0.12.2/test_inputs/codegen/cloog/jacobi-shared.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/jacobi-shared.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { S1[i0, i1] -> [1 - g1 + i0, 1 - g2 + i1, t0, t1] : exists (e0 = [(-1 + h0)/2], e1 = [(-2016b0 - g1)/2048], e2 = [(-992b1 - g2)/1024], e3 = [(-1 + t0 - i0)/16], e4 = [(-1 + t1 - i1)/32]: g0 = h0 and 2e0 = -1 + h0 and 2048e1 = -2016b0 - g1 and 1024e2 = -992b1 - g2 and 16e3 = -1 + t0 - i0 and 32e4 = -1 + t1 - i1 and h0 >= 1 and h0 <= -1 + 2T and i0 >= 2 and i0 <= -2 + N and i1 >= 2 and i1 <= -2 + N and b1 <= 31 and b1 >= 0 and b0 <= 63 and b0 >= 0 and i1 <= 31 + g2 and i1 >= g2 and N >= 4 and i0 >= g1 and i0 <= 31 + g1 and g2 <= -2 + N and g2 >= -29 and g1 <= -2 + N and g1 >= -29 and g1 >= 32b0 and g2 >= 32b1 and 32b0 <= -2 + N and 32b1 <= -2 + N and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 31) } -[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { : exists (e0 = [(-32b0 + g1)/2048], e1 = [(-32b1 + g2)/1024]: g0 = h0 and 2048e0 = -32b0 + g1 and 1024e1 = -32b1 + g2 and g2 <= -2 + N and g2 >= -29 and g1 <= -2 + N and g1 >= -29 and b1 >= 0 and b1 <= 31 and b0 <= 63 and 32b1 <= -2 + N and 32b0 <= -2 + N and b0 >= 0 and N >= 4 and h0 >= 0 and h0 <= -1 + 2T and g2 >= 32b1 and g1 >= 32b0 and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 31) } -[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { [i, j, k, l] -> separate[x] : x >= 3 } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/jacobi-shared.st isl-0.15/test_inputs/codegen/cloog/jacobi-shared.st --- isl-0.12.2/test_inputs/codegen/cloog/jacobi-shared.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/jacobi-shared.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { S1[i0, i1] : exists (e0 = floor((-1 + h0)/2), e1 = floor((-32b0 + g1)/2048), e2 = floor((-32b1 + g2)/1024), e3 = floor((-15 - t0 + i0)/16), e4 = floor((-31 - t1 + i1)/32): g0 = h0 and 2e0 = -1 + h0 and 2048e1 = -32b0 + g1 and 1024e2 = -32b1 + g2 and 16e3 = -15 - t0 + i0 and 32e4 = -31 - t1 + i1 and h0 >= 1 and h0 <= -1 + 2T and i0 >= 2 and i0 <= -2 + N and i1 >= 2 and i1 <= -2 + N and b1 <= 31 and b1 >= 0 and b0 <= 63 and b0 >= 0 and i1 <= 31 + g2 and i1 >= g2 and N >= 4 and i0 >= g1 and i0 <= 31 + g1 and g2 <= -2 + N and g2 >= -29 and g1 <= -2 + N and g1 >= -29 and g1 >= 32b0 and g2 >= 32b1 and 32b0 <= -2 + N and 32b1 <= -2 + N and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 31) }" +child: + context: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { [] : exists (e0 = floor((-32b0 + g1)/2048), e1 = floor((-32b1 + g2)/1024): g0 = h0 and 2048e0 = -32b0 + g1 and 1024e1 = -32b1 + g2 and g2 <= -2 + N and g2 >= -29 and g1 <= -2 + N and g1 >= -29 and b1 >= 0 and b1 <= 31 and b0 <= 63 and 32b1 <= -2 + N and 32b0 <= -2 + N and b0 >= 0 and N >= 4 and h0 >= 0 and h0 <= -1 + 2T and g2 >= 32b1 and g1 >= 32b0 and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 31) }" + child: + schedule: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> [{ S1[i0, i1] -> [(1 - g1 + i0)] }, { S1[i0, i1] -> [(1 - g2 + i1)] }, { S1[i0, i1] -> [(t0)] }, { S1[i0, i1] -> [(t1)] }]" + options: "[T, N, h0, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { separate[x] : x >= 3 }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/largeur.in isl-0.15/test_inputs/codegen/cloog/largeur.in --- isl-0.12.2/test_inputs/codegen/cloog/largeur.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/largeur.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [i1, i0] : i0 >= 1 and i0 <= M and i1 >= i0 and i1 <= M } -[M] -> { : M >= 0 } -[M] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/largeur.st isl-0.15/test_inputs/codegen/cloog/largeur.st --- isl-0.12.2/test_inputs/codegen/cloog/largeur.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/largeur.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= i0 and i1 <= M }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }, { S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/levenshtein-1-2-3.c isl-0.15/test_inputs/codegen/cloog/levenshtein-1-2-3.c --- isl-0.12.2/test_inputs/codegen/cloog/levenshtein-1-2-3.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/levenshtein-1-2-3.c 2015-06-02 09:28:10.000000000 +0000 @@ -13,7 +13,7 @@ } for (int c0 = N + 2; c0 < 2 * M - N - 1; c0 += 1) { S7(c0, -N + (N + c0 + 1) / 2 - 1); - if ((-N + c0) % 2 == 0) { + if ((N - c0) % 2 == 0) { S5(c0, (-N + c0) / 2); S8(c0, (-N + c0) / 2); } @@ -21,7 +21,7 @@ S6(c0, c1); S8(c0, c1); } - if ((-N + c0) % 2 == 0) { + if ((N - c0) % 2 == 0) { S4(c0, (N + c0) / 2); S8(c0, (N + c0) / 2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/levenshtein-1-2-3.in isl-0.15/test_inputs/codegen/cloog/levenshtein-1-2-3.in --- isl-0.12.2/test_inputs/codegen/cloog/levenshtein-1-2-3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/levenshtein-1-2-3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S8[i0, i1] -> [i0, i1, 7] : i0 >= 1 + N and 2i1 <= N + i0 and 2i1 >= -N + i0 and i0 <= -2 + 2M - N and N <= -2 + M and N >= 1; S1[0, 0] -> [0, 0, 0] : N <= -2 + M and N >= 1; S5[i0, i1] -> [i0, j, 4] : 2j = -N + i0 and 2i1 = -N + i0 and i0 >= 2 + N and i0 <= -2 + 2M - N and N >= 1; S7[i0, i1] -> [i0, i1, 6] : i0 >= 1 + N and 2i1 <= -1 - N + i0 and i0 <= -2 + 2M - N and 2i1 >= -2 - N + i0 and N <= -2 + M and N >= 1; S2[i0, 0] -> [i0, 0, 1] : i0 >= 1 and i0 <= N and N <= -2 + M; S3[i0, i0] -> [i0, i0, 2] : i0 >= 1 and i0 <= N and N <= -2 + M; S4[i0, i1] -> [i0, j, 3] : 2j = N + i0 and 2i1 = N + i0 and i0 >= 2 + N and i0 <= -2 + 2M - N and N >= 1; S6[i0, i1] -> [i0, i1, 5] : 2i1 <= -1 + N + i0 and i1 <= -1 + i0 and i1 >= 1 - M + i0 and 2i1 >= 1 - N + i0 and i1 >= 1 and i1 <= -1 + M and N <= -2 + M } -[M, N] -> { : N <= -2 + M and N >= 1 } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/levenshtein-1-2-3.st isl-0.15/test_inputs/codegen/cloog/levenshtein-1-2-3.st --- isl-0.12.2/test_inputs/codegen/cloog/levenshtein-1-2-3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/levenshtein-1-2-3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S5[i0, i1] : 2i1 = -N + i0 and i0 >= 2 + N and i0 <= -2 + 2M - N and N >= 1; S3[i0, i0] : i0 >= 1 and i0 <= N and N <= -2 + M; S7[i0, i1] : i0 >= 1 + N and 2i1 <= -1 - N + i0 and i0 <= -2 + 2M - N and 2i1 >= -2 - N + i0 and N <= -2 + M and N >= 1; S6[i0, i1] : 2i1 <= -1 + N + i0 and i1 <= -1 + i0 and i1 >= 1 - M + i0 and 2i1 >= 1 - N + i0 and i1 >= 1 and i1 <= -1 + M and N <= -2 + M; S1[0, 0] : N <= -2 + M and N >= 1; S2[i0, 0] : i0 >= 1 and i0 <= N and N <= -2 + M; S4[i0, i1] : 2i1 = N + i0 and i0 >= 2 + N and i0 <= -2 + 2M - N and N >= 1; S8[i0, i1] : i0 >= 1 + N and 2i1 <= N + i0 and 2i1 >= -N + i0 and i0 <= -2 + 2M - N and N <= -2 + M and N >= 1 }" +child: + context: "[M, N] -> { [] : N <= -2 + M and N >= 1 }" + child: + schedule: "[M, N] -> [{ S7[i0, i1] -> [(i0)]; S5[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)]; S8[i0, i1] -> [(i0)]; S6[i0, i1] -> [(i0)] }, { S7[i0, i1] -> [(i1)]; S5[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)]; S8[i0, i1] -> [(i1)]; S6[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" + - filter: "[M, N] -> { S3[i0, i1] }" + - filter: "[M, N] -> { S4[i0, i1] }" + - filter: "[M, N] -> { S5[i0, i1] }" + - filter: "[M, N] -> { S6[i0, i1] }" + - filter: "[M, N] -> { S7[i0, i1] }" + - filter: "[M, N] -> { S8[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lex.in isl-0.15/test_inputs/codegen/cloog/lex.in --- isl-0.12.2/test_inputs/codegen/cloog/lex.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lex.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[i0] -> [i0, -1, 0] : i0 >= 0 and i0 <= 10; S1[i0] -> [i0, 0, 0] : i0 >= 0 and i0 <= 10 } -{ : } -{ [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lex.st isl-0.15/test_inputs/codegen/cloog/lex.st --- isl-0.12.2/test_inputs/codegen/cloog/lex.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lex.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S1[i0] : i0 >= 0 and i0 <= 10; S2[i0] : i0 >= 0 and i0 <= 10 }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S2[i0] }" + - filter: "{ S1[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lineality-1-2.in isl-0.15/test_inputs/codegen/cloog/lineality-1-2.in --- isl-0.12.2/test_inputs/codegen/cloog/lineality-1-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lineality-1-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i0] -> [i0, i0, 1] : i0 >= 1 and i0 <= M; S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i1 >= 1 and i0 <= M and i1 <= M } -[M] -> { : M >= 2 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lineality-1-2.st isl-0.15/test_inputs/codegen/cloog/lineality-1-2.st --- isl-0.12.2/test_inputs/codegen/cloog/lineality-1-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lineality-1-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i1 >= 1 and i0 <= M and i1 <= M; S2[i0, i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lineality-2-1-2.c isl-0.15/test_inputs/codegen/cloog/lineality-2-1-2.c --- isl-0.12.2/test_inputs/codegen/cloog/lineality-2-1-2.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lineality-2-1-2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,12 +1,12 @@ for (int c0 = 1; c0 <= M; c0 += 1) { for (int c1 = 1; c1 <= min(M, c0 + 1); c1 += 1) S1(c0, c1); - if (c0 + 1 >= M) { - S2(c0, c0 + 2); - } else { + if (M >= c0 + 2) { S1(c0, c0 + 2); S2(c0, c0 + 2); } for (int c1 = c0 + 3; c1 <= M; c1 += 1) S1(c0, c1); + if (c0 + 1 >= M) + S2(c0, c0 + 2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lineality-2-1-2.in isl-0.15/test_inputs/codegen/cloog/lineality-2-1-2.in --- isl-0.12.2/test_inputs/codegen/cloog/lineality-2-1-2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lineality-2-1-2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, 2 + i0] -> [i0, 2 + i0, 1] : i0 >= 1 and i0 <= M; S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i1 >= 1 and i0 <= M and i1 <= M } -[M] -> { : M >= 2 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lineality-2-1-2.st isl-0.15/test_inputs/codegen/cloog/lineality-2-1-2.st --- isl-0.12.2/test_inputs/codegen/cloog/lineality-2-1-2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lineality-2-1-2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i1 >= 1 and i0 <= M and i1 <= M; S2[i0, 2 + i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/logo.in isl-0.15/test_inputs/codegen/cloog/logo.in --- isl-0.12.2/test_inputs/codegen/cloog/logo.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/logo.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [i0, i1, 1] : i0 >= 2 and i0 <= 6 and i1 >= 0 and i1 <= 4; S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i1 <= 7 and i1 >= -1 + i0 } -[M] -> { : } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/logopar.in isl-0.15/test_inputs/codegen/cloog/logopar.in --- isl-0.12.2/test_inputs/codegen/cloog/logopar.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/logopar.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m, n] -> { S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i1 <= m and i1 >= -1 + i0; S2[i0, i1] -> [i0, i1, 1] : i0 >= 2 and i0 <= n and i1 >= 0 and i1 <= n } -[m, n] -> { : n <= m and m >= 0 and n >= 2 } -[m, n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/logopar.st isl-0.15/test_inputs/codegen/cloog/logopar.st --- isl-0.12.2/test_inputs/codegen/cloog/logopar.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/logopar.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[m, n] -> { S1[i0, i1] : i0 >= 1 and i1 <= m and i1 >= -1 + i0; S2[i0, i1] : i0 >= 2 and i0 <= n and i1 >= 0 and i1 <= n }" +child: + context: "[m, n] -> { [] : n <= m and m >= 0 and n >= 2 }" + child: + schedule: "[m, n] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)] }]" + options: "[m, n] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n] -> { S1[i0, i1] }" + - filter: "[m, n] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/logo.st isl-0.15/test_inputs/codegen/cloog/logo.st --- isl-0.12.2/test_inputs/codegen/cloog/logo.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/logo.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i1 <= 7 and i1 >= -1 + i0; S2[i0, i1] : i0 >= 2 and i0 <= 6 and i1 >= 0 and i1 <= 4 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lu2.in isl-0.15/test_inputs/codegen/cloog/lu2.in --- isl-0.12.2/test_inputs/codegen/cloog/lu2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lu2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i0, n, i0, i3] -> [i0, n, i0, i3, 0, 0] : i0 >= 1 and i0 <= n and i3 >= 1 + i0 and i3 <= n; S2[i0, i1, i2, i1, i0] -> [i0, i1, i2, i1, i0, 1] : i2 >= 1 and i2 <= n and i2 <= -1 + i1 and i1 <= n and i2 <= -1 + i0 and i0 <= n } -[n] -> { : } -[n] -> { [i, j, k, l, m, n'] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lu2.st isl-0.15/test_inputs/codegen/cloog/lu2.st --- isl-0.12.2/test_inputs/codegen/cloog/lu2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lu2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[n] -> { S2[i0, i1, i2, i1, i0] : i2 >= 1 and i2 <= n and i2 <= -1 + i1 and i1 <= n and i2 <= -1 + i0 and i0 <= n; S1[i0, n, i0, i3] : i0 >= 1 and i0 <= n and i3 >= 1 + i0 and i3 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2, i3, i4] -> [(i0)]; S1[i0, i1, i2, i3] -> [(i0)] }, { S2[i0, i1, i2, i3, i4] -> [(i1)]; S1[i0, i1, i2, i3] -> [(i1)] }, { S2[i0, i1, i2, i3, i4] -> [(i2)]; S1[i0, i1, i2, i3] -> [(i2)] }, { S2[i0, i1, i2, i3, i4] -> [(i3)]; S1[i0, i1, i2, i3] -> [(i3)] }, { S2[i0, i1, i2, i3, i4] -> [(i4)]; S1[i0, i1, i2, i3] -> [(0)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1, i2, i3] }" + - filter: "[n] -> { S2[i0, i1, i2, i3, i4] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lu.in isl-0.15/test_inputs/codegen/cloog/lu.in --- isl-0.12.2/test_inputs/codegen/cloog/lu.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lu.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S2[i0, i1, i2] -> [i2, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 + i0 and i2 <= n; S1[i0, i1] -> [i0, n] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n } -[n] -> { : } -[n] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lu.st isl-0.15/test_inputs/codegen/cloog/lu.st --- isl-0.12.2/test_inputs/codegen/cloog/lu.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lu.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S2[i0, i1, i2] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 + i0 and i2 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1, i2] -> [(i1)]; S1[i0, i1] -> [(n)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lux.in isl-0.15/test_inputs/codegen/cloog/lux.in --- isl-0.12.2/test_inputs/codegen/cloog/lux.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lux.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i0, M, i3] -> [i0, i0, M, i3, 0, 0] : i0 >= 1 and i0 <= M and i3 >= 1 + i0 and i3 <= M; S2[i0, i1, i2, i2, i0] -> [i0, i1, i2, i2, i0, 1] : i1 >= 1 and i1 <= M and i2 >= 1 + i1 and i2 <= M and i1 <= -1 + i0 and i0 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m, n] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/lux.st isl-0.15/test_inputs/codegen/cloog/lux.st --- isl-0.12.2/test_inputs/codegen/cloog/lux.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/lux.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i0, M, i3] : i0 >= 1 and i0 <= M and i3 >= 1 + i0 and i3 <= M; S2[i0, i1, i2, i2, i0] : i1 >= 1 and i1 <= M and i2 >= 1 + i1 and i2 <= M and i1 <= -1 + i0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i0)]; S2[i0, i1, i2, i3, i4] -> [(i0)] }, { S1[i0, i1, i2, i3] -> [(i1)]; S2[i0, i1, i2, i3, i4] -> [(i1)] }, { S1[i0, i1, i2, i3] -> [(i2)]; S2[i0, i1, i2, i3, i4] -> [(i2)] }, { S1[i0, i1, i2, i3] -> [(i3)]; S2[i0, i1, i2, i3, i4] -> [(i3)] }, { S1[i0, i1, i2, i3] -> [(0)]; S2[i0, i1, i2, i3, i4] -> [(i4)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2, i3] }" + - filter: "[M] -> { S2[i0, i1, i2, i3, i4] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/merge.in isl-0.15/test_inputs/codegen/cloog/merge.in --- isl-0.12.2/test_inputs/codegen/cloog/merge.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/merge.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S3[i0] -> [i0, 2] : i0 >= 0 and i0 <= 10; S2[i0] -> [i0, 1] : i0 >= 2 and i0 <= 10; S1[0] -> [0, 0] } -{ : } -{ [i, j] -> atomic[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/merge.st isl-0.15/test_inputs/codegen/cloog/merge.st --- isl-0.12.2/test_inputs/codegen/cloog/merge.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/merge.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +domain: "{ S3[i0] : i0 >= 0 and i0 <= 10; S1[0]; S2[i0] : i0 >= 2 and i0 <= 10 }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0] -> [(i0)]; S3[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "{ atomic[i0] }" + child: + sequence: + - filter: "{ S1[i0] }" + - filter: "{ S2[i0] }" + - filter: "{ S3[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-1-1.c isl-0.15/test_inputs/codegen/cloog/min-1-1.c --- isl-0.12.2/test_inputs/codegen/cloog/min-1-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-1-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 1; c0 <= N; c0 += 1) - for (int c1 = 0; c1 <= min(min(N - c0, c0), M); c1 += 1) + for (int c1 = 0; c1 <= min(min(M, c0), N - c0); c1 += 1) S1(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-1-1.in isl-0.15/test_inputs/codegen/cloog/min-1-1.in --- isl-0.12.2/test_inputs/codegen/cloog/min-1-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-1-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i1 >= 0 and i1 <= M and i1 <= i0 and i1 <= N - i0 } -[M, N] -> { : } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-1-1.st isl-0.15/test_inputs/codegen/cloog/min-1-1.st --- isl-0.12.2/test_inputs/codegen/cloog/min-1-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-1-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 1 and i1 >= 0 and i1 <= M and i1 <= i0 and i1 <= N - i0 }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-2-1.c isl-0.15/test_inputs/codegen/cloog/min-2-1.c --- isl-0.12.2/test_inputs/codegen/cloog/min-2-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-2-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ for (int c0 = 1; c0 <= N; c0 += 1) - for (int c1 = 0; c1 <= min(min(N - c0, c0), M); c1 += 1) - for (int c2 = 0; c2 <= min(min(M, N - c0), c0); c2 += 1) + for (int c1 = 0; c1 <= min(min(M, c0), N - c0); c1 += 1) + for (int c2 = 0; c2 <= min(min(M, c0), N - c0); c2 += 1) S1(c0, c1, c2); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-2-1.in isl-0.15/test_inputs/codegen/cloog/min-2-1.in --- isl-0.12.2/test_inputs/codegen/cloog/min-2-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-2-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1, i2] -> [i0, i1, i2, 0] : i0 >= 1 and i1 >= 0 and i1 <= M and i1 <= i0 and i1 <= N - i0 and i2 >= 0 and i2 <= M and i2 <= i0 and i2 <= N - i0 } -[M, N] -> { : } -[M, N] -> { [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-2-1.st isl-0.15/test_inputs/codegen/cloog/min-2-1.st --- isl-0.12.2/test_inputs/codegen/cloog/min-2-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-2-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[i0, i1, i2] : i0 >= 1 and i1 >= 0 and i1 <= M and i1 <= i0 and i1 <= N - i0 and i2 >= 0 and i2 <= M and i2 <= i0 and i2 <= N - i0 }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-3-1.c isl-0.15/test_inputs/codegen/cloog/min-3-1.c --- isl-0.12.2/test_inputs/codegen/cloog/min-3-1.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-3-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ -for (int c0 = 0; c0 <= min(M, 10); c0 += 1) - for (int c1 = 0; c1 <= min(M, 10); c1 += 1) +for (int c0 = 0; c0 <= min(10, M); c0 += 1) + for (int c1 = 0; c1 <= min(10, M); c1 += 1) S1(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-3-1.in isl-0.15/test_inputs/codegen/cloog/min-3-1.in --- isl-0.12.2/test_inputs/codegen/cloog/min-3-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-3-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [i0, i1, 0] : i0 >= 0 and i0 <= M and i0 <= 10 and i1 >= 0 and i1 <= M and i1 <= 10 } -[M] -> { : M >= 0 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-3-1.st isl-0.15/test_inputs/codegen/cloog/min-3-1.st --- isl-0.12.2/test_inputs/codegen/cloog/min-3-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-3-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 0 and i0 <= M and i0 <= 10 and i1 >= 0 and i1 <= M and i1 <= 10 }" +child: + context: "[M] -> { [] : M >= 0 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-4-1.c isl-0.15/test_inputs/codegen/cloog/min-4-1.c --- isl-0.12.2/test_inputs/codegen/cloog/min-4-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-4-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,2 +1,2 @@ -for (int c0 = max(-N, -M); c0 <= min(O, N); c0 += 1) +for (int c0 = max(-M, -N); c0 <= min(N, O); c0 += 1) S1(c0); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-4-1.in isl-0.15/test_inputs/codegen/cloog/min-4-1.in --- isl-0.12.2/test_inputs/codegen/cloog/min-4-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-4-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O] -> { S1[i0] -> [i0, 0] : i0 >= -M and i0 >= -N and i0 <= N and i0 <= O } -[M, N, O] -> { : } -[M, N, O] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/min-4-1.st isl-0.15/test_inputs/codegen/cloog/min-4-1.st --- isl-0.12.2/test_inputs/codegen/cloog/min-4-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/min-4-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N, O] -> { S1[i0] : i0 >= -M and i0 >= -N and i0 <= N and i0 <= O }" +child: + context: "[M, N, O] -> { [] }" + child: + schedule: "[M, N, O] -> [{ S1[i0] -> [(i0)] }]" + options: "[M, N, O] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod2.in isl-0.15/test_inputs/codegen/cloog/mod2.in --- isl-0.12.2/test_inputs/codegen/cloog/mod2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i] -> [i, 0] : exists (e0 = [(i)/3]: i >= 0 and i <= 3 and 3e0 <= i and 3e0 >= -1 + i) } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod2.st isl-0.15/test_inputs/codegen/cloog/mod2.st --- isl-0.12.2/test_inputs/codegen/cloog/mod2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i] : exists (e0 = floor((1 + i)/3): 3e0 <= i and 3e0 >= -1 + i and i >= 0 and i <= 3) }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i] -> [(i)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod3.c isl-0.15/test_inputs/codegen/cloog/mod3.c --- isl-0.12.2/test_inputs/codegen/cloog/mod3.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod3.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = max(32 * h0 - 1991, 0); c0 <= min(999, 32 * h0 + 31); c0 += 1) +for (int c0 = max(0, 32 * h0 - 1991); c0 <= min(999, 32 * h0 + 31); c0 += 1) if ((32 * h0 - c0 + 32) % 64 >= 1) for (int c1 = 0; c1 <= 999; c1 += 1) S1(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod3.in isl-0.15/test_inputs/codegen/cloog/mod3.in --- isl-0.12.2/test_inputs/codegen/cloog/mod3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[h0] -> { S1[i0, i1] -> [i0, i1, 0] : exists (e0 = [(32 + 32h0 - i0)/64]: i0 >= 0 and i0 <= 999 and i0 >= -2015 + 32h0 and 32e0 >= -999 + 32h0 - i0 and i1 >= 0 and i1 <= 999 and 64e0 >= -31 + 32h0 - i0 and 64e0 <= 31 + 32h0 - i0 and i0 <= 32 + 32h0) } -[h0] -> { : h0 <= 93 and h0 >= 0 } -[h0] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod3.st isl-0.15/test_inputs/codegen/cloog/mod3.st --- isl-0.12.2/test_inputs/codegen/cloog/mod3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[h0] -> { S1[i0, i1] : exists (e0 = floor((32 + 32h0 - i0)/64): 64e0 <= 31 + 32h0 - i0 and 64e0 >= -31 + 32h0 - i0 and i0 >= 0 and i0 <= 999 and i0 >= -2015 + 32h0 and 32e0 >= -999 + 32h0 - i0 and i1 >= 0 and i1 <= 999 and i0 <= 32 + 32h0) }" +child: + context: "[h0] -> { [] : h0 <= 93 and h0 >= 0 }" + child: + schedule: "[h0] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[h0] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod4.in isl-0.15/test_inputs/codegen/cloog/mod4.in --- isl-0.12.2/test_inputs/codegen/cloog/mod4.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod4.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[j, div41, div42, 2, mod6_a] -> [j, div41, k, 2, m, 1] : 3k = 1 + j and 3div42 = 1 + j and 3m = -2 + j and 3mod6_a = -2 + j and 3div41 >= 1 + j and 3div41 <= 2 + j and j >= 1 and j <= 10; S1[j, div41, div42, 2, mod6_a] -> [j, div41, div42, 2, m, 0] : 3m = -2 + j and 3mod6_a = -2 + j and j >= 1 and j <= 10 and 3div41 >= j and 3div42 >= -1 + j and 3div42 <= 1 + j and 3div41 <= 2 + j; S3[j, div41, div42, 2, mod6_a] -> [j, div41, div42, 2, m, 2] : 3m = -2 + j and 3mod6_a = -2 + j and j >= 1 and j <= 10 and 3div41 >= j and 3div42 >= -1 + j and 3div42 <= 1 + j and 3div41 <= 2 + j } -{ : } -{ [i, j, k, l, m, n] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod4.st isl-0.15/test_inputs/codegen/cloog/mod4.st --- isl-0.12.2/test_inputs/codegen/cloog/mod4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +domain: "{ S1[j, div41, div42, 2, mod6_a] : 3mod6_a = -2 + j and j >= 1 and j <= 10 and 3div41 >= j and 3div42 >= -1 + j and 3div42 <= 1 + j and 3div41 <= 2 + j; S2[j, div41, div42, 2, mod6_a] : 3div42 = 1 + j and 3mod6_a = -2 + j and 3div41 >= 1 + j and 3div41 <= 2 + j and j >= 1 and j <= 10; S3[j, div41, div42, 2, mod6_a] : 3mod6_a = -2 + j and j >= 1 and j <= 10 and 3div41 >= j and 3div42 >= -1 + j and 3div42 <= 1 + j and 3div41 <= 2 + j }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[j, div41, div42, mod6, mod6_a] -> [(j)]; S3[j, div41, div42, mod6, mod6_a] -> [(j)]; S2[j, div41, div42, mod6, mod6_a] -> [(j)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(div41)]; S3[j, div41, div42, mod6, mod6_a] -> [(div41)]; S2[j, div41, div42, mod6, mod6_a] -> [(div41)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(div42)]; S3[j, div41, div42, mod6, mod6_a] -> [(div42)]; S2[j, div41, div42, mod6, mod6_a] -> [(div42)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(mod6)]; S3[j, div41, div42, mod6, mod6_a] -> [(mod6)]; S2[j, div41, div42, mod6, mod6_a] -> [(mod6)] }, { S1[j, div41, div42, mod6, mod6_a] -> [(mod6_a)]; S3[j, div41, div42, mod6, mod6_a] -> [(mod6_a)]; S2[j, div41, div42, mod6, mod6_a] -> [(mod6_a)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[j, div41, div42, mod6, mod6_a] }" + - filter: "{ S2[j, div41, div42, mod6, mod6_a] }" + - filter: "{ S3[j, div41, div42, mod6, mod6_a] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mode.c isl-0.15/test_inputs/codegen/cloog/mode.c --- isl-0.12.2/test_inputs/codegen/cloog/mode.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mode.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 0; c0 <= M; c0 += 1) { - for (int c1 = 0; c1 <= min(c0, N); c1 += 1) { + for (int c1 = 0; c1 <= min(N, c0); c1 += 1) { S1(c0, c1); S2(c0, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mode.in isl-0.15/test_inputs/codegen/cloog/mode.in --- isl-0.12.2/test_inputs/codegen/cloog/mode.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mode.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1] -> [i0, i1, 0] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= i0; S2[i0, i1] -> [i0, i1, 1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N } -[M, N] -> { : } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mode.st isl-0.15/test_inputs/codegen/cloog/mode.st --- isl-0.12.2/test_inputs/codegen/cloog/mode.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mode.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= i0; S2[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod.in isl-0.15/test_inputs/codegen/cloog/mod.in --- isl-0.12.2/test_inputs/codegen/cloog/mod.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0] -> [i0, 0] : exists (e0 = [(1 + i0)/3]: i0 >= 0 and i0 <= 3 and 3e0 <= i0 and 3e0 >= -1 + i0) } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mod.st isl-0.15/test_inputs/codegen/cloog/mod.st --- isl-0.12.2/test_inputs/codegen/cloog/mod.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mod.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i0] : exists (e0 = floor((1 + i0)/3): 3e0 <= i0 and 3e0 >= -1 + i0 and i0 >= 0 and i0 <= 3) }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0] -> [(i0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/multi-mm-1.in isl-0.15/test_inputs/codegen/cloog/multi-mm-1.in --- isl-0.12.2/test_inputs/codegen/cloog/multi-mm-1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/multi-mm-1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1] -> [i0, i1, 0] : i1 >= 0 and i1 <= i0 and i0 <= M; S2[i0, i1] -> [i0, i1, 1] : i1 >= 0 and i1 <= i0 and i0 <= M and i1 <= N } -[M, N] -> { : N <= M and N >= 1 } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/multi-mm-1.st isl-0.15/test_inputs/codegen/cloog/multi-mm-1.st --- isl-0.12.2/test_inputs/codegen/cloog/multi-mm-1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/multi-mm-1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0, i1] : i1 >= 0 and i1 <= i0 and i0 <= M; S2[i0, i1] : i1 >= 0 and i1 <= i0 and i0 <= M and i1 <= N }" +child: + context: "[M, N] -> { [] : N <= M and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/multi-stride2.in isl-0.15/test_inputs/codegen/cloog/multi-stride2.in --- isl-0.12.2/test_inputs/codegen/cloog/multi-stride2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/multi-stride2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1, i2] -> [i0, j, k, 0] : 2i1 = -1 + i0 and 2j = -1 + i0 and 3k = -2 + i0 and 3i2 = -2 + i0 and i0 >= 0 and i0 <= 100 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/multi-stride2.st isl-0.15/test_inputs/codegen/cloog/multi-stride2.st --- isl-0.12.2/test_inputs/codegen/cloog/multi-stride2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/multi-stride2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i1 = -1 + i0 and 3i2 = -2 + i0 and i0 >= 0 and i0 <= 100 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/multi-stride.in isl-0.15/test_inputs/codegen/cloog/multi-stride.in --- isl-0.12.2/test_inputs/codegen/cloog/multi-stride.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/multi-stride.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1, i2] -> [i0, j, k, 0] : 2i1 = -1 + i0 and 2j = -1 + i0 and 6k = -2 + i0 and 6i2 = -2 + i0 and i0 >= 0 and i0 <= 100 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/multi-stride.st isl-0.15/test_inputs/codegen/cloog/multi-stride.st --- isl-0.12.2/test_inputs/codegen/cloog/multi-stride.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/multi-stride.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i1 = -1 + i0 and 6i2 = -2 + i0 and i0 >= 0 and i0 <= 100 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mxm-shared.c isl-0.15/test_inputs/codegen/cloog/mxm-shared.c --- isl-0.12.2/test_inputs/codegen/cloog/mxm-shared.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mxm-shared.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,3 @@ -if (g4 == 0 && t1 <= 7 && N >= g0 + t1 + 1) { - for (int c0 = t0; c0 <= min(N - g1 - 1, 127); c0 += 16) - S1(g0 + t1, g1 + c0); -} else if (g4 % 4 == 0 && N >= g0 + t1 + 1 && t1 <= 7 && g4 >= 4) - for (int c0 = t0; c0 <= min(N - g1 - 1, 127); c0 += 16) +if (N >= g0 + t1 + 1 && t1 <= 7 && g4 % 4 == 0) + for (int c0 = t0; c0 <= min(127, N - g1 - 1); c0 += 16) S1(g0 + t1, g1 + c0); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mxm-shared.in isl-0.15/test_inputs/codegen/cloog/mxm-shared.in --- isl-0.12.2/test_inputs/codegen/cloog/mxm-shared.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mxm-shared.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { S1[g0 + t1, i1] -> [-g1 + i1, t1, t0, t1] : (exists (e0 = [(-g1)/128], e1 = [(128b1 + 31g1)/4096], e2 = [(t0 - i1)/16], e3 = [(-120b0 - g0)/128]: g4 = 0 and g2 = 8b0 and g3 = 128b1 and 128e0 = -g1 and 4096e1 = 128b1 + 31g1 and 16e2 = t0 - i1 and 128e3 = -120b0 - g0 and g1 >= 128b1 and t1 <= -1 + N - g0 and g0 >= 8b0 and i1 <= -1 + N and b0 <= 15 and b0 >= 0 and b1 <= 31 and b1 >= 0 and i1 <= 127 + g1 and t1 >= 0 and t1 <= 7 and i1 >= g1 and t0 >= 0 and t0 <= 15)) or (exists (e0 = [(-g1)/128], e1 = [(128b1 + 31g1)/4096], e2 = [(t0 - i1)/16], e3 = [(-120b0 - g0)/128]: g4 = 0 and g2 = 8b0 and g3 = 128b1 and 128e0 = -g1 and 4096e1 = 128b1 + 31g1 and 16e2 = t0 - i1 and 128e3 = -120b0 - g0 and g1 >= 128b1 and t1 <= -1 + N - g0 and g0 >= 8b0 and i1 <= -1 + N and b0 <= 15 and b0 >= 0 and b1 <= 31 and b1 >= 0 and i1 <= 127 + g1 and t1 >= 0 and t1 <= 7 and i1 >= g1 and t0 >= 0 and t0 <= 15 and N >= 1)) or (exists (e0 = [(-g1)/128], e1 = [(128b1 + 31g1)/4096], e2 = [(t0 - i1)/16], e3 = [(-120b0 - g0)/128]: g4 = 0 and g2 = 8b0 and g3 = 128b1 and 128e0 = -g1 and 4096e1 = 128b1 + 31g1 and 16e2 = t0 - i1 and 128e3 = -120b0 - g0 and g0 >= 8b0 and t1 <= -1 + N - g0 and g1 >= 128b1 and i1 <= -1 + N and N >= 1 and t1 <= 7 and b1 <= 31 and b1 >= 0 and b0 <= 15 and b0 >= 0 and t0 <= 15 and i1 <= 127 + g1 and i1 >= g1 and t1 >= 0 and t0 >= 0)); S1[g0 + t1, i1] -> [-g1 + i1, t1, t0, t1] : exists (e0 = [(g4)/4], e1 = [(-g1)/128], e2 = [(128b1 + 31g1)/4096], e3 = [(t0 - i1)/16], e4 = [(-120b0 - g0)/128]: g3 = 128b1 and g2 = 8b0 and 4e0 = g4 and 128e1 = -g1 and 4096e2 = 128b1 + 31g1 and 16e3 = t0 - i1 and 128e4 = -120b0 - g0 and g0 >= 8b0 and t1 <= -1 + N - g0 and g1 >= 128b1 and i1 <= -1 + N and g4 <= -1 + N and t1 <= 7 and b1 <= 31 and b1 >= 0 and b0 <= 15 and b0 >= 0 and g4 >= 0 and i1 <= 127 + g1 and i1 >= g1 and t1 >= 0 and t0 >= 0 and t0 <= 15) } -[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { : exists (e0 = [(g0)/8], e1 = [(-128b1 + g1)/4096], e2 = [(8b0 - g0)/128]: g2 = 8b0 and g3 = 128b1 and 8e0 = g0 and 4096e1 = -128b1 + g1 and 128e2 = 8b0 - g0 and b0 >= 0 and g4 <= -1 + N and b0 <= 15 and g1 <= -1 + N and g4 >= 0 and b1 <= 31 and g0 <= -1 + N and g1 >= 128b1 and b1 >= 0 and g0 >= 8b0 and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 15) } -[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/mxm-shared.st isl-0.15/test_inputs/codegen/cloog/mxm-shared.st --- isl-0.12.2/test_inputs/codegen/cloog/mxm-shared.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/mxm-shared.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { S1[g0 + t1, i1] : (exists (e0 = floor((g1)/128), e1 = floor((128b1 - g1)/4096), e2 = floor((-8b0 + g0)/128), e3 = floor((-t0 + i1)/16): g3 = 128b1 and g4 = 0 and g2 = 8b0 and 128e0 = g1 and 4096e1 = 128b1 - g1 and 128e2 = -8b0 + g0 and 16e3 = -t0 + i1 and b0 <= 15 and b0 >= 0 and b1 <= 31 and b1 >= 0 and g0 >= 8b0 and g1 >= 128b1 and t0 <= 15 and t0 >= 0 and t1 <= 7 and t1 >= 0 and t1 <= -1 + N - g0 and i1 >= g1 and i1 <= 127 + g1 and i1 <= -1 + N)) or (exists (e0 = floor((g1)/128), e1 = floor((128b1 - g1)/4096), e2 = floor((g4)/4), e3 = floor((-8b0 + g0)/128), e4 = floor((-t0 + i1)/16): g3 = 128b1 and g2 = 8b0 and 128e0 = g1 and 4096e1 = 128b1 - g1 and 4e2 = g4 and 128e3 = -8b0 + g0 and 16e4 = -t0 + i1 and b0 <= 15 and b0 >= 0 and b1 <= 31 and b1 >= 0 and g0 >= 8b0 and g1 >= 128b1 and g4 >= 0 and g4 <= -1 + N and t0 <= 15 and t0 >= 0 and t1 <= 7 and t1 >= 0 and t1 <= -1 + N - g0 and i1 >= g1 and i1 <= 127 + g1 and i1 <= -1 + N)) }" +child: + context: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { [] : exists (e0 = floor((g0)/8), e1 = floor((-128b1 + g1)/4096), e2 = floor((8b0 - g0)/128): g2 = 8b0 and g3 = 128b1 and 8e0 = g0 and 4096e1 = -128b1 + g1 and 128e2 = 8b0 - g0 and b0 >= 0 and g4 <= -1 + N and b0 <= 15 and g1 <= -1 + N and g4 >= 0 and b1 <= 31 and g0 <= -1 + N and g1 >= 128b1 and b1 >= 0 and g0 >= 8b0 and t0 >= 0 and t0 <= 15 and t1 >= 0 and t1 <= 15) }" + child: + schedule: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> [{ S1[i0, i1] -> [(-g1 + i1)] }, { S1[i0, i1] -> [(t1)] }, { S1[i0, i1] -> [(t0)] }, { S1[i0, i1] -> [(t1)] }]" + options: "[N, b0, b1, g0, g1, g2, g3, g4, t0, t1] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/no_lindep.in isl-0.15/test_inputs/codegen/cloog/no_lindep.in --- isl-0.12.2/test_inputs/codegen/cloog/no_lindep.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/no_lindep.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[2 + N] -> [1 + M, N] } -[M, N] -> { : } -[M, N] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/no_lindep.st isl-0.15/test_inputs/codegen/cloog/no_lindep.st --- isl-0.12.2/test_inputs/codegen/cloog/no_lindep.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/no_lindep.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[2 + N] }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0] -> [(1 + M)] }, { S1[i0] -> [(N)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_basic1.in isl-0.15/test_inputs/codegen/cloog/nul_basic1.in --- isl-0.12.2/test_inputs/codegen/cloog/nul_basic1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_basic1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [i0, j, 0] : 2j = i0 and 2i1 = i0 and i0 >= 0 and i0 <= M } -[M] -> { : } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_basic1.st isl-0.15/test_inputs/codegen/cloog/nul_basic1.st --- isl-0.12.2/test_inputs/codegen/cloog/nul_basic1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_basic1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : 2i1 = i0 and i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_basic2.in isl-0.15/test_inputs/codegen/cloog/nul_basic2.in --- isl-0.12.2/test_inputs/codegen/cloog/nul_basic2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_basic2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S2[i0, i1] -> [i0, j, 1] : 4j = i0 and 4i1 = i0 and i0 >= 1 and i0 <= n; S1[i0, i1] -> [i0, j, 0] : 2j = i0 and 2i1 = i0 and i0 >= 1 and i0 <= n } -[n] -> { : n >= 2 } -[n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_basic2.st isl-0.15/test_inputs/codegen/cloog/nul_basic2.st --- isl-0.12.2/test_inputs/codegen/cloog/nul_basic2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_basic2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[n] -> { S1[i0, i1] : 2i1 = i0 and i0 >= 1 and i0 <= n; S2[i0, i1] : 4i1 = i0 and i0 >= 1 and i0 <= n }" +child: + context: "[n] -> { [] : n >= 2 }" + child: + schedule: "[n] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1] }" + - filter: "[n] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_complex1.c isl-0.15/test_inputs/codegen/cloog/nul_complex1.c --- isl-0.12.2/test_inputs/codegen/cloog/nul_complex1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_complex1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 0; c0 <= 5 * n; c0 += 1) - for (int c1 = max(2 * floord(c0 - 1, 3) + 2, -((n + c0 + 1) % 2) - n + c0 + 1); c1 <= min(c0, n + c0 - (n + c0 + 2) / 3); c1 += 2) - S1((-2 * c0 + 3 * c1) / 2, c0 - c1); + for (int c1 = max(-((5 * n - c0 + 1) % 2) - n + c0 + 1, 2 * ((c0 + 2) / 3)); c1 <= min(c0, n + c0 - (n + c0 + 2) / 3); c1 += 2) + S1((3 * c1 / 2) - c0, c0 - c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_complex1.in isl-0.15/test_inputs/codegen/cloog/nul_complex1.in --- isl-0.12.2/test_inputs/codegen/cloog/nul_complex1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_complex1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i0, i1] -> [2i0 + 3i1, 2i0 + 2i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= n } -[n] -> { : } -[n] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_complex1.st isl-0.15/test_inputs/codegen/cloog/nul_complex1.st --- isl-0.12.2/test_inputs/codegen/cloog/nul_complex1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_complex1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0, i1] -> [(2i0 + 3i1)] }, { S1[i0, i1] -> [(2i0 + 2i1)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_lcpc.c isl-0.15/test_inputs/codegen/cloog/nul_lcpc.c --- isl-0.12.2/test_inputs/codegen/cloog/nul_lcpc.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_lcpc.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ { - for (int c0 = 1; c0 <= 5; c0 += 2) { + for (int c0 = 1; c0 <= 6; c0 += 2) { for (int c2 = 1; c2 <= c0; c2 += 1) { S1(c0, (c0 - 1) / 2, c2); S2(c0, (c0 - 1) / 2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_lcpc.in isl-0.15/test_inputs/codegen/cloog/nul_lcpc.in --- isl-0.12.2/test_inputs/codegen/cloog/nul_lcpc.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_lcpc.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m, n, p] -> { S1[i, k, j] -> [i, j', j, 0] : 2k = -1 + i and 2j' = -1 + i and i >= 1 and i <= m and j >= 1 and j <= p; S2[i, k, j] -> [i, j', j, 1] : 2k = -1 + i and 2j' = -1 + i and i >= 1 and i <= n and j >= 1 and j <= i } -[m, n, p] -> { : n = 6 and m >= 7 and p >= 7 } -[m, n, p] -> { [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/nul_lcpc.st isl-0.15/test_inputs/codegen/cloog/nul_lcpc.st --- isl-0.12.2/test_inputs/codegen/cloog/nul_lcpc.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/nul_lcpc.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[m, n, p] -> { S1[i, k, j] : 2k = -1 + i and i >= 1 and i <= m and j >= 1 and j <= p; S2[i, k, j] : 2k = -1 + i and i >= 1 and i <= n and j >= 1 and j <= i }" +child: + context: "[m, n, p] -> { [] : n = 6 and m >= 7 and p >= 7 }" + child: + schedule: "[m, n, p] -> [{ S1[i, k, j] -> [(i)]; S2[i, k, j] -> [(i)] }, { S1[i, k, j] -> [(k)]; S2[i, k, j] -> [(k)] }, { S1[i, k, j] -> [(j)]; S2[i, k, j] -> [(j)] }]" + options: "[m, n, p] -> { separate[i0] }" + child: + sequence: + - filter: "[m, n, p] -> { S1[i, k, j] }" + - filter: "[m, n, p] -> { S2[i, k, j] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/orc.c isl-0.15/test_inputs/codegen/cloog/orc.c --- isl-0.12.2/test_inputs/codegen/cloog/orc.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/orc.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,16 +1,16 @@ { - for (int c1 = 0; c1 <= 2; c1 += 1) { - S1(c1); - for (int c2 = 0; c2 <= -c1 + 11; c2 += 1) { - S2(c1, c2); - S3(c1, c2); + for (int c0 = 0; c0 <= 2; c0 += 1) { + S1(c0); + for (int c1 = 0; c1 <= -c0 + 11; c1 += 1) { + S2(c0, c1); + S3(c0, c1); } - S4(c1); + S4(c0); } - for (int c1 = 0; c1 <= 14; c1 += 1) { - S5(c1); - for (int c2 = 0; c2 <= 9; c2 += 1) - S6(c1, c2); - S7(c1); + for (int c0 = 0; c0 <= 14; c0 += 1) { + S5(c0); + for (int c1 = 0; c1 <= 9; c1 += 1) + S6(c0, c1); + S7(c0); } } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/orc.in isl-0.15/test_inputs/codegen/cloog/orc.in --- isl-0.12.2/test_inputs/codegen/cloog/orc.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/orc.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[i0, i1] -> [0, 1 + 3i0, 2i1] : i0 >= 0 and i0 <= 2 and i1 >= 0 and i1 <= 11 - i0; S4[i0] -> [0, 2 + 3i0, 0] : i0 >= 0 and i0 <= 2; S5[i0] -> [2, 3i0, 0] : i0 >= 0 and i0 <= 14; S6[i0, i1] -> [2, 1 + 3i0, i1] : i0 >= 0 and i0 <= 14 and i1 >= 0 and i1 <= 9; S1[i0] -> [0, 3i0, 0] : i0 >= 0 and i0 <= 2; S7[i0] -> [2, 2 + 3i0, 0] : i0 >= 0 and i0 <= 14; S3[i0, i1] -> [0, 1 + 3i0, 1 + 2i1] : i0 >= 0 and i0 <= 2 and i1 >= 0 and i1 <= 11 - i0 } -{ : } -{ [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/orc.st isl-0.15/test_inputs/codegen/cloog/orc.st --- isl-0.12.2/test_inputs/codegen/cloog/orc.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/orc.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,13 @@ +domain: "{ S5[i] : i >= 0 and i <= 14; S6[i, j] : i >= 0 and i <= 14 and j >= 0 and j <= 9; S7[i] : i >= 0 and i <= 14; S4[i] : i >= 0 and i <= 2; S2[i, j] : i >= 0 and i <= 2 and j >= 0 and j <= 11 - i; S1[i] : i >= 0 and i <= 2; S3[i, j] : i >= 0 and i <= 2 and j >= 0 and j <= 11 - i }" +child: + context: "{ [] }" + child: + sequence: + - filter: "{ S4[i0]; S2[i0, i1]; S1[i0]; S3[i0, i1] }" + child: + schedule: "[{ S3[i0, i1] -> [(1 + 3i0)]; S2[i0, i1] -> [(1 + 3i0)]; S1[i0] -> [(3i0)]; S4[i0] -> [(2 + 3i0)] }, { S3[i0, i1] -> [(1 + 2i1)]; S2[i0, i1] -> [(2i1)]; S1[i0] -> [(0)]; S4[i0] -> [(0)] }]" + options: "{ separate[i0] }" + - filter: "{ S5[i0]; S6[i0, i1]; S7[i0] }" + child: + schedule: "[{ S6[i0, i1] -> [(1 + 3i0)]; S7[i0] -> [(2 + 3i0)]; S5[i0] -> [(3i0)] }, { S6[i0, i1] -> [(i1)]; S7[i0] -> [(0)]; S5[i0] -> [(0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/otl.c isl-0.15/test_inputs/codegen/cloog/otl.c --- isl-0.12.2/test_inputs/codegen/cloog/otl.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/otl.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ if (M >= 3 && N >= 4) for (int c0 = 1; c0 < (2 * M + 2 * N - 2) / 5; c0 += 1) - for (int c1 = max(c0 - (M + 2) / 5, (c0 + 1) / 2); c1 <= min(min((2 * N + 5 * c0 + 1) / 10, c0), (M + 2 * N) / 5 - 1); c1 += 1) - for (int c2 = max(max(max(max(c0 - (M + N + 4) / 5 + 1, c1 - (N + 6) / 5 + 1), floord(-N + 5 * c0 - 3, 10) + 1), 0), c0 - c1 - 1); c2 <= min(min(min((M + N - 2) / 5, (N + 5 * c0 + 3) / 10), c0 - c1 + (N - 1) / 5 + 1), c1); c2 += 1) - for (int c3 = max(max(max(2 * c1 - (2 * N + 5) / 5 + 1, 2 * c2 - (N + 2) / 5), c1 + c2 - (N + 3) / 5), c0); c3 <= min(min(min(min(min(c1 + (M - 2) / 5 + 1, 2 * c2 + (N - 2) / 5 + 1), c0 + 1), c1 + c2 + 1), (2 * M + 2 * N - 1) / 5 - 1), c2 + (M + N) / 5); c3 += 1) - for (int c4 = max(max(max(max(c0 - c2, c3 - (M + 2) / 5), c0 - (M + 6) / 5 + 1), (c3 + 1) / 2), c1); c4 <= min(min(min(min(min(min(min((M + 2 * N + 1) / 5 - 1, (2 * N + 5 * c0 + 3) / 10), (2 * N + 5 * c3 + 2) / 10), c0 - c2 + N / 5 + 1), c2 + (N + 2) / 5), -c2 + c3 + (N - 1) / 5 + 1), c0), c1 + 1); c4 += 1) + for (int c1 = max(c0 - (M + 2) / 5, (c0 + 1) / 2); c1 <= min(min(c0, (M + 2 * N) / 5 - 1), (2 * N + 5 * c0 + 1) / 10); c1 += 1) + for (int c2 = max(max(max(max(0, c0 - c1 - 1), c1 - (N + 6) / 5 + 1), c0 - (M + N + 4) / 5 + 1), floord(-N + 5 * c0 - 3, 10) + 1); c2 <= min(min(min(c1, (M + N - 2) / 5), c0 - c1 + (N - 1) / 5 + 1), (N + 5 * c0 + 3) / 10); c2 += 1) + for (int c3 = max(max(max(c0, 2 * c1 - (2 * N + 5) / 5 + 1), c1 + c2 - (N + 3) / 5), 2 * c2 - (N + 2) / 5); c3 <= min(min(min(min(min(c0 + 1, c1 + c2 + 1), c1 + (M - 2) / 5 + 1), 2 * c2 + (N - 2) / 5 + 1), (2 * M + 2 * N - 1) / 5 - 1), c2 + (M + N) / 5); c3 += 1) + for (int c4 = max(max(max(max(c1, c0 - c2), c0 - (M + 6) / 5 + 1), c3 - (M + 2) / 5), (c3 + 1) / 2); c4 <= min(min(min(min(min(min(min(c0, c1 + 1), -c2 + c3 + (N - 1) / 5 + 1), c0 - c2 + N / 5 + 1), (M + 2 * N + 1) / 5 - 1), c2 + (N + 2) / 5), (2 * N + 5 * c0 + 3) / 10), (2 * N + 5 * c3 + 2) / 10); c4 += 1) S1(c0, c1, c2, c3, c4, c2); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/otl.in isl-0.15/test_inputs/codegen/cloog/otl.in --- isl-0.12.2/test_inputs/codegen/cloog/otl.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/otl.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1, i2, i3, i4, i2] -> [i0, i1, i2, i3, i4, i2] : 5i0 <= -7 + 2M + 2N and i4 >= i0 - i2 and 10i2 >= -2 - N + 5i0 and i2 >= -1 + i0 - i1 and 2i4 >= i0 and i0 >= 1 and i1 >= 1 and 2i1 >= i0 and i2 >= 0 and 5i2 >= 1 - M - N + 5i0 and 5i4 >= -1 - M + 5i0 and i3 >= i0 and 5i1 >= -2 - M + 5i0 and i3 >= 1 and 5i3 >= -3 - N + 5i1 + 5i2 and 5i2 <= 4 + N + 5i0 - 5i1 and i4 >= 1 and i2 <= i0 and 5i3 >= -2N + 10i1 and 5i1 <= -5 + M + 2N and 10i1 <= 1 + 2N + 5i0 and 5i2 >= -1 - N + 5i1 and i4 >= i1 and i3 >= i1 and i2 <= i1 and i1 <= i0 and 5i4 <= 4 + N - 5i2 + 5i3 and 5i4 <= 5 + N + 5i0 - 5i2 and 5i3 >= -2 - N + 10i2 and 5i2 <= -2 + M + N and 10i2 <= 3 + N + 5i0 and N >= 4 and i4 >= i2 and i3 >= i2 and M >= 3 and i4 <= i0 and 5i3 <= -6 + 2M + 2N and i4 >= -1 - i2 + i3 and 5i3 <= 3 + N + 10i2 and i3 <= 1 + i1 + i2 and i4 <= 1 + i1 and 2i4 >= i3 and 5i4 <= 2 + N + 5i2 and i3 <= 1 + 2i1 and i4 <= i3 and 5i3 <= M + N + 5i2 and 5i4 >= -2 - M + 5i3 and 10i4 <= 3 + 2N + 5i0 and i3 <= 1 + i0 and 5i3 <= 3 + M + 5i1 and 5i4 <= -4 + M + 2N and 10i4 <= 2 + 2N + 5i3 } -[M, N] -> { : M >= 1 and N >= 1 } -[M, N] -> { [i, j, k, l, m, n] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/otl.st isl-0.15/test_inputs/codegen/cloog/otl.st --- isl-0.12.2/test_inputs/codegen/cloog/otl.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/otl.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M, N] -> { S1[outerTimeTileIter, outerProcTileIter1, outerProcTileIter2, innerTimeTileIter, innerProcTileIter1, outerProcTileIter2] : 5outerTimeTileIter <= -7 + 2M + 2N and innerProcTileIter1 >= outerTimeTileIter - outerProcTileIter2 and 10outerProcTileIter2 >= -2 - N + 5outerTimeTileIter and outerProcTileIter2 >= -1 + outerTimeTileIter - outerProcTileIter1 and 2innerProcTileIter1 >= outerTimeTileIter and outerTimeTileIter >= 1 and outerProcTileIter1 >= 1 and 2outerProcTileIter1 >= outerTimeTileIter and outerProcTileIter2 >= 0 and 5outerProcTileIter2 >= 1 - M - N + 5outerTimeTileIter and 5innerProcTileIter1 >= -1 - M + 5outerTimeTileIter and innerTimeTileIter >= outerTimeTileIter and 5outerProcTileIter1 >= -2 - M + 5outerTimeTileIter and innerTimeTileIter >= 1 and 5innerTimeTileIter >= -3 - N + 5outerProcTileIter1 + 5outerProcTileIter2 and 5outerProcTileIter2 <= 4 + N + 5outerTimeTileIter - 5outerProcTileIter1 and innerProcTileIter1 >= 1 and outerProcTileIter2 <= outerTimeTileIter and 5innerTimeTileIter >= -2N + 10outerProcTileIter1 and 5outerProcTileIter1 <= -5 + M + 2N and 10outerProcTileIter1 <= 1 + 2N + 5outerTimeTileIter and 5outerProcTileIter2 >= -1 - N + 5outerProcTileIter1 and innerProcTileIter1 >= outerProcTileIter1 and innerTimeTileIter >= outerProcTileIter1 and outerProcTileIter2 <= outerProcTileIter1 and outerProcTileIter1 <= outerTimeTileIter and 5innerProcTileIter1 <= 4 + N - 5outerProcTileIter2 + 5innerTimeTileIter and 5innerProcTileIter1 <= 5 + N + 5outerTimeTileIter - 5outerProcTileIter2 and 5innerTimeTileIter >= -2 - N + 10outerProcTileIter2 and 5outerProcTileIter2 <= -2 + M + N and 10outerProcTileIter2 <= 3 + N + 5outerTimeTileIter and N >= 4 and innerProcTileIter1 >= outerProcTileIter2 and innerTimeTileIter >= outerProcTileIter2 and M >= 3 and innerProcTileIter1 <= outerTimeTileIter and 5innerTimeTileIter <= -6 + 2M + 2N and innerProcTileIter1 >= -1 - outerProcTileIter2 + innerTimeTileIter and 5innerTimeTileIter <= 3 + N + 10outerProcTileIter2 and innerTimeTileIter <= 1 + outerProcTileIter1 + outerProcTileIter2 and innerProcTileIter1 <= 1 + outerProcTileIter1 and 2innerProcTileIter1 >= innerTimeTileIter and 5innerProcTileIter1 <= 2 + N + 5outerProcTileIter2 and innerTimeTileIter <= 1 + 2outerProcTileIter1 and innerProcTileIter1 <= innerTimeTileIter and 5innerTimeTileIter <= M + N + 5outerProcTileIter2 and 5innerProcTileIter1 >= -2 - M + 5innerTimeTileIter and 10innerProcTileIter1 <= 3 + 2N + 5outerTimeTileIter and innerTimeTileIter <= 1 + outerTimeTileIter and 5innerTimeTileIter <= 3 + M + 5outerProcTileIter1 and 5innerProcTileIter1 <= -4 + M + 2N and 10innerProcTileIter1 <= 2 + 2N + 5innerTimeTileIter }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2, i3, i4, i5] -> [(i0)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i1)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i2)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i3)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i4)] }, { S1[i0, i1, i2, i3, i4, i5] -> [(i5)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/param-split.c isl-0.15/test_inputs/codegen/cloog/param-split.c --- isl-0.12.2/test_inputs/codegen/cloog/param-split.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/param-split.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 0; c0 <= (M >= 0 ? M : 0); c0 += 1) { +for (int c0 = 0; c0 <= (M <= 0 ? 0 : M); c0 += 1) { if (M >= c0) S1(c0); if (c0 == 0) diff -Nru isl-0.12.2/test_inputs/codegen/cloog/param-split.in isl-0.15/test_inputs/codegen/cloog/param-split.in --- isl-0.12.2/test_inputs/codegen/cloog/param-split.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/param-split.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0] -> [i0, 0] : i0 >= 0 and i0 <= M; S2[0] -> [0, 1] } -[M] -> { : } -[M] -> { [i, j] -> atomic[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/param-split.st isl-0.15/test_inputs/codegen/cloog/param-split.st --- isl-0.12.2/test_inputs/codegen/cloog/param-split.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/param-split.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M] -> { S2[0]; S1[i0] : i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S2[i0] -> [(i0)]; S1[i0] -> [(i0)] }]" + options: "[M] -> { atomic[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0] }" + - filter: "[M] -> { S2[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/pouchet.c isl-0.15/test_inputs/codegen/cloog/pouchet.c --- isl-0.12.2/test_inputs/codegen/cloog/pouchet.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/pouchet.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 1; c0 <= floord(Ny, 2) + 2; c0 += 1) - for (int c1 = max(c0 / 2 + 1, c0 - 1); c1 <= min(c0, (Ny + 2 * c0) / 4); c1 += 1) + for (int c1 = max(c0 - 1, c0 / 2 + 1); c1 <= min(c0, (Ny + 2 * c0) / 4); c1 += 1) { if (Ny + 2 * c0 >= 4 * c1 + 1) { for (int c2 = 1; c2 <= 2; c2 += 1) { S1(c0 - c1, c1, 2 * c0 - 2 * c1, -2 * c0 + 4 * c1, c2); @@ -7,4 +7,5 @@ } } else for (int c2 = 1; c2 <= 2; c2 += 1) - S2((-Ny + 2 * c0) / 4, (Ny + 2 * c0) / 4, (-Ny + 2 * c0) / 2, Ny - 1, c2); + S2((-Ny + 2 * c0) / 4, (Ny + 2 * c0) / 4, (-Ny / 2) + c0, Ny - 1, c2); + } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/pouchet.in isl-0.15/test_inputs/codegen/cloog/pouchet.in --- isl-0.12.2/test_inputs/codegen/cloog/pouchet.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/pouchet.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[Ny] -> { S1[i0, i1, 2i0, -2i0 + 2i1, i4] -> [i0 + i1, i1, i4, 2i0, -2i0 + 2i1, i4] : i0 >= 0 and i0 <= 1 and i1 >= 1 + i0 and 2i1 <= -1 + Ny + 2i0 and i4 >= 1 and i4 <= 2; S2[i0, i1, 2i0, -1 - 2i0 + 2i1, i4] -> [i0 + i1, i1, i4, 2i0, -2i0 + 2i1, 1 + i4] : i0 >= 0 and i0 <= 1 and i1 >= 1 + i0 and 2i1 <= Ny + 2i0 and i4 >= 1 and i4 <= 2 } -[Ny] -> { : } -[Ny] -> { [i, j, k, l, m, n] -> separate[x] : x >= 2 } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/pouchet.st isl-0.15/test_inputs/codegen/cloog/pouchet.st --- isl-0.12.2/test_inputs/codegen/cloog/pouchet.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/pouchet.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[Ny] -> { S1[i0, i1, 2i0, -2i0 + 2i1, i4] : i0 >= 0 and i0 <= 1 and i1 >= 1 + i0 and 2i1 <= -1 + Ny + 2i0 and i4 >= 1 and i4 <= 2; S2[i0, i1, 2i0, -1 - 2i0 + 2i1, i4] : i0 >= 0 and i0 <= 1 and i1 >= 1 + i0 and 2i1 <= Ny + 2i0 and i4 >= 1 and i4 <= 2 }" +child: + context: "[Ny] -> { [] }" + child: + schedule: "[Ny] -> [{ S1[i0, i1, i2, i3, i4] -> [(i0 + i1)]; S2[i0, i1, i2, i3, i4] -> [(i0 + i1)] }, { S1[i0, i1, i2, i3, i4] -> [(i1)]; S2[i0, i1, i2, i3, i4] -> [(i1)] }, { S1[i0, i1, i2, i3, i4] -> [(i4)]; S2[i0, i1, i2, i3, i4] -> [(i4)] }, { S1[i0, i1, i2, i3, i4] -> [(i2)]; S2[i0, i1, i2, i3, i4] -> [(i2)] }, { S1[i0, i1, i2, i3, i4] -> [(i3)]; S2[i0, i1, i2, i3, i4] -> [(1 + i3)] }, { S1[i0, i1, i2, i3, i4] -> [(i4)]; S2[i0, i1, i2, i3, i4] -> [(1 + i4)] }]" + options: "[Ny] -> { separate[x] : x >= 2 }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/rectangle.c isl-0.15/test_inputs/codegen/cloog/rectangle.c --- isl-0.12.2/test_inputs/codegen/cloog/rectangle.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/rectangle.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 0; c0 <= 2 * n; c0 += 1) - for (int c1 = max(0, -n + c0); c1 <= min(c0, n); c1 += 1) + for (int c1 = max(0, -n + c0); c1 <= min(n, c0); c1 += 1) S1(c1, c0 - c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/rectangle.in isl-0.15/test_inputs/codegen/cloog/rectangle.in --- isl-0.12.2/test_inputs/codegen/cloog/rectangle.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/rectangle.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i0, i1] -> [i0 + i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= n } -[n] -> { : n >= 0 } -[n] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/rectangle.st isl-0.15/test_inputs/codegen/cloog/rectangle.st --- isl-0.12.2/test_inputs/codegen/cloog/rectangle.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/rectangle.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 0 and i0 <= n and i1 >= 0 and i1 <= n }" +child: + context: "[n] -> { [] : n >= 0 }" + child: + schedule: "[n] -> [{ S1[i0, i1] -> [(i0 + i1)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-bastoul3.in isl-0.15/test_inputs/codegen/cloog/reservoir-bastoul3.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-bastoul3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-bastoul3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1, i2] -> [i0, i1, k, 0] : 2k = i0 - i1 and 2i2 = i0 - i1 and i1 >= 1 and i1 <= 3 and i1 <= -2 + i0 and i1 >= -6 + i0 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-bastoul3.st isl-0.15/test_inputs/codegen/cloog/reservoir-bastoul3.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-bastoul3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-bastoul3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i2 = i0 - i1 and i1 >= 1 and i1 <= 3 and i1 <= -2 + i0 and i1 >= -6 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-cholesky2.c isl-0.15/test_inputs/codegen/cloog/reservoir-cholesky2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-cholesky2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-cholesky2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,9 +1,9 @@ -for (int c1 = 2; c1 < 3 * M; c1 += 1) { - if ((c1 - 2) % 3 == 0) - S1((c1 + 1) / 3); - for (int c3 = (c1 + 1) / 3 + 1; c3 <= min(c1 - 2, M); c3 += 1) - for (int c5 = -c3 + (c1 + c3 + 1) / 2 + 1; c5 <= min(c1 - c3, c3); c5 += 1) - S3(c1 - c3 - c5 + 1, c3, c5); - for (int c3 = -c1 + 2 * ((2 * c1 + 1) / 3) + 2; c3 <= min(c1, M); c3 += 2) - S2((c1 - c3 + 2) / 2, c3); +for (int c0 = 2; c0 < 3 * M; c0 += 1) { + if ((c0 - 2) % 3 == 0) + S1((c0 + 1) / 3); + for (int c1 = (c0 + 1) / 3 + 1; c1 <= min(M, c0 - 2); c1 += 1) + for (int c2 = -c1 + (c0 + c1 + 1) / 2 + 1; c2 <= min(c1, c0 - c1); c2 += 1) + S3(c0 - c1 - c2 + 1, c1, c2); + for (int c1 = -c0 + 2 * ((2 * c0 + 1) / 3) + 2; c1 <= min(M, c0); c1 += 2) + S2(((c0 - c1) / 2) + 1, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-cholesky2.in isl-0.15/test_inputs/codegen/cloog/reservoir-cholesky2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-cholesky2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-cholesky2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S3[i0, i1, i2] -> [0, -1 + i0 + i1 + i2, 1, i1, 1, i2, 0] : i0 >= 1 and i1 <= M and i2 >= 1 + i0 and i2 <= i1; S2[i0, i1] -> [0, -2 + 2i0 + i1, 2, i1, 0, 0, 0] : i0 >= 1 and i1 >= 1 + i0 and i1 <= M; S1[i0] -> [0, -1 + 3i0, 0, 0, 0, 0, 0] : i0 >= 1 and i0 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-cholesky2.st isl-0.15/test_inputs/codegen/cloog/reservoir-cholesky2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-cholesky2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-cholesky2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,20 @@ +domain: "[M] -> { S3[i0, i1, i2] : i0 >= 1 and i1 <= M and i2 >= 1 + i0 and i2 <= i1; S2[i0, i1] : i0 >= 1 and i1 >= 1 + i0 and i1 <= M; S1[i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0] -> [(-1 + 3i0)]; S3[i0, i1, i2] -> [(-1 + i0 + i1 + i2)]; S2[i0, i1] -> [(-2 + 2i0 + i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0] }" + - filter: "[M] -> { S3[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion1.c isl-0.15/test_inputs/codegen/cloog/reservoir-fusion1.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-fusion1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ { - for (int c1 = 0; c1 <= M; c1 += 1) - S1(c1); - for (int c1 = 1; c1 <= M; c1 += 1) - S2(c1); - for (int c1 = 0; c1 <= M; c1 += 1) - S3(c1); + for (int c0 = 0; c0 <= M; c0 += 1) + S1(c0); + for (int c0 = 1; c0 <= M; c0 += 1) + S2(c0); + for (int c0 = 0; c0 <= M; c0 += 1) + S3(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion1.in isl-0.15/test_inputs/codegen/cloog/reservoir-fusion1.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-fusion1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0] -> [0, i0, 0] : i0 >= 0 and i0 <= M; S3[i0] -> [2, i0, 0] : i0 >= 0 and i0 <= M; S2[i0] -> [1, i0, 0] : i0 >= 1 and i0 <= M } -[M] -> { : M >= 1 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion1.st isl-0.15/test_inputs/codegen/cloog/reservoir-fusion1.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-fusion1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,17 @@ +domain: "[M] -> { S3[i0] : i0 >= 0 and i0 <= M; S2[i0] : i0 >= 1 and i0 <= M; S1[i0] : i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + sequence: + - filter: "[M] -> { S1[i0] }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0] }" + child: + schedule: "[M] -> [{ S2[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S3[i0] }" + child: + schedule: "[M] -> [{ S3[i0] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion2.c isl-0.15/test_inputs/codegen/cloog/reservoir-fusion2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-fusion2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,12 +1,12 @@ if (N >= 1) { - for (int c3 = 1; c3 <= M; c3 += 1) - S1(1, c3); - for (int c1 = 2; c1 <= N; c1 += 1) { - for (int c3 = 1; c3 <= M; c3 += 1) - S2(c1 - 1, c3); - for (int c3 = 1; c3 <= M; c3 += 1) - S1(c1, c3); + for (int c1 = 1; c1 <= M; c1 += 1) + S1(1, c1); + for (int c0 = 2; c0 <= N; c0 += 1) { + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0 - 1, c1); + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); } - for (int c3 = 1; c3 <= M; c3 += 1) - S2(N, c3); + for (int c1 = 1; c1 <= M; c1 += 1) + S2(N, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion2.in isl-0.15/test_inputs/codegen/cloog/reservoir-fusion2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-fusion2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0, i1] -> [0, 1 + i0, 0, i1, 0] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S1[i0, i1] -> [0, i0, 1, i1, 0] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M } -[M, N] -> { : } -[M, N] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion2.st isl-0.15/test_inputs/codegen/cloog/reservoir-fusion2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-fusion2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-fusion2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(1 + i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S1[i0, i1] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi2.c isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,3 @@ -for (int c1 = 0; c1 < M; c1 += 1) - for (int c3 = 0; c3 < M; c3 += 1) - S1(c1, c3); +for (int c0 = 0; c0 < M; c0 += 1) + for (int c1 = 0; c1 < M; c1 += 1) + S1(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi2.in isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 0 and i0 <= -1 + M and i1 >= 0 and i1 <= -1 + M } -[M] -> { : M >= 1 } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi2.st isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,9 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 0 and i0 <= -1 + M and i1 >= 0 and i1 <= -1 + M }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi3.c isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi3.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi3.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi3.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ -for (int c1 = 1; c1 <= M; c1 += 1) { - for (int c3 = 2; c3 < N; c3 += 1) - for (int c5 = 2; c5 < N; c5 += 1) - S1(c1, c3, c5); - for (int c3 = 2; c3 < N; c3 += 1) - for (int c5 = 2; c5 < N; c5 += 1) - S2(c1, c3, c5); +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S1(c0, c2, c3); + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S2(c0, c2, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi3.in isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi3.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0, i1, i2] -> [0, 1 + 2i0, 1, i1, 0, i2, 0] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N; S1[i0, i1, i2] -> [0, 2i0, 0, i1, 0, i2, 0] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N } -[M, N] -> { : } -[M, N] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi3.st isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi3.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-jacobi3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-jacobi3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,22 @@ +domain: "[M, N] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(2i0)]; S2[i0, i1, i2] -> [(1 + 2i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam1.c isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam1.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,10 +1,10 @@ -for (int c1 = -99; c1 <= 100; c1 += 1) { - if (c1 <= 0) - S1(1, -c1 + 1); - for (int c3 = max(-2 * c1 + 3, 1); c3 <= min(-2 * c1 + 199, 199); c3 += 2) { - S2((2 * c1 + c3 - 1) / 2, (c3 + 1) / 2); - S1((2 * c1 + c3 + 1) / 2, (c3 + 1) / 2); +for (int c0 = -99; c0 <= 100; c0 += 1) { + if (c0 >= 1) + S2(c0, 1); + for (int c1 = max(1, -c0 + 1); c1 <= min(99, -c0 + 100); c1 += 1) { + S1(c0 + c1, c1); + S2(c0 + c1, c1 + 1); } - if (c1 >= 1) - S2(100, -c1 + 101); + if (c0 <= 0) + S1(c0 + 100, 100); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam1.in isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam1.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[i0, i1] -> [0, 1 + i0 - i1, 0, -1 + 2i1, 1] : i0 >= 1 and i0 <= 100 and i1 >= 1 and i1 <= 100; S1[i0, i1] -> [0, i0 - i1, 0, 2i1, 0] : i0 >= 1 and i0 <= 100 and i1 >= 1 and i1 <= 100 } -{ : } -{ [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam1.st isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam1.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,13 @@ +domain: "{ S2[i0, i1] : i0 >= 1 and i0 <= 100 and i1 >= 1 and i1 <= 100; S1[i0, i1] : i0 >= 1 and i0 <= 100 and i1 >= 1 and i1 <= 100 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1] -> [(i0 - i1)]; S2[i0, i1] -> [(1 + i0 - i1)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1] -> [(2i1)]; S2[i0, i1] -> [(-1 + 2i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam2.c isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,10 +1,10 @@ { - for (int c1 = 1; c1 <= M; c1 += 1) - S1(c1); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 2; c3 <= N; c3 += 1) - S2(c1, c3); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - S3(c1, c3); + for (int c0 = 1; c0 <= M; c0 += 1) + S1(c0); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 2; c1 <= N; c1 += 1) + S2(c0, c1); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + S3(c0, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam2.in isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0] -> [0, i0, 0, 0, 0] : i0 >= 1 and i0 <= M; S2[i0, i1] -> [1, i0, 1, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= N; S3[i0, i1] -> [2, i0, 2, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + N } -[M, N] -> { : M >= 1 and N >= 1 } -[M, N] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam2.st isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,23 @@ +domain: "[M, N] -> { S3[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + N; S1[i0] : i0 >= 1 and i0 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= N }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + sequence: + - filter: "[M, N] -> { S1[i0] }" + child: + schedule: "[M, N] -> [{ S1[i0] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S3[i0, i1] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam3.c isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam3.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam3.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam3.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,11 +1,11 @@ -for (int c1 = 5; c1 <= 5 * M; c1 += 1) { - for (int c3 = max(2, floord(-M + c1, 4)); c3 < min((c1 + 1) / 3 - 2, M); c3 += 1) - for (int c5 = max(-M - c3 + (M + c1) / 2 - 2, 1); c5 < min(-2 * c3 + (c1 + c3) / 2 - 2, c3); c5 += 1) - S1(c1 - 2 * c3 - 2 * c5 - 5, c3, c5); - for (int c3 = max(1, floord(-M + c1, 4)); c3 < (c1 + 1) / 5; c3 += 1) - S2(c1 - 4 * c3 - 3, c3); - if (c1 % 5 == 0) - S4(c1 / 5); - for (int c3 = max(-((c1 - 1) % 3) + 3, -3 * M - c1 + 3 * ((M + c1) / 2) + 1); c3 < (c1 + 1) / 5; c3 += 3) - S3((c1 - 2 * c3 - 1) / 3, c3); +for (int c0 = 5; c0 <= 5 * M; c0 += 1) { + for (int c1 = max(2, floord(-M + c0, 4)); c1 < min(-((5 * M - c0 + 1) % 2) + M, (c0 + 1) / 3 - 2); c1 += 1) + for (int c2 = max(1, -M - c1 + (M + c0) / 2 - 2); c2 < min(c1, -2 * c1 + (c0 + c1) / 2 - 2); c2 += 1) + S1(c0 - 2 * c1 - 2 * c2 - 5, c1, c2); + for (int c1 = max(1, floord(-M + c0, 4)); c1 < (c0 + 1) / 5; c1 += 1) + S2(c0 - 4 * c1 - 3, c1); + if (c0 % 5 == 0) + S4(c0 / 5); + for (int c1 = max(-3 * M - c0 + 3 * ((M + c0) / 2) + 1, -((c0 - 1) % 3) + 3); c1 < (c0 + 1) / 5; c1 += 3) + S3((c0 - 2 * c1 - 1) / 3, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam3.in isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam3.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2] -> [0, 5 + i0 + 2i1 + 2i2, 0, i1, 0, i2, 0] : i0 <= M and i1 <= -1 + i0 and i2 >= 1 and i2 <= -1 + i1; S3[i0, i1] -> [0, 1 + 3i0 + 2i1, 2, i1, 0, 0, 0] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S2[i0, i1] -> [0, 3 + i0 + 4i1, 1, i1, 1, 0, 0] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S4[i0] -> [0, 5i0, 2, 0, 0, 0, 0] : i0 >= 1 and i0 <= M } -[M] -> { : M >= 1 } -[M] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam3.st isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam3.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,23 @@ +domain: "[M] -> { S4[i0] : i0 >= 1 and i0 <= M; S3[i0, i1] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S2[i0, i1] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S1[i0, i1, i2] : i0 <= M and i1 <= -1 + i0 and i2 >= 1 and i2 <= -1 + i1 }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + schedule: "[M] -> [{ S4[i0] -> [(5i0)]; S1[i0, i1, i2] -> [(5 + i0 + 2i1 + 2i2)]; S3[i0, i1] -> [(1 + 3i0 + 2i1)]; S2[i0, i1] -> [(3 + i0 + 4i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S4[i0]; S3[i0, i1] }" + child: + schedule: "[M] -> [{ S4[i0] -> [(0)]; S3[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam4.c isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam4.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam4.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam4.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,10 +1,10 @@ -for (int c1 = 1; c1 < 2 * M - 1; c1 += 1) { - for (int c3 = max(-c1 + 1, -M + 1); c3 < 0; c3 += 1) { - for (int c7 = max(-M + c1 + 1, 1); c7 <= min(M - 1, c1 + c3); c7 += 1) - S1(c7, c1 + c3 - c7, -c3); - for (int c5 = max(-M + c1 + 1, -c3); c5 < min(M, c1); c5 += 1) - S2(c1 - c5, c3 + c5, c5); +for (int c0 = 1; c0 < 2 * M - 1; c0 += 1) { + for (int c1 = max(-M + 1, -c0 + 1); c1 < 0; c1 += 1) { + for (int c3 = max(1, -M + c0 + 1); c3 <= min(M - 1, c0 + c1); c3 += 1) + S1(c3, c0 + c1 - c3, -c1); + for (int c2 = max(-M + c0 + 1, -c1); c2 < min(M, c0); c2 += 1) + S2(c0 - c2, c1 + c2, c2); } - for (int c7 = max(1, -M + c1 + 1); c7 <= min(c1, M - 1); c7 += 1) - S1(c7, c1 - c7, 0); + for (int c3 = max(1, -M + c0 + 1); c3 <= min(M - 1, c0); c3 += 1) + S1(c3, c0 - c3, 0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam4.in isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam4.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam4.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam4.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2] -> [0, i0 + i1 + i2, 0, -i2, 0, i2, 0] : i0 >= 1 and i0 <= -1 + M and i1 >= 0 and i2 >= 0 and i2 <= -1 + M - i1; S2[i0, i1, i2] -> [0, i0 + i2, 0, i1 - i2, 1, i2, 0] : i0 >= 1 and i0 <= -1 + M and i1 >= 0 and i2 >= 1 + i1 and i2 <= -1 + M } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam4.st isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam4.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,19 @@ +domain: "[M] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + M and i1 >= 0 and i2 >= 1 + i1 and i2 <= -1 + M; S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + M and i1 >= 0 and i2 >= 0 and i2 <= -1 + M - i1 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0 + i1 + i2)]; S2[i0, i1, i2] -> [(i0 + i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(-i2)]; S2[i0, i1, i2] -> [(i1 - i2)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam5.c isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam5.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam5.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam5.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,11 +1,11 @@ { - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S1(c1, c3); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S2(c1, c3); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S3(c1, c3); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S3(c0, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam5.in isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam5.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam5.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam5.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [1, i0, 0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S1[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S3[i0, i1] -> [2, i0, 0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam5.st isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam5.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam5.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam5.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,26 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S3[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S3[i0, i1] }" + child: + schedule: "[M] -> [{ S3[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S3[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam6.c isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam6.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam6.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam6.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ { - for (int c1 = 0; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S1(c1, c3); - for (int c1 = 0; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S2(c3, c1); + for (int c0 = 0; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); + for (int c0 = 0; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c1, c0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam6.in isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam6.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam6.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam6.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [1, i1, 0, i0, 0] : i0 >= 1 and i0 <= M and i1 >= 0 and i1 <= M; S1[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 0 and i0 <= M and i1 >= 1 and i1 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam6.st isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam6.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-lim-lam6.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-lim-lam6.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,19 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 0 and i1 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c isl-0.15/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,17 +1,17 @@ -if (N >= 0 && M >= 0) - for (int c1 = -4; c1 <= 3 * M + N; c1 += 1) { - if (c1 >= 3 * M) { - S2(M, -3 * M + c1); - } else if (3 * floord(c1 - 2, 3) + 2 == c1 && c1 >= -1 && 3 * M >= c1 + 4) - S1((c1 + 4) / 3, 0); - for (int c3 = max(-3 * M + c1 + 3, c1 + 3 * floord(-c1 - 1, 3) + 3); c3 <= min(N - 1, c1); c3 += 3) { - S2((c1 - c3) / 3, c3); - S1((c1 - c3 + 3) / 3, c3 + 1); +if (M >= 0 && N >= 0) + for (int c0 = -4; c0 <= 3 * M + N; c0 += 1) { + if (c0 >= 0 && 3 * M + 1 >= c0 && (c0 + 1) % 3 >= 1 && N + 1 >= (c0 + 1) % 3) + S2((c0 + 1) / 3, ((c0 + 1) % 3) - 1); + for (int c1 = max(-3 * M + c0 - 2, (c0 + 4) % 3); c1 <= min(min(N - 2, c0 - 2), -3 * M + c0 + 3); c1 += 3) + S2((c0 - c1 - 2) / 3, c1 + 2); + for (int c1 = max(-3 * M + c0 + 4, (c0 + 4) % 3); c1 < min(N - 1, c0 - 1); c1 += 3) { + S1((c0 - c1 + 4) / 3, c1); + S2((c0 - c1 - 2) / 3, c1 + 2); } - if (N + 3 * floord(-N + c1, 3) == c1 && 3 * M + N >= c1 + 3 && c1 >= N) { - S2((-N + c1) / 3, N); - } else if (N >= c1 + 4) - S1(0, c1 + 4); - for (int c3 = max(-3 * M + c1, c1 + 3 * floord(-c1 - 1, 3) + 3); c3 <= min(N, c1); c3 += 3) - S3((c1 - c3) / 3, c3); + if (3 * M + N >= c0 + 4 && c0 >= N + 1 && ((-N + c0) % 3) + N >= 2 && (-N + c0) % 3 >= 1) + S1((-N + c0 + 3) / 3 + 1, ((-N + c0) % 3) + N - 2); + for (int c1 = max(max(c0 + 1, -3 * M + c0 + 4), (c0 + 4) % 3); c1 <= min(N, c0 + 4); c1 += 3) + S1((c0 - c1 + 4) / 3, c1); + for (int c1 = max(-3 * M + c0, (c0 + 6) % 3); c1 <= min(N, c0); c1 += 3) + S3((c0 - c1) / 3, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-liu-zhuge1.in isl-0.15/test_inputs/codegen/cloog/reservoir-liu-zhuge1.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-liu-zhuge1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-liu-zhuge1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0, i1] -> [0, 3i0 + i1, 0, i1, 0] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N; S3[i0, i1] -> [0, 3i0 + i1, 1, i1, 0] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N; S1[i0, i1] -> [0, -4 + 3i0 + i1, 0, i1, 0] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N } -[M, N] -> { : } -[M, N] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st isl-0.15/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-liu-zhuge1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S3[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N; S1[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N; S2[i0, i1] : i0 >= 0 and i0 <= M and i1 >= 0 and i1 <= N }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(-4 + 3i0 + i1)]; S2[i0, i1] -> [(3i0 + i1)]; S3[i0, i1] -> [(3i0 + i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1]; S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S3[i0, i1] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner3.c isl-0.15/test_inputs/codegen/cloog/reservoir-loechner3.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner3.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner3.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 2; c3 <= M + c1; c3 += 1) - for (int c5 = max(-c1 + c3, 1); c5 <= min(M, c3 - 1); c5 += 1) - S1(c1, c5, c3 - c5); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 2; c1 <= M + c0; c1 += 1) + for (int c2 = max(1, -c0 + c1); c2 <= min(M, c1 - 1); c2 += 1) + S1(c0, c2, c1 - c2); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner3.in isl-0.15/test_inputs/codegen/cloog/reservoir-loechner3.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2] -> [0, i0, 0, i1 + i2, 0, i1, 0] : i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= i0 } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner3.st isl-0.15/test_inputs/codegen/cloog/reservoir-loechner3.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,12 @@ +domain: "[M] -> { S1[i0, i1, i2] : i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= i0 }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i1 + i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner4.c isl-0.15/test_inputs/codegen/cloog/reservoir-loechner4.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner4.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner4.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ -for (int c1 = 2; c1 <= 2 * M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - for (int c5 = 1; c5 <= M; c5 += 1) - for (int c7 = max(1, -M + c1); c7 <= min(c1 - 1, M); c7 += 1) - S1(c5, c3, c7, c1 - c7); +for (int c0 = 2; c0 <= 2 * M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + for (int c2 = 1; c2 <= M; c2 += 1) + for (int c3 = max(1, -M + c0); c3 <= min(M, c0 - 1); c3 += 1) + S1(c2, c1, c3, c0 - c3); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner4.in isl-0.15/test_inputs/codegen/cloog/reservoir-loechner4.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner4.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner4.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2, i3] -> [0, i2 + i3, 0, i1, 0, i0, 0, i2, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M and i3 >= 1 and i3 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o, p, q] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner4.st isl-0.15/test_inputs/codegen/cloog/reservoir-loechner4.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,15 @@ +domain: "[M] -> { S1[i0, i1, i2, i3] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M and i3 >= 1 and i3 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i2 + i3)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner5.c isl-0.15/test_inputs/codegen/cloog/reservoir-loechner5.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner5.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner5.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ -for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - for (int c5 = 1; c5 <= M; c5 += 1) - for (int c7 = 1; c7 <= M; c7 += 1) - S1(c3, c5, c1, c7); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + for (int c2 = 1; c2 <= M; c2 += 1) + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c1, c2, c0, c3); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner5.in isl-0.15/test_inputs/codegen/cloog/reservoir-loechner5.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner5.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner5.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2, i3] -> [0, i2, 0, i0, 0, i1, 0, i3, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M and i3 >= 1 and i3 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o, p, q] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner5.st isl-0.15/test_inputs/codegen/cloog/reservoir-loechner5.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-loechner5.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-loechner5.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,15 @@ +domain: "[M] -> { S1[i0, i1, i2, i3] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M and i3 >= 1 and i3 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2, i3] -> [(i3)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-long.c isl-0.15/test_inputs/codegen/cloog/reservoir-long.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-long.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-long.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,14 @@ +for (int c0 = 1; c0 < O; c0 += 1) { + for (int c1 = Q; c1 < N; c1 += 1) { + for (int c2 = P; c2 < M; c2 += 1) + S1(c0, c1, c2); + for (int c2 = 1; c2 < M; c2 += 1) + S2(c0, c1, c2); + } + for (int c1 = 1; c1 < N; c1 += 1) { + for (int c2 = P; c2 < M; c2 += 1) + S3(c0, c1, c2); + for (int c2 = 1; c2 < M; c2 += 1) + S4(c0, c1, c2); + } +} diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-long.st isl-0.15/test_inputs/codegen/cloog/reservoir-long.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-long.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-long.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,36 @@ +domain: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S3[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S4[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R, S, T, U] -> { [] : M >= 10 and N >= 10 and O >= 10 and P >= 1 and P <= 2 and Q >= 1 and Q <= 2 and R >= 1 and R <= 2 and S >= 0 and S <= 1 and T >= 0 and T <= 1 and U >= 0 and U <= 1 }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2]; S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i1)]; S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2]; S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i1)]; S3[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp2.c isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,18 +1,18 @@ { - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = Q; c3 < N; c3 += 1) - for (int c5 = P; c5 < M; c5 += 1) - S1(c1, c3, c5); - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = Q; c3 < N; c3 += 1) - for (int c5 = 1; c5 < M; c5 += 1) - S2(c1, c3, c5); - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - for (int c5 = P; c5 < M; c5 += 1) - S3(c1, c3, c5); - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - for (int c5 = 1; c5 < M; c5 += 1) - S4(c1, c3, c5); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S1(c0, c1, c2); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S2(c0, c1, c2); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S3(c0, c1, c2); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S4(c0, c1, c2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp2.in isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] -> [0, i0, 0, i1, 0, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S4[i0, i1, i2] -> [3, i0, 1, i1, 1, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] -> [1, i0, 0, i1, 1, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S3[i0, i1, i2] -> [2, i0, 1, i1, 0, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M } -[M, N, O, P, Q, R, S, T, U] -> { : } -[M, N, O, P, Q, R, S, T, U] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp2.st isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,45 @@ +domain: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S3[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S4[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R, S, T, U] -> { [] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp.c isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,85 +1,85 @@ { if (N >= 2) - for (int c1 = 1; c1 < O; c1 += 1) { - for (int c5 = 1; c5 <= M; c5 += 1) - S1(c1, 1, c5); - for (int c5 = 1; c5 < M; c5 += 1) { - S6(c1, 1, c5); - S7(c1, 1, c5); + for (int c0 = 1; c0 < O; c0 += 1) { + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c0, 1, c3); + for (int c3 = 1; c3 < M; c3 += 1) { + S6(c0, 1, c3); + S7(c0, 1, c3); } if (N >= 3) { - for (int c5 = 1; c5 <= M; c5 += 1) - S3(c1, 1, c5); - for (int c5 = 1; c5 <= M; c5 += 1) - S1(c1, 2, c5); - for (int c5 = 1; c5 < M; c5 += 1) { - S6(c1, 2, c5); - S7(c1, 2, c5); + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, 1, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c0, 2, c3); + for (int c3 = 1; c3 < M; c3 += 1) { + S6(c0, 2, c3); + S7(c0, 2, c3); } - for (int c5 = 1; c5 < M; c5 += 1) - S11(c1, 1, c5); + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, 1, c3); } else { - for (int c5 = 1; c5 <= M; c5 += 1) - S3(c1, 1, c5); - for (int c5 = 1; c5 < M; c5 += 1) - S11(c1, 1, c5); + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, 1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, 1, c3); } - for (int c3 = 3; c3 < 2 * N - 4; c3 += 2) { - for (int c5 = 1; c5 < M; c5 += 1) - S10(c1, (c3 - 1) / 2, c5); - for (int c5 = 1; c5 <= M; c5 += 1) - S3(c1, (c3 + 1) / 2, c5); - for (int c5 = 1; c5 <= M; c5 += 1) - S1(c1, (c3 + 3) / 2, c5); - for (int c5 = 1; c5 < M; c5 += 1) { - S6(c1, (c3 + 3) / 2, c5); - S7(c1, (c3 + 3) / 2, c5); + for (int c1 = 3; c1 < 2 * N - 4; c1 += 2) { + for (int c3 = 1; c3 < M; c3 += 1) + S10(c0, (c1 - 1) / 2, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, (c1 + 1) / 2, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S1(c0, (c1 + 3) / 2, c3); + for (int c3 = 1; c3 < M; c3 += 1) { + S6(c0, (c1 + 3) / 2, c3); + S7(c0, (c1 + 3) / 2, c3); } - for (int c5 = 1; c5 < M; c5 += 1) - S11(c1, (c3 + 1) / 2, c5); + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, (c1 + 1) / 2, c3); } if (N >= 3) { - for (int c5 = 1; c5 < M; c5 += 1) - S10(c1, N - 2, c5); - for (int c5 = 1; c5 <= M; c5 += 1) - S3(c1, N - 1, c5); - for (int c5 = 1; c5 < M; c5 += 1) - S11(c1, N - 1, c5); + for (int c3 = 1; c3 < M; c3 += 1) + S10(c0, N - 2, c3); + for (int c3 = 1; c3 <= M; c3 += 1) + S3(c0, N - 1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S11(c0, N - 1, c3); } - for (int c5 = 1; c5 < M; c5 += 1) - S10(c1, N - 1, c5); + for (int c3 = 1; c3 < M; c3 += 1) + S10(c0, N - 1, c3); } - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) { - for (int c5 = 1; c5 <= M; c5 += 1) - S2(c1, c3, c5); - for (int c5 = 1; c5 < M; c5 += 1) - S8(c1, c3, c5); - for (int c5 = 1; c5 < M; c5 += 1) - S9(c1, c3, c5); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) { + for (int c3 = 1; c3 <= M; c3 += 1) + S2(c0, c1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S8(c0, c1, c3); + for (int c3 = 1; c3 < M; c3 += 1) + S9(c0, c1, c3); } - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - for (int c5 = 1; c5 < M; c5 += 1) - S4(c1, c3, c5); - for (int c1 = 1; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - for (int c5 = 1; c5 < M; c5 += 1) - S5(c1, c3, c5); - for (int c1 = R; c1 < O; c1 += 1) - for (int c3 = Q; c3 < N; c3 += 1) - for (int c5 = P; c5 < M; c5 += 1) - S12(c1, c3, c5); - for (int c1 = R; c1 < O; c1 += 1) - for (int c3 = Q; c3 < N; c3 += 1) - for (int c5 = 1; c5 < M; c5 += 1) - S13(c1, c3, c5); - for (int c1 = R; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - for (int c5 = P; c5 < M; c5 += 1) - S14(c1, c3, c5); - for (int c1 = R; c1 < O; c1 += 1) - for (int c3 = 1; c3 < N; c3 += 1) - for (int c5 = 1; c5 < M; c5 += 1) - S15(c1, c3, c5); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S4(c0, c1, c2); + for (int c0 = 1; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S5(c0, c1, c2); + for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S12(c0, c1, c2); + for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = Q; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S13(c0, c1, c2); + for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = P; c2 < M; c2 += 1) + S14(c0, c1, c2); + for (int c0 = R; c0 < O; c0 += 1) + for (int c1 = 1; c1 < N; c1 += 1) + for (int c2 = 1; c2 < M; c2 += 1) + S15(c0, c1, c2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp.in isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O, P, Q, R, S, T, U] -> { S8[i0, i1, i2] -> [1, i0, 0, 2i1, 1, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S11[i0, i1, i2] -> [0, i0, 0, 2i1, 4, i2, 1] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S6[i0, i1, i2] -> [0, i0, 0, -2 + 2i1, 2, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S9[i0, i1, i2] -> [1, i0, 0, 1 + 2i1, 3, i2, 1] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S1[i0, i1, i2] -> [0, i0, 0, -3 + 2i1, 2, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S4[i0, i1, i2] -> [2, i0, 0, i1, 1, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] -> [1, i0, 0, 2i1, 0, i2, 1] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S7[i0, i1, i2] -> [0, i0, 0, -2 + 2i1, 2, i2, 1] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S10[i0, i1, i2] -> [0, i0, 0, 1 + 2i1, 0, i2, 0] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S3[i0, i1, i2] -> [0, i0, 0, -1 + 2i1, 1, i2, 2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S15[i0, i1, i2] -> [7, i0, 1, i1, 1, i2, 0] : i0 >= R and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S5[i0, i1, i2] -> [3, i0, 0, i1, 1, i2, 1] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S13[i0, i1, i2] -> [5, i0, 0, i1, 1, i2, 0] : i0 >= R and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S12[i0, i1, i2] -> [4, i0, 0, i1, 0, i2, 0] : i0 >= R and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S14[i0, i1, i2] -> [6, i0, 1, i1, 0, i2, 0] : i0 >= R and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M } -[M, N, O, P, Q, R, S, T, U] -> { : } -[M, N, O, P, Q, R, S, T, U] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp.st isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-interp.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-interp.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,115 @@ +domain: "[M, N, O, P, Q, R, S, T, U] -> { S8[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S12[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S5[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S10[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S6[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S1[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S3[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S4[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S15[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S11[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S7[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S9[i0, i1, i2] : i0 >= 1 and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M; S14[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= 1 and i1 <= -1 + N and i2 >= P and i2 <= -1 + M; S13[i0, i1, i2] : i0 >= R and i0 <= -1 + O and i1 >= Q and i1 <= -1 + N and i2 >= 1 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R, S, T, U] -> { [] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S10[i0, i1, i2]; S6[i0, i1, i2]; S3[i0, i1, i2]; S1[i0, i1, i2]; S11[i0, i1, i2]; S7[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S11[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S6[i0, i1, i2] -> [(i0)]; S10[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S7[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S11[i0, i1, i2] -> [(2i1)]; S1[i0, i1, i2] -> [(-3 + 2i1)]; S6[i0, i1, i2] -> [(-2 + 2i1)]; S10[i0, i1, i2] -> [(1 + 2i1)]; S3[i0, i1, i2] -> [(-1 + 2i1)]; S7[i0, i1, i2] -> [(-2 + 2i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S10[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S10[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S6[i0, i1, i2]; S1[i0, i1, i2]; S7[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S1[i0, i1, i2] -> [(i2)]; S6[i0, i1, i2] -> [(i2)]; S7[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S6[i0, i1, i2]; S1[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S7[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S11[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S11[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2]; S9[i0, i1, i2]; S8[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i0)]; S8[i0, i1, i2] -> [(i0)]; S9[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(2i1)]; S8[i0, i1, i2] -> [(2i1)]; S9[i0, i1, i2] -> [(1 + 2i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S8[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S8[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S9[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S9[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S4[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S4[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S5[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S5[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S5[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S5[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S12[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S12[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S12[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S12[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S13[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S13[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S13[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S13[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S14[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S14[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S14[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S14[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R, S, T, U] -> { S15[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S15[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S15[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R, S, T, U] -> [{ S15[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R, S, T, U] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-psinv.c isl-0.15/test_inputs/codegen/cloog/reservoir-mg-psinv.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-psinv.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-psinv.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,9 +1,9 @@ -for (int c1 = 2; c1 < O; c1 += 1) - for (int c3 = 3; c3 < 2 * N - 2; c3 += 2) { - for (int c5 = 1; c5 <= M; c5 += 1) { - S1(c1, (c3 + 1) / 2, c5); - S2(c1, (c3 + 1) / 2, c5); +for (int c0 = 2; c0 < O; c0 += 1) + for (int c1 = 3; c1 < 2 * N - 2; c1 += 2) { + for (int c3 = 1; c3 <= M; c3 += 1) { + S1(c0, (c1 + 1) / 2, c3); + S2(c0, (c1 + 1) / 2, c3); } - for (int c5 = 2; c5 < M; c5 += 1) - S3(c1, (c3 + 1) / 2, c5); + for (int c3 = 2; c3 < M; c3 += 1) + S3(c0, (c1 + 1) / 2, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-psinv.in isl-0.15/test_inputs/codegen/cloog/reservoir-mg-psinv.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-psinv.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-psinv.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O] -> { S1[i0, i1, i2] -> [0, i0, 0, -1 + 2i1, 0, i2, 0] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S2[i0, i1, i2] -> [0, i0, 0, -1 + 2i1, 0, i2, 1] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S3[i0, i1, i2] -> [0, i0, 0, 2i1, 1, i2, 0] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M } -[M, N, O] -> { : } -[M, N, O] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-psinv.st isl-0.15/test_inputs/codegen/cloog/reservoir-mg-psinv.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-psinv.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-psinv.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,23 @@ +domain: "[M, N, O] -> { S3[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S1[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M }" +child: + context: "[M, N, O] -> { [] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(2i1)]; S2[i0, i1, i2] -> [(-1 + 2i1)]; S1[i0, i1, i2] -> [(-1 + 2i1)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S2[i0, i1, i2]; S1[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S1[i0, i1, i2] }" + - filter: "[M, N, O] -> { S2[i0, i1, i2] }" + - filter: "[M, N, O] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-resid.c isl-0.15/test_inputs/codegen/cloog/reservoir-mg-resid.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-resid.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-resid.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,9 +1,9 @@ -for (int c1 = 2; c1 < O; c1 += 1) - for (int c3 = 3; c3 < 2 * N - 2; c3 += 2) { - for (int c5 = 1; c5 <= M; c5 += 1) { - S1(c1, (c3 + 1) / 2, c5); - S2(c1, (c3 + 1) / 2, c5); +for (int c0 = 2; c0 < O; c0 += 1) + for (int c1 = 3; c1 < 2 * N - 2; c1 += 2) { + for (int c3 = 1; c3 <= M; c3 += 1) { + S1(c0, (c1 + 1) / 2, c3); + S2(c0, (c1 + 1) / 2, c3); } - for (int c5 = 2; c5 < M; c5 += 1) - S3(c1, (c3 + 1) / 2, c5); + for (int c3 = 2; c3 < M; c3 += 1) + S3(c0, (c1 + 1) / 2, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-resid.in isl-0.15/test_inputs/codegen/cloog/reservoir-mg-resid.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-resid.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-resid.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O] -> { S1[i0, i1, i2] -> [0, i0, 0, -1 + 2i1, 0, i2, 0] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S2[i0, i1, i2] -> [0, i0, 0, -1 + 2i1, 0, i2, 1] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S3[i0, i1, i2] -> [0, i0, 0, 2i1, 1, i2, 0] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M } -[M, N, O] -> { : } -[M, N, O] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-resid.st isl-0.15/test_inputs/codegen/cloog/reservoir-mg-resid.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-resid.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-resid.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,23 @@ +domain: "[M, N, O] -> { S3[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S2[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M; S1[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 1 and i2 <= M }" +child: + context: "[M, N, O] -> { [] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(2i1)]; S2[i0, i1, i2] -> [(-1 + 2i1)]; S1[i0, i1, i2] -> [(-1 + 2i1)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S2[i0, i1, i2]; S1[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O] -> { S1[i0, i1, i2] }" + - filter: "[M, N, O] -> { S2[i0, i1, i2] }" + - filter: "[M, N, O] -> { S3[i0, i1, i2] }" + child: + schedule: "[M, N, O] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-rprj3.c isl-0.15/test_inputs/codegen/cloog/reservoir-mg-rprj3.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-rprj3.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-rprj3.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,33 +1,35 @@ if (M >= 2 && N >= 3) - for (int c1 = 2; c1 < O; c1 += 1) { - for (int c5 = 2; c5 <= M; c5 += 1) - S1(c1, 2, c5); - for (int c3 = 3; c3 < N; c3 += 1) { - for (int c5 = 2; c5 <= M; c5 += 1) - S2(c1, c3 - 1, c5); + for (int c0 = 2; c0 < O; c0 += 1) { + for (int c2 = 2; c2 <= M; c2 += 1) + S1(c0, 2, c2); + for (int c1 = 3; c1 < N; c1 += 1) { + for (int c2 = 2; c2 <= M; c2 += 1) + S2(c0, c1 - 1, c2); + if (M >= 3) + S4(c0, c1 - 1, 2); + for (int c2 = 2; c2 < M - 1; c2 += 1) { + S3(c0, c1 - 1, c2); + S5(c0, c1 - 1, c2); + S4(c0, c1 - 1, c2 + 1); + } if (M >= 3) { - S4(c1, c3 - 1, 2); - for (int c5 = 2; c5 < M - 1; c5 += 1) { - S3(c1, c3 - 1, c5); - S5(c1, c3 - 1, c5); - S4(c1, c3 - 1, c5 + 1); - } - S3(c1, c3 - 1, M - 1); - S5(c1, c3 - 1, M - 1); + S3(c0, c1 - 1, M - 1); + S5(c0, c1 - 1, M - 1); } - for (int c5 = 2; c5 <= M; c5 += 1) - S1(c1, c3, c5); + for (int c2 = 2; c2 <= M; c2 += 1) + S1(c0, c1, c2); + } + for (int c2 = 2; c2 <= M; c2 += 1) + S2(c0, N - 1, c2); + if (M >= 3) + S4(c0, N - 1, 2); + for (int c2 = 2; c2 < M - 1; c2 += 1) { + S3(c0, N - 1, c2); + S5(c0, N - 1, c2); + S4(c0, N - 1, c2 + 1); } - for (int c5 = 2; c5 <= M; c5 += 1) - S2(c1, N - 1, c5); if (M >= 3) { - S4(c1, N - 1, 2); - for (int c5 = 2; c5 < M - 1; c5 += 1) { - S3(c1, N - 1, c5); - S5(c1, N - 1, c5); - S4(c1, N - 1, c5 + 1); - } - S3(c1, N - 1, M - 1); - S5(c1, N - 1, M - 1); + S3(c0, N - 1, M - 1); + S5(c0, N - 1, M - 1); } } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-rprj3.in isl-0.15/test_inputs/codegen/cloog/reservoir-mg-rprj3.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-rprj3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-rprj3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O, P, Q, R] -> { S1[i0, i1, i2] -> [0, i0, 0, i1, 2, i2, 0] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= M; S4[i0, i1, i2] -> [0, i0, 0, 1 + i1, 1, -1 + i2, 2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S3[i0, i1, i2] -> [0, i0, 0, 1 + i1, 1, i2, 0] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S5[i0, i1, i2] -> [0, i0, 0, 1 + i1, 1, i2, 1] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S2[i0, i1, i2] -> [0, i0, 0, 1 + i1, 0, i2, 1] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= M } -[M, N, O, P, Q, R] -> { : } -[M, N, O, P, Q, R] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-rprj3.st isl-0.15/test_inputs/codegen/cloog/reservoir-mg-rprj3.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-mg-rprj3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-mg-rprj3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,28 @@ +domain: "[M, N, O, P, Q, R] -> { S2[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= M; S4[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S1[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= M; S5[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M; S3[i0, i1, i2] : i0 >= 2 and i0 <= -1 + O and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + M }" +child: + context: "[M, N, O, P, Q, R] -> { [] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S5[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S4[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S5[i0, i1, i2] -> [(1 + i1)]; S3[i0, i1, i2] -> [(1 + i1)]; S4[i0, i1, i2] -> [(1 + i1)]; S1[i0, i1, i2] -> [(i1)]; S2[i0, i1, i2] -> [(1 + i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S4[i0, i1, i2]; S5[i0, i1, i2]; S3[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S5[i0, i1, i2] -> [(i2)]; S3[i0, i1, i2] -> [(i2)]; S4[i0, i1, i2] -> [(-1 + i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S3[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S5[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S4[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali1.c isl-0.15/test_inputs/codegen/cloog/reservoir-pingali1.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,7 +1,7 @@ -for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 < 2 * N; c3 += 1) { - for (int c5 = max(1, -N + c3); c5 < (c3 + 1) / 2; c5 += 1) - S1(c1, c3 - c5, c5); - if ((c3 - 1) % 2 == 0) - S2(c1, (c3 + 1) / 2); +for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 < 2 * N; c1 += 1) { + for (int c2 = max(1, -N + c1); c2 < (c1 + 1) / 2; c2 += 1) + S1(c0, c1 - c2, c2); + if ((c1 - 1) % 2 == 0) + S2(c0, (c1 + 1) / 2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali1.in isl-0.15/test_inputs/codegen/cloog/reservoir-pingali1.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1, i2] -> [0, i0, 0, i1 + i2, 0, i2, 0] : i0 >= 1 and i0 <= M and i1 <= N and i2 >= 1 and i2 <= -1 + i1; S2[i0, i1] -> [0, i0, 0, -1 + 2i1, 1, 0, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= N } -[M, N] -> { : } -[M, N] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali1.st isl-0.15/test_inputs/codegen/cloog/reservoir-pingali1.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,16 @@ +domain: "[M, N] -> { S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= N; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 <= N and i2 >= 1 and i2 <= -1 + i1 }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(-1 + 2i1)]; S1[i0, i1, i2] -> [(i1 + i2)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali2.c isl-0.15/test_inputs/codegen/cloog/reservoir-pingali2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ { - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S1(c1, c3); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S2(c1, c3); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali2.in isl-0.15/test_inputs/codegen/cloog/reservoir-pingali2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [1, i0, 1, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S1[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali2.st isl-0.15/test_inputs/codegen/cloog/reservoir-pingali2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,19 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali3.c isl-0.15/test_inputs/codegen/cloog/reservoir-pingali3.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali3.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali3.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,9 +1,9 @@ { - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S1(c1, c3); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - for (int c5 = 1; c5 <= M; c5 += 1) - S2(c1, c3, c5); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + for (int c2 = 1; c2 <= M; c2 += 1) + S2(c0, c1, c2); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali3.in isl-0.15/test_inputs/codegen/cloog/reservoir-pingali3.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1, i2] -> [1, i0, 0, i1, 1, i2, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M; S1[i0, i1] -> [0, i0, 0, i1, 0, 0, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali3.st isl-0.15/test_inputs/codegen/cloog/reservoir-pingali3.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,22 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M and i2 >= 1 and i2 <= M }" +child: + context: "[M] -> { [] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali4.c isl-0.15/test_inputs/codegen/cloog/reservoir-pingali4.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali4.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali4.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ { - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S1(c1, c3); - for (int c1 = 1; c1 <= M; c1 += 1) - for (int c3 = 1; c3 <= M; c3 += 1) - S2(c1, c3); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S1(c0, c1); + for (int c0 = 1; c0 <= M; c0 += 1) + for (int c1 = 1; c1 <= M; c1 += 1) + S2(c0, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali4.in isl-0.15/test_inputs/codegen/cloog/reservoir-pingali4.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali4.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali4.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [1, i0, 0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S1[i0, i1] -> [0, i0, 0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M } -[M] -> { : M >= 2 } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali4.st isl-0.15/test_inputs/codegen/cloog/reservoir-pingali4.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,19 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali5.c isl-0.15/test_inputs/codegen/cloog/reservoir-pingali5.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali5.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali5.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,10 +1,10 @@ -for (int c1 = 3; c1 < 2 * M; c1 += 1) { - for (int c3 = c1 / 2 + 2; c3 <= M; c3 += 1) - for (int c7 = c1 / 2 + 1; c7 < min(c1, c3); c7 += 1) - S1(c7, c1 - c7, c3); - for (int c3 = max(1, -M + c1); c3 < (c1 + 1) / 2; c3 += 1) - S2(c1 - c3, c3); - for (int c3 = c1 / 2 + 2; c3 <= M; c3 += 1) - for (int c7 = c1 / 2 + 1; c7 < min(c1, c3); c7 += 1) - S3(c7, c1 - c7, c3); +for (int c0 = 3; c0 < 2 * M; c0 += 1) { + for (int c1 = c0 / 2 + 2; c1 <= M; c1 += 1) + for (int c3 = c0 / 2 + 1; c3 < min(c0, c1); c3 += 1) + S1(c3, c0 - c3, c1); + for (int c1 = max(1, -M + c0); c1 < (c0 + 1) / 2; c1 += 1) + S2(c0 - c1, c1); + for (int c1 = c0 / 2 + 2; c1 <= M; c1 += 1) + for (int c3 = c0 / 2 + 1; c3 < min(c0, c1); c3 += 1) + S3(c3, c0 - c3, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali5.in isl-0.15/test_inputs/codegen/cloog/reservoir-pingali5.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali5.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali5.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1, i2] -> [0, i0 + i1, 0, i2, 0, i2, 0] : i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M; S3[i0, i1, i2] -> [0, i0 + i1, 2, i2, 2, i2, 0] : i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M; S2[i0, i1] -> [0, i0 + i1, 1, i1, 1, 0, 0] : i0 <= M and i1 >= 1 and i1 <= -1 + i0 } -[M] -> { : } -[M] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali5.st isl-0.15/test_inputs/codegen/cloog/reservoir-pingali5.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali5.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali5.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,26 @@ +domain: "[M] -> { S3[i0, i1, i2] : i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M; S2[i0, i1] : i0 <= M and i1 >= 1 and i1 <= -1 + i0; S1[i0, i1, i2] : i1 >= 1 and i1 <= -1 + i0 and i2 >= 1 + i0 and i2 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i0 + i1)]; S3[i0, i1, i2] -> [(i0 + i1)]; S2[i0, i1] -> [(i0 + i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S2[i0, i1] }" + child: + schedule: "[M] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + - filter: "[M] -> { S3[i0, i1, i2] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" + child: + schedule: "[M] -> [{ S3[i0, i1, i2] -> [(i2)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali6.c isl-0.15/test_inputs/codegen/cloog/reservoir-pingali6.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali6.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali6.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,8 +1,8 @@ -for (int c1 = 1; c1 <= M; c1 += 1) { - for (int c3 = 2; c3 < N; c3 += 1) - for (int c5 = 2; c5 < N; c5 += 1) - S1(c1, c3, c5); - for (int c3 = 2; c3 < N; c3 += 1) - for (int c5 = 2; c5 < N; c5 += 1) - S2(c1, c3, c5); +for (int c0 = 1; c0 <= M; c0 += 1) { + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S1(c0, c2, c3); + for (int c2 = 2; c2 < N; c2 += 1) + for (int c3 = 2; c3 < N; c3 += 1) + S2(c0, c2, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali6.in isl-0.15/test_inputs/codegen/cloog/reservoir-pingali6.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali6.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali6.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S2[i0, i1, i2] -> [0, 1 + 2i0, 1, i1, 0, i2, 0] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N; S1[i0, i1, i2] -> [0, 2i0, 0, i1, 0, i2, 0] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N } -[M, N] -> { : M >= 1 and N >= 1 } -[M, N] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali6.st isl-0.15/test_inputs/codegen/cloog/reservoir-pingali6.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-pingali6.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-pingali6.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,22 @@ +domain: "[M, N] -> { S2[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N; S1[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 2 and i1 <= -1 + N and i2 >= 2 and i2 <= -1 + N }" +child: + context: "[M, N] -> { [] : M >= 1 and N >= 1 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(2i0)]; S2[i0, i1, i2] -> [(1 + 2i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S1[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-QR.c isl-0.15/test_inputs/codegen/cloog/reservoir-QR.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-QR.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-QR.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,53 +1,53 @@ if (N >= 1) { S1(0); if (N == 1) { - for (int c3 = 0; c3 < M; c3 += 1) - S2(0, c3); + for (int c1 = 0; c1 < M; c1 += 1) + S2(0, c1); S3(0); - for (int c3 = 0; c3 < M; c3 += 1) - S4(0, c3); + for (int c1 = 0; c1 < M; c1 += 1) + S4(0, c1); S10(0); S5(0); } else { - for (int c3 = 0; c3 < M; c3 += 1) - S2(0, c3); + for (int c1 = 0; c1 < M; c1 += 1) + S2(0, c1); S3(0); - for (int c3 = 0; c3 < M; c3 += 1) - S4(0, c3); + for (int c1 = 0; c1 < M; c1 += 1) + S4(0, c1); S10(0); S1(1); S5(0); } - for (int c1 = 2; c1 < N; c1 += 1) { - for (int c3 = c1 - 1; c3 < N; c3 += 1) { - S6(c1 - 2, c3); - for (int c5 = c1 - 2; c5 < M; c5 += 1) - S7(c1 - 2, c3, c5); - S8(c1 - 2, c3); - for (int c5 = c1 - 2; c5 < M; c5 += 1) - S9(c1 - 2, c3, c5); + for (int c0 = 2; c0 < N; c0 += 1) { + for (int c1 = c0 - 1; c1 < N; c1 += 1) { + S6(c0 - 2, c1); + for (int c2 = c0 - 2; c2 < M; c2 += 1) + S7(c0 - 2, c1, c2); + S8(c0 - 2, c1); + for (int c2 = c0 - 2; c2 < M; c2 += 1) + S9(c0 - 2, c1, c2); } - for (int c3 = c1 - 1; c3 < M; c3 += 1) - S2(c1 - 1, c3); - S3(c1 - 1); - for (int c3 = c1 - 1; c3 < M; c3 += 1) - S4(c1 - 1, c3); - S10(c1 - 1); - S1(c1); - S5(c1 - 1); + for (int c1 = c0 - 1; c1 < M; c1 += 1) + S2(c0 - 1, c1); + S3(c0 - 1); + for (int c1 = c0 - 1; c1 < M; c1 += 1) + S4(c0 - 1, c1); + S10(c0 - 1); + S1(c0); + S5(c0 - 1); } if (N >= 2) { S6(N - 2, N - 1); - for (int c5 = N - 2; c5 < M; c5 += 1) - S7(N - 2, N - 1, c5); + for (int c2 = N - 2; c2 < M; c2 += 1) + S7(N - 2, N - 1, c2); S8(N - 2, N - 1); - for (int c5 = N - 2; c5 < M; c5 += 1) - S9(N - 2, N - 1, c5); - for (int c3 = N - 1; c3 < M; c3 += 1) - S2(N - 1, c3); + for (int c2 = N - 2; c2 < M; c2 += 1) + S9(N - 2, N - 1, c2); + for (int c1 = N - 1; c1 < M; c1 += 1) + S2(N - 1, c1); S3(N - 1); - for (int c3 = N - 1; c3 < M; c3 += 1) - S4(N - 1, c3); + for (int c1 = N - 1; c1 < M; c1 += 1) + S4(N - 1, c1); S10(N - 1); S5(N - 1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-QR.in isl-0.15/test_inputs/codegen/cloog/reservoir-QR.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-QR.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-QR.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0] -> [0, i0, 5, 0, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N; S9[i0, i1, i2] -> [0, 2 + i0, 0, i1, 3, i2, 0] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N and i2 >= i0 and i2 <= -1 + M; S10[i0] -> [0, 1 + i0, 4, 0, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N; S3[i0] -> [0, 1 + i0, 2, 0, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N; S6[i0, i1] -> [0, 2 + i0, 0, i1, 0, 0, 0] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N; S8[i0, i1] -> [0, 2 + i0, 0, i1, 2, 0, 0] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N; S2[i0, i1] -> [0, 1 + i0, 1, i1, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N and i1 >= i0 and i1 <= -1 + M; S4[i0, i1] -> [0, 1 + i0, 3, i1, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N and i1 >= i0 and i1 <= -1 + M; S7[i0, i1, i2] -> [0, 2 + i0, 0, i1, 1, i2, 0] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N and i2 >= i0 and i2 <= -1 + M; S5[i0] -> [0, 1 + i0, 6, 0, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N } -[M, N] -> { : } -[M, N] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-QR.st isl-0.15/test_inputs/codegen/cloog/reservoir-QR.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-QR.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-QR.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,36 @@ +domain: "[M, N] -> { S5[i0] : i0 >= 0 and i0 <= -1 + N; S1[i0] : i0 >= 0 and i0 <= -1 + N; S3[i0] : i0 >= 0 and i0 <= -1 + N; S2[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= i0 and i1 <= -1 + M; S6[i0, i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N; S9[i0, i1, i2] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N and i2 >= i0 and i2 <= -1 + M; S4[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= i0 and i1 <= -1 + M; S8[i0, i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N; S10[i0] : i0 >= 0 and i0 <= -1 + N; S7[i0, i1, i2] : i0 >= 0 and i1 >= 1 + i0 and i1 <= -1 + N and i2 >= i0 and i2 <= -1 + M }" +child: + context: "[M, N] -> { [] }" + child: + schedule: "[M, N] -> [{ S3[i0] -> [(1 + i0)]; S10[i0] -> [(1 + i0)]; S5[i0] -> [(1 + i0)]; S7[i0, i1, i2] -> [(2 + i0)]; S9[i0, i1, i2] -> [(2 + i0)]; S2[i0, i1] -> [(1 + i0)]; S4[i0, i1] -> [(1 + i0)]; S8[i0, i1] -> [(2 + i0)]; S1[i0] -> [(i0)]; S6[i0, i1] -> [(2 + i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S6[i0, i1]; S9[i0, i1, i2]; S8[i0, i1]; S7[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2] -> [(i1)]; S9[i0, i1, i2] -> [(i1)]; S8[i0, i1] -> [(i1)]; S6[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S6[i0, i1] }" + - filter: "[M, N] -> { S7[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S8[i0, i1] }" + - filter: "[M, N] -> { S9[i0, i1, i2] }" + child: + schedule: "[M, N] -> [{ S9[i0, i1, i2] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S2[i0, i1] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S3[i0] }" + - filter: "[M, N] -> { S4[i0, i1] }" + child: + schedule: "[M, N] -> [{ S4[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + - filter: "[M, N] -> { S10[i0] }" + - filter: "[M, N] -> { S1[i0] }" + - filter: "[M, N] -> { S5[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride2.c isl-0.15/test_inputs/codegen/cloog/reservoir-stride2.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride2.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-stride2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,2 +1,2 @@ -for (int c1 = 2; c1 <= M; c1 += 7) - S1(c1, (c1 - 2) / 7); +for (int c0 = 2; c0 <= M; c0 += 7) + S1(c0, (c0 - 2) / 7); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride2.in isl-0.15/test_inputs/codegen/cloog/reservoir-stride2.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-stride2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [0, i0, 0, 0, 0] : 7i1 = -2 + i0 and i0 >= 0 and i0 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride2.st isl-0.15/test_inputs/codegen/cloog/reservoir-stride2.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-stride2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : 7i1 = -2 + i0 and i0 >= 0 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride.c isl-0.15/test_inputs/codegen/cloog/reservoir-stride.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-stride.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,2 +1,2 @@ -for (int c1 = 2; c1 <= M; c1 += 7) - S1(c1, (c1 - 2) / 7); +for (int c0 = 2; c0 <= M; c0 += 7) + S1(c0, (c0 - 2) / 7); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride.in isl-0.15/test_inputs/codegen/cloog/reservoir-stride.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-stride.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0, i1] -> [0, i0, 0, 0, 0] : 7i1 = -2 + i0 and i0 >= 2 and i0 <= M } -[M] -> { : } -[M] -> { [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride.st isl-0.15/test_inputs/codegen/cloog/reservoir-stride.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-stride.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-stride.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0, i1] : 7i1 = -2 + i0 and i0 >= 2 and i0 <= M }" +child: + context: "[M] -> { [] }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-tang-xue1.c isl-0.15/test_inputs/codegen/cloog/reservoir-tang-xue1.c --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-tang-xue1.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-tang-xue1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ -for (int c1 = 0; c1 <= 9; c1 += 2) - for (int c3 = 0; c3 <= min(4, c1 + 3); c3 += 2) - for (int c5 = max(c1, 1); c5 <= min(c1 + 1, c1 - c3 + 4); c5 += 1) - for (int c7 = max(-c1 + c3 + c5, 1); c7 <= min(4, -c1 + c3 + c5 + 1); c7 += 1) - S1(c1 / 2, (-c1 + c3) / 2, -c1 + c5, -c3 + c7); +for (int c0 = 0; c0 <= 9; c0 += 2) + for (int c1 = 0; c1 <= min(4, c0 + 3); c1 += 2) + for (int c2 = max(1, c0); c2 <= min(c0 + 1, c0 - c1 + 4); c2 += 1) + for (int c3 = max(1, -c0 + c1 + c2); c3 <= min(4, -c0 + c1 + c2 + 1); c3 += 1) + S1(c0 / 2, (-c0 + c1) / 2, -c0 + c2, -c1 + c3); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-tang-xue1.in isl-0.15/test_inputs/codegen/cloog/reservoir-tang-xue1.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-tang-xue1.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-tang-xue1.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1, i2, i3] -> [0, 2i0, 0, 2i0 + 2i1, 0, 2i0 + i2, 0, 2i0 + 2i1 + i3, 0] : i3 <= 4 - 2i0 - 2i1 and i3 >= i2 and i2 <= 9 - 2i0 and i2 >= 0 and i2 >= 1 - 2i0 and i3 <= 1 + i2 and i2 <= 1 and i3 >= 1 - 2i0 - 2i1 } -{ : } -{ [i, j, k, l, m, n, o, p, q] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-tang-xue1.st isl-0.15/test_inputs/codegen/cloog/reservoir-tang-xue1.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-tang-xue1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-tang-xue1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,15 @@ +domain: "{ S1[i0, i1, i2, i3] : i3 <= 4 - 2i0 - 2i1 and i3 >= i2 and i2 <= 9 - 2i0 and i2 >= 0 and i2 >= 1 - 2i0 and i3 <= 1 + i2 and i2 <= 1 and i3 >= 1 - 2i0 - 2i1 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0 + 2i1)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0 + i2)] }]" + options: "{ separate[i0] }" + child: + schedule: "[{ S1[i0, i1, i2, i3] -> [(2i0 + 2i1 + i3)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-two.in isl-0.15/test_inputs/codegen/cloog/reservoir-two.in --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-two.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-two.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i1, i2] -> [i0, j, k, 0] : 2i1 = 3 - i0 and 2j = 3 - i0 and 2k = 9 + i0 and 2i2 = 9 + i0 and i0 >= 0 and i0 <= 1 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/reservoir-two.st isl-0.15/test_inputs/codegen/cloog/reservoir-two.st --- isl-0.12.2/test_inputs/codegen/cloog/reservoir-two.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/reservoir-two.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S1[i0, i1, i2] : 2i1 = 3 - i0 and 2i2 = 9 + i0 and i0 >= 0 and i0 <= 1 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i0, i1, i2] -> [(i0)] }, { S1[i0, i1, i2] -> [(i1)] }, { S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/singleton.in isl-0.15/test_inputs/codegen/cloog/singleton.in --- isl-0.12.2/test_inputs/codegen/cloog/singleton.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/singleton.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[] -> [-1]; S1[] -> [0] } -{ : } -{ [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/singleton.st isl-0.15/test_inputs/codegen/cloog/singleton.st --- isl-0.12.2/test_inputs/codegen/cloog/singleton.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/singleton.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +domain: "{ S1[]; S2[] }" +child: + context: "{ [] }" + child: + sequence: + - filter: "{ S2[] }" + - filter: "{ S1[] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/sor1d.c isl-0.15/test_inputs/codegen/cloog/sor1d.c --- isl-0.12.2/test_inputs/codegen/cloog/sor1d.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/sor1d.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,13 @@ +if (M >= 1 && N >= 3) + for (int c0 = -1; c0 <= (3 * M + N - 5) / 100; c0 += 1) { + for (int c1 = max(max(0, c0 - (2 * M + N + 95) / 100 + 1), floord(-N + 100 * c0 + 106, 300)); c1 <= min(min(c0, M / 100), (c0 + 1) / 3); c1 += 1) + for (int c2 = max(200 * c1 - 3, 100 * c0 - 100 * c1); c2 <= min(min(2 * M + N - 5, 100 * c0 - 100 * c1 + 99), N + 200 * c1 + 193); c2 += 1) { + if (c1 >= 1 && N + 200 * c1 >= c2 + 7) + S3(c0 - c1, c1 - 1, c1, 100 * c1 - 1, -200 * c1 + c2 + 6); + for (int c3 = max(max(1, 100 * c1), -N + (N + c2) / 2 + 3); c3 <= min(min(M, 100 * c1 + 99), c2 / 2 + 1); c3 += 1) + S1(c0 - c1, c1, c3, c2 - 2 * c3 + 4); + if (M >= 100 * c1 + 100 && c2 >= 200 * c1 + 197) + S2(c0 - c1, c1, c1 + 1, 100 * c1 + 99, -200 * c1 + c2 - 194); + } + S4(c0); + } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/sor1d.st isl-0.15/test_inputs/codegen/cloog/sor1d.st --- isl-0.12.2/test_inputs/codegen/cloog/sor1d.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/sor1d.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,24 @@ +domain: "[M, N] -> { S2[i0, i1, 1 + i1, 99 + 100i1, i4] : i4 >= 3 and i4 >= -193 - 200i1 and i4 >= -194 + 100i0 - 200i1 and 100i0 >= -284 - 3N and i4 <= -1 + N and i4 <= -201 + 2M + N - 200i1 and i4 <= -95 + 100i0 - 200i1 and 100i0 >= -94 - N and 50i0 >= -45 - N and 3N >= -134 - M and i1 >= 0 and N >= 4 and 200i1 >= -192 - N and 200i1 >= -193 - N + 100i0 and 100i0 <= -7 + 2M + N and 7N >= -463 - 2M and 100i1 <= -100 + M and i0 >= 0 and 200i1 <= -204 + 2M + N and 2i1 <= -1 + i0 and 5N >= -75 - 2M and N >= 8 - 2M and 50i0 <= -6 + M + N and 50i0 <= 89 + M + 2N and 100i0 <= -15 + 2M + 3N and M >= 2 and 100i1 <= -5 + M + N and 2N >= -39 - M and 200i1 <= 96 + N + 100i0 and 3N >= 16 - 2M and 100i1 >= -94 - N + 50i0 and N >= 6 - M and 100i1 >= -94 - N; S3[i0, i1, 1 + i1, 99 + 100i1, i4] : i4 >= 3 and i4 >= -193 - 200i1 and i4 >= -194 + 100i0 - 200i1 and 100i0 >= -284 - 3N and i4 <= -1 + N and i4 <= -201 + 2M + N - 200i1 and i4 <= -95 + 100i0 - 200i1 and 100i0 >= -94 - N and 50i0 >= -45 - N and 3N >= -134 - M and i1 >= 0 and N >= 4 and 200i1 >= -192 - N and 200i1 >= -193 - N + 100i0 and 100i0 <= -7 + 2M + N and 7N >= -463 - 2M and 100i1 <= -100 + M and i0 >= 0 and 200i1 <= -204 + 2M + N and 2i1 <= -1 + i0 and 5N >= -75 - 2M and N >= 8 - 2M and 50i0 <= -6 + M + N and 50i0 <= 89 + M + 2N and 100i0 <= -15 + 2M + 3N and M >= 2 and 100i1 <= -5 + M + N and 2N >= -39 - M and 200i1 <= 96 + N + 100i0 and 3N >= 16 - 2M and 100i1 >= -94 - N + 50i0 and N >= 6 - M and 100i1 >= -94 - N; S4[i0] : 200i0 >= -781 - 3N and 200i0 >= -391 - N and 50i0 >= -268 - N and 100i0 >= -392 - N and i0 >= -1 and 200i0 <= 377 + 6M + 5N and 100i0 <= 335 + 3M + 3N and 100i0 <= 190 + 3M + 2N and 200i0 <= -13 + 6M + 3N and 100i0 <= -5 + 3M + N and 3N >= -484 - 2M and N >= -95 - M and N >= -192 - 3M and 5N >= -873 - 3M and 2N >= -189 - 3M and 7N >= -1062 - 6M and 5N >= -771 - 6M and 4N >= -579 - 3M and N >= 3 and N >= 5 - 2M and M >= 1; S1[i0, i1, i2, i3] : i3 >= 4 + 100i0 - 2i2 and i3 >= 2 and i3 <= 103 + 100i0 - 2i2 and i3 <= -1 + N and i2 >= 1 and i2 >= 100i1 and 2i2 >= 5 - N + 100i0 and i2 <= M and i2 <= 99 + 100i1 and i2 <= 50 + 50i0 and i1 >= 0 and 200i1 >= -193 - N + 100i0 and 100i1 <= M and 2i1 <= 1 + i0 and i0 >= 0 and 100i0 <= -5 + 2M + N and N >= 3 and N >= -94 - 2M and M >= 1 }" +child: + context: "[M, N] -> { [] : M >= 0 and N >= 0 }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2, i3, i4] -> [(i0 + i1)]; S1[i0, i1, i2, i3] -> [(i0 + i1)]; S3[i0, i1, i2, i3, i4] -> [(1 + i0 + i1)]; S4[i0] -> [(i0)] }]" + options: "[M, N] -> { atomic[i0] }" + child: + sequence: + - filter: "[M, N] -> { S2[i0, i1, i2, i3, i4]; S3[i0, i1, i2, i3, i4]; S1[i0, i1, i2, i3] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2, i3, i4] -> [(i1)]; S1[i0, i1, i2, i3] -> [(i1)]; S3[i0, i1, i2, i3, i4] -> [(i2)] }, { S2[i0, i1, i2, i3, i4] -> [(-4 + 2i3 + i4)]; S1[i0, i1, i2, i3] -> [(-4 + 2i2 + i3)]; S3[i0, i1, i2, i3, i4] -> [(-4 + 2i3 + i4)] }, { S2[i0, i1, i2, i3, i4] -> [(i3)]; S1[i0, i1, i2, i3] -> [(i2)]; S3[i0, i1, i2, i3, i4] -> [(i3)] }]" + options: "[M, N] -> { atomic[i0] }" + child: + sequence: + - filter: "[M, N] -> { S3[i0, i1, i2, i3, i4] }" + child: + schedule: "[M, N] -> [{ S3[i0, i1, i2, i3, i4] -> [(i1)] }, { S3[i0, i1, i2, i3, i4] -> [(i4)] }]" + options: "[M, N] -> { atomic[i0] }" + - filter: "[M, N] -> { S1[i0, i1, i2, i3] }" + - filter: "[M, N] -> { S2[i0, i1, i2, i3, i4] }" + child: + schedule: "[M, N] -> [{ S2[i0, i1, i2, i3, i4] -> [(i2)] }, { S2[i0, i1, i2, i3, i4] -> [(i4)] }]" + options: "[M, N] -> { atomic[i0] }" + - filter: "[M, N] -> { S4[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/square+triangle-1-1-2-3.in isl-0.15/test_inputs/codegen/cloog/square+triangle-1-1-2-3.in --- isl-0.12.2/test_inputs/codegen/cloog/square+triangle-1-1-2-3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/square+triangle-1-1-2-3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S2[i0, i1] -> [i0, i1, 1] : i1 >= 2 and i1 <= i0 and i0 <= M; S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M } -[M] -> { : M >= 1 } -[M] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st isl-0.15/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st --- isl-0.12.2/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/square+triangle-1-1-2-3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M] -> { S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= M; S2[i0, i1] : i1 >= 2 and i1 <= i0 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 1 }" + child: + schedule: "[M] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M] -> { separate[i0] }" + child: + sequence: + - filter: "[M] -> { S1[i0, i1] }" + - filter: "[M] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride2.in isl-0.15/test_inputs/codegen/cloog/stride2.in --- isl-0.12.2/test_inputs/codegen/cloog/stride2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[27] -> [27, 0]; S2[i0, i1] -> [i0, j] : 3i1 = i0 and 3j = i0 and i0 >= 3 and i0 <= 100 } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride2.st isl-0.15/test_inputs/codegen/cloog/stride2.st --- isl-0.12.2/test_inputs/codegen/cloog/stride2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S2[i0, i1] : 3i1 = i0 and i0 >= 3 and i0 <= 100; S1[27] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride3.c isl-0.15/test_inputs/codegen/cloog/stride3.c --- isl-0.12.2/test_inputs/codegen/cloog/stride3.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride3.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,2 +1,2 @@ -for (int c0 = max(m, 1); c0 <= n; c0 += 1) +for (int c0 = max(1, m); c0 <= n; c0 += 1) S1(c0); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride3.in isl-0.15/test_inputs/codegen/cloog/stride3.in --- isl-0.12.2/test_inputs/codegen/cloog/stride3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[m, n] -> { S1[i0] -> [50i0, 0] : i0 >= 1 and i0 <= n and i0 >= m } -[m, n] -> { : } -[m, n] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride3.st isl-0.15/test_inputs/codegen/cloog/stride3.st --- isl-0.12.2/test_inputs/codegen/cloog/stride3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[m, n] -> { S1[i] : i >= 1 and i <= n and i >= m }" +child: + context: "[m, n] -> { [] }" + child: + schedule: "[m, n] -> [{ S1[i0] -> [(50i0)] }]" + options: "[m, n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride4.in isl-0.15/test_inputs/codegen/cloog/stride4.in --- isl-0.12.2/test_inputs/codegen/cloog/stride4.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride4.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[t] -> { S1[i0, t] -> [i0, t, 0] : exists (e0 = [(t - i0)/16]: 16e0 = t - i0 and i0 >= 0 and i0 <= 99 and t >= 0 and t <= 15) } -[t] -> { : } -[t] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride4.st isl-0.15/test_inputs/codegen/cloog/stride4.st --- isl-0.12.2/test_inputs/codegen/cloog/stride4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[t] -> { S1[i0, t] : exists (e0 = floor((t - i0)/16): 16e0 = t - i0 and i0 >= 0 and i0 <= 99 and t >= 0 and t <= 15) }" +child: + context: "[t] -> { [] }" + child: + schedule: "[t] -> [{ S1[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)] }]" + options: "[t] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride.in isl-0.15/test_inputs/codegen/cloog/stride.in --- isl-0.12.2/test_inputs/codegen/cloog/stride.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[25] -> [25, 0]; S2[i0, i1] -> [i0, j] : 3i1 = i0 and 3j = i0 and i0 >= 3 and i0 <= 100 } -{ : } -{ [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/stride.st isl-0.15/test_inputs/codegen/cloog/stride.st --- isl-0.12.2/test_inputs/codegen/cloog/stride.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/stride.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "{ S2[i0, i1] : 3i1 = i0 and i0 >= 3 and i0 <= 100; S1[25] }" +child: + context: "{ [] }" + child: + schedule: "[{ S2[i0, i1] -> [(i0)]; S1[i0] -> [(i0)] }, { S2[i0, i1] -> [(i1)]; S1[i0] -> [(0)] }]" + options: "{ separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/swim.c isl-0.15/test_inputs/codegen/cloog/swim.c --- isl-0.12.2/test_inputs/codegen/cloog/swim.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/swim.c 2015-06-02 09:28:10.000000000 +0000 @@ -26,13 +26,13 @@ S25(); S26(); S27(); - for (int c1 = 1; c1 <= N; c1 += 1) { - for (int c3 = 1; c3 <= N; c3 += 1) { - S28(c1, c3); - S29(c1, c3); - S30(c1, c3); + for (int c0 = 1; c0 <= N; c0 += 1) { + for (int c1 = 1; c1 <= N; c1 += 1) { + S28(c0, c1); + S29(c0, c1); + S30(c0, c1); } - S31(c1); + S31(c0); } S32(); S33(); @@ -41,119 +41,119 @@ S35(); S36(); S37(); - for (int c1 = 2; c1 <= P; c1 += 1) { - S38(c1); - S39(c1); - for (int c3 = 1; c3 <= Q; c3 += 1) - for (int c5 = 1; c5 <= R; c5 += 1) { - S40(c1, c3, c5); - S41(c1, c3, c5); - S42(c1, c3, c5); - S43(c1, c3, c5); + for (int c0 = 2; c0 <= P; c0 += 1) { + S38(c0); + S39(c0); + for (int c1 = 1; c1 <= Q; c1 += 1) + for (int c2 = 1; c2 <= R; c2 += 1) { + S40(c0, c1, c2); + S41(c0, c1, c2); + S42(c0, c1, c2); + S43(c0, c1, c2); } - for (int c3 = 1; c3 <= Q; c3 += 1) { - S44(c1, c3); - S45(c1, c3); - S46(c1, c3); - S47(c1, c3); - } - for (int c3 = 1; c3 <= R; c3 += 1) { - S48(c1, c3); - S49(c1, c3); - S50(c1, c3); - S51(c1, c3); - } - S52(c1); - S53(c1); - S54(c1); - S55(c1); - S56(c1); - S57(c1); - S58(c1); - for (int c3 = 1; c3 <= Q; c3 += 1) - for (int c5 = 1; c5 <= R; c5 += 1) { - S59(c1, c3, c5); - S60(c1, c3, c5); - S61(c1, c3, c5); + for (int c1 = 1; c1 <= Q; c1 += 1) { + S44(c0, c1); + S45(c0, c1); + S46(c0, c1); + S47(c0, c1); + } + for (int c1 = 1; c1 <= R; c1 += 1) { + S48(c0, c1); + S49(c0, c1); + S50(c0, c1); + S51(c0, c1); + } + S52(c0); + S53(c0); + S54(c0); + S55(c0); + S56(c0); + S57(c0); + S58(c0); + for (int c1 = 1; c1 <= Q; c1 += 1) + for (int c2 = 1; c2 <= R; c2 += 1) { + S59(c0, c1, c2); + S60(c0, c1, c2); + S61(c0, c1, c2); } - for (int c3 = 1; c3 <= Q; c3 += 1) { - S62(c1, c3); - S63(c1, c3); - S64(c1, c3); - } - for (int c3 = 1; c3 <= R; c3 += 1) { - S65(c1, c3); - S66(c1, c3); - S67(c1, c3); - } - S68(c1); - S69(c1); - S70(c1); - S71(c1); - S72(c1); - S73(c1); - S74(c1); - S75(c1); - S76(c1); - S77(c1); - S78(c1); - S79(c1); - S80(c1); - S81(c1); - S82(c1); - S83(c1); - S84(c1); - S85(c1); - S86(c1); - S87(c1); - S88(c1); - S89(c1); - S90(c1); - S91(c1); - S92(c1); - S93(c1); - S94(c1); - for (int c3 = 1; c3 <= N; c3 += 1) { - for (int c5 = 1; c5 <= N; c5 += 1) { - S95(c1, c3, c5); - S96(c1, c3, c5); - S97(c1, c3, c5); + for (int c1 = 1; c1 <= Q; c1 += 1) { + S62(c0, c1); + S63(c0, c1); + S64(c0, c1); + } + for (int c1 = 1; c1 <= R; c1 += 1) { + S65(c0, c1); + S66(c0, c1); + S67(c0, c1); + } + S68(c0); + S69(c0); + S70(c0); + S71(c0); + S72(c0); + S73(c0); + S74(c0); + S75(c0); + S76(c0); + S77(c0); + S78(c0); + S79(c0); + S80(c0); + S81(c0); + S82(c0); + S83(c0); + S84(c0); + S85(c0); + S86(c0); + S87(c0); + S88(c0); + S89(c0); + S90(c0); + S91(c0); + S92(c0); + S93(c0); + S94(c0); + for (int c1 = 1; c1 <= N; c1 += 1) { + for (int c2 = 1; c2 <= N; c2 += 1) { + S95(c0, c1, c2); + S96(c0, c1, c2); + S97(c0, c1, c2); } - S98(c1, c3); + S98(c0, c1); } - S99(c1); - S100(c1); - S101(c1); - for (int c3 = 1; c3 <= Q; c3 += 1) - for (int c5 = 1; c5 <= R; c5 += 1) { - S102(c1, c3, c5); - S103(c1, c3, c5); - S104(c1, c3, c5); - S105(c1, c3, c5); - S106(c1, c3, c5); - S107(c1, c3, c5); + S99(c0); + S100(c0); + S101(c0); + for (int c1 = 1; c1 <= Q; c1 += 1) + for (int c2 = 1; c2 <= R; c2 += 1) { + S102(c0, c1, c2); + S103(c0, c1, c2); + S104(c0, c1, c2); + S105(c0, c1, c2); + S106(c0, c1, c2); + S107(c0, c1, c2); } - for (int c3 = 1; c3 <= Q; c3 += 1) { - S108(c1, c3); - S109(c1, c3); - S110(c1, c3); - S111(c1, c3); - S112(c1, c3); - S113(c1, c3); - } - for (int c3 = 1; c3 <= R; c3 += 1) { - S114(c1, c3); - S115(c1, c3); - S116(c1, c3); - S117(c1, c3); - S118(c1, c3); - S119(c1, c3); - } - S120(c1); - S121(c1); - S122(c1); - S123(c1); - S124(c1); - S125(c1); + for (int c1 = 1; c1 <= Q; c1 += 1) { + S108(c0, c1); + S109(c0, c1); + S110(c0, c1); + S111(c0, c1); + S112(c0, c1); + S113(c0, c1); + } + for (int c1 = 1; c1 <= R; c1 += 1) { + S114(c0, c1); + S115(c0, c1); + S116(c0, c1); + S117(c0, c1); + S118(c0, c1); + S119(c0, c1); + } + S120(c0); + S121(c0); + S122(c0); + S123(c0); + S124(c0); + S125(c0); } } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/swim.in isl-0.15/test_inputs/codegen/cloog/swim.in --- isl-0.12.2/test_inputs/codegen/cloog/swim.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/swim.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N, O, P, Q, R] -> { S84[i0] -> [34, i0, 31, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S6[] -> [5, 0, 0, 0, 0, 0, 0] : M = 1; S25[] -> [24, 0, 0, 0, 0, 0, 0] : M = 1; S115[i0, i1] -> [34, i0, 48, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S64[i0, i1] -> [34, i0, 13, i1, 2, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S62[i0, i1] -> [34, i0, 13, i1, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S40[i0, i1, i2] -> [34, i0, 2, i1, 0, i2, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S123[i0] -> [34, i0, 52, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S5[] -> [4, 0, 0, 0, 0, 0, 0] : M = 1; S15[] -> [14, 0, 0, 0, 0, 0, 0] : M = 1; S76[i0] -> [34, i0, 23, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S39[i0] -> [34, i0, 1, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S13[] -> [12, 0, 0, 0, 0, 0, 0] : M = 1; S28[i0, i1] -> [27, i0, 0, i1, 0, 0, 0] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S70[i0] -> [34, i0, 17, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S53[i0] -> [34, i0, 6, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S121[i0] -> [34, i0, 50, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S47[i0, i1] -> [34, i0, 3, i1, 3, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S59[i0, i1, i2] -> [34, i0, 12, i1, 0, i2, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S71[i0] -> [34, i0, 18, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S77[i0] -> [34, i0, 24, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S63[i0, i1] -> [34, i0, 13, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S51[i0, i1] -> [34, i0, 4, i1, 3, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S100[i0] -> [34, i0, 44, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S22[] -> [21, 0, 0, 0, 0, 0, 0] : M = 1; S95[i0, i1, i2] -> [34, i0, 42, i1, 0, i2, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S8[] -> [7, 0, 0, 0, 0, 0, 0] : M = 1; S120[i0] -> [34, i0, 49, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S50[i0, i1] -> [34, i0, 4, i1, 2, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S45[i0, i1] -> [34, i0, 3, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S72[i0] -> [34, i0, 19, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S52[i0] -> [34, i0, 5, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S7[] -> [6, 0, 0, 0, 0, 0, 0] : M = 1; S78[i0] -> [34, i0, 25, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S110[i0, i1] -> [34, i0, 47, i1, 2, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S124[i0] -> [34, i0, 53, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S60[i0, i1, i2] -> [34, i0, 12, i1, 0, i2, 1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S27[] -> [26, 0, 0, 0, 0, 0, 0] : M = 1; S114[i0, i1] -> [34, i0, 48, i1, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S49[i0, i1] -> [34, i0, 4, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S94[i0] -> [34, i0, 41, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S57[i0] -> [34, i0, 10, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S66[i0, i1] -> [34, i0, 14, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S18[] -> [17, 0, 0, 0, 0, 0, 0] : M = 1; S92[i0] -> [34, i0, 39, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S3[] -> [2, 0, 0, 0, 0, 0, 0] : M = 1; S35[] -> [31, 0, 0, 0, 0, 0, 0] : M = 1 and O <= 1; S36[] -> [32, 0, 0, 0, 0, 0, 0] : M = 1; S10[] -> [9, 0, 0, 0, 0, 0, 0] : M = 1; S2[] -> [1, 0, 0, 0, 0, 0, 0] : M = 1; S48[i0, i1] -> [34, i0, 4, i1, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S30[i0, i1] -> [27, i0, 0, i1, 2, 0, 0] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S75[i0] -> [34, i0, 22, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S83[i0] -> [34, i0, 30, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S87[i0] -> [34, i0, 34, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S88[i0] -> [34, i0, 35, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S33[] -> [29, 0, 0, 0, 0, 0, 0] : M = 1; S101[i0] -> [34, i0, 45, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S21[] -> [20, 0, 0, 0, 0, 0, 0] : M = 1; S32[] -> [28, 0, 0, 0, 0, 0, 0] : M = 1; S118[i0, i1] -> [34, i0, 48, i1, 4, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S79[i0] -> [34, i0, 26, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S38[i0] -> [34, i0, 0, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S108[i0, i1] -> [34, i0, 47, i1, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S65[i0, i1] -> [34, i0, 14, i1, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S91[i0] -> [34, i0, 38, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S17[] -> [16, 0, 0, 0, 0, 0, 0] : M = 1; S80[i0] -> [34, i0, 27, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S54[i0] -> [34, i0, 7, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S46[i0, i1] -> [34, i0, 3, i1, 2, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S68[i0] -> [34, i0, 15, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S116[i0, i1] -> [34, i0, 48, i1, 2, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S43[i0, i1, i2] -> [34, i0, 2, i1, 0, i2, 3] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S26[] -> [25, 0, 0, 0, 0, 0, 0] : M = 1; S31[i0] -> [27, i0, 1, 0, 0, 0, 0] : M = 1 and i0 >= 1 and i0 <= N; S69[i0] -> [34, i0, 16, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S24[] -> [23, 0, 0, 0, 0, 0, 0] : M = 1; S90[i0] -> [34, i0, 37, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S89[i0] -> [34, i0, 36, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S82[i0] -> [34, i0, 29, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S67[i0, i1] -> [34, i0, 14, i1, 2, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S58[i0] -> [34, i0, 11, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S109[i0, i1] -> [34, i0, 47, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S122[i0] -> [34, i0, 51, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S61[i0, i1, i2] -> [34, i0, 12, i1, 0, i2, 2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S1[] -> [0, 0, 0, 0, 0, 0, 0] : M = 1; S4[] -> [3, 0, 0, 0, 0, 0, 0] : M = 1; S86[i0] -> [34, i0, 33, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S14[] -> [13, 0, 0, 0, 0, 0, 0] : M = 1; S93[i0] -> [34, i0, 40, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S56[i0] -> [34, i0, 9, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S37[] -> [33, 0, 0, 0, 0, 0, 0] : M = 1; S125[i0] -> [34, i0, 54, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S96[i0, i1, i2] -> [34, i0, 42, i1, 0, i2, 1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S9[] -> [8, 0, 0, 0, 0, 0, 0] : M = 1; S41[i0, i1, i2] -> [34, i0, 2, i1, 0, i2, 1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S102[i0, i1, i2] -> [34, i0, 46, i1, 0, i2, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S112[i0, i1] -> [34, i0, 47, i1, 4, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S16[] -> [15, 0, 0, 0, 0, 0, 0] : M = 1; S85[i0] -> [34, i0, 32, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S42[i0, i1, i2] -> [34, i0, 2, i1, 0, i2, 2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S12[] -> [11, 0, 0, 0, 0, 0, 0] : M = 1; S55[i0] -> [34, i0, 8, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S11[] -> [10, 0, 0, 0, 0, 0, 0] : M = 1; S19[] -> [18, 0, 0, 0, 0, 0, 0] : M = 1; S107[i0, i1, i2] -> [34, i0, 46, i1, 0, i2, 5] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S98[i0, i1] -> [34, i0, 42, i1, 1, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N; S104[i0, i1, i2] -> [34, i0, 46, i1, 0, i2, 2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S29[i0, i1] -> [27, i0, 0, i1, 1, 0, 0] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S20[] -> [19, 0, 0, 0, 0, 0, 0] : M = 1; S103[i0, i1, i2] -> [34, i0, 46, i1, 0, i2, 1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S105[i0, i1, i2] -> [34, i0, 46, i1, 0, i2, 3] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S97[i0, i1, i2] -> [34, i0, 42, i1, 0, i2, 2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S44[i0, i1] -> [34, i0, 3, i1, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S106[i0, i1, i2] -> [34, i0, 46, i1, 0, i2, 4] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S34[] -> [30, 0, 0, 0, 0, 0, 0] : M = 1; S111[i0, i1] -> [34, i0, 47, i1, 3, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S99[i0] -> [34, i0, 43, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S81[i0] -> [34, i0, 28, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S23[] -> [22, 0, 0, 0, 0, 0, 0] : M = 1; S117[i0, i1] -> [34, i0, 48, i1, 3, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S74[i0] -> [34, i0, 21, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P; S113[i0, i1] -> [34, i0, 47, i1, 5, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S119[i0, i1] -> [34, i0, 48, i1, 5, 0, 0] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S73[i0] -> [34, i0, 20, 0, 0, 0, 0] : M = 1 and i0 >= 2 and i0 <= P } -[M, N, O, P, Q, R] -> { : } -[M, N, O, P, Q, R] -> { [i, j, k, l, m, n, o] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/swim.st isl-0.15/test_inputs/codegen/cloog/swim.st --- isl-0.12.2/test_inputs/codegen/cloog/swim.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/swim.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,223 @@ +domain: "[M, N, O, P, Q, R] -> { S40[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S106[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S99[i0] : M = 1 and i0 >= 2 and i0 <= P; S83[i0] : M = 1 and i0 >= 2 and i0 <= P; S86[i0] : M = 1 and i0 >= 2 and i0 <= P; S56[i0] : M = 1 and i0 >= 2 and i0 <= P; S124[i0] : M = 1 and i0 >= 2 and i0 <= P; S66[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S46[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S64[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S22[] : M = 1; S15[] : M = 1; S30[i0, i1] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S14[] : M = 1; S12[] : M = 1; S87[i0] : M = 1 and i0 >= 2 and i0 <= P; S110[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S73[i0] : M = 1 and i0 >= 2 and i0 <= P; S44[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S31[i0] : M = 1 and i0 >= 1 and i0 <= N; S118[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S8[] : M = 1; S125[i0] : M = 1 and i0 >= 2 and i0 <= P; S63[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S25[] : M = 1; S51[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S91[i0] : M = 1 and i0 >= 2 and i0 <= P; S84[i0] : M = 1 and i0 >= 2 and i0 <= P; S35[] : M = 1 and O <= 1; S97[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S75[i0] : M = 1 and i0 >= 2 and i0 <= P; S19[] : M = 1; S50[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S114[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S13[] : M = 1; S72[i0] : M = 1 and i0 >= 2 and i0 <= P; S78[i0] : M = 1 and i0 >= 2 and i0 <= P; S39[i0] : M = 1 and i0 >= 2 and i0 <= P; S102[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S107[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S68[i0] : M = 1 and i0 >= 2 and i0 <= P; S32[] : M = 1; S41[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S69[i0] : M = 1 and i0 >= 2 and i0 <= P; S3[] : M = 1; S100[i0] : M = 1 and i0 >= 2 and i0 <= P; S11[] : M = 1; S76[i0] : M = 1 and i0 >= 2 and i0 <= P; S88[i0] : M = 1 and i0 >= 2 and i0 <= P; S49[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S45[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S10[] : M = 1; S80[i0] : M = 1 and i0 >= 2 and i0 <= P; S61[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S67[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S70[i0] : M = 1 and i0 >= 2 and i0 <= P; S29[i0, i1] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S60[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S21[] : M = 1; S92[i0] : M = 1 and i0 >= 2 and i0 <= P; S47[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S24[] : M = 1; S16[] : M = 1; S105[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S18[] : M = 1; S48[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S5[] : M = 1; S113[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S7[] : M = 1; S38[i0] : M = 1 and i0 >= 2 and i0 <= P; S54[i0] : M = 1 and i0 >= 2 and i0 <= P; S109[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S23[] : M = 1; S82[i0] : M = 1 and i0 >= 2 and i0 <= P; S59[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S77[i0] : M = 1 and i0 >= 2 and i0 <= P; S101[i0] : M = 1 and i0 >= 2 and i0 <= P; S37[] : M = 1; S71[i0] : M = 1 and i0 >= 2 and i0 <= P; S121[i0] : M = 1 and i0 >= 2 and i0 <= P; S115[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S104[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S94[i0] : M = 1 and i0 >= 2 and i0 <= P; S6[] : M = 1; S43[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S1[] : M = 1; S98[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N; S55[i0] : M = 1 and i0 >= 2 and i0 <= P; S58[i0] : M = 1 and i0 >= 2 and i0 <= P; S42[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S89[i0] : M = 1 and i0 >= 2 and i0 <= P; S53[i0] : M = 1 and i0 >= 2 and i0 <= P; S111[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S52[i0] : M = 1 and i0 >= 2 and i0 <= P; S85[i0] : M = 1 and i0 >= 2 and i0 <= P; S26[] : M = 1; S79[i0] : M = 1 and i0 >= 2 and i0 <= P; S81[i0] : M = 1 and i0 >= 2 and i0 <= P; S57[i0] : M = 1 and i0 >= 2 and i0 <= P; S4[] : M = 1; S123[i0] : M = 1 and i0 >= 2 and i0 <= P; S36[] : M = 1; S65[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S34[] : M = 1; S119[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S9[] : M = 1; S28[i0, i1] : M = 1 and i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= N; S20[] : M = 1; S117[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S112[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S103[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q and i2 >= 1 and i2 <= R; S17[] : M = 1; S96[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S95[i0, i1, i2] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= N and i2 >= 1 and i2 <= N; S62[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S90[i0] : M = 1 and i0 >= 2 and i0 <= P; S120[i0] : M = 1 and i0 >= 2 and i0 <= P; S116[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= R; S108[i0, i1] : M = 1 and i0 >= 2 and i0 <= P and i1 >= 1 and i1 <= Q; S74[i0] : M = 1 and i0 >= 2 and i0 <= P; S93[i0] : M = 1 and i0 >= 2 and i0 <= P; S2[] : M = 1; S27[] : M = 1; S122[i0] : M = 1 and i0 >= 2 and i0 <= P; S33[] : M = 1 }" +child: + context: "[M, N, O, P, Q, R] -> { [] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S1[] }" + - filter: "[M, N, O, P, Q, R] -> { S2[] }" + - filter: "[M, N, O, P, Q, R] -> { S3[] }" + - filter: "[M, N, O, P, Q, R] -> { S4[] }" + - filter: "[M, N, O, P, Q, R] -> { S5[] }" + - filter: "[M, N, O, P, Q, R] -> { S6[] }" + - filter: "[M, N, O, P, Q, R] -> { S7[] }" + - filter: "[M, N, O, P, Q, R] -> { S8[] }" + - filter: "[M, N, O, P, Q, R] -> { S9[] }" + - filter: "[M, N, O, P, Q, R] -> { S10[] }" + - filter: "[M, N, O, P, Q, R] -> { S11[] }" + - filter: "[M, N, O, P, Q, R] -> { S12[] }" + - filter: "[M, N, O, P, Q, R] -> { S13[] }" + - filter: "[M, N, O, P, Q, R] -> { S14[] }" + - filter: "[M, N, O, P, Q, R] -> { S15[] }" + - filter: "[M, N, O, P, Q, R] -> { S16[] }" + - filter: "[M, N, O, P, Q, R] -> { S17[] }" + - filter: "[M, N, O, P, Q, R] -> { S18[] }" + - filter: "[M, N, O, P, Q, R] -> { S19[] }" + - filter: "[M, N, O, P, Q, R] -> { S20[] }" + - filter: "[M, N, O, P, Q, R] -> { S21[] }" + - filter: "[M, N, O, P, Q, R] -> { S22[] }" + - filter: "[M, N, O, P, Q, R] -> { S23[] }" + - filter: "[M, N, O, P, Q, R] -> { S24[] }" + - filter: "[M, N, O, P, Q, R] -> { S25[] }" + - filter: "[M, N, O, P, Q, R] -> { S26[] }" + - filter: "[M, N, O, P, Q, R] -> { S27[] }" + - filter: "[M, N, O, P, Q, R] -> { S30[i0, i1]; S28[i0, i1]; S31[i0]; S29[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S31[i0] -> [(i0)]; S29[i0, i1] -> [(i0)]; S30[i0, i1] -> [(i0)]; S28[i0, i1] -> [(i0)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S30[i0, i1]; S28[i0, i1]; S29[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S29[i0, i1] -> [(i1)]; S30[i0, i1] -> [(i1)]; S28[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S28[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S29[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S30[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S31[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S32[] }" + - filter: "[M, N, O, P, Q, R] -> { S33[] }" + - filter: "[M, N, O, P, Q, R] -> { S34[] }" + - filter: "[M, N, O, P, Q, R] -> { S35[] }" + - filter: "[M, N, O, P, Q, R] -> { S36[] }" + - filter: "[M, N, O, P, Q, R] -> { S37[] }" + - filter: "[M, N, O, P, Q, R] -> { S58[i0]; S116[i0, i1]; S120[i0]; S106[i0, i1, i2]; S102[i0, i1, i2]; S114[i0, i1]; S113[i0, i1]; S122[i0]; S83[i0]; S103[i0, i1, i2]; S71[i0]; S50[i0, i1]; S98[i0, i1]; S65[i0, i1]; S82[i0]; S109[i0, i1]; S51[i0, i1]; S60[i0, i1, i2]; S91[i0]; S78[i0]; S101[i0]; S123[i0]; S111[i0, i1]; S97[i0, i1, i2]; S67[i0, i1]; S117[i0, i1]; S88[i0]; S79[i0]; S46[i0, i1]; S56[i0]; S45[i0, i1]; S74[i0]; S49[i0, i1]; S75[i0]; S115[i0, i1]; S119[i0, i1]; S42[i0, i1, i2]; S57[i0]; S62[i0, i1]; S99[i0]; S107[i0, i1, i2]; S100[i0]; S104[i0, i1, i2]; S70[i0]; S89[i0]; S125[i0]; S44[i0, i1]; S93[i0]; S90[i0]; S84[i0]; S105[i0, i1, i2]; S95[i0, i1, i2]; S66[i0, i1]; S77[i0]; S38[i0]; S41[i0, i1, i2]; S92[i0]; S87[i0]; S47[i0, i1]; S108[i0, i1]; S54[i0]; S76[i0]; S112[i0, i1]; S80[i0]; S55[i0]; S39[i0]; S59[i0, i1, i2]; S121[i0]; S86[i0]; S110[i0, i1]; S48[i0, i1]; S68[i0]; S53[i0]; S72[i0]; S85[i0]; S52[i0]; S69[i0]; S61[i0, i1, i2]; S43[i0, i1, i2]; S124[i0]; S73[i0]; S81[i0]; S63[i0, i1]; S118[i0, i1]; S96[i0, i1, i2]; S40[i0, i1, i2]; S94[i0]; S64[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S99[i0] -> [(i0)]; S97[i0, i1, i2] -> [(i0)]; S53[i0] -> [(i0)]; S101[i0] -> [(i0)]; S60[i0, i1, i2] -> [(i0)]; S40[i0, i1, i2] -> [(i0)]; S103[i0, i1, i2] -> [(i0)]; S55[i0] -> [(i0)]; S89[i0] -> [(i0)]; S56[i0] -> [(i0)]; S87[i0] -> [(i0)]; S115[i0, i1] -> [(i0)]; S123[i0] -> [(i0)]; S88[i0] -> [(i0)]; S70[i0] -> [(i0)]; S59[i0, i1, i2] -> [(i0)]; S52[i0] -> [(i0)]; S54[i0] -> [(i0)]; S63[i0, i1] -> [(i0)]; S92[i0] -> [(i0)]; S93[i0] -> [(i0)]; S119[i0, i1] -> [(i0)]; S76[i0] -> [(i0)]; S57[i0] -> [(i0)]; S44[i0, i1] -> [(i0)]; S79[i0] -> [(i0)]; S61[i0, i1, i2] -> [(i0)]; S69[i0] -> [(i0)]; S117[i0, i1] -> [(i0)]; S121[i0] -> [(i0)]; S84[i0] -> [(i0)]; S83[i0] -> [(i0)]; S43[i0, i1, i2] -> [(i0)]; S98[i0, i1] -> [(i0)]; S78[i0] -> [(i0)]; S114[i0, i1] -> [(i0)]; S66[i0, i1] -> [(i0)]; S77[i0] -> [(i0)]; S109[i0, i1] -> [(i0)]; S42[i0, i1, i2] -> [(i0)]; S58[i0] -> [(i0)]; S71[i0] -> [(i0)]; S68[i0] -> [(i0)]; S116[i0, i1] -> [(i0)]; S81[i0] -> [(i0)]; S125[i0] -> [(i0)]; S80[i0] -> [(i0)]; S73[i0] -> [(i0)]; S110[i0, i1] -> [(i0)]; S72[i0] -> [(i0)]; S51[i0, i1] -> [(i0)]; S122[i0] -> [(i0)]; S38[i0] -> [(i0)]; S39[i0] -> [(i0)]; S90[i0] -> [(i0)]; S113[i0, i1] -> [(i0)]; S46[i0, i1] -> [(i0)]; S47[i0, i1] -> [(i0)]; S96[i0, i1, i2] -> [(i0)]; S45[i0, i1] -> [(i0)]; S49[i0, i1] -> [(i0)]; S118[i0, i1] -> [(i0)]; S50[i0, i1] -> [(i0)]; S102[i0, i1, i2] -> [(i0)]; S112[i0, i1] -> [(i0)]; S86[i0] -> [(i0)]; S124[i0] -> [(i0)]; S41[i0, i1, i2] -> [(i0)]; S100[i0] -> [(i0)]; S104[i0, i1, i2] -> [(i0)]; S75[i0] -> [(i0)]; S62[i0, i1] -> [(i0)]; S85[i0] -> [(i0)]; S105[i0, i1, i2] -> [(i0)]; S82[i0] -> [(i0)]; S111[i0, i1] -> [(i0)]; S48[i0, i1] -> [(i0)]; S65[i0, i1] -> [(i0)]; S120[i0] -> [(i0)]; S107[i0, i1, i2] -> [(i0)]; S106[i0, i1, i2] -> [(i0)]; S95[i0, i1, i2] -> [(i0)]; S108[i0, i1] -> [(i0)]; S91[i0] -> [(i0)]; S67[i0, i1] -> [(i0)]; S74[i0] -> [(i0)]; S64[i0, i1] -> [(i0)]; S94[i0] -> [(i0)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S38[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S39[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S40[i0, i1, i2]; S41[i0, i1, i2]; S43[i0, i1, i2]; S42[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S43[i0, i1, i2] -> [(i1)]; S41[i0, i1, i2] -> [(i1)]; S40[i0, i1, i2] -> [(i1)]; S42[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S43[i0, i1, i2] -> [(i2)]; S41[i0, i1, i2] -> [(i2)]; S40[i0, i1, i2] -> [(i2)]; S42[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S40[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S41[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S42[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S43[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S46[i0, i1]; S45[i0, i1]; S44[i0, i1]; S47[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S47[i0, i1] -> [(i1)]; S46[i0, i1] -> [(i1)]; S44[i0, i1] -> [(i1)]; S45[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S44[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S45[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S46[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S47[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S51[i0, i1]; S49[i0, i1]; S50[i0, i1]; S48[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S51[i0, i1] -> [(i1)]; S49[i0, i1] -> [(i1)]; S48[i0, i1] -> [(i1)]; S50[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S48[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S49[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S50[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S51[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S52[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S53[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S54[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S55[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S56[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S57[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S58[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S60[i0, i1, i2]; S59[i0, i1, i2]; S61[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S61[i0, i1, i2] -> [(i1)]; S59[i0, i1, i2] -> [(i1)]; S60[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S61[i0, i1, i2] -> [(i2)]; S59[i0, i1, i2] -> [(i2)]; S60[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S59[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S60[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S61[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S62[i0, i1]; S63[i0, i1]; S64[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S64[i0, i1] -> [(i1)]; S62[i0, i1] -> [(i1)]; S63[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S62[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S63[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S64[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S65[i0, i1]; S66[i0, i1]; S67[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S66[i0, i1] -> [(i1)]; S65[i0, i1] -> [(i1)]; S67[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S65[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S66[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S67[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S68[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S69[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S70[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S71[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S72[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S73[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S74[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S75[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S76[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S77[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S78[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S79[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S80[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S81[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S82[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S83[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S84[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S85[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S86[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S87[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S88[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S89[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S90[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S91[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S92[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S93[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S94[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S96[i0, i1, i2]; S98[i0, i1]; S97[i0, i1, i2]; S95[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S98[i0, i1] -> [(i1)]; S95[i0, i1, i2] -> [(i1)]; S96[i0, i1, i2] -> [(i1)]; S97[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S96[i0, i1, i2]; S97[i0, i1, i2]; S95[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S95[i0, i1, i2] -> [(i2)]; S96[i0, i1, i2] -> [(i2)]; S97[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S95[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S96[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S97[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S98[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S99[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S100[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S101[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S107[i0, i1, i2]; S105[i0, i1, i2]; S102[i0, i1, i2]; S104[i0, i1, i2]; S106[i0, i1, i2]; S103[i0, i1, i2] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S102[i0, i1, i2] -> [(i1)]; S103[i0, i1, i2] -> [(i1)]; S104[i0, i1, i2] -> [(i1)]; S107[i0, i1, i2] -> [(i1)]; S106[i0, i1, i2] -> [(i1)]; S105[i0, i1, i2] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S102[i0, i1, i2] -> [(i2)]; S103[i0, i1, i2] -> [(i2)]; S104[i0, i1, i2] -> [(i2)]; S107[i0, i1, i2] -> [(i2)]; S106[i0, i1, i2] -> [(i2)]; S105[i0, i1, i2] -> [(i2)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S102[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S103[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S104[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S105[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S106[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S107[i0, i1, i2] }" + - filter: "[M, N, O, P, Q, R] -> { S113[i0, i1]; S112[i0, i1]; S108[i0, i1]; S111[i0, i1]; S110[i0, i1]; S109[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S110[i0, i1] -> [(i1)]; S112[i0, i1] -> [(i1)]; S111[i0, i1] -> [(i1)]; S113[i0, i1] -> [(i1)]; S109[i0, i1] -> [(i1)]; S108[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S108[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S109[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S110[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S111[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S112[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S113[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S119[i0, i1]; S114[i0, i1]; S117[i0, i1]; S115[i0, i1]; S118[i0, i1]; S116[i0, i1] }" + child: + schedule: "[M, N, O, P, Q, R] -> [{ S115[i0, i1] -> [(i1)]; S116[i0, i1] -> [(i1)]; S118[i0, i1] -> [(i1)]; S117[i0, i1] -> [(i1)]; S119[i0, i1] -> [(i1)]; S114[i0, i1] -> [(i1)] }]" + options: "[M, N, O, P, Q, R] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N, O, P, Q, R] -> { S114[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S115[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S116[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S117[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S118[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S119[i0, i1] }" + - filter: "[M, N, O, P, Q, R] -> { S120[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S121[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S122[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S123[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S124[i0] }" + - filter: "[M, N, O, P, Q, R] -> { S125[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/test.in isl-0.15/test_inputs/codegen/cloog/test.in --- isl-0.12.2/test_inputs/codegen/cloog/test.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/test.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S1[i0, i1] -> [i0, i1, 0] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S2[i0, i0] -> [i0, i0, 1] : i0 >= 3 and i0 <= N } -[M, N] -> { : N >= M and M >= 4 } -[M, N] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/test.st isl-0.15/test_inputs/codegen/cloog/test.st --- isl-0.12.2/test_inputs/codegen/cloog/test.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/test.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "[M, N] -> { S1[i0, i1] : i0 >= 1 and i0 <= N and i1 >= 1 and i1 <= M; S2[i0, i0] : i0 >= 3 and i0 <= N }" +child: + context: "[M, N] -> { [] : N >= M and M >= 4 }" + child: + schedule: "[M, N] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S1[i0, i1] }" + - filter: "[M, N] -> { S2[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/thomasset.c isl-0.15/test_inputs/codegen/cloog/thomasset.c --- isl-0.12.2/test_inputs/codegen/cloog/thomasset.c 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/thomasset.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,6 +1,6 @@ { for (int c0 = 0; c0 <= floord(n - 1, 3); c0 += 1) - for (int c2 = 3 * c0 + 1; c2 <= min(3 * c0 + 3, n); c2 += 1) + for (int c2 = 3 * c0 + 1; c2 <= min(n, 3 * c0 + 3); c2 += 1) S1(c2, c0); for (int c0 = floord(n, 3); c0 <= 2 * floord(n, 3); c0 += 1) for (int c1 = 0; c1 < n; c1 += 1) diff -Nru isl-0.12.2/test_inputs/codegen/cloog/thomasset.in isl-0.15/test_inputs/codegen/cloog/thomasset.in --- isl-0.12.2/test_inputs/codegen/cloog/thomasset.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/thomasset.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S2[i0, i1, 0, i3, i4] -> [i3 + i4, -1 + i0] : i0 <= n and i1 <= n and i1 >= 1 and i0 >= 1 and 3i4 <= i1 and 3i4 >= -2 + i1 and 3i3 <= n and 3i3 >= -2 + n; S1[i0, i1] -> [i1, 0] : i0 <= n and i0 >= 1 and 3i1 <= -1 + i0 and 3i1 >= -3 + i0 } -[n] -> { : } -[n] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/thomasset.st isl-0.15/test_inputs/codegen/cloog/thomasset.st --- isl-0.12.2/test_inputs/codegen/cloog/thomasset.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/thomasset.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i, j] : i <= n and i >= 1 and 3j <= -1 + i and 3j >= -3 + i; S2[i, j, 0, p, q] : i <= n and j <= n and j >= 1 and i >= 1 and 3q <= j and 3q >= -2 + j and 3p <= n and 3p >= -2 + n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2, i3, i4] -> [(i2 + i3 + i4)]; S1[i0, i1] -> [(i1)] }, { S2[i0, i1, i2, i3, i4] -> [(-1 + i0)]; S1[i0, i1] -> [(0)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/tiling.c isl-0.15/test_inputs/codegen/cloog/tiling.c --- isl-0.12.2/test_inputs/codegen/cloog/tiling.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/tiling.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 0; c0 <= n / 10; c0 += 1) - for (int c1 = 10 * c0; c1 <= min(10 * c0 + 9, n); c1 += 1) + for (int c1 = 10 * c0; c1 <= min(n, 10 * c0 + 9); c1 += 1) S1(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/tiling.in isl-0.15/test_inputs/codegen/cloog/tiling.in --- isl-0.12.2/test_inputs/codegen/cloog/tiling.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/tiling.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[ii, i] -> [ii, i, 0] : i >= 0 and i <= n and i <= 9 + 10ii and i >= 10ii } -[n] -> { : n >= 0 } -[n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/tiling.st isl-0.15/test_inputs/codegen/cloog/tiling.st --- isl-0.12.2/test_inputs/codegen/cloog/tiling.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/tiling.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[ii, i] : i >= 0 and i <= n and i <= 9 + 10ii and i >= 10ii }" +child: + context: "[n] -> { [] : n >= 0 }" + child: + schedule: "[n] -> [{ S1[ii, i] -> [(ii)] }, { S1[ii, i] -> [(i)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/uday_scalars.c isl-0.15/test_inputs/codegen/cloog/uday_scalars.c --- isl-0.12.2/test_inputs/codegen/cloog/uday_scalars.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/uday_scalars.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,6 @@ { - for (int c2 = 0; c2 <= n; c2 += 1) - S1(c2, 0, 0); - for (int c2 = 0; c2 <= n; c2 += 1) - S2(0, c2, 0); + for (int c0 = 0; c0 <= n; c0 += 1) + S1(c0, 0, 0); + for (int c0 = 0; c0 <= n; c0 += 1) + S2(0, c0, 0); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/uday_scalars.in isl-0.15/test_inputs/codegen/cloog/uday_scalars.in --- isl-0.12.2/test_inputs/codegen/cloog/uday_scalars.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/uday_scalars.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i0, 0, 0] -> [0, 1, i0, 0] : i0 >= 0 and i0 <= n; S2[0, i1, 0] -> [1, 0, i1, 1] : i1 >= 0 and i1 <= n } -[n] -> { : } -[n] -> { [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/uday_scalars.st isl-0.15/test_inputs/codegen/cloog/uday_scalars.st --- isl-0.12.2/test_inputs/codegen/cloog/uday_scalars.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/uday_scalars.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,13 @@ +domain: "[n] -> { S1[j, 0, 0] : j >= 0 and j <= n; S2[0, l, 0] : l >= 0 and l <= n }" +child: + context: "[n] -> { [] }" + child: + sequence: + - filter: "[n] -> { S1[i0, i1, i2] }" + child: + schedule: "[n] -> [{ S1[i0, i1, i2] -> [(i0)] }]" + options: "[n] -> { separate[i0] }" + - filter: "[n] -> { S2[i0, i1, i2] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2] -> [(i1)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/union.in isl-0.15/test_inputs/codegen/cloog/union.in --- isl-0.12.2/test_inputs/codegen/cloog/union.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/union.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S1[i0] -> [i0] : M <= 10 and i0 >= 0 and i0 <= 100; S1[i0] -> [-i0] : M >= 11 and i0 >= 0 and i0 <= 100 } -[M] -> { : M >= 1 or M <= -1 } -[M] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/union.st isl-0.15/test_inputs/codegen/cloog/union.st --- isl-0.12.2/test_inputs/codegen/cloog/union.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/union.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S1[i0] : i0 >= 0 and i0 <= 100 }" +child: + context: "[M] -> { [] : M >= 1 or M <= -1 }" + child: + schedule: "[M] -> [{ S1[i0] -> [(i0)] : M <= 10; S1[i0] -> [(-i0)] : M >= 11 }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/unroll2.c isl-0.15/test_inputs/codegen/cloog/unroll2.c --- isl-0.12.2/test_inputs/codegen/cloog/unroll2.c 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/unroll2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,6 +1,5 @@ -{ - if (n <= 9 && n >= 0) +if (n >= -1 && n <= 9) { + if (n >= 0) S1(n); - if (n <= 9 && n >= -1) - S1(n + 1); + S1(n + 1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/unroll2.in isl-0.15/test_inputs/codegen/cloog/unroll2.in --- isl-0.12.2/test_inputs/codegen/cloog/unroll2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/unroll2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i] -> [i, 0] : i >= n and i <= 1 + n and n <= 9 and i >= 0 } -[n] -> { : } -[n] -> { [i, j] -> unroll[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/unroll2.st isl-0.15/test_inputs/codegen/cloog/unroll2.st --- isl-0.12.2/test_inputs/codegen/cloog/unroll2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/unroll2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i] : i >= n and i <= 1 + n and n <= 9 and i >= 0 }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i] -> [(i)] }]" + options: "[n] -> { unroll[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/unroll.in isl-0.15/test_inputs/codegen/cloog/unroll.in --- isl-0.12.2/test_inputs/codegen/cloog/unroll.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/unroll.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S1[i] -> [i, 0] : i >= 0 and i <= 10 } -[n] -> { : } -[n] -> { [i, j] -> unroll[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/unroll.st isl-0.15/test_inputs/codegen/cloog/unroll.st --- isl-0.12.2/test_inputs/codegen/cloog/unroll.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/unroll.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i] : i >= 0 and i <= 10 }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i] -> [(i)] }]" + options: "[n] -> { unroll[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/usvd_e_t.in isl-0.15/test_inputs/codegen/cloog/usvd_e_t.in --- isl-0.12.2/test_inputs/codegen/cloog/usvd_e_t.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/usvd_e_t.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S19[i0, i1, i2] -> [i0, i1, i2, 18] : i0 >= 8 and i1 >= 1 and i2 <= 0 and i2 >= -10 + i0 and i1 <= -6 + i0; S21[i0, i1, -7 + i0] -> [i0, i1, -7 + i0, 20] : i0 <= 10 and i1 >= 4 and i1 <= 8 and i0 >= 7; S17[i0, i1, -6 + i0] -> [i0, i1, -6 + i0, 16] : i0 >= 7 and i1 >= 4 and i0 <= 10 and i1 <= -2 + i0; S4[i0, i1, -1] -> [i0, i1, -1, 3] : i0 <= 8 and i1 >= 1 and i1 <= -4 + i0; S1[i0, 0, 0] -> [i0, 0, 0, 0] : i0 >= 0 and i0 <= 4; S10[i0, 4, 0] -> [i0, 4, 0, 9] : i0 >= 7 and i0 <= 10; S16[i0, i1, -6 + i0] -> [i0, i1, -6 + i0, 15] : i0 <= 10 and i1 >= 4 and i0 >= 7 and i1 <= -2 + i0; S24[i0, i1, i2] -> [i0, i1, i2, 23] : i0 >= 8 and i1 >= 4 and i1 <= 8 and i2 <= 3 and i2 >= -7 + i0; S23[i0, i1, i2] -> [i0, i1, i2, 22] : i0 <= 9 and i1 >= 4 and i1 <= 8 and i2 >= 0 and i2 <= -7 + i0; S7[i0, i1, 0] -> [i0, i1, 0, 6] : i0 >= 5 and i1 <= 0 and i1 >= -9 + i0; S25[i0, i1, 4] -> [i0, i1, 4, 24] : i0 >= 10 and i0 <= 14 and i1 >= 1 and i1 <= 5; S18[i0, i1, i2] -> [i0, i1, i2, 17] : i0 <= 10 and i1 >= 1 and i2 >= 4 and i2 <= -4 + i0 and i1 <= -5 + i0; S14[i0, i1, i2] -> [i0, i1, i2, 13] : i0 >= 8 and i1 <= 4 and i2 <= 0 and i2 >= -12 + i0 and i1 >= -6 + i0; S6[i0, i1, 0] -> [i0, i1, 0, 5] : i0 <= 8 and i1 >= -4 and i1 <= -9 + i0; S8[i0, i1, 0] -> [i0, i1, 0, 7] : i0 >= 3 and i0 <= 7 and i1 >= 7 and i1 <= 11; S15[i0, i1, i2] -> [i0, i1, i2, 14] : i0 <= 10 and i1 >= 1 and i1 <= 5 and i2 >= 4 and i2 <= -4 + i0; S11[i0, -3 + i0, i2] -> [i0, -3 + i0, i2, 10] : i0 <= 10 and i0 >= 7 and i2 <= 4 and i2 >= -7 + i0; S20[i0, i1, i2] -> [i0, i1, i2, 19] : i0 >= 8 and i1 <= 4 and i2 >= -4 and i2 <= 0 and i1 >= -6 + i0; S12[i0, -2 + i0, i2] -> [i0, -2 + i0, i2, 11] : i0 >= 7 and i0 <= 10 and i2 <= 4 and i2 >= -7 + i0; S9[i0, 4, 0] -> [i0, 4, 0, 8] : i0 >= 7 and i0 <= 10; S22[i0, i1, -7 + i0] -> [i0, i1, -7 + i0, 21] : i0 >= 7 and i1 >= 5 and i1 <= 9 and i0 <= 10; S13[i0, i1, i2] -> [i0, i1, i2, 12] : i0 <= 10 and i1 >= 4 and i2 <= 4 and i2 >= -7 + i0 and i1 <= -4 + i0; S26[i0, i1, 3] -> [i0, i1, 3, 25] : i0 >= 10 and i0 <= 14 and i1 >= 1 and i1 <= 5; S3[i0, 0, 0] -> [i0, 0, 0, 2] : i0 >= 4 and i0 <= 8; S5[i0, i1, 0] -> [i0, i1, 0, 4] : i0 >= 4 and i1 <= 4 and i1 >= -4 + i0; S2[i0, i1, 0] -> [i0, i1, 0, 1] : i0 >= 0 and i0 <= 4 and i1 >= 0 and i1 <= 4 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/usvd_e_t.st isl-0.15/test_inputs/codegen/cloog/usvd_e_t.st --- isl-0.12.2/test_inputs/codegen/cloog/usvd_e_t.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/usvd_e_t.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,34 @@ +domain: "{ S22[i0, i1, -7 + i0] : i0 >= 7 and i1 >= 5 and i1 <= 9 and i0 <= 10; S21[i0, i1, -7 + i0] : i0 <= 10 and i1 >= 4 and i1 <= 8 and i0 >= 7; S4[i0, i1, -1] : i0 <= 8 and i1 >= 1 and i1 <= -4 + i0; S8[i0, i1, 0] : i0 >= 3 and i0 <= 7 and i1 >= 7 and i1 <= 11; S25[i0, i1, 4] : i0 >= 10 and i0 <= 14 and i1 >= 1 and i1 <= 5; S15[i0, i1, i2] : i0 <= 10 and i1 >= 1 and i1 <= 5 and i2 >= 4 and i2 <= -4 + i0; S6[i0, i1, 0] : i0 <= 8 and i1 >= -4 and i1 <= -9 + i0; S16[i0, i1, -6 + i0] : i0 <= 10 and i1 >= 4 and i0 >= 7 and i1 <= -2 + i0; S7[i0, i1, 0] : i0 >= 5 and i1 <= 0 and i1 >= -9 + i0; S1[i0, 0, 0] : i0 >= 0 and i0 <= 4; S2[i0, i1, 0] : i0 >= 0 and i0 <= 4 and i1 >= 0 and i1 <= 4; S26[i0, i1, 3] : i0 >= 10 and i0 <= 14 and i1 >= 1 and i1 <= 5; S10[i0, 4, 0] : i0 >= 7 and i0 <= 10; S12[i0, -2 + i0, i2] : i0 >= 7 and i0 <= 10 and i2 <= 4 and i2 >= -7 + i0; S23[i0, i1, i2] : i0 <= 9 and i1 >= 4 and i1 <= 8 and i2 >= 0 and i2 <= -7 + i0; S13[i0, i1, i2] : i0 <= 10 and i1 >= 4 and i2 <= 4 and i2 >= -7 + i0 and i1 <= -4 + i0; S20[i0, i1, i2] : i0 >= 8 and i1 <= 4 and i2 >= -4 and i2 <= 0 and i1 >= -6 + i0; S24[i0, i1, i2] : i0 >= 8 and i1 >= 4 and i1 <= 8 and i2 <= 3 and i2 >= -7 + i0; S19[i0, i1, i2] : i0 >= 8 and i1 >= 1 and i2 <= 0 and i2 >= -10 + i0 and i1 <= -6 + i0; S11[i0, -3 + i0, i2] : i0 <= 10 and i0 >= 7 and i2 <= 4 and i2 >= -7 + i0; S14[i0, i1, i2] : i0 >= 8 and i1 <= 4 and i2 <= 0 and i2 >= -12 + i0 and i1 >= -6 + i0; S3[i0, 0, 0] : i0 >= 4 and i0 <= 8; S9[i0, 4, 0] : i0 >= 7 and i0 <= 10; S18[i0, i1, i2] : i0 <= 10 and i1 >= 1 and i2 >= 4 and i2 <= -4 + i0 and i1 <= -5 + i0; S5[i0, i1, 0] : i0 >= 4 and i1 <= 4 and i1 >= -4 + i0; S17[i0, i1, -6 + i0] : i0 >= 7 and i1 >= 4 and i0 <= 10 and i1 <= -2 + i0 }" +child: + context: "{ [] }" + child: + schedule: "[{ S8[i0, i1, i2] -> [(i0)]; S21[i0, i1, i2] -> [(i0)]; S9[i0, i1, i2] -> [(i0)]; S10[i0, i1, i2] -> [(i0)]; S24[i0, i1, i2] -> [(i0)]; S15[i0, i1, i2] -> [(i0)]; S12[i0, i1, i2] -> [(i0)]; S7[i0, i1, i2] -> [(i0)]; S6[i0, i1, i2] -> [(i0)]; S23[i0, i1, i2] -> [(i0)]; S22[i0, i1, i2] -> [(i0)]; S16[i0, i1, i2] -> [(i0)]; S17[i0, i1, i2] -> [(i0)]; S25[i0, i1, i2] -> [(i0)]; S18[i0, i1, i2] -> [(i0)]; S26[i0, i1, i2] -> [(i0)]; S5[i0, i1, i2] -> [(i0)]; S2[i0, i1, i2] -> [(i0)]; S4[i0, i1, i2] -> [(i0)]; S13[i0, i1, i2] -> [(i0)]; S3[i0, i1, i2] -> [(i0)]; S14[i0, i1, i2] -> [(i0)]; S19[i0, i1, i2] -> [(i0)]; S20[i0, i1, i2] -> [(i0)]; S11[i0, i1, i2] -> [(i0)]; S1[i0, i1, i2] -> [(i0)] }, { S8[i0, i1, i2] -> [(i1)]; S21[i0, i1, i2] -> [(i1)]; S9[i0, i1, i2] -> [(i1)]; S10[i0, i1, i2] -> [(i1)]; S24[i0, i1, i2] -> [(i1)]; S15[i0, i1, i2] -> [(i1)]; S12[i0, i1, i2] -> [(i1)]; S7[i0, i1, i2] -> [(i1)]; S6[i0, i1, i2] -> [(i1)]; S23[i0, i1, i2] -> [(i1)]; S22[i0, i1, i2] -> [(i1)]; S16[i0, i1, i2] -> [(i1)]; S17[i0, i1, i2] -> [(i1)]; S25[i0, i1, i2] -> [(i1)]; S18[i0, i1, i2] -> [(i1)]; S26[i0, i1, i2] -> [(i1)]; S5[i0, i1, i2] -> [(i1)]; S2[i0, i1, i2] -> [(i1)]; S4[i0, i1, i2] -> [(i1)]; S13[i0, i1, i2] -> [(i1)]; S3[i0, i1, i2] -> [(i1)]; S14[i0, i1, i2] -> [(i1)]; S19[i0, i1, i2] -> [(i1)]; S20[i0, i1, i2] -> [(i1)]; S11[i0, i1, i2] -> [(i1)]; S1[i0, i1, i2] -> [(i1)] }, { S8[i0, i1, i2] -> [(i2)]; S21[i0, i1, i2] -> [(i2)]; S9[i0, i1, i2] -> [(i2)]; S10[i0, i1, i2] -> [(i2)]; S24[i0, i1, i2] -> [(i2)]; S15[i0, i1, i2] -> [(i2)]; S12[i0, i1, i2] -> [(i2)]; S7[i0, i1, i2] -> [(i2)]; S6[i0, i1, i2] -> [(i2)]; S23[i0, i1, i2] -> [(i2)]; S22[i0, i1, i2] -> [(i2)]; S16[i0, i1, i2] -> [(i2)]; S17[i0, i1, i2] -> [(i2)]; S25[i0, i1, i2] -> [(i2)]; S18[i0, i1, i2] -> [(i2)]; S26[i0, i1, i2] -> [(i2)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1, i2] -> [(i2)]; S4[i0, i1, i2] -> [(i2)]; S13[i0, i1, i2] -> [(i2)]; S3[i0, i1, i2] -> [(i2)]; S14[i0, i1, i2] -> [(i2)]; S19[i0, i1, i2] -> [(i2)]; S20[i0, i1, i2] -> [(i2)]; S11[i0, i1, i2] -> [(i2)]; S1[i0, i1, i2] -> [(i2)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1, i2] }" + - filter: "{ S2[i0, i1, i2] }" + - filter: "{ S3[i0, i1, i2] }" + - filter: "{ S4[i0, i1, i2] }" + - filter: "{ S5[i0, i1, i2] }" + - filter: "{ S6[i0, i1, i2] }" + - filter: "{ S7[i0, i1, i2] }" + - filter: "{ S8[i0, i1, i2] }" + - filter: "{ S9[i0, i1, i2] }" + - filter: "{ S10[i0, i1, i2] }" + - filter: "{ S11[i0, i1, i2] }" + - filter: "{ S12[i0, i1, i2] }" + - filter: "{ S13[i0, i1, i2] }" + - filter: "{ S14[i0, i1, i2] }" + - filter: "{ S15[i0, i1, i2] }" + - filter: "{ S16[i0, i1, i2] }" + - filter: "{ S17[i0, i1, i2] }" + - filter: "{ S18[i0, i1, i2] }" + - filter: "{ S19[i0, i1, i2] }" + - filter: "{ S20[i0, i1, i2] }" + - filter: "{ S21[i0, i1, i2] }" + - filter: "{ S22[i0, i1, i2] }" + - filter: "{ S23[i0, i1, i2] }" + - filter: "{ S24[i0, i1, i2] }" + - filter: "{ S25[i0, i1, i2] }" + - filter: "{ S26[i0, i1, i2] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vasilache.c isl-0.15/test_inputs/codegen/cloog/vasilache.c --- isl-0.12.2/test_inputs/codegen/cloog/vasilache.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vasilache.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,23 +1,23 @@ { S1(); S2(); - for (int c1 = 0; c1 < N; c1 += 1) - for (int c3 = 0; c3 < N; c3 += 1) { - S4(c1, c3); - S5(c1, c3); + for (int c0 = 0; c0 < N; c0 += 1) + for (int c1 = 0; c1 < N; c1 += 1) { + S4(c0, c1); + S5(c0, c1); } - for (int c1 = 0; c1 < N; c1 += 1) - for (int c3 = 0; c3 < N; c3 += 1) - for (int c5 = 0; c5 <= (N - 1) / 32; c5 += 1) { - S7(c1, c3, c5, 32 * c5); - for (int c7 = 32 * c5 + 1; c7 <= min(N - 1, 32 * c5 + 31); c7 += 1) { - S6(c1, c3, c5, c7 - 1); - S7(c1, c3, c5, c7); + for (int c0 = 0; c0 < N; c0 += 1) + for (int c1 = 0; c1 < N; c1 += 1) + for (int c2 = 0; c2 <= (N - 1) / 32; c2 += 1) { + S7(c0, c1, c2, 32 * c2); + for (int c3 = 32 * c2 + 1; c3 <= min(N - 1, 32 * c2 + 31); c3 += 1) { + S6(c0, c1, c2, c3 - 1); + S7(c0, c1, c2, c3); } - if (N >= 32 * c5 + 33) { - S6(c1, c3, c5, 32 * c5 + 31); + if (32 * c2 + 31 >= N) { + S6(c0, c1, c2, N - 1); } else - S6(c1, c3, c5, N - 1); + S6(c0, c1, c2, 32 * c2 + 31); } S8(); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vasilache.in isl-0.15/test_inputs/codegen/cloog/vasilache.in --- isl-0.12.2/test_inputs/codegen/cloog/vasilache.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vasilache.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M, N] -> { S4[i0, i1] -> [3, i0, 0, i1, 0, 0, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S1[] -> [0, 0, 0, 0, 0, 0, 0, 0, 0]; S6[i0, i1, i2, i3] -> [4, i0, 0, i1, 0, i2, 0, 1 + i3, 0] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N and i3 >= 0 and i3 <= -1 + N and i3 >= 32i2 and i3 <= 31 + 32i2; S7[i0, i1, i2, i3] -> [4, i0, 0, i1, 0, i2, 0, i3, 1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N and i3 >= 0 and i3 <= -1 + N and i3 >= 32i2 and i3 <= 31 + 32i2; S5[i0, i1] -> [3, i0, 0, i1, 1, 0, 0, 0, 0] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S2[] -> [1, 0, 0, 0, 0, 0, 0, 0, 0]; S8[] -> [5, 0, 0, 0, 0, 0, 0, 0, 0]; S3[] -> [2, 0, 0, 0, 0, 0, 0, 0, 0] : M >= 79 } -[M, N] -> { : M <= 3 and N >= 100 } -[M, N] -> { [i, j, k, l, m, n, o, p, q] -> separate[x] : x >= 7 } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vasilache.st isl-0.15/test_inputs/codegen/cloog/vasilache.st --- isl-0.12.2/test_inputs/codegen/cloog/vasilache.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vasilache.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,37 @@ +domain: "[M, N] -> { S5[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S8[]; S2[]; S7[i0, i1, i2, i3] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N and i3 >= 0 and i3 <= -1 + N and i3 >= 32i2 and i3 <= 31 + 32i2; S4[i0, i1] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N; S1[]; S3[] : M >= 79; S6[i0, i1, i2, i3] : i0 >= 0 and i0 <= -1 + N and i1 >= 0 and i1 <= -1 + N and i3 >= 0 and i3 <= -1 + N and i3 >= 32i2 and i3 <= 31 + 32i2 }" +child: + context: "[M, N] -> { [] : M <= 3 and N >= 100 }" + child: + sequence: + - filter: "[M, N] -> { S1[] }" + - filter: "[M, N] -> { S2[] }" + - filter: "[M, N] -> { S3[] }" + - filter: "[M, N] -> { S5[i0, i1]; S4[i0, i1] }" + child: + schedule: "[M, N] -> [{ S5[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S5[i0, i1] -> [(i1)]; S4[i0, i1] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S4[i0, i1] }" + - filter: "[M, N] -> { S5[i0, i1] }" + - filter: "[M, N] -> { S7[i0, i1, i2, i3]; S6[i0, i1, i2, i3] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i0)]; S6[i0, i1, i2, i3] -> [(i0)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i1)]; S6[i0, i1, i2, i3] -> [(i1)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i2)]; S6[i0, i1, i2, i3] -> [(i2)] }]" + options: "[M, N] -> { separate[i0] }" + child: + schedule: "[M, N] -> [{ S7[i0, i1, i2, i3] -> [(i3)]; S6[i0, i1, i2, i3] -> [(1 + i3)] }]" + options: "[M, N] -> { separate[i0] }" + child: + sequence: + - filter: "[M, N] -> { S6[i0, i1, i2, i3] }" + - filter: "[M, N] -> { S7[i0, i1, i2, i3] }" + - filter: "[M, N] -> { S8[] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vivien2.c isl-0.15/test_inputs/codegen/cloog/vivien2.c --- isl-0.12.2/test_inputs/codegen/cloog/vivien2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vivien2.c 2015-06-02 09:28:10.000000000 +0000 @@ -4,47 +4,46 @@ for (int c0 = 2; c0 <= n + 29; c0 += 1) { if (c0 >= 3) { S4(c0 - c0 / 2 - 1, c0 / 2 + 1); - if (c0 + 2 >= 2 * n) { - for (int c2 = 1; c2 < -n + c0; c2 += 1) - S5(-n + c0, n, c2); - } else if (c0 >= 5) { + if (c0 >= 5 && 2 * n >= c0 + 3) { S4(c0 - c0 / 2 - 2, c0 / 2 + 2); - for (int c2 = 1; c2 < (c0 + 1) / 2 - 1; c2 += 1) + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); } - } - for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(n - c0, -1); c1 += 1) { - S4(-c1, c0 + c1); - S6(-c1 + 2, c0 + c1 - 2); - for (int c2 = 1; c2 <= -c1; c2 += 1) - S5(-c1 + 1, c0 + c1 - 1, c2); - } - if (c0 >= n + 2 && 2 * n >= c0 + 3) { - S6(-n + c0 + 1, n - 1); - for (int c2 = 1; c2 < -n + c0; c2 += 1) - S5(-n + c0, n, c2); - } - if (c0 >= n + 3) { - S6(-n + c0, n); - S1(c0 - 1); - } else { - if (c0 >= 5 && n + 1 >= c0) { - S6(2, c0 - 2); - S1(c0 - 1); - } else if (c0 <= 4 && c0 >= 3) + for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) { + S4(-c1, c0 + c1); + S6(-c1 + 2, c0 + c1 - 2); + for (int c2 = 1; c2 <= -c1; c2 += 1) + S5(-c1 + 1, c0 + c1 - 1, c2); + } + if (2 * n >= c0 + 3 && c0 >= n + 2) { + S6(-n + c0 + 1, n - 1); + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + if (c0 == n + 2) { + S6(2, n); + S1(n + 1); + } + } else if (c0 + 2 >= 2 * n) + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + if (c0 >= n + 3) { + S6(-n + c0, n); S1(c0 - 1); - if (c0 >= 3 && n + 1 >= c0) - S6(1, c0 - 1); - if (c0 == n + 2) { - S6(2, n); - S1(n + 1); + } else { + if (c0 <= 4) { + S1(c0 - 1); + } else if (n + 1 >= c0) { + S6(2, c0 - 2); + S1(c0 - 1); + } + if (n + 1 >= c0) + S6(1, c0 - 1); } - } - if (c0 == 2) + } else S1(1); if (c0 % 2 == 0) S3(c0 / 2); - for (int c1 = max(-n + c0, 1); c1 < (c0 + 1) / 2; c1 += 1) + for (int c1 = max(1, -n + c0); c1 < (c0 + 1) / 2; c1 += 1) S2(c0 - c1, c1); } for (int c0 = n + 30; c0 <= 2 * n; c0 += 1) { @@ -55,7 +54,7 @@ S5(-n + c0, n, c2); } else { S4(c0 - c0 / 2 - 2, c0 / 2 + 2); - for (int c2 = 1; c2 < (c0 + 1) / 2 - 1; c2 += 1) + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); } for (int c1 = -c0 + c0 / 2 + 3; c1 <= n - c0; c1 += 1) { diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vivien2.in isl-0.15/test_inputs/codegen/cloog/vivien2.in --- isl-0.12.2/test_inputs/codegen/cloog/vivien2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vivien2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S6[i0, i1] -> [2i0 + 2i1, 2 - i0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S2[i0, i1] -> [1 + 2i0 + 2i1, i1, 0] : 29i1 >= 1 - i0 and i0 <= n and i1 >= 1 and i1 <= -1 + i0; S1[i0] -> [2 + 2i0, 0, 0] : i0 >= 1 - 27n and i0 <= 28 + n; S4[i0, i1] -> [2i0 + 2i1, -i0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S3[i0] -> [1 + 4i0, 0, 0] : i0 >= 1 and i0 <= n; S5[i0, i1, i2] -> [2i0 + 2i1, 1 - i0, i2] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 and i2 <= -1 + i0 } -[n] -> { : n >= 30 } -[n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vivien2.st isl-0.15/test_inputs/codegen/cloog/vivien2.st --- isl-0.12.2/test_inputs/codegen/cloog/vivien2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vivien2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S2[i, j] : 29j >= 1 - i and i <= n and j >= 1 and j <= -1 + i; S1[i] : i >= 1 - 27n and i <= 28 + n; S4[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S5[i, j, k] : i >= 1 and i <= n and j >= 1 + i and j <= n and k >= 1 and k <= -1 + i; S6[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S3[i] : i >= 1 and i <= n }" +child: + context: "[n] -> { [] : n >= 30 }" + child: + schedule: "[n] -> [{ S1[i0] -> [(2 + 2i0)]; S4[i0, i1] -> [(2i0 + 2i1)]; S6[i0, i1] -> [(2i0 + 2i1)]; S3[i0] -> [(1 + 4i0)]; S5[i0, i1, i2] -> [(2i0 + 2i1)]; S2[i0, i1] -> [(1 + 2i0 + 2i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(-i0)]; S6[i0, i1] -> [(2 - i0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(1 - i0)]; S2[i0, i1] -> [(i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(0)]; S6[i0, i1] -> [(0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1] -> [(0)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vivien.c isl-0.15/test_inputs/codegen/cloog/vivien.c --- isl-0.12.2/test_inputs/codegen/cloog/vivien.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vivien.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,54 +1,60 @@ { for (int c0 = -27 * n + 2; c0 <= 1; c0 += 1) S1(c0 - 1); - for (int c0 = 2; c0 <= min(n + 29, 2 * n); c0 += 1) { - if (2 * n >= c0 + 1 && c0 >= 3) - S4(c0 - c0 / 2 - 1, c0 / 2 + 1); - if (2 * n >= c0 + 1 && c0 + 2 >= 2 * n) { - for (int c2 = 1; c2 < -n + c0; c2 += 1) - S5(-n + c0, n, c2); - } else if (2 * n >= c0 + 3 && c0 >= 5) { - S4(c0 - c0 / 2 - 2, c0 / 2 + 2); - for (int c2 = 1; c2 < (c0 + 1) / 2 - 1; c2 += 1) - S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); - } - for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(n - c0, -1); c1 += 1) { - S4(-c1, c0 + c1); - S6(-c1 + 2, c0 + c1 - 2); - for (int c2 = 1; c2 <= -c1; c2 += 1) - S5(-c1 + 1, c0 + c1 - 1, c2); - } - if (2 * n >= c0 + 3 && c0 >= n + 2) { - S6(-n + c0 + 1, n - 1); - for (int c2 = 1; c2 < -n + c0; c2 += 1) - S5(-n + c0, n, c2); - } - if (2 * n >= c0 + 1 && c0 >= n + 3) { - S6(-n + c0, n); - } else { - if (n + 1 >= c0 && c0 >= 5) { - S6(2, c0 - 2); - S1(c0 - 1); - } else if (c0 <= 4 && c0 >= 3 && n + 1 >= c0) - S1(c0 - 1); - if (n + 1 >= c0 && c0 >= 3) - S6(1, c0 - 1); - } - if (c0 >= n + 3) { - S1(c0 - 1); - } else if (c0 == n + 2 && n >= 3) { - S6(2, n); - S1(n + 1); - } - if (c0 == 2) { + for (int c0 = 2; c0 <= min(2 * n, n + 29); c0 += 1) { + if (c0 >= 3) { + if (2 * n >= c0 + 1) { + S4(c0 - c0 / 2 - 1, c0 / 2 + 1); + if (c0 + 2 >= 2 * n) { + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } else if (c0 >= 5) { + S4(c0 - c0 / 2 - 2, c0 / 2 + 2); + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) + S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); + } + } + for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) { + S4(-c1, c0 + c1); + S6(-c1 + 2, c0 + c1 - 2); + for (int c2 = 1; c2 <= -c1; c2 += 1) + S5(-c1 + 1, c0 + c1 - 1, c2); + } + if (2 * n >= c0 + 3 && c0 >= n + 2) { + S6(-n + c0 + 1, n - 1); + for (int c2 = 1; c2 < -n + c0; c2 += 1) + S5(-n + c0, n, c2); + } + if (n >= 3 && c0 == n + 2) { + S6(2, n); + S1(n + 1); + } else { + if (c0 >= n + 3 && 2 * n >= c0 + 1) + S6(-n + c0, n); + if (c0 >= n + 3) { + S1(c0 - 1); + } else { + if (n + 1 >= c0 && c0 <= 4) { + S1(c0 - 1); + } else if (c0 >= 5 && n + 1 >= c0) { + S6(2, c0 - 2); + S1(c0 - 1); + } + if (n + 1 >= c0) + S6(1, c0 - 1); + } + } + if (n == 2 && c0 == 4) + S1(3); + } else S1(1); - } else if (c0 == 4 && n == 2) - S1(3); if (c0 % 2 == 0) S3(c0 / 2); - for (int c1 = max(-n + c0, 1); c1 < (c0 + 1) / 2; c1 += 1) + for (int c1 = max(1, -n + c0); c1 < (c0 + 1) / 2; c1 += 1) S2(c0 - c1, c1); } + for (int c0 = max(2 * n + 1, -27 * n + 2); c0 <= n + 29; c0 += 1) + S1(c0 - 1); for (int c0 = n + 30; c0 <= 2 * n; c0 += 1) { if (2 * n >= c0 + 1) { S4(c0 - c0 / 2 - 1, c0 / 2 + 1); @@ -57,7 +63,7 @@ S5(-n + c0, n, c2); } else { S4(c0 - c0 / 2 - 2, c0 / 2 + 2); - for (int c2 = 1; c2 < (c0 + 1) / 2 - 1; c2 += 1) + for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1) S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2); } for (int c1 = -c0 + c0 / 2 + 3; c1 <= n - c0; c1 += 1) { @@ -78,6 +84,4 @@ for (int c1 = -n + c0; c1 < (c0 + 1) / 2; c1 += 1) S2(c0 - c1, c1); } - for (int c0 = max(2 * n + 1, -27 * n + 2); c0 <= n + 29; c0 += 1) - S1(c0 - 1); } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vivien.in isl-0.15/test_inputs/codegen/cloog/vivien.in --- isl-0.12.2/test_inputs/codegen/cloog/vivien.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vivien.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S6[i0, i1] -> [2i0 + 2i1, 2 - i0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S2[i0, i1] -> [1 + 2i0 + 2i1, i1, 0] : 29i1 >= 1 - i0 and i0 <= n and i1 >= 1 and i1 <= -1 + i0; S1[i0] -> [2 + 2i0, 0, 0] : i0 >= 1 - 27n and i0 <= 28 + n; S4[i0, i1] -> [2i0 + 2i1, -i0, 0] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n; S3[i0] -> [1 + 4i0, 0, 0] : i0 >= 1 and i0 <= n; S5[i0, i1, i2] -> [2i0 + 2i1, 1 - i0, i2] : i0 >= 1 and i0 <= n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 and i2 <= -1 + i0 } -[n] -> { : } -[n] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/vivien.st isl-0.15/test_inputs/codegen/cloog/vivien.st --- isl-0.12.2/test_inputs/codegen/cloog/vivien.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/vivien.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S2[i, j] : 29j >= 1 - i and i <= n and j >= 1 and j <= -1 + i; S1[i] : i >= 1 - 27n and i <= 28 + n; S4[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S5[i, j, k] : i >= 1 and i <= n and j >= 1 + i and j <= n and k >= 1 and k <= -1 + i; S6[i, j] : i >= 1 and i <= n and j >= 1 + i and j <= n; S3[i] : i >= 1 and i <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S1[i0] -> [(2 + 2i0)]; S4[i0, i1] -> [(2i0 + 2i1)]; S6[i0, i1] -> [(2i0 + 2i1)]; S3[i0] -> [(1 + 4i0)]; S5[i0, i1, i2] -> [(2i0 + 2i1)]; S2[i0, i1] -> [(1 + 2i0 + 2i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(-i0)]; S6[i0, i1] -> [(2 - i0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(1 - i0)]; S2[i0, i1] -> [(i1)] }, { S1[i0] -> [(0)]; S4[i0, i1] -> [(0)]; S6[i0, i1] -> [(0)]; S3[i0] -> [(0)]; S5[i0, i1, i2] -> [(i2)]; S2[i0, i1] -> [(0)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/walters2.in isl-0.15/test_inputs/codegen/cloog/walters2.in --- isl-0.12.2/test_inputs/codegen/cloog/walters2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/walters2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[j, i] -> [j, i, 0] : j >= 1 and j <= 24 and i >= 1 and i <= 50; S2[j, 51] -> [j, 51, 1] : j >= 1 and j <= 24; S2[25, i] -> [25, i, 1] : i >= 1 and i <= 51; S2[0, i] -> [0, i, 1] : i >= 0 and i <= 51; S2[j, 0] -> [j, 0, 1] : j >= 1 and j <= 25 } -{ : } -{ [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/walters2.st isl-0.15/test_inputs/codegen/cloog/walters2.st --- isl-0.12.2/test_inputs/codegen/cloog/walters2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/walters2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S2[j, 51] : j <= 24 and j >= 1; S2[25, i] : i <= 51 and i >= 1; S2[j, 0] : j <= 25 and j >= 1; S2[0, i] : i <= 51 and i >= 0; S1[j, i] : j >= 1 and j <= 24 and i >= 1 and i <= 50 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[j, i] -> [(j)]; S2[j, i] -> [(j)] }, { S1[j, i] -> [(i)]; S2[j, i] -> [(i)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[j, i] }" + - filter: "{ S2[j, i] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/walters3.in isl-0.15/test_inputs/codegen/cloog/walters3.in --- isl-0.12.2/test_inputs/codegen/cloog/walters3.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/walters3.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[j, a, b] -> [j, j', b, 1] : 2a = j and 2j' = j and j >= 1 and j <= 10 and 2b <= j and 2b >= -1 + j; S1[j, a, b] -> [j, j', k, 0] : 2a = j and 2j' = j and 2k = j and 2b = j and j <= 8 and j >= 2 } -{ : } -{ [i, j, k, l] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/walters3.st isl-0.15/test_inputs/codegen/cloog/walters3.st --- isl-0.12.2/test_inputs/codegen/cloog/walters3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/walters3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +domain: "{ S2[j, a, b] : 2a = j and j >= 1 and j <= 10 and 2b <= j and 2b >= -1 + j; S1[j, a, b] : 2a = j and 2b = j and j <= 8 and j >= 2 }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[j, a, b] -> [(j)]; S2[j, a, b] -> [(j)] }, { S1[j, a, b] -> [(a)]; S2[j, a, b] -> [(a)] }, { S1[j, a, b] -> [(b)]; S2[j, a, b] -> [(b)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[j, a, b] }" + - filter: "{ S2[j, a, b] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/walters.in isl-0.15/test_inputs/codegen/cloog/walters.in --- isl-0.12.2/test_inputs/codegen/cloog/walters.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/walters.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S2[i, div36, div37, div38] -> [i, div36, k, div38, 1] : 3div37 = 2 + i and 3k = 2 + i and i >= 1 and i <= 10 and 3div36 >= -2 + i and 3div38 <= 1 + i and 3div38 >= -1 + i and 3div36 <= i; S1[i, div36, div37, div38] -> [i, j, div37, div38, 0] : 3j = i and 3div36 = i and i >= 3 and i <= 10 and 3div37 >= i and 3div38 <= 1 + i and 3div37 <= 2 + i and 3div38 >= -1 + i; S3[i, div36, div37, div38] -> [i, div36, div37, l, 2] : 3l = 1 + i and 3div38 = 1 + i and i <= 10 and i >= 2 and 3div36 >= -2 + i and 3div37 <= 2 + i and 3div36 <= i and 3div37 >= i; S4[i, div36, div37, div38] -> [i, div36, div37, div38, 3] : i >= 1 and i <= 10 and 3div36 <= i and 3div36 >= -2 + i and 3div37 <= 2 + i and 3div37 >= i and 3div38 <= 1 + i and 3div38 >= -1 + i } -{ : } -{ [i, j, k, l, m] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/walters.st isl-0.15/test_inputs/codegen/cloog/walters.st --- isl-0.12.2/test_inputs/codegen/cloog/walters.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/walters.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,12 @@ +domain: "{ S2[i, div36, div37, div38] : 3div37 = 2 + i and i >= 1 and i <= 10 and 3div36 >= -2 + i and 3div38 <= 1 + i and 3div38 >= -1 + i and 3div36 <= i; S4[i, div36, div37, div38] : i >= 1 and i <= 10 and 3div36 <= i and 3div36 >= -2 + i and 3div37 <= 2 + i and 3div37 >= i and 3div38 <= 1 + i and 3div38 >= -1 + i; S1[i, div36, div37, div38] : 3div36 = i and i >= 3 and i <= 10 and 3div37 >= i and 3div38 <= 1 + i and 3div37 <= 2 + i and 3div38 >= -1 + i; S3[i, div36, div37, div38] : 3div38 = 1 + i and i <= 10 and i >= 2 and 3div36 >= -2 + i and 3div37 <= 2 + i and 3div36 <= i and 3div37 >= i }" +child: + context: "{ [] }" + child: + schedule: "[{ S1[i, div36, div37, div38] -> [(i)]; S4[i, div36, div37, div38] -> [(i)]; S3[i, div36, div37, div38] -> [(i)]; S2[i, div36, div37, div38] -> [(i)] }, { S1[i, div36, div37, div38] -> [(div36)]; S4[i, div36, div37, div38] -> [(div36)]; S3[i, div36, div37, div38] -> [(div36)]; S2[i, div36, div37, div38] -> [(div36)] }, { S1[i, div36, div37, div38] -> [(div37)]; S4[i, div36, div37, div38] -> [(div37)]; S3[i, div36, div37, div38] -> [(div37)]; S2[i, div36, div37, div38] -> [(div37)] }, { S1[i, div36, div37, div38] -> [(div38)]; S4[i, div36, div37, div38] -> [(div38)]; S3[i, div36, div37, div38] -> [(div38)]; S2[i, div36, div37, div38] -> [(div38)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i, div36, div37, div38] }" + - filter: "{ S2[i, div36, div37, div38] }" + - filter: "{ S3[i, div36, div37, div38] }" + - filter: "{ S4[i, div36, div37, div38] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/wavefront.c isl-0.15/test_inputs/codegen/cloog/wavefront.c --- isl-0.12.2/test_inputs/codegen/cloog/wavefront.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/wavefront.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 2; c0 <= n + m; c0 += 1) - for (int c1 = max(-m + c0, 1); c1 <= min(n, c0 - 1); c1 += 1) + for (int c1 = max(1, -m + c0); c1 <= min(n, c0 - 1); c1 += 1) S1(c1, c0 - c1); diff -Nru isl-0.12.2/test_inputs/codegen/cloog/wavefront.in isl-0.15/test_inputs/codegen/cloog/wavefront.in --- isl-0.12.2/test_inputs/codegen/cloog/wavefront.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/wavefront.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n, m] -> { S1[i0, i1] -> [i0 + i1, i0] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= m } -[n, m] -> { : } -[n, m] -> { [i, j] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/wavefront.st isl-0.15/test_inputs/codegen/cloog/wavefront.st --- isl-0.12.2/test_inputs/codegen/cloog/wavefront.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/wavefront.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n, m] -> { S1[i0, i1] : i0 >= 1 and i0 <= n and i1 >= 1 and i1 <= m }" +child: + context: "[n, m] -> { [] }" + child: + schedule: "[n, m] -> [{ S1[i0, i1] -> [(i0 + i1)] }, { S1[i0, i1] -> [(i0)] }]" + options: "[n, m] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/yosr2.in isl-0.15/test_inputs/codegen/cloog/yosr2.in --- isl-0.12.2/test_inputs/codegen/cloog/yosr2.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/yosr2.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[M] -> { S3[i0, i1, i2] -> [i0] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 and i2 <= -1 + i0; S4[i0, i1] -> [i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S1[i0, i1] -> [i0] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0; S2[i0] -> [0] : i0 >= 1 and i0 <= M } -[M] -> { : M >= 2 } -[M] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/yosr2.st isl-0.15/test_inputs/codegen/cloog/yosr2.st --- isl-0.12.2/test_inputs/codegen/cloog/yosr2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/yosr2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[M] -> { S4[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M; S3[i0, i1, i2] : i0 >= 1 and i0 <= M and i1 >= 1 + i0 and i1 <= M and i2 >= 1 and i2 <= -1 + i0; S1[i0, i1] : i0 >= 1 and i0 <= M and i1 >= 1 and i1 <= -1 + i0; S2[i0] : i0 >= 1 and i0 <= M }" +child: + context: "[M] -> { [] : M >= 2 }" + child: + schedule: "[M] -> [{ S2[i0] -> [(0)]; S1[i0, i1] -> [(i0)]; S4[i0, i1] -> [(i1)]; S3[i0, i1, i2] -> [(i0)] }]" + options: "[M] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/yosr.c isl-0.15/test_inputs/codegen/cloog/yosr.c --- isl-0.12.2/test_inputs/codegen/cloog/yosr.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/yosr.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,10 +1,10 @@ { for (int c0 = 1; c0 < n; c0 += 1) { - for (int c2 = c0 + 1; c2 <= n; c2 += 1) - S1(c0, c2); for (int c1 = 1; c1 < c0; c1 += 1) for (int c2 = c1 + 1; c2 <= n; c2 += 1) S2(c1, c2, c0); + for (int c2 = c0 + 1; c2 <= n; c2 += 1) + S1(c0, c2); } for (int c1 = 1; c1 < n; c1 += 1) for (int c2 = c1 + 1; c2 <= n; c2 += 1) diff -Nru isl-0.12.2/test_inputs/codegen/cloog/yosr.in isl-0.15/test_inputs/codegen/cloog/yosr.in --- isl-0.12.2/test_inputs/codegen/cloog/yosr.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/yosr.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n] -> { S2[i0, i1, i2] -> [i2] : i0 >= 1 and i0 <= -1 + n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 + i0 and i2 <= n; S1[i0, i1] -> [i0] : i0 >= 1 and i0 <= -1 + n and i1 >= 1 + i0 and i1 <= n } -[n] -> { : } -[n] -> { [i] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/yosr.st isl-0.15/test_inputs/codegen/cloog/yosr.st --- isl-0.12.2/test_inputs/codegen/cloog/yosr.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/yosr.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +domain: "[n] -> { S1[i0, i1] : i0 >= 1 and i0 <= -1 + n and i1 >= 1 + i0 and i1 <= n; S2[i0, i1, i2] : i0 >= 1 and i0 <= -1 + n and i1 >= 1 + i0 and i1 <= n and i2 >= 1 + i0 and i2 <= n }" +child: + context: "[n] -> { [] }" + child: + schedule: "[n] -> [{ S2[i0, i1, i2] -> [(i2)]; S1[i0, i1] -> [(i0)] }]" + options: "[n] -> { separate[i0] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/youcef.in isl-0.15/test_inputs/codegen/cloog/youcef.in --- isl-0.12.2/test_inputs/codegen/cloog/youcef.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/youcef.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -{ S1[i0, i0] -> [i0, i0, 0] : i0 >= 0 and i0 <= 5; S2[i0, i1] -> [i0, i1, 1] : i0 >= 0 and i0 <= 5 and i1 >= i0 and i1 <= 5; S3[i0, 5] -> [i0, 5, 2] : i0 >= 0 and i0 <= 5 } -{ : } -{ [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/youcefn.in isl-0.15/test_inputs/codegen/cloog/youcefn.in --- isl-0.12.2/test_inputs/codegen/cloog/youcefn.in 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/youcefn.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[n, m] -> { S3[i0, n] -> [i0, n, 2] : i0 >= 1 and i0 <= m; S2[i0, i1] -> [i0, i1, 1] : i0 >= 1 and i0 <= n and i1 >= i0 and i1 <= n; S1[i0, i0] -> [i0, i0, 0] : i0 >= 1 and i0 <= n } -[n, m] -> { : n >= 2 and m >= n } -[n, m] -> { [i, j, k] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/cloog/youcefn.st isl-0.15/test_inputs/codegen/cloog/youcefn.st --- isl-0.12.2/test_inputs/codegen/cloog/youcefn.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/youcefn.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +domain: "[n, m] -> { S1[i0, i0] : i0 >= 1 and i0 <= n; S3[i0, n] : i0 >= 1 and i0 <= m; S2[i0, i1] : i0 >= 1 and i0 <= n and i1 >= i0 and i1 <= n }" +child: + context: "[n, m] -> { [] : n >= 2 and m >= n }" + child: + schedule: "[n, m] -> [{ S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)]; S3[i0, i1] -> [(i0)] }, { S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)]; S3[i0, i1] -> [(i1)] }]" + options: "[n, m] -> { separate[i0] }" + child: + sequence: + - filter: "[n, m] -> { S1[i0, i1] }" + - filter: "[n, m] -> { S2[i0, i1] }" + - filter: "[n, m] -> { S3[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/cloog/youcef.st isl-0.15/test_inputs/codegen/cloog/youcef.st --- isl-0.12.2/test_inputs/codegen/cloog/youcef.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/cloog/youcef.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +domain: "{ S2[i0, i1] : i0 >= 0 and i0 <= 5 and i1 >= i0 and i1 <= 5; S1[i0, i0] : i0 >= 0 and i0 <= 5; S3[i0, 5] : i0 >= 0 and i0 <= 5 }" +child: + context: "{ [] }" + child: + schedule: "[{ S3[i0, i1] -> [(i0)]; S1[i0, i1] -> [(i0)]; S2[i0, i1] -> [(i0)] }, { S3[i0, i1] -> [(i1)]; S1[i0, i1] -> [(i1)]; S2[i0, i1] -> [(i1)] }]" + options: "{ separate[i0] }" + child: + sequence: + - filter: "{ S1[i0, i1] }" + - filter: "{ S2[i0, i1] }" + - filter: "{ S3[i0, i1] }" diff -Nru isl-0.12.2/test_inputs/codegen/component0.c isl-0.15/test_inputs/codegen/component0.c --- isl-0.12.2/test_inputs/codegen/component0.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component0.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +{ + A(); + for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/component0.st isl-0.15/test_inputs/codegen/component0.st --- isl-0.12.2/test_inputs/codegen/component0.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component0.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,3 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" diff -Nru isl-0.12.2/test_inputs/codegen/component1.c isl-0.15/test_inputs/codegen/component1.c --- isl-0.12.2/test_inputs/codegen/component1.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component1.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +{ + A(); + for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/component1.st isl-0.15/test_inputs/codegen/component1.st --- isl-0.12.2/test_inputs/codegen/component1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + sequence: + - filter: "{ A[] }" + - filter: "{ B[i] }" diff -Nru isl-0.12.2/test_inputs/codegen/component2.c isl-0.15/test_inputs/codegen/component2.c --- isl-0.12.2/test_inputs/codegen/component2.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component2.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) { + B(c0); + if (c0 == 0) + A(); +} diff -Nru isl-0.12.2/test_inputs/codegen/component2.st isl-0.15/test_inputs/codegen/component2.st --- isl-0.12.2/test_inputs/codegen/component2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + sequence: + - filter: "{ B[i] }" + - filter: "{ A[] }" diff -Nru isl-0.12.2/test_inputs/codegen/component3.c isl-0.15/test_inputs/codegen/component3.c --- isl-0.12.2/test_inputs/codegen/component3.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component3.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +{ + A(); + for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/component3.st isl-0.15/test_inputs/codegen/component3.st --- isl-0.12.2/test_inputs/codegen/component3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + set: + - filter: "{ B[i] }" + - filter: "{ A[] }" diff -Nru isl-0.12.2/test_inputs/codegen/component4.c isl-0.15/test_inputs/codegen/component4.c --- isl-0.12.2/test_inputs/codegen/component4.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component4.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +{ + for (int c1 = 0; c1 <= 9; c1 += 1) + A(c1); + for (int c0 = 0; c0 <= 9; c0 += 1) + for (int c2 = 0; c2 <= 9; c2 += 1) + B(c0, c2); +} diff -Nru isl-0.12.2/test_inputs/codegen/component4.st isl-0.15/test_inputs/codegen/component4.st --- isl-0.12.2/test_inputs/codegen/component4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +domain: "{ A[i] : 0 <= i < 10; B[i,j] : 0 <= i,j < 10 }" +child: + schedule: "[{ A[i] -> [0]; B[i,j] -> [i] }]" + child: + sequence: + - filter: "{ A[i] }" + - filter: "{ B[i,j] }" diff -Nru isl-0.12.2/test_inputs/codegen/component5.c isl-0.15/test_inputs/codegen/component5.c --- isl-0.12.2/test_inputs/codegen/component5.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component5.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 9; c0 += 1) + for (int c1 = 0; c1 <= 9; c1 += 1) { + if (c0 == 0) + A(c1); + B(c0, c1); + } diff -Nru isl-0.12.2/test_inputs/codegen/component5.st isl-0.15/test_inputs/codegen/component5.st --- isl-0.12.2/test_inputs/codegen/component5.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component5.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,9 @@ +domain: "{ A[i] : 0 <= i < 10; B[i,j] : 0 <= i,j < 10 }" +child: + schedule: "[{ A[i] -> [0]; B[i,j] -> [i] }]" + child: + schedule: "[{ A[i] -> [i]; B[i,j] -> [j] }]" + child: + sequence: + - filter: "{ A[i] }" + - filter: "{ B[i,j] }" diff -Nru isl-0.12.2/test_inputs/codegen/component6.c isl-0.15/test_inputs/codegen/component6.c --- isl-0.12.2/test_inputs/codegen/component6.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component6.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +{ + A(); + for (int c0 = 0; c0 <= 9; c0 += 1) + B(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/component6.st isl-0.15/test_inputs/codegen/component6.st --- isl-0.12.2/test_inputs/codegen/component6.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/component6.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +# Check that components are still detected in presence of nested context node +domain: "{ A[]; B[i] : 0 <= i < 10 }" +child: + schedule: "[{ A[] -> [0]; B[i] -> [i] }]" + child: + context: "[n] -> { [i] : 0 <= n <= i }" + child: + sequence: + - filter: "{ A[] }" + - filter: "{ B[i] }" diff -Nru isl-0.12.2/test_inputs/codegen/dwt.c isl-0.15/test_inputs/codegen/dwt.c --- isl-0.12.2/test_inputs/codegen/dwt.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/dwt.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,8 @@ -for (int c0 = 0; c0 < Ncl; c0 += 1) +for (int c0 = 0; c0 < Ncl; c0 += 1) { if (Ncl >= c0 + 2 && c0 >= 1) { S(c0, 28); } else if (c0 == 0) { S(0, 26); } else S(Ncl - 1, 27); +} diff -Nru isl-0.12.2/test_inputs/codegen/empty.c isl-0.15/test_inputs/codegen/empty.c --- isl-0.12.2/test_inputs/codegen/empty.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/empty.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 10; c0 += 1) { + S0(c0); + if (c0 == 5) + S2(); + S1(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/empty.in isl-0.15/test_inputs/codegen/empty.in --- isl-0.12.2/test_inputs/codegen/empty.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/empty.in 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,5 @@ +# Earlier versions of isl would end up with an empty partial +# executed relation and fail to detect this emptiness. +[M] -> { S0[i] -> [i, -M] : 0 <= i <= 10; S1[i] -> [i, 0] : 0 <= i <= 10; S2[] -> [5, 0] } +[M] -> { : M >= 1 } +{ } diff -Nru isl-0.12.2/test_inputs/codegen/filter.c isl-0.15/test_inputs/codegen/filter.c --- isl-0.12.2/test_inputs/codegen/filter.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/filter.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,8 @@ +if (n >= m + 1) { + for (int c0 = 0; c0 < n; c0 += 1) + for (int c2 = 0; c2 < n; c2 += 1) + A(c0, c2); +} else + for (int c0 = 0; c0 < n; c0 += 1) + for (int c2 = 0; c2 < n; c2 += 1) + A(c0, c2); diff -Nru isl-0.12.2/test_inputs/codegen/filter.st isl-0.15/test_inputs/codegen/filter.st --- isl-0.12.2/test_inputs/codegen/filter.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/filter.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,18 @@ +# Check proper handling of filters that turn out to be empty on their paths +domain: "[n,m] -> { A[i,j] : 0 <= i,j < n }" +child: + set: + - filter: "[n,m] -> { A[i,j] : m < n }" + child: + schedule: "[{ A[i,j] -> [i] }]" + child: + set: + - filter: "[n,m] -> { A[i,j] : m < n }" + - filter: "[n,m] -> { A[i,j] : m >= n }" + - filter: "[n,m] -> { A[i,j] : m >= n }" + child: + schedule: "[{ A[i,j] -> [i] }]" + child: + set: + - filter: "[n,m] -> { A[i,j] : m < n }" + - filter: "[n,m] -> { A[i,j] : m >= n }" diff -Nru isl-0.12.2/test_inputs/codegen/gemm.c isl-0.15/test_inputs/codegen/gemm.c --- isl-0.12.2/test_inputs/codegen/gemm.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/gemm.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 < ni; c0 += 1) + for (int c1 = 0; c1 < nj; c1 += 1) { + S_2(c0, c1); + for (int c2 = 0; c2 < nk; c2 += 1) + S_4(c0, c1, c2); + } diff -Nru isl-0.12.2/test_inputs/codegen/gemm.st isl-0.15/test_inputs/codegen/gemm.st --- isl-0.12.2/test_inputs/codegen/gemm.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/gemm.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,12 @@ +domain: "[ni, nj, nk] -> { S_4[i, j, k] : k <= -1 + nk and k >= 0 and j <= -1 + nj and j >= 0 and i <= -1 + ni and i >= 0; S_2[i, j] : j <= -1 + nj and j >= 0 and i <= -1 + ni and i >= 0 }" +child: + set: + - filter: "[ni, nj, nk] -> { S_4[i, j, k]; S_2[i, j] }" + child: + schedule: "[ni, nj, nk] -> [{ S_4[i, j, k] -> [(i)]; S_2[i, j] -> [(i)] }, { S_4[i, j, k] -> [(j)]; S_2[i, j] -> [(j)] }, { S_4[i, j, k] -> [(k)]; S_2[i, j] -> [(0)] }]" + permutable: 1 + coincident: [ 1, 1, 0 ] + child: + sequence: + - filter: "[ni, nj, nk] -> { S_2[i, j] }" + - filter: "[ni, nj, nk] -> { S_4[i, j, k] }" diff -Nru isl-0.12.2/test_inputs/codegen/hoist2.c isl-0.15/test_inputs/codegen/hoist2.c --- isl-0.12.2/test_inputs/codegen/hoist2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/hoist2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 1; c0 <= 5; c0 += 1) - for (int c1 = max(t1, t1 - 64 * b + 64); c1 <= min(70, -((c0 + 1) % 2) - c0 + 73); c1 += 64) + for (int c1 = t1 - 64 * b + 64; c1 <= min(70, -((c0 - 1) % 2) - c0 + 73); c1 += 64) A(c0, 64 * b + c1 - 8); diff -Nru isl-0.12.2/test_inputs/codegen/hoist.c isl-0.15/test_inputs/codegen/hoist.c --- isl-0.12.2/test_inputs/codegen/hoist.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/hoist.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -if (nj >= t1 + 1 && ni >= t0 + 1) +if (ni >= t0 + 1 && nj >= t1 + 1) for (int c2 = 0; c2 <= min(15, nk - 1); c2 += 1) { S_1(t0, t1, c2); if (nj >= t1 + 17) { diff -Nru isl-0.12.2/test_inputs/codegen/isolate1.c isl-0.15/test_inputs/codegen/isolate1.c --- isl-0.12.2/test_inputs/codegen/isolate1.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate1.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,8 @@ +{ + for (int c0 = 0; c0 <= 3; c0 += 1) + A(c0); + for (int c0 = 4; c0 <= 6; c0 += 1) + A(c0); + for (int c0 = 7; c0 <= 99; c0 += 1) + A(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/isolate1.st isl-0.15/test_inputs/codegen/isolate1.st --- isl-0.12.2/test_inputs/codegen/isolate1.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate1.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +# Check that the isolate option is adjusted by schedule space scaling +domain: "{ A[i] : 0 <= i < 100 }" +child: + schedule: "[{ A[i] -> [3i] }]" + options: "{ isolate[[] -> [x]] : 10 <= x <= 20 }" diff -Nru isl-0.12.2/test_inputs/codegen/isolate2.c isl-0.15/test_inputs/codegen/isolate2.c --- isl-0.12.2/test_inputs/codegen/isolate2.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate2.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,11 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) { + if (c0 >= 4 && c0 <= 6) { + for (int c1 = 0; c1 <= 99; c1 += 1) + A(c0, c1); + } else if (c0 >= 7) { + for (int c1 = 0; c1 <= 99; c1 += 1) + A(c0, c1); + } else + for (int c1 = 0; c1 <= 99; c1 += 1) + A(c0, c1); +} diff -Nru isl-0.12.2/test_inputs/codegen/isolate2.st isl-0.15/test_inputs/codegen/isolate2.st --- isl-0.12.2/test_inputs/codegen/isolate2.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate2.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +# Check that the isolate option is adjusted by schedule space scaling +domain: "{ A[i,j] : 0 <= i,j < 100 }" +child: + schedule: "[{ A[i,j] -> [3i] }]" + child: + schedule: "[{ A[i,j] -> [3j] }]" + options: "{ isolate[[x] -> [y]] : 10 <= x <= 20 }" diff -Nru isl-0.12.2/test_inputs/codegen/isolate3.c isl-0.15/test_inputs/codegen/isolate3.c --- isl-0.12.2/test_inputs/codegen/isolate3.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate3.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,17 @@ +{ + for (int c0 = 0; c0 <= 9; c0 += 1) + A(c0); + A(10); + A(11); + A(12); + A(13); + A(14); + A(15); + A(16); + A(17); + A(18); + A(19); + A(20); + for (int c0 = 21; c0 <= 99; c0 += 1) + A(c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/isolate3.st isl-0.15/test_inputs/codegen/isolate3.st --- isl-0.12.2/test_inputs/codegen/isolate3.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate3.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +# Check use of options specific to isolated part +domain: "{ A[i] : 0 <= i < 100 }" +child: + schedule: "[{ A[i] -> [i] }]" + options: "{ isolate[[] -> [x]] : 10 <= x <= 20; [isolate[] -> unroll[x]] }" diff -Nru isl-0.12.2/test_inputs/codegen/isolate4.c isl-0.15/test_inputs/codegen/isolate4.c --- isl-0.12.2/test_inputs/codegen/isolate4.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate4.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,13 @@ +{ + A(0); + A(1); + A(2); + A(3); + A(4); + for (int c0 = 5; c0 <= 15; c0 += 1) + A(c0); + A(16); + A(17); + A(18); + A(19); +} diff -Nru isl-0.12.2/test_inputs/codegen/isolate4.st isl-0.15/test_inputs/codegen/isolate4.st --- isl-0.12.2/test_inputs/codegen/isolate4.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate4.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +# Check that generic options are not applied to isolated part +domain: "{ A[i] : 0 <= i < 20 }" +child: + schedule: "[{ A[i] -> [i] }]" + options: "{ isolate[[] -> [x]] : 5 <= x <= 15; unroll[x] }" diff -Nru isl-0.12.2/test_inputs/codegen/isolate5.c isl-0.15/test_inputs/codegen/isolate5.c --- isl-0.12.2/test_inputs/codegen/isolate5.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate5.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,23 @@ +{ + for (int c0 = 0; c0 <= 9; c0 += 1) + for (int c1 = 0; c1 <= 1; c1 += 1) { + if (c0 % 2 == 0) { + A(c0 / 2, c1); + } else + B((c0 - 1) / 2, c1); + } + for (int c0 = 10; c0 <= 89; c0 += 1) + for (int c1 = 0; c1 <= 1; c1 += 1) { + if (c0 % 2 == 0) { + A(c0 / 2, c1); + } else + B((c0 - 1) / 2, c1); + } + for (int c0 = 90; c0 <= 199; c0 += 1) + for (int c1 = 0; c1 <= 1; c1 += 1) { + if (c0 % 2 == 0) { + A(c0 / 2, c1); + } else + B((c0 - 1) / 2, c1); + } +} diff -Nru isl-0.12.2/test_inputs/codegen/isolate5.st isl-0.15/test_inputs/codegen/isolate5.st --- isl-0.12.2/test_inputs/codegen/isolate5.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate5.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +# Check that use of isolate option prevents shifted stride detection +domain: "{ A[i,j] : 0 <= i < 100 and 0 <= j < 2; B[i,j] : 0 <= i < 100 and 0 <= j < 2 }" +child: + schedule: "[{ A[i,j] -> [2i]; B[i,j] -> [2i+1] }, { A[i,j] -> [j]; B[i,j] -> [j]}]" + options: "{ isolate[[] -> [x, y]] : 10 <= x < 90 }" diff -Nru isl-0.12.2/test_inputs/codegen/isolate6.c isl-0.15/test_inputs/codegen/isolate6.c --- isl-0.12.2/test_inputs/codegen/isolate6.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate6.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,26 @@ +{ + for (int c0 = 0; c0 <= 8; c0 += 1) { + for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) + for (int c2 = 10 * c0; c2 <= 10 * c0 + 9; c2 += 1) { + A(c2, 10 * c1); + A(c2, 10 * c1 + 1); + A(c2, 10 * c1 + 2); + A(c2, 10 * c1 + 3); + A(c2, 10 * c1 + 4); + A(c2, 10 * c1 + 5); + A(c2, 10 * c1 + 6); + A(c2, 10 * c1 + 7); + A(c2, 10 * c1 + 8); + A(c2, 10 * c1 + 9); + } + for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); + } + for (int c0 = 9; c0 <= 10; c0 += 1) + for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) + for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) + A(c2, c3); +} diff -Nru isl-0.12.2/test_inputs/codegen/isolate6.st isl-0.15/test_inputs/codegen/isolate6.st --- isl-0.12.2/test_inputs/codegen/isolate6.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/isolate6.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,8 @@ +# Example from the manual +domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" +child: + schedule: "[{ A[i,j] -> [floor(i/10)] }, \ + { A[i,j] -> [floor(j/10)] }, \ + { A[i,j] -> [i] }, { A[i,j] -> [j] }]" + options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ + 10a+9+10b+9 <= 100; [isolate[] -> unroll[3]] }" diff -Nru isl-0.12.2/test_inputs/codegen/lu.c isl-0.15/test_inputs/codegen/lu.c --- isl-0.12.2/test_inputs/codegen/lu.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/lu.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,17 @@ +for (int c0 = 0; c0 < n - 1; c0 += 32) + for (int c1 = c0; c1 < n; c1 += 32) + for (int c2 = c0; c2 < n; c2 += 32) { + if (c1 >= c0 + 32) { + for (int c3 = c0; c3 <= min(c0 + 31, c2 + 30); c3 += 1) + for (int c4 = c1; c4 <= min(n - 1, c1 + 31); c4 += 1) + for (int c5 = max(c2, c3 + 1); c5 <= min(n - 1, c2 + 31); c5 += 1) + S_6(c3, c4, c5); + } else + for (int c3 = c0; c3 <= min(min(n - 2, c0 + 31), c2 + 30); c3 += 1) { + for (int c5 = max(c2, c3 + 1); c5 <= min(n - 1, c2 + 31); c5 += 1) + S_2(c3, c5); + for (int c4 = c3 + 1; c4 <= min(n - 1, c0 + 31); c4 += 1) + for (int c5 = max(c2, c3 + 1); c5 <= min(n - 1, c2 + 31); c5 += 1) + S_6(c3, c4, c5); + } + } diff -Nru isl-0.12.2/test_inputs/codegen/lu.in isl-0.15/test_inputs/codegen/lu.in --- isl-0.12.2/test_inputs/codegen/lu.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/lu.in 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,4 @@ +# Check that the stride of the second loop is properly detected +[n] -> { S_2[k, j] -> [o0, o0, o2, k, k, j, 1] : exists (e0 = floor((o2)/32), e1 = floor((o0)/32): 32e0 = o2 and 32e1 = o0 and o0 <= k and o0 >= -31 + k and k >= 0 and j <= -1 + n and o2 <= j and o2 >= -31 + j and j >= 1 + k); S_6[k, i, j] -> [o0, o1, o2, k, i, j, 0] : exists (e0 = floor((o0)/32), e1 = floor((o1)/32), e2 = floor((o2)/32): 32e0 = o0 and 32e1 = o1 and 32e2 = o2 and o0 <= k and o0 >= -31 + k and o1 <= i and o1 >= -31 + i and o2 <= j and o2 >= -31 + j and k >= 0 and i >= 1 + k and j <= -1 + n and j >= 1 + k and i <= -1 + n) } +{ : } +{ [a,b,c,d,e,f,g] -> atomic[x] : x < 3; [a,b,c,d,e,f,g] -> separate[x] : x >= 3 } diff -Nru isl-0.12.2/test_inputs/codegen/omega/basics-1.c isl-0.15/test_inputs/codegen/omega/basics-1.c --- isl-0.12.2/test_inputs/codegen/omega/basics-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/basics-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = -9; c0 <= 9; c0 += 1) - for (int c1 = max(-c0 + 1, 1); c1 <= min(-c0 + 10, 10); c1 += 1) + for (int c1 = max(1, -c0 + 1); c1 <= min(10, -c0 + 10); c1 += 1) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/code_gen-0.c isl-0.15/test_inputs/codegen/omega/code_gen-0.c --- isl-0.12.2/test_inputs/codegen/omega/code_gen-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/code_gen-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,6 +1,6 @@ for (int c0 = 1; c0 <= 8; c0 += 1) for (int c1 = 0; c1 <= 7; c1 += 1) { - if (c1 <= 4 && c0 <= 6 && c0 >= 2) + if (c0 >= 2 && c0 <= 6 && c1 <= 4) s1(c0, c1); if (c1 + 1 >= c0) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/code_gen-1.c isl-0.15/test_inputs/codegen/omega/code_gen-1.c --- isl-0.12.2/test_inputs/codegen/omega/code_gen-1.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/code_gen-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,16 +1,15 @@ for (int c0 = 1; c0 <= 8; c0 += 1) { - if (c0 <= 6) - for (int c1 = 0; c1 < c0 - 1; c1 += 1) - s1(c0, c1); if (c0 >= 2) { + if (c0 <= 6) + for (int c1 = 0; c1 < c0 - 1; c1 += 1) + s1(c0, c1); for (int c1 = c0 - 1; c1 <= 4; c1 += 1) { s1(c0, c1); s0(c0, c1); } - for (int c1 = max(c0 - 1, 5); c1 <= 7; c1 += 1) + for (int c1 = max(5, c0 - 1); c1 <= 7; c1 += 1) s0(c0, c1); - } - if (c0 == 1) + } else for (int c1 = 0; c1 <= 7; c1 += 1) s0(1, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/dagstuhl1-1.c isl-0.15/test_inputs/codegen/omega/dagstuhl1-1.c --- isl-0.12.2/test_inputs/codegen/omega/dagstuhl1-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/dagstuhl1-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,2 +1,2 @@ for (int c0 = 0; c0 <= 99; c0 += 1) - s0(c0, (c0 + 10) % 10, (c0 + 10) / 10 - 1); + s0(c0, c0 % 10, (c0 + 10) / 10 - 1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/guard1-0.c isl-0.15/test_inputs/codegen/omega/guard1-0.c --- isl-0.12.2/test_inputs/codegen/omega/guard1-0.c 2013-08-20 14:50:16.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/guard1-0.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,2 +1,2 @@ -if (n + 3 * floord(-n + m - 2, 3) + 2 == m) +if ((n - m + 2) % 3 == 0) s0(n, m); diff -Nru isl-0.12.2/test_inputs/codegen/omega/guard1-1.c isl-0.15/test_inputs/codegen/omega/guard1-1.c --- isl-0.12.2/test_inputs/codegen/omega/guard1-1.c 2013-08-20 14:50:16.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/guard1-1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,2 +1,2 @@ -if (n + 2 * floord(-n + m - 1, 2) + 1 == m) +if ((n - m + 1) % 2 == 0) s0(n, m); diff -Nru isl-0.12.2/test_inputs/codegen/omega/hpf-0.c isl-0.15/test_inputs/codegen/omega/hpf-0.c --- isl-0.12.2/test_inputs/codegen/omega/hpf-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/hpf-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -if (P1 == P2 && P2 >= 0 && P2 <= 3) - for (int c0 = 0; c0 <= min(-P2 + 4, 2); c0 += 1) - for (int c2 = -P2 - c0 + 3 * floord(P2 + c0 - 1, 3) + 3; c2 <= 3; c2 += 3) +if (P2 >= 0 && P2 <= 3 && P1 == P2) + for (int c0 = 0; c0 <= min(2, -P2 + 4); c0 += 1) + for (int c2 = (-P2 - c0 + 6) % 3; c2 <= 3; c2 += 3) s0(c0, c0, c2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/omega/if_then-2.c isl-0.15/test_inputs/codegen/omega/if_then-2.c --- isl-0.12.2/test_inputs/codegen/omega/if_then-2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/if_then-2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 100; c0 += 1) +for (int c0 = 1; c0 <= 100; c0 += 1) { if (n >= 2) { s0(c0); for (int c1 = 1; c1 <= 100; c1 += 1) { @@ -8,3 +8,4 @@ } else for (int c1 = 1; c1 <= 100; c1 += 1) s2(c0, c1); +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/if_then-4.c isl-0.15/test_inputs/codegen/omega/if_then-4.c --- isl-0.12.2/test_inputs/codegen/omega/if_then-4.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/if_then-4.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ for (int c0 = 4; c0 <= 100; c0 += 4) { for (int c1 = 1; c1 <= 100; c1 += 1) s0(c0, c1); - if (c0 <= 96 && c0 >= 8) + if (c0 >= 8 && c0 <= 96) for (int c1 = 10; c1 <= 100; c1 += 1) s1(c0 + 2, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/if_then-5.c isl-0.15/test_inputs/codegen/omega/if_then-5.c --- isl-0.12.2/test_inputs/codegen/omega/if_then-5.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/if_then-5.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ for (int c0 = 4; c0 <= 100; c0 += 4) { for (int c1 = 1; c1 <= 100; c1 += 1) s0(c0, c1); - if (c0 <= 96 && c0 >= 8) + if (c0 >= 8 && c0 <= 96) for (int c1 = 10; c1 <= 100; c1 += 1) s1(c0 + 2, c1); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/iter8-0.c isl-0.15/test_inputs/codegen/omega/iter8-0.c --- isl-0.12.2/test_inputs/codegen/omega/iter8-0.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/iter8-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,2 +1,2 @@ -for (int c0 = max(exprVar2 + 8 * floord(-exprVar2 + exprVar1 - 1, 8) + 9, exprVar2 + 1); c0 <= 16; c0 += 8) +for (int c0 = max(exprVar2 + 1, exprVar2 + 8 * floord(-exprVar2 + exprVar1 - 1, 8) + 9); c0 <= 16; c0 += 8) s0(c0); diff -Nru isl-0.12.2/test_inputs/codegen/omega/iter9-0.c isl-0.15/test_inputs/codegen/omega/iter9-0.c --- isl-0.12.2/test_inputs/codegen/omega/iter9-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/iter9-0.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,11 +1,11 @@ for (int c0 = 1; c0 <= 15; c0 += 1) { - if (8 * floord(7 * exprVar1 + 7, 8) + 8 >= 7 * exprVar1 + c0) { + if (((-exprVar1 + 15) % 8) + c0 <= 15) { s4(c0); s0(c0); s3(c0); s2(c0); s1(c0); } - if (8 * floord(7 * exprVar1 + 7, 8) + 8 >= 7 * exprVar1 + c0 || (exprVar1 + 8 * floord(-exprVar1 + c0 - 1, 8) + 1 == c0 && c0 >= exprVar1 + 1)) + if (((-exprVar1 + 15) % 8) + c0 <= 15 || (c0 >= exprVar1 + 1 && (exprVar1 - c0 + 1) % 8 == 0)) s5(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lefur00-0.c isl-0.15/test_inputs/codegen/omega/lefur00-0.c --- isl-0.12.2/test_inputs/codegen/omega/lefur00-0.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lefur00-0.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 0; c0 <= 15; c0 += 1) - for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(c0 + 1, 15); c1 += 1) - for (int c2 = max(max(max(67 * c0 - (c0 + 1) / 3, 1), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(100 * c0 + 99, 1000), 133 * c0 - 67 * c1 + floord(c0 + c1 - 1, 3) + 133); c2 += 1) - for (int c3 = max(max(100 * c1 + (c2 + 1) / 2, 200 * c0 - c2), c2); c3 <= min(min(200 * c0 - c2 + 199, 100 * c1 + (c2 + 1) / 2 + 99), 2 * c2 + 1); c3 += 1) + for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1) + for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1) + for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1) s0(c0, c1, c2, c3); diff -Nru isl-0.12.2/test_inputs/codegen/omega/lefur01-0.c isl-0.15/test_inputs/codegen/omega/lefur01-0.c --- isl-0.12.2/test_inputs/codegen/omega/lefur01-0.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lefur01-0.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 0; c0 <= 15; c0 += 1) - for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(c0 + 1, 15); c1 += 1) - for (int c2 = max(max(max(67 * c0 - (c0 + 1) / 3, 1), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(100 * c0 + 99, 1000), 133 * c0 - 67 * c1 + floord(c0 + c1 - 1, 3) + 133); c2 += 1) - for (int c3 = max(max(100 * c1 + (c2 + 1) / 2, 200 * c0 - c2), c2); c3 <= min(min(200 * c0 - c2 + 199, 100 * c1 + (c2 + 1) / 2 + 99), 2 * c2 + 1); c3 += 1) + for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1) + for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1) + for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1) s0(c0, c1, c2, c3); diff -Nru isl-0.12.2/test_inputs/codegen/omega/lefur01-1.c isl-0.15/test_inputs/codegen/omega/lefur01-1.c --- isl-0.12.2/test_inputs/codegen/omega/lefur01-1.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lefur01-1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 0; c0 <= 15; c0 += 1) - for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(c0 + 1, 15); c1 += 1) - for (int c2 = max(max(max(1, 67 * c1 - (c1 + 2) / 3), 67 * c0 - (c0 + 1) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(100 * c0 + 99, 1000), 133 * c0 - 67 * c1 + floord(c0 + c1 - 1, 3) + 133); c2 += 1) - for (int c3 = max(max(100 * c1 + (c2 + 1) / 2, 200 * c0 - c2), c2); c3 <= min(min(200 * c0 - c2 + 199, 100 * c1 + (c2 + 1) / 2 + 99), 2 * c2 + 1); c3 += 1) + for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1) + for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1) + for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1) s0(c0, c1, c2, c3); diff -Nru isl-0.12.2/test_inputs/codegen/omega/lefur03-0.c isl-0.15/test_inputs/codegen/omega/lefur03-0.c --- isl-0.12.2/test_inputs/codegen/omega/lefur03-0.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lefur03-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ for (int c0 = 0; c0 <= 3; c0 += 1) - for (int c1 = max(2 * c0 - 3, 0); c1 <= min(3, c0 + c0 / 2 + 1); c1 += 1) - for (int c2 = c0; c2 <= min(min(2 * c0 - c1 + 1, 3 * c1 + 2), 3); c2 += 1) - for (int c3 = max(max(max(c2 + floord(3 * c1 - c2 - 1, 6), c1 - (-c1 + 3) / 3), c0 - (-c0 + 3) / 3), 0); c3 <= min(c0 + 1, 3); c3 += 1) - for (int c4 = max(max(max(max(250 * c3 + 1, 333 * c2 + (c2 + 1) / 3), 333 * c1 + c1 / 3), -200 * c1 + 400 * c3 - 199), 667 * c0 - 333 * c1 - (c0 + c1 + 3) / 3 - 332); c4 <= min(min(min(min(1000, -200 * c1 + 400 * c3 + 400), 500 * c0 + 499), 333 * c2 - (-c2 + 3) / 3 + 333), 333 * c3 - (-c3 + 3) / 3 + 334); c4 += 1) - for (int c5 = max(max(max(c4, 1000 * c3 - 2 * c4 + 2), 500 * c1 + (c4 + 1) / 2), 1000 * c0 - c4); c5 <= min(min(min(1000 * c0 - c4 + 999, 500 * c1 + (c4 + 1) / 2 + 499), 1000 * c3 - 2 * c4 + 1001), 2 * c4 + 1); c5 += 1) + for (int c1 = max(2 * c0 - 3, c0 / 2); c1 <= min(3, c0 + 1); c1 += 1) + for (int c2 = c0; c2 <= min(min(3, 2 * c0 - c1 + 1), 3 * c1 + 2); c2 += 1) + for (int c3 = max(max(max(0, c1 - (-c1 + 3) / 3), c0 - (-c2 + 3) / 3), c2 + floord(3 * c1 - c2 - 1, 6)); c3 <= min(3, c0 + 1); c3 += 1) + for (int c4 = max(max(max(max(-200 * c1 + 400 * c3 - 199, 250 * c3 + 1), 667 * c0 - 333 * c1 - (c0 + c1 + 3) / 3 - 332), 333 * c1 + c1 / 3), 333 * c2 + (c2 + 1) / 3); c4 <= min(min(min(min(1000, 500 * c0 + 499), -200 * c1 + 400 * c3 + 400), 333 * c2 - (-c2 + 3) / 3 + 333), 333 * c3 - (-c3 + 3) / 3 + 334); c4 += 1) + for (int c5 = max(max(max(c4, 1000 * c0 - c4), 1000 * c3 - 2 * c4 + 2), 500 * c1 + (c4 + 1) / 2); c5 <= min(min(min(2 * c4 + 1, 1000 * c0 - c4 + 999), 1000 * c3 - 2 * c4 + 1001), 500 * c1 + (c4 + 1) / 2 + 499); c5 += 1) s0(c0, c1, c2, c3, c4, c5); diff -Nru isl-0.12.2/test_inputs/codegen/omega/lefur04-0.c isl-0.15/test_inputs/codegen/omega/lefur04-0.c --- isl-0.12.2/test_inputs/codegen/omega/lefur04-0.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lefur04-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,8 +1,8 @@ for (int c0 = 0; c0 <= 3; c0 += 1) - for (int c1 = max(2 * c0 - 3, c0 / 2); c1 <= min(c0 + 1, 3); c1 += 1) + for (int c1 = max(2 * c0 - 3, c0 / 2); c1 <= min(3, c0 + 1); c1 += 1) for (int c2 = c0; c2 <= min(min(3, 2 * c0 - c1 + 1), 3 * c1 + 2); c2 += 1) - for (int c3 = max(max(max(c2 - (c2 + 2) / 3, c2 + floord(3 * c1 - c2 - 1, 6)), c1 - (-c1 + 3) / 3), c0 - (-c2 + 3) / 3); c3 <= min(c0 + c0 / 2 + 1, 3); c3 += 1) - for (int c5 = max(max(max(max(c1 - (c1 - 2 * c3 + 5) / 5, 0), c3 - (c3 + 3) / 3), 2 * c3 - 4), c2 - (c2 + 3) / 3); c5 <= min(min(c1 + 1, c3), -c2 + 2 * c3 - (c2 + 3) / 3 + 2); c5 += 1) - for (int c6 = max(max(max(max(max(1000 * c0 - 500 * c5 - 501, -200 * c1 + 400 * c3 - 199), 333 * c1 + c1 / 3), 250 * c3 + 1), 667 * c0 - 333 * c1 - (c0 + c1 + 3) / 3 - 332), 333 * c2 + (c2 + 1) / 3); c6 <= min(min(min(min(min(min(-200 * c1 + 400 * c3 + 400, 500 * c0 + 499), 333 * c2 - (-c2 + 3) / 3 + 333), 333 * c3 - (-c3 + 3) / 3 + 334), 500 * c5 + 501), 1000), 1000 * c0 - 500 * c5 + 997); c6 += 1) - for (int c7 = max(max(max(max(c6, 500 * c5 + 2), 1000 * c3 - 2 * c6 + 2), 500 * c1 + (c6 + 1) / 2), 1000 * c0 - c6); c7 <= min(min(min(min(500 * c5 + 501, 2 * c6 + 1), 1000 * c0 - c6 + 999), 500 * c1 + (c6 + 1) / 2 + 499), 1000 * c3 - 2 * c6 + 1001); c7 += 1) + for (int c3 = max(max(max(c1 - (-c1 + 3) / 3, c0 - (-c2 + 3) / 3), c2 - (c2 + 2) / 3), c2 + floord(3 * c1 - c2 - 1, 6)); c3 <= min(3, c0 + c2 / 3 + 1); c3 += 1) + for (int c5 = max(max(max(max(0, 2 * c3 - 4), c1 - (-c1 + 3) / 3), c2 - (c2 + 3) / 3), c3 - (c3 + 3) / 3); c5 <= min(min(c1 + 1, c3), -c2 + 2 * c3 - (c2 + 3) / 3 + 2); c5 += 1) + for (int c6 = max(max(max(max(max(-200 * c1 + 400 * c3 - 199, 250 * c3 + 1), 1000 * c0 - 500 * c5 - 501), 667 * c0 - 333 * c1 - (c0 + c1 + 3) / 3 - 332), 333 * c1 + c1 / 3), 333 * c2 + (c2 + 1) / 3); c6 <= min(min(min(min(min(min(1000, 500 * c0 + 499), -200 * c1 + 400 * c3 + 400), 500 * c5 + 501), 1000 * c0 - 500 * c5 + 997), 333 * c2 - (-c2 + 3) / 3 + 333), 333 * c3 - (-c3 + 3) / 3 + 334); c6 += 1) + for (int c7 = max(max(max(max(500 * c5 + 2, c6), 1000 * c0 - c6), 1000 * c3 - 2 * c6 + 2), 500 * c1 + (c6 + 1) / 2); c7 <= min(min(min(min(500 * c5 + 501, 2 * c6 + 1), 1000 * c0 - c6 + 999), 1000 * c3 - 2 * c6 + 1001), 500 * c1 + (c6 + 1) / 2 + 499); c7 += 1) s0(c0, c1, c2, c3, c2 / 3, c5, c6, c7); diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift1-1.c isl-0.15/test_inputs/codegen/omega/lift1-1.c --- isl-0.12.2/test_inputs/codegen/omega/lift1-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift1-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ for (int c0 = 1; c0 <= 100; c0 += 1) for (int c1 = 1; c1 <= 100; c1 += 1) for (int c2 = 1; c2 <= 100; c2 += 1) - for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) { if (c0 >= 61) { for (int c4 = 1; c4 <= 100; c4 += 1) s1(c0, c1, c2, c3, c4); @@ -10,3 +10,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift1-2.c isl-0.15/test_inputs/codegen/omega/lift1-2.c --- isl-0.12.2/test_inputs/codegen/omega/lift1-2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift1-2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,6 +1,6 @@ for (int c0 = 1; c0 <= 100; c0 += 1) for (int c1 = 1; c1 <= 100; c1 += 1) - for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) { if (c0 >= 61) { for (int c3 = 1; c3 <= 100; c3 += 1) for (int c4 = 1; c4 <= 100; c4 += 1) @@ -11,3 +11,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift1-3.c isl-0.15/test_inputs/codegen/omega/lift1-3.c --- isl-0.12.2/test_inputs/codegen/omega/lift1-3.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift1-3.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 1; c0 <= 100; c0 += 1) - for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) { if (c0 >= 61) { for (int c2 = 1; c2 <= 100; c2 += 1) for (int c3 = 1; c3 <= 100; c3 += 1) @@ -12,3 +12,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift1-4.c isl-0.15/test_inputs/codegen/omega/lift1-4.c --- isl-0.12.2/test_inputs/codegen/omega/lift1-4.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift1-4.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 100; c0 += 1) +for (int c0 = 1; c0 <= 100; c0 += 1) { if (c0 >= 61) { for (int c1 = 1; c1 <= 100; c1 += 1) for (int c2 = 1; c2 <= 100; c2 += 1) @@ -13,3 +13,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift2-0.c isl-0.15/test_inputs/codegen/omega/lift2-0.c --- isl-0.12.2/test_inputs/codegen/omega/lift2-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift2-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -4,6 +4,6 @@ for (int c3 = 1; c3 <= 100; c3 += 1) for (int c4 = 1; c4 <= 100; c4 += 1) { s1(c0, c1, c2, c3, c4); - if (c0 <= 60 && c0 >= 5) + if (c0 >= 5 && c0 <= 60) s0(c0, c1, c2, c3, c4); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift2-1.c isl-0.15/test_inputs/codegen/omega/lift2-1.c --- isl-0.12.2/test_inputs/codegen/omega/lift2-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift2-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,7 +1,7 @@ for (int c0 = 1; c0 <= 100; c0 += 1) for (int c1 = 1; c1 <= 100; c1 += 1) for (int c2 = 1; c2 <= 100; c2 += 1) - for (int c3 = 1; c3 <= 100; c3 += 1) + for (int c3 = 1; c3 <= 100; c3 += 1) { if (c0 >= 61) { for (int c4 = 1; c4 <= 100; c4 += 1) s1(c0, c1, c2, c3, c4); @@ -13,3 +13,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift2-2.c isl-0.15/test_inputs/codegen/omega/lift2-2.c --- isl-0.12.2/test_inputs/codegen/omega/lift2-2.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift2-2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,6 +1,6 @@ for (int c0 = 1; c0 <= 100; c0 += 1) for (int c1 = 1; c1 <= 100; c1 += 1) - for (int c2 = 1; c2 <= 100; c2 += 1) + for (int c2 = 1; c2 <= 100; c2 += 1) { if (c0 >= 61) { for (int c3 = 1; c3 <= 100; c3 += 1) for (int c4 = 1; c4 <= 100; c4 += 1) @@ -15,3 +15,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift2-3.c isl-0.15/test_inputs/codegen/omega/lift2-3.c --- isl-0.12.2/test_inputs/codegen/omega/lift2-3.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift2-3.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ for (int c0 = 1; c0 <= 100; c0 += 1) - for (int c1 = 1; c1 <= 100; c1 += 1) + for (int c1 = 1; c1 <= 100; c1 += 1) { if (c0 >= 61) { for (int c2 = 1; c2 <= 100; c2 += 1) for (int c3 = 1; c3 <= 100; c3 += 1) @@ -17,3 +17,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lift2-4.c isl-0.15/test_inputs/codegen/omega/lift2-4.c --- isl-0.12.2/test_inputs/codegen/omega/lift2-4.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lift2-4.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 100; c0 += 1) +for (int c0 = 1; c0 <= 100; c0 += 1) { if (c0 >= 61) { for (int c1 = 1; c1 <= 100; c1 += 1) for (int c2 = 1; c2 <= 100; c2 += 1) @@ -19,3 +19,4 @@ s1(c0, c1, c2, c3, c4); s0(c0, c1, c2, c3, c4); } +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/lu-0.c isl-0.15/test_inputs/codegen/omega/lu-0.c --- isl-0.12.2/test_inputs/codegen/omega/lu-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lu-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -2,9 +2,9 @@ for (int c1 = c0 - 1; c1 <= n; c1 += 64) for (int c2 = c0; c2 <= n; c2 += 1) { for (int c3 = c0; c3 <= min(min(c0 + 63, c1 + 62), c2 - 1); c3 += 1) - for (int c4 = max(c3 + 1, c1); c4 <= min(c1 + 63, n); c4 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) s1(c3, c4, c2); if (c0 + 63 >= c2) - for (int c4 = max(c2 + 1, c1); c4 <= min(n, c1 + 63); c4 += 1) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) s0(c2, c4); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lu-1.c isl-0.15/test_inputs/codegen/omega/lu-1.c --- isl-0.12.2/test_inputs/codegen/omega/lu-1.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lu-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -2,9 +2,9 @@ for (int c1 = c0 - 1; c1 <= n; c1 += 64) for (int c2 = c0; c2 <= n; c2 += 1) { for (int c3 = c0; c3 <= min(min(c0 + 63, c1 + 62), c2 - 1); c3 += 1) - for (int c4 = max(c3 + 1, c1); c4 <= min(c1 + 63, n); c4 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) s1(c3, c4, c2); if (c0 + 63 >= c2) - for (int c4 = max(c2 + 1, c1); c4 <= min(n, c1 + 63); c4 += 1) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) s0(c2, c4); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lu-2.c isl-0.15/test_inputs/codegen/omega/lu-2.c --- isl-0.12.2/test_inputs/codegen/omega/lu-2.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lu-2.c 2015-04-19 12:02:52.000000000 +0000 @@ -2,9 +2,9 @@ for (int c1 = c0 - 1; c1 <= n; c1 += 64) for (int c2 = c0; c2 <= n; c2 += 1) { for (int c3 = c0; c3 <= min(min(c0 + 63, c1 + 62), c2 - 1); c3 += 1) - for (int c4 = max(c3 + 1, c1); c4 <= min(c1 + 63, n); c4 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) s1(c3, c4, c2); if (c0 + 63 >= c2) - for (int c4 = max(c2 + 1, c1); c4 <= min(n, c1 + 63); c4 += 1) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) s0(c2, c4); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lu-3.c isl-0.15/test_inputs/codegen/omega/lu-3.c --- isl-0.12.2/test_inputs/codegen/omega/lu-3.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lu-3.c 2015-04-19 12:02:52.000000000 +0000 @@ -2,13 +2,13 @@ for (int c1 = c0 - 1; c1 <= n; c1 += 64) { for (int c2 = c0; c2 <= min(n, c0 + 63); c2 += 1) { for (int c3 = c0; c3 <= min(c1 + 62, c2 - 1); c3 += 1) - for (int c4 = max(c3 + 1, c1); c4 <= min(c1 + 63, n); c4 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) s1(c3, c4, c2); - for (int c4 = max(c2 + 1, c1); c4 <= min(n, c1 + 63); c4 += 1) + for (int c4 = max(c1, c2 + 1); c4 <= min(n, c1 + 63); c4 += 1) s0(c2, c4); } for (int c2 = c0 + 64; c2 <= n; c2 += 1) for (int c3 = c0; c3 <= min(c0 + 63, c1 + 62); c3 += 1) - for (int c4 = max(c3 + 1, c1); c4 <= min(c1 + 63, n); c4 += 1) + for (int c4 = max(c1, c3 + 1); c4 <= min(n, c1 + 63); c4 += 1) s1(c3, c4, c2); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lu_spmd-0.c isl-0.15/test_inputs/codegen/omega/lu_spmd-0.c --- isl-0.12.2/test_inputs/codegen/omega/lu_spmd-0.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lu_spmd-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,13 +1,12 @@ if (ub >= lb) for (int c0 = 1; c0 <= ub; c0 += 1) for (int c1 = c0; c1 <= n; c1 += 1) { - if (lb >= c0 + 1) { - s3(c0, c1, lb, c0, c1); - } else if (c1 >= c0 + 1) { + if (c0 >= lb && c1 >= c0 + 1) { s0(c0, c1); if (n >= ub + 1) s2(c0, c1); - } - for (int c3 = max(c0, lb); c3 <= ub; c3 += 1) + } else if (lb >= c0 + 1) + s3(c0, c1, lb, c0, c1); + for (int c3 = max(lb, c0); c3 <= ub; c3 += 1) s1(c0, c1, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/lu_spmd-1.c isl-0.15/test_inputs/codegen/omega/lu_spmd-1.c --- isl-0.12.2/test_inputs/codegen/omega/lu_spmd-1.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/lu_spmd-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,13 +1,12 @@ if (ub >= lb) for (int c0 = 1; c0 <= ub; c0 += 1) for (int c1 = c0; c1 <= n; c1 += 1) { - if (lb >= c0 + 1) { - s3(c0, c1, lb, c0, c1); - } else if (c1 >= c0 + 1) { + if (c0 >= lb && c1 >= c0 + 1) { s0(c0, c1); if (n >= ub + 1) s2(c0, c1); - } - for (int c3 = max(c0, lb); c3 <= ub; c3 += 1) + } else if (lb >= c0 + 1) + s3(c0, c1, lb, c0, c1); + for (int c3 = max(lb, c0); c3 <= ub; c3 += 1) s1(c0, c1, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/m10-1.c isl-0.15/test_inputs/codegen/omega/m10-1.c --- isl-0.12.2/test_inputs/codegen/omega/m10-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m10-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,5 +1,5 @@ -for (int c0 = 1; c0 <= 18; c0 += 1) - if (c0 <= 9 && c0 >= 2) { +for (int c0 = 1; c0 <= 18; c0 += 1) { + if (c0 >= 2 && c0 <= 9) { for (int c1 = 1; c1 <= 9; c1 += 1) { if (c0 % 2 == 0) s0(c1, c0 / 2); @@ -11,3 +11,4 @@ } else if (c0 % 2 == 0) for (int c1 = 1; c1 <= 9; c1 += 1) s0(c1, c0 / 2); +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/m11-0.c isl-0.15/test_inputs/codegen/omega/m11-0.c --- isl-0.12.2/test_inputs/codegen/omega/m11-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m11-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,6 +1,6 @@ for (int c0 = 1; c0 <= min(4, floord(2 * m - 1, 17) + 1); c0 += 1) for (int c1 = 1; c1 <= 2; c1 += 1) - for (int c2 = 0; c2 <= min(-c1 + c1 / 2 + 3, -c0 - c1 + (2 * m + 3 * c0 + 10 * c1 + 6) / 20 + 1); c2 += 1) - for (int c3 = 8 * c0 + (c0 + 1) / 2 - 8; c3 <= min(min(8 * c0 + c0 / 2, 30), m - 5 * c1 - 10 * c2 + 5); c3 += 1) - for (int c4 = 5 * c1 + 10 * c2 - 4; c4 <= min(m - c3 + 1, 5 * c1 + 10 * c2); c4 += 1) + for (int c2 = 0; c2 <= min(2, -c0 - c1 + (2 * m + 3 * c0 + 10 * c1 + 6) / 20 + 1); c2 += 1) + for (int c3 = 8 * c0 + (c0 + 1) / 2 - 8; c3 <= min(min(30, m - 5 * c1 - 10 * c2 + 5), 8 * c0 + c0 / 2); c3 += 1) + for (int c4 = 5 * c1 + 10 * c2 - 4; c4 <= min(5 * c1 + 10 * c2, m - c3 + 1); c4 += 1) s0(c0, c1, c2, c3, c4, -9 * c0 + c3 + c0 / 2 + 9, -5 * c1 - 5 * c2 + c4 + 5); diff -Nru isl-0.12.2/test_inputs/codegen/omega/m1-1.c isl-0.15/test_inputs/codegen/omega/m1-1.c --- isl-0.12.2/test_inputs/codegen/omega/m1-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m1-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 9; c0 += 1) +for (int c0 = 1; c0 <= 9; c0 += 1) { if (c0 >= 6) { for (int c1 = 1; c1 <= 9; c1 += 1) s0(c0, c1); @@ -10,3 +10,4 @@ s0(5, c1); s1(5, c1); } +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/m2-0.c isl-0.15/test_inputs/codegen/omega/m2-0.c --- isl-0.12.2/test_inputs/codegen/omega/m2-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m2-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 2; c0 <= 9; c0 += 1) +for (int c0 = 2; c0 <= 9; c0 += 1) { if (c0 >= 5) { s1(c0, 1); for (int c1 = 2; c1 <= 9; c1 += 1) { @@ -8,3 +8,4 @@ } else for (int c1 = 2; c1 <= 9; c1 += 1) s0(c0, c1); +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/m3-0.c isl-0.15/test_inputs/codegen/omega/m3-0.c --- isl-0.12.2/test_inputs/codegen/omega/m3-0.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m3-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = -9; c0 <= 9; c0 += 1) - for (int c1 = max(-c0 + 1, 1); c1 <= min(-c0 + 10, 10); c1 += 1) + for (int c1 = max(1, -c0 + 1); c1 <= min(10, -c0 + 10); c1 += 1) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/m7-1.c isl-0.15/test_inputs/codegen/omega/m7-1.c --- isl-0.12.2/test_inputs/codegen/omega/m7-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m7-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 9; c0 += 1) +for (int c0 = 1; c0 <= 9; c0 += 1) { if (c0 % 2 == 0) { for (int c1 = 1; c1 <= 9; c1 += 1) { s0(c1, c0); @@ -7,3 +7,4 @@ } else for (int c1 = 1; c1 <= 9; c1 += 1) s0(c1, c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/m8-1.c isl-0.15/test_inputs/codegen/omega/m8-1.c --- isl-0.12.2/test_inputs/codegen/omega/m8-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/m8-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 2; c0 <= 8; c0 += 2) +for (int c0 = 2; c0 <= 8; c0 += 2) { if (c0 % 4 == 0) { for (int c1 = 1; c1 <= 9; c1 += 1) { s0(c1, c0); @@ -7,3 +7,4 @@ } else for (int c1 = 1; c1 <= 9; c1 += 1) s1(c1, c0); +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/p6-1.c isl-0.15/test_inputs/codegen/omega/p6-1.c --- isl-0.12.2/test_inputs/codegen/omega/p6-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/p6-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = -9; c0 <= 9; c0 += 1) - for (int c1 = max(-c0 + 1, 1); c1 <= min(-c0 + 10, 10); c1 += 1) + for (int c1 = max(1, -c0 + 1); c1 <= min(10, -c0 + 10); c1 += 1) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/p.delft-0.c isl-0.15/test_inputs/codegen/omega/p.delft-0.c --- isl-0.12.2/test_inputs/codegen/omega/p.delft-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/p.delft-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -if (P1 == P2 && P2 >= 0 && P2 <= 3) - for (int c0 = 0; c0 <= min(-P2 + 4, 2); c0 += 1) - for (int c2 = -P2 - c0 + 3 * floord(P2 + c0 - 1, 3) + 3; c2 <= 3; c2 += 3) +if (P2 >= 0 && P2 <= 3 && P1 == P2) + for (int c0 = 0; c0 <= min(2, -P2 + 4); c0 += 1) + for (int c2 = (-P2 - c0 + 6) % 3; c2 <= 3; c2 += 3) s0(c0, c0, c2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/omega/p.delft2-0.c isl-0.15/test_inputs/codegen/omega/p.delft2-0.c --- isl-0.12.2/test_inputs/codegen/omega/p.delft2-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/p.delft2-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,11 +1,10 @@ -if (P2 <= 3 && P2 >= 0 && P1 <= 3 && P1 >= 0) +if (P1 >= 0 && P1 <= 3 && P2 >= 0 && P2 <= 3) for (int c0 = P1 - 1; c0 <= 3; c0 += 1) - if (P1 + 2 * floord(-P1 + c0 - 1, 2) + 1 == c0) - for (int c2 = 0; c2 <= -((P1 + 4) / 4) + 8; c2 += 1) - if ((5 * c0 + 2 * c2 + 5) % 9 <= 2) - for (int c3 = 0; c3 <= -((P2 + 4) / 4) + 8; c3 += 1) - if ((5 * P2 + 2 * c3) % 9 <= 3) - if (c0 + 1 == P1 && (5 * P1 + 2 * c2) % 9 <= 2 && P1 >= 1) { - s0(P1 - 1, P2, c2, c3, ((5 * P1 + 2 * c2) % 9) + 1, (-4 * P2 + 2 * c3 + 9) % 9); - } else if (c2 % 4 == 0 && c0 == 3 && P1 == 0) - s0(3, P2, c2, c3, (-c2 + 12) / 4, (-4 * P2 + 2 * c3 + 9) % 9); + for (int c2 = 0; c2 <= 7; c2 += 1) + for (int c3 = 0; c3 <= 7; c3 += 1) + if ((5 * P2 + 2 * c3) % 9 <= 3) { + if (P1 >= 1 && c0 + 1 == P1 && (5 * P1 + 2 * c2) % 9 <= 2) { + s0(P1 - 1, P2, c2, c3, ((5 * P1 + 2 * c2) % 9) + 1, (-4 * P2 + 2 * c3 + 9) % 9); + } else if (P1 == 0 && c0 == 3 && c2 % 4 == 0) + s0(3, P2, c2, c3, (-c2 / 4) + 3, (-4 * P2 + 2 * c3 + 9) % 9); + } diff -Nru isl-0.12.2/test_inputs/codegen/omega/stride2-0.c isl-0.15/test_inputs/codegen/omega/stride2-0.c --- isl-0.12.2/test_inputs/codegen/omega/stride2-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/stride2-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 0; c0 <= n; c0 += 32) - for (int c1 = c0; c1 <= min(c0 + 31, n); c1 += 1) + for (int c1 = c0; c1 <= min(n, c0 + 31); c1 += 1) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/stride3-0.c isl-0.15/test_inputs/codegen/omega/stride3-0.c --- isl-0.12.2/test_inputs/codegen/omega/stride3-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/stride3-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 3; c0 <= n; c0 += 32) - for (int c1 = c0; c1 <= min(c0 + 31, n); c1 += 1) + for (int c1 = c0; c1 <= min(n, c0 + 31); c1 += 1) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/stride5-0.c isl-0.15/test_inputs/codegen/omega/stride5-0.c --- isl-0.12.2/test_inputs/codegen/omega/stride5-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/stride5-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ -for (int c0 = 2; c0 <= min(-2 * n + 400, 100); c0 += 2) +for (int c0 = 2; c0 <= min(100, -2 * n + 400); c0 += 2) for (int c1 = 2 * n + c0; c1 <= 400; c1 += 2) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/stride6-0.c isl-0.15/test_inputs/codegen/omega/stride6-0.c --- isl-0.12.2/test_inputs/codegen/omega/stride6-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/stride6-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 1; c0 <= 101; c0 += 1) - for (int c1 = -((c0 + 1) % 2) + c0 + 1; c1 <= 400; c1 += 2) + for (int c1 = -((c0 - 1) % 2) + c0 + 1; c1 <= 400; c1 += 2) s0(c0, c1); diff -Nru isl-0.12.2/test_inputs/codegen/omega/stride7-0.c isl-0.15/test_inputs/codegen/omega/stride7-0.c --- isl-0.12.2/test_inputs/codegen/omega/stride7-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/stride7-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 36; c0 += 1) +for (int c0 = 1; c0 <= 36; c0 += 1) { if (c0 <= 3) { for (int c1 = 1; c1 <= 9; c1 += 1) s1(c1, c0); @@ -11,3 +11,4 @@ } else if (c0 % 4 == 0) for (int c1 = 1; c1 <= 9; c1 += 1) s0(c1, c0 / 4); +} diff -Nru isl-0.12.2/test_inputs/codegen/omega/substitution-1.c isl-0.15/test_inputs/codegen/omega/substitution-1.c --- isl-0.12.2/test_inputs/codegen/omega/substitution-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/substitution-1.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,3 @@ for (int c0 = 0; c0 <= 14; c0 += 1) - for (int c1 = max(2 * c0 - 12, -c0 + 3 * floord(c0 - 1, 2) + 3); c1 <= min(2 * c0, c0 / 2 + 9); c1 += 3) + for (int c1 = max(2 * c0 - 12, -c0 + 3 * ((c0 + 1) / 2)); c1 <= min(2 * c0, c0 / 2 + 9); c1 += 3) s0((2 * c0 - c1) / 3, (-c0 + 2 * c1) / 3); diff -Nru isl-0.12.2/test_inputs/codegen/omega/syr2k-0.c isl-0.15/test_inputs/codegen/omega/syr2k-0.c --- isl-0.12.2/test_inputs/codegen/omega/syr2k-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/syr2k-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= min(2 * b - 1, n); c0 += 1) - for (int c1 = max(-b + 1, -n + 1); c1 <= min(n - c0, b - c0); c1 += 1) - for (int c2 = max(1, c0 + c1); c2 <= min(n + c1, n); c2 += 1) +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) + for (int c1 = max(-n + 1, -b + 1); c1 <= min(b - c0, n - c0); c1 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/omega/syr2k-1.c isl-0.15/test_inputs/codegen/omega/syr2k-1.c --- isl-0.12.2/test_inputs/codegen/omega/syr2k-1.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/syr2k-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= min(2 * b - 1, n); c0 += 1) +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) for (int c1 = -b + 1; c1 <= b - c0; c1 += 1) - for (int c2 = max(c0 + c1, 1); c2 <= min(n + c1, n); c2 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/omega/syr2k-2.c isl-0.15/test_inputs/codegen/omega/syr2k-2.c --- isl-0.12.2/test_inputs/codegen/omega/syr2k-2.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/syr2k-2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= min(2 * b - 1, n); c0 += 1) - for (int c1 = max(-b + 1, -n + 1); c1 <= min(n - c0, b - c0); c1 += 1) - for (int c2 = max(1, c0 + c1); c2 <= min(n + c1, n); c2 += 1) +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) + for (int c1 = max(-n + 1, -b + 1); c1 <= min(b - c0, n - c0); c1 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/omega/syr2k-3.c isl-0.15/test_inputs/codegen/omega/syr2k-3.c --- isl-0.12.2/test_inputs/codegen/omega/syr2k-3.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/syr2k-3.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= min(2 * b - 1, n); c0 += 1) +for (int c0 = 1; c0 <= min(n, 2 * b - 1); c0 += 1) for (int c1 = -b + 1; c1 <= b - c0; c1 += 1) - for (int c2 = max(c0 + c1, 1); c2 <= min(n + c1, n); c2 += 1) + for (int c2 = max(1, c0 + c1); c2 <= min(n, n + c1); c2 += 1) s0(-c0 - c1 + c2 + 1, -c1 + c2, c2); diff -Nru isl-0.12.2/test_inputs/codegen/omega/ts1d-check0-0.c isl-0.15/test_inputs/codegen/omega/ts1d-check0-0.c --- isl-0.12.2/test_inputs/codegen/omega/ts1d-check0-0.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/ts1d-check0-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -3,7 +3,7 @@ s0(1, c1, 1, 0, 0); for (int c1 = 0; c1 <= floord(T - 1, 500); c1 += 1) for (int c2 = 1000 * c1; c2 <= min(N + 2 * T - 3, N + 1000 * c1 + 997); c2 += 1) { - for (int c3 = max(-((N + c2) % 2) - N - 1000 * c1 + c2 + 2, 0); c3 <= min(min(998, 2 * T - 1000 * c1 - 2), -1000 * c1 + c2 - 2); c3 += 2) { + for (int c3 = max(0, -((N + c2) % 2) - N - 1000 * c1 + c2 + 2); c3 <= min(min(998, 2 * T - 1000 * c1 - 2), -1000 * c1 + c2 - 2); c3 += 2) { s1(2, 1000 * c1 + c3, 0, -1000 * c1 + c2 - c3, 1); s2(2, 1000 * c1 + c3 + 1, 0, -1000 * c1 + c2 - c3 - 1, 1); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/ts1d-check-sblock-0.c isl-0.15/test_inputs/codegen/omega/ts1d-check-sblock-0.c --- isl-0.12.2/test_inputs/codegen/omega/ts1d-check-sblock-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/ts1d-check-sblock-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,13 +1,14 @@ { - for (int c1 = 0; c1 <= 1; c1 += 1) + for (int c1 = 0; c1 <= 1; c1 += 1) { if (c1 == 1) { s0(1, 1, 1, 0, 0); s0(1, 1, 1, N - 1, 0); } else for (int c3 = 0; c3 < N; c3 += 1) s0(1, 0, 1, c3, 0); + } for (int c1 = 0; c1 <= floord(T - 1, 1000); c1 += 1) for (int c2 = 1000 * c1 + 1; c2 <= min(N + T - 3, N + 1000 * c1 + 997); c2 += 1) - for (int c3 = max(-N - 1000 * c1 + c2 + 2, 0); c3 <= min(min(999, T - 1000 * c1 - 1), -1000 * c1 + c2 - 1); c3 += 1) + for (int c3 = max(0, -N - 1000 * c1 + c2 + 2); c3 <= min(min(999, T - 1000 * c1 - 1), -1000 * c1 + c2 - 1); c3 += 1) s1(2, 1000 * c1 + c3, 1, -1000 * c1 + c2 - c3, 1); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c isl-0.15/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c --- isl-0.12.2/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/ts1d-mp-i_ts-m_b-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,30 +1,31 @@ { - for (int c1 = -1; c1 < (T >= 1 ? T : 0); c1 += 1) - for (int c2 = 0; c2 < N; c2 += 1) - if (c2 == 0 && T >= c1 + 1 && c1 >= 0) { + for (int c1 = -1; c1 < T; c1 += 1) + for (int c2 = 0; c2 < N; c2 += 1) { + if (c1 == -1) { + s0(1, -1, c2, 0, 0); + } else if (c2 == 0) { s0(1, c1, 0, 0, 0); - } else if (c2 + 1 == N && T >= c1 + 1 && c1 >= 0) { + } else if (c2 + 1 == N) s0(1, c1, N - 1, 0, 0); - } else if (c1 == -1 && c2 >= 0 && N >= c2 + 1) - s0(1, -1, c2, 0, 0); + } for (int c1 = 0; c1 <= floord(T - 1, 500); c1 += 1) { for (int c3 = -((c1 + 9) / 8) + 2; c3 <= floord(N - 500 * c1 - 3, 4000) + 1; c3 += 1) - for (int c4 = max(1000 * c1 + 4000 * c3 - 3999, 500 * c1 + 1); c4 <= min(min(2 * N - 4000 * c3 + 3995, N + T - 3), 1000 * c1 + 4000 * c3 - 3000); c4 += 1) - for (int c5 = max(0, -N - 500 * c1 + c4 + 2); c5 <= min(min(-500 * c1 + c4 - 1, -500 * c1 - 2000 * c3 + (c4 + 1) / 2 + 1999), T - 500 * c1 - 1); c5 += 1) + for (int c4 = max(500 * c1 + 1, 1000 * c1 + 4000 * c3 - 3999); c4 <= min(min(N + T - 3, 1000 * c1 + 4000 * c3 - 3000), 2 * N - 4000 * c3 + 3995); c4 += 1) + for (int c5 = max(0, -N - 500 * c1 + c4 + 2); c5 <= min(min(T - 500 * c1 - 1, -500 * c1 + c4 - 1), -500 * c1 - 2000 * c3 + (c4 + 1) / 2 + 1999); c5 += 1) s1(2, 500 * c1 + c5, 1, -500 * c1 + c4 - c5, 1); for (int c3 = max(-((T + 4000) / 4000) + 2, -((c1 + 9) / 8) + 2); c3 <= floord(N - 500 * c1 - 3, 4000) + 1; c3 += 1) - for (int c4 = max(1000 * c1 + 4000 * c3 - 3999, -4000 * c3 + 4000); c4 <= min(min(2 * N - 4000 * c3 + 3995, 2 * T + 4000 * c3 - 4000), 1000 * c1 + 4000 * c3 - 3000); c4 += 1) + for (int c4 = max(1000 * c1 + 4000 * c3 - 3999, -4000 * c3 + 4000); c4 <= min(min(2 * T + 4000 * c3 - 4000, 1000 * c1 + 4000 * c3 - 3000), 2 * N - 4000 * c3 + 3995); c4 += 1) s2(2, -2000 * c3 + (c4 + 1) / 2 + 1999, 1, 2000 * c3 + c4 - (c4 + 1) / 2 - 1999, 1); for (int c3 = -((c1 + 7) / 8) + 1; c3 <= min(floord(N + T - 1000 * c1 - 1004, 4000) + 1, floord(N - 500 * c1 - 504, 4000) + 1); c3 += 1) - for (int c4 = max(1000 * c1 + 4000 * c3 - 2999, 500 * c1 + 1); c4 <= min(min(N + T - 3, N + 500 * c1 + 497), 1000 * c1 + 4000 * c3); c4 += 1) - for (int c5 = max(0, -N - 500 * c1 + c4 + 2); c5 <= min(min(-500 * c1 + c4 - 1, 499), T - 500 * c1 - 1); c5 += 1) + for (int c4 = max(500 * c1 + 1, 1000 * c1 + 4000 * c3 - 2999); c4 <= min(min(N + T - 3, N + 500 * c1 + 497), 1000 * c1 + 4000 * c3); c4 += 1) + for (int c5 = max(0, -N - 500 * c1 + c4 + 2); c5 <= min(min(499, T - 500 * c1 - 1), -500 * c1 + c4 - 1); c5 += 1) s3(2, 500 * c1 + c5, 1, -500 * c1 + c4 - c5, 1); for (int c3 = max(-((T + 4000) / 4000) + 1, -((c1 + 9) / 8) + 1); c3 <= floord(N - 500 * c1 - 3, 4000); c3 += 1) - for (int c4 = max(1000 * c1 + 4000 * c3 + 1, -4000 * c3); c4 <= min(min(2 * N - 4000 * c3 - 5, 2 * T + 4000 * c3), 1000 * c1 + 4000 * c3 + 1000); c4 += 1) + for (int c4 = max(-4000 * c3, 1000 * c1 + 4000 * c3 + 1); c4 <= min(min(2 * N - 4000 * c3 - 5, 2 * T + 4000 * c3), 1000 * c1 + 4000 * c3 + 1000); c4 += 1) s4(2, -2000 * c3 + (c4 + 1) / 2 - 1, 1, 2000 * c3 + c4 - (c4 + 1) / 2 + 1, 1); for (int c3 = -((c1 + 8) / 8) + 1; c3 <= min(floord(N + T - 1000 * c1 - 4, 4000), floord(N - 500 * c1 + 496, 4000)); c3 += 1) - for (int c4 = max(-4000 * c3 + 2, 1000 * c1 + 4000 * c3 + 1); c4 <= min(min(min(N + T - 3, N + 500 * c1 + 497), 2 * T + 4000 * c3 - 2), 1000 * c1 + 4000 * c3 + 998); c4 += 1) - for (int c5 = max(-500 * c1 - 2000 * c3 + (c4 + 1) / 2, -N - 500 * c1 + c4 + 2); c5 <= min(min(499, -500 * c1 + c4 - 1), T - 500 * c1 - 1); c5 += 1) + for (int c4 = max(1000 * c1 + 4000 * c3 + 1, -4000 * c3 + 2); c4 <= min(min(min(N + T - 3, N + 500 * c1 + 497), 2 * T + 4000 * c3 - 2), 1000 * c1 + 4000 * c3 + 998); c4 += 1) + for (int c5 = max(-N - 500 * c1 + c4 + 2, -500 * c1 - 2000 * c3 + (c4 + 1) / 2); c5 <= min(min(499, T - 500 * c1 - 1), -500 * c1 + c4 - 1); c5 += 1) s5(2, 500 * c1 + c5, 1, -500 * c1 + c4 - c5, 1); } if (T >= 1) diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak1-0.c isl-0.15/test_inputs/codegen/omega/wak1-0.c --- isl-0.12.2/test_inputs/codegen/omega/wak1-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak1-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,26 +1,26 @@ { - for (int c0 = a2; c0 <= min(min(b2, a3 - 1), a1 - 1); c0 += 1) + for (int c0 = a2; c0 <= min(min(a1 - 1, a3 - 1), b2); c0 += 1) s1(c0); - for (int c0 = a3; c0 <= min(b3, a1 - 1); c0 += 1) { + for (int c0 = a1; c0 <= min(b1, a3 - 1); c0 += 1) { + s0(c0); if (c0 >= a2 && b2 >= c0) s1(c0); - s2(c0); } - for (int c0 = max(max(a3, b3 + 1), a2); c0 <= min(b2, a1 - 1); c0 += 1) + for (int c0 = max(max(a1, b1 + 1), a2); c0 <= min(a3 - 1, b2); c0 += 1) s1(c0); - for (int c0 = a1; c0 <= b1; c0 += 1) { - s0(c0); - if (b2 >= c0 && c0 >= a2) + for (int c0 = a3; c0 <= b3; c0 += 1) { + if (c0 >= a1 && b1 >= c0) + s0(c0); + if (c0 >= a2 && b2 >= c0) s1(c0); - if (b3 >= c0 && c0 >= a3) - s2(c0); + s2(c0); } - for (int c0 = max(max(a1, b1 + 1), a2); c0 <= min(b2, a3 - 1); c0 += 1) + for (int c0 = max(max(a3, b3 + 1), a2); c0 <= min(a1 - 1, b2); c0 += 1) s1(c0); - for (int c0 = max(max(a1, b1 + 1), a3); c0 <= b3; c0 += 1) { + for (int c0 = max(max(a1, a3), b3 + 1); c0 <= b1; c0 += 1) { + s0(c0); if (c0 >= a2 && b2 >= c0) s1(c0); - s2(c0); } for (int c0 = max(max(max(max(a1, b1 + 1), a3), b3 + 1), a2); c0 <= b2; c0 += 1) s1(c0); diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak1-1.c isl-0.15/test_inputs/codegen/omega/wak1-1.c --- isl-0.12.2/test_inputs/codegen/omega/wak1-1.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak1-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,50 +1,50 @@ { - for (int c0 = a3; c0 <= min(min(a2 - 1, b3), a1 - 1); c0 += 1) - s2(c0); - for (int c0 = a2; c0 <= min(min(b2, a3 - 1), a1 - 1); c0 += 1) + for (int c0 = a2; c0 <= min(min(a1 - 1, a3 - 1), b2); c0 += 1) s1(c0); - for (int c0 = max(a3, a2); c0 <= min(min(b2, b3), a1 - 1); c0 += 1) { + for (int c0 = a3; c0 <= min(min(a1 - 1, b3), a2 - 1); c0 += 1) + s2(c0); + for (int c0 = max(a3, a2); c0 <= min(min(a1 - 1, b3), b2); c0 += 1) { s1(c0); s2(c0); } - for (int c0 = max(max(a3, a2), b2 + 1); c0 <= min(b3, a1 - 1); c0 += 1) - s2(c0); - for (int c0 = a1; c0 <= min(min(a2 - 1, a3 - 1), b1); c0 += 1) + for (int c0 = a1; c0 <= min(min(b1, a3 - 1), a2 - 1); c0 += 1) s0(c0); - for (int c0 = max(a1, a3); c0 <= min(min(a2 - 1, b3), b1); c0 += 1) { - s0(c0); - s2(c0); - } - for (int c0 = max(max(a1, b1 + 1), a3); c0 <= min(a2 - 1, b3); c0 += 1) - s2(c0); - for (int c0 = max(a1, a2); c0 <= min(min(b2, a3 - 1), b1); c0 += 1) { + for (int c0 = max(a1, a2); c0 <= min(min(b1, a3 - 1), b2); c0 += 1) { s0(c0); s1(c0); } - for (int c0 = max(max(a1, b1 + 1), a2); c0 <= min(b2, a3 - 1); c0 += 1) + for (int c0 = max(max(a1, b1 + 1), a2); c0 <= min(a3 - 1, b2); c0 += 1) s1(c0); - for (int c0 = max(max(a1, a3), a2); c0 <= min(min(b2, b3), b1); c0 += 1) { + for (int c0 = max(a1, a3); c0 <= min(min(b1, b3), a2 - 1); c0 += 1) { + s0(c0); + s2(c0); + } + for (int c0 = max(max(a1, b1 + 1), a3); c0 <= min(b3, a2 - 1); c0 += 1) + s2(c0); + for (int c0 = max(max(a1, a3), a2); c0 <= min(min(b1, b3), b2); c0 += 1) { s0(c0); s1(c0); s2(c0); } - for (int c0 = max(max(max(a1, b1 + 1), a3), a2); c0 <= min(b2, b3); c0 += 1) { + for (int c0 = max(max(max(a1, b1 + 1), a3), a2); c0 <= min(b3, b2); c0 += 1) { s1(c0); s2(c0); } - for (int c0 = max(max(a1, a2), b2 + 1); c0 <= min(a3 - 1, b1); c0 += 1) + for (int c0 = max(max(a3, a2), b2 + 1); c0 <= min(a1 - 1, b3); c0 += 1) + s2(c0); + for (int c0 = max(max(a1, a2), b2 + 1); c0 <= min(b1, a3 - 1); c0 += 1) s0(c0); - for (int c0 = max(max(max(a1, a3), a2), b2 + 1); c0 <= min(b3, b1); c0 += 1) { + for (int c0 = max(max(max(a1, a3), a2), b2 + 1); c0 <= min(b1, b3); c0 += 1) { s0(c0); s2(c0); } for (int c0 = max(max(max(max(a1, b1 + 1), a3), a2), b2 + 1); c0 <= b3; c0 += 1) s2(c0); - for (int c0 = max(max(a3, b3 + 1), a2); c0 <= min(b2, a1 - 1); c0 += 1) + for (int c0 = max(max(a3, b3 + 1), a2); c0 <= min(a1 - 1, b2); c0 += 1) s1(c0); - for (int c0 = max(max(a1, a3), b3 + 1); c0 <= min(a2 - 1, b1); c0 += 1) + for (int c0 = max(max(a1, a3), b3 + 1); c0 <= min(b1, a2 - 1); c0 += 1) s0(c0); - for (int c0 = max(max(max(a1, a3), b3 + 1), a2); c0 <= min(b2, b1); c0 += 1) { + for (int c0 = max(max(max(a1, a3), b3 + 1), a2); c0 <= min(b1, b2); c0 += 1) { s0(c0); s1(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak2-0.c isl-0.15/test_inputs/codegen/omega/wak2-0.c --- isl-0.12.2/test_inputs/codegen/omega/wak2-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak2-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,15 +1,15 @@ { - for (int c0 = a1; c0 <= min(a2 - 1, b1); c0 += 1) + for (int c0 = a1; c0 <= min(b1, a2 - 1); c0 += 1) for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); if (c2 >= d2 + 1) { - for (int c0 = max(a1, a2); c0 <= min(b2, b1); c0 += 1) + for (int c0 = max(a1, a2); c0 <= min(b1, b2); c0 += 1) for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); } else for (int c0 = a2; c0 <= b2; c0 += 1) { if (c0 >= a1 && b1 >= c0) - for (int c1_0 = c1; c1_0 <= min(c2 - 1, d1); c1_0 += 1) + for (int c1_0 = c1; c1_0 <= min(d1, c2 - 1); c1_0 += 1) s0(c0, c1_0); for (int c1_0 = c2; c1_0 <= d2; c1_0 += 1) { if (c0 >= a1 && b1 >= c0 && c1_0 >= c1 && d1 >= c1_0) @@ -17,7 +17,7 @@ s1(c0, c1_0); } if (c0 >= a1 && b1 >= c0) - for (int c1_0 = max(d2 + 1, c1); c1_0 <= d1; c1_0 += 1) + for (int c1_0 = max(c1, d2 + 1); c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); } for (int c0 = max(max(a1, a2), b2 + 1); c0 <= b1; c0 += 1) diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak2-1.c isl-0.15/test_inputs/codegen/omega/wak2-1.c --- isl-0.12.2/test_inputs/codegen/omega/wak2-1.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak2-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,13 +1,13 @@ { - for (int c0 = a1; c0 <= min(a2 - 1, b1); c0 += 1) + for (int c0 = a1; c0 <= min(b1, a2 - 1); c0 += 1) for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); if (c2 >= d2 + 1) { - for (int c0 = max(a1, a2); c0 <= min(b2, b1); c0 += 1) + for (int c0 = max(a1, a2); c0 <= min(b1, b2); c0 += 1) for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); } else - for (int c0 = a2; c0 <= b2; c0 += 1) + for (int c0 = a2; c0 <= b2; c0 += 1) { if (a1 >= c0 + 1) { for (int c1_0 = c2; c1_0 <= d2; c1_0 += 1) s1(c0, c1_0); @@ -15,19 +15,20 @@ for (int c1_0 = c2; c1_0 <= d2; c1_0 += 1) s1(c0, c1_0); } else { - for (int c1_0 = c1; c1_0 <= min(c2 - 1, d1); c1_0 += 1) + for (int c1_0 = c1; c1_0 <= min(d1, c2 - 1); c1_0 += 1) s0(c0, c1_0); - for (int c1_0 = c2; c1_0 <= min(d2, c1 - 1); c1_0 += 1) + for (int c1_0 = c2; c1_0 <= min(c1 - 1, d2); c1_0 += 1) s1(c0, c1_0); - for (int c1_0 = max(c2, c1); c1_0 <= min(d1, d2); c1_0 += 1) { + for (int c1_0 = max(c1, c2); c1_0 <= min(d1, d2); c1_0 += 1) { s0(c0, c1_0); s1(c0, c1_0); } - for (int c1_0 = max(d2 + 1, c1); c1_0 <= d1; c1_0 += 1) + for (int c1_0 = max(c1, d2 + 1); c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); - for (int c1_0 = max(max(d1 + 1, c1), c2); c1_0 <= d2; c1_0 += 1) + for (int c1_0 = max(max(c1, d1 + 1), c2); c1_0 <= d2; c1_0 += 1) s1(c0, c1_0); } + } for (int c0 = max(max(a1, a2), b2 + 1); c0 <= b1; c0 += 1) for (int c1_0 = c1; c1_0 <= d1; c1_0 += 1) s0(c0, c1_0); diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak3-1.c isl-0.15/test_inputs/codegen/omega/wak3-1.c --- isl-0.12.2/test_inputs/codegen/omega/wak3-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak3-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,11 +1,11 @@ { - for (int c0 = a; c0 <= min(b, a + 9); c0 += 1) + for (int c0 = a; c0 <= min(a + 9, b); c0 += 1) s0(c0); - for (int c0 = a + 10; c0 <= min(b, a + 19); c0 += 1) { + for (int c0 = a + 10; c0 <= min(a + 19, b); c0 += 1) { s0(c0); s1(c0); } - for (int c0 = max(a + 10, b + 1); c0 <= min(b + 10, a + 19); c0 += 1) + for (int c0 = max(a + 10, b + 1); c0 <= min(a + 19, b + 10); c0 += 1) s1(c0); for (int c0 = a + 20; c0 <= b; c0 += 1) { s0(c0); diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak4-0.c isl-0.15/test_inputs/codegen/omega/wak4-0.c --- isl-0.12.2/test_inputs/codegen/omega/wak4-0.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak4-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = max(max(max(max(a1, a2), a3), a4), a5); c0 <= min(min(min(min(b5, b4), b3), b2), b1); c0 += 1) { +for (int c0 = max(max(max(max(a1, a2), a3), a4), a5); c0 <= min(min(min(min(b1, b2), b3), b4), b5); c0 += 1) { s0(c0); s1(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/wak4-1.c isl-0.15/test_inputs/codegen/omega/wak4-1.c --- isl-0.12.2/test_inputs/codegen/omega/wak4-1.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/wak4-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = max(max(max(max(a1, a2), a3), a4), a5); c0 <= min(min(min(min(b5, b4), b3), b2), b1); c0 += 1) { +for (int c0 = max(max(max(max(a1, a2), a3), a4), a5); c0 <= min(min(min(min(b1, b2), b3), b4), b5); c0 += 1) { s0(c0); s1(c0); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/x-0.c isl-0.15/test_inputs/codegen/omega/x-0.c --- isl-0.12.2/test_inputs/codegen/omega/x-0.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/x-0.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,14 +1,14 @@ for (int c0 = 1; c0 <= 11; c0 += 1) { - for (int c1 = max(1, -c0 + 9); c1 <= min(-c0 + 12, c0 - 4); c1 += 1) - s0(c1, c0 + c1 - 8); - for (int c1 = max(c0 - 3, 1); c1 <= min(-c0 + 8, c0); c1 += 1) + for (int c1 = max(1, c0 - 3); c1 <= min(c0, -c0 + 8); c1 += 1) s1(c1, c0 - c1 + 1); - for (int c1 = max(c0 - 3, -c0 + 9); c1 <= min(-c0 + 12, c0); c1 += 1) { + for (int c1 = max(1, -c0 + 9); c1 <= min(c0 - 4, -c0 + 12); c1 += 1) + s0(c1, c0 + c1 - 8); + for (int c1 = max(c0 - 3, -c0 + 9); c1 <= min(c0, -c0 + 12); c1 += 1) { s0(c1, c0 + c1 - 8); s1(c1, c0 - c1 + 1); } for (int c1 = max(c0 - 3, -c0 + 13); c1 <= min(8, c0); c1 += 1) s1(c1, c0 - c1 + 1); - for (int c1 = max(c0 + 1, -c0 + 9); c1 <= min(-c0 + 12, 8); c1 += 1) + for (int c1 = max(c0 + 1, -c0 + 9); c1 <= min(8, -c0 + 12); c1 += 1) s0(c1, c0 + c1 - 8); } diff -Nru isl-0.12.2/test_inputs/codegen/omega/x-1.c isl-0.15/test_inputs/codegen/omega/x-1.c --- isl-0.12.2/test_inputs/codegen/omega/x-1.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/omega/x-1.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,14 +1,14 @@ for (int c0 = 1; c0 <= 11; c0 += 1) { - for (int c1 = max(1, -c0 + 9); c1 <= min(-c0 + 12, c0 - 4); c1 += 1) - s0(c1, c0 + c1 - 8); - for (int c1 = max(c0 - 3, 1); c1 <= min(-c0 + 8, c0); c1 += 1) + for (int c1 = max(1, c0 - 3); c1 <= min(c0, -c0 + 8); c1 += 1) s1(c1, c0 - c1 + 1); - for (int c1 = max(c0 - 3, -c0 + 9); c1 <= min(-c0 + 12, c0); c1 += 1) { + for (int c1 = max(1, -c0 + 9); c1 <= min(c0 - 4, -c0 + 12); c1 += 1) + s0(c1, c0 + c1 - 8); + for (int c1 = max(c0 - 3, -c0 + 9); c1 <= min(c0, -c0 + 12); c1 += 1) { s0(c1, c0 + c1 - 8); s1(c1, c0 - c1 + 1); } for (int c1 = max(c0 - 3, -c0 + 13); c1 <= min(8, c0); c1 += 1) s1(c1, c0 - c1 + 1); - for (int c1 = max(c0 + 1, -c0 + 9); c1 <= min(-c0 + 12, 8); c1 += 1) + for (int c1 = max(c0 + 1, -c0 + 9); c1 <= min(8, -c0 + 12); c1 += 1) s0(c1, c0 + c1 - 8); } diff -Nru isl-0.12.2/test_inputs/codegen/pldi2012/figure7_c.c isl-0.15/test_inputs/codegen/pldi2012/figure7_c.c --- isl-0.12.2/test_inputs/codegen/pldi2012/figure7_c.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/pldi2012/figure7_c.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 1; c0 <= 100; c0 += 1) +for (int c0 = 1; c0 <= 100; c0 += 1) { if (n >= 2) { s0(c0); for (int c1 = 1; c1 <= 100; c1 += 1) { @@ -8,3 +8,4 @@ } else for (int c1 = 1; c1 <= 100; c1 += 1) s2(c0, c1); +} diff -Nru isl-0.12.2/test_inputs/codegen/pldi2012/figure8_b.c isl-0.15/test_inputs/codegen/pldi2012/figure8_b.c --- isl-0.12.2/test_inputs/codegen/pldi2012/figure8_b.c 2013-05-28 07:39:08.000000000 +0000 +++ isl-0.15/test_inputs/codegen/pldi2012/figure8_b.c 2015-04-19 12:02:52.000000000 +0000 @@ -3,6 +3,6 @@ s1(c0); s0(c0 + 2); } - if (n >= 4 * floord(n, 4) + 2 && n >= 0) + if (n >= 2 && n % 4 >= 2) s1(-(n % 4) + n + 2); } diff -Nru isl-0.12.2/test_inputs/codegen/roman.c isl-0.15/test_inputs/codegen/roman.c --- isl-0.12.2/test_inputs/codegen/roman.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/roman.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,32 @@ +{ + for (int c1 = 0; c1 <= min(np1 - i, -i + 1); c1 += 1) { + S_9(c1); + S_12(c1); + } + for (int c1 = max(0, -i + 2); c1 <= -((-np1 + i + 4294967295) % 4294967296) + 4294967295; c1 += 1) { + S_9(c1); + S_10(c1); + for (int c3 = 0; c3 <= min(19, i + c1 - 3); c3 += 1) { + S_15(c1, c3); + for (int c5 = 0; c5 < c3; c5 += 1) { + S_16(c1, c3, c5); + S_17(c1, c3, c5); + } + S_16(c1, c3, c3); + S_18(c1, c3); + S_24(c1, c3); + S_19(c1, c3); + } + if (np1 >= i && i + c1 <= 21) { + S_15(c1, i + c1 - 2); + for (int c5 = 0; c5 < i + c1 - 2; c5 += 1) { + S_16(c1, i + c1 - 2, c5); + S_17(c1, i + c1 - 2, c5); + } + S_16(c1, i + c1 - 2, i + c1 - 2); + S_18(c1, i + c1 - 2); + S_24(c1, i + c1 - 2); + } + S_12(c1); + } +} diff -Nru isl-0.12.2/test_inputs/codegen/roman.in isl-0.15/test_inputs/codegen/roman.in --- isl-0.12.2/test_inputs/codegen/roman.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/roman.in 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,5 @@ +# Older versions of isl would get confused on this input due to disappearing +# div constraints. +[np1, i] -> { S_17[i0, i1, i2] -> [0, i0, 2, i1, 1, i2, 1] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296], e2 = [(i1)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i2 >= 0 and 4294967296e2 <= i1 and 4294967296e2 >= -4294967295 + i1 and 4294967296e2 <= i1 - i2 and i2 <= 19 and i0 >= 2 - i and i2 <= -1 + i1); S_18[i0, i1] -> [0, i0, 2, i1, 2, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i); S_24[i0, i1] -> [0, i0, 2, i1, 3, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i); S_15[i0, i1] -> [0, i0, 2, i1, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i); S_9[i0] -> [0, i0, 0, 0, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20); S_10[i0] -> [0, i0, 1, 0, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i0 >= 2 - i); S_19[i0, i1] -> [0, i0, 2, i1, 4, 0, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i0 >= 2 - i and i1 <= -3 + i + i0); S_12[i0] -> [0, i0, 3, 0, 0, 0, 0] : exists (e0 = [(np1 - i)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20); S_16[i0, i1, i2] -> [0, i0, 2, i1, 1, i2, 0] : exists (e0 = [(np1 - i)/4294967296], e1 = [(-2 + i + i0)/4294967296], e2 = [(i1)/4294967296]: i0 >= 0 and 4294967296e0 <= np1 - i and 4294967296e0 >= -4294967295 + np1 - i and 4294967296e0 <= np1 - i - i0 and i0 <= 20 and i1 >= 0 and 4294967296e1 <= -2 + i + i0 and 4294967296e1 >= -4294967297 + i + i0 and 4294967296e1 <= -2 + i + i0 - i1 and i1 <= 19 and i2 >= 0 and 4294967296e2 <= i1 and 4294967296e2 >= -4294967295 + i1 and 4294967296e2 <= i1 - i2 and i2 <= 19 and i0 >= 2 - i) } +[np1, i] -> { : exists (e0 = [(np1 - i)/4294967296]: 4294967296e0 <= np1 - i and 4294967296e0 >= -20 + np1 - i and np1 >= -2147483648 and np1 <= 2147483647 and i >= -2147483648 and i <= 2147483647) } +[np1, i] -> { [i0, i1, i2, i3, i4, i5, i6] -> separate[o0] } diff -Nru isl-0.12.2/test_inputs/codegen/separate2.c isl-0.15/test_inputs/codegen/separate2.c --- isl-0.12.2/test_inputs/codegen/separate2.c 2014-01-12 11:34:14.000000000 +0000 +++ isl-0.15/test_inputs/codegen/separate2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,9 +1,9 @@ if ((length - 1) % 16 <= 14) for (int c0 = 0; c0 <= 1; c0 += 1) for (int c5 = 0; c5 <= 31; c5 += 1) - for (int c6 = 0; c6 <= 30; c6 += 1) { - if ((2 * c5 - c6 + 31) % 32 == 31 && 2 * ((length - 1) % 16) + 2 * c5 == 2 * ((length - 1) % 32) + c6 && c6 + 62 >= 2 * ((length - 1) % 16) + 2 * c5 && 2 * length + c6 >= 2 * ((length - 1) % 16) + 4 && 2 * ((length - 1) % 16) >= c6 && 2 * ((length - 1) % 16) + 2 * c5 >= c6) - S_3(c0, 0, (-(2 * ((length - 1) % 16)) + 2 * length + c6 - 2) / 2); + for (int c6 = max(0, 2 * ((length - 1) % 16) + 2 * c5 - 60); c6 <= 30; c6 += 1) { + if (length + c5 >= ((length - 1) % 32) + 2 && (length - 1) % 32 >= c5 && 2 * ((length - 1) % 32) + c6 >= 2 * c5 && 2 * c5 + 30 >= 2 * ((length - 1) % 32) + c6 && 2 * ((length - 1) % 32) + c6 == 2 * ((length - 1) % 16) + 2 * c5 && (2 * c5 - c6) % 32 == 0) + S_3(c0, 0, (c6 / 2) - ((length - 1) % 16) + length - 1); if (length <= 16 && length >= c5 + 1 && c6 >= 1 && length >= c6) S_0(c0, c5, c6 - 1); } diff -Nru isl-0.12.2/test_inputs/codegen/separate.st isl-0.15/test_inputs/codegen/separate.st --- isl-0.12.2/test_inputs/codegen/separate.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/separate.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,4 @@ +domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" +child: + schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" + options: "{ separate[x] }" diff -Nru isl-0.12.2/test_inputs/codegen/separation_class2.c isl-0.15/test_inputs/codegen/separation_class2.c --- isl-0.12.2/test_inputs/codegen/separation_class2.c 2013-10-16 16:33:52.000000000 +0000 +++ isl-0.15/test_inputs/codegen/separation_class2.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,6 +1,6 @@ { - for (int c0 = 0; c0 < -(n % 8) + n - 7; c0 += 8) { - for (int c1 = 0; c1 < -(n % 8) + n - 7; c1 += 8) + for (int c0 = 0; c0 < -(n % 8) + n; c0 += 8) { + for (int c1 = 0; c1 < -(n % 8) + n; c1 += 8) for (int c2 = 0; c2 <= 7; c2 += 1) for (int c3 = 0; c3 <= 7; c3 += 1) A(c0 + c2, c1 + c3); @@ -10,6 +10,6 @@ } for (int c1 = 0; c1 < n; c1 += 8) for (int c2 = 0; c2 < n % 8; c2 += 1) - for (int c3 = 0; c3 <= min(n - c1 - 1, 7); c3 += 1) + for (int c3 = 0; c3 <= min(7, n - c1 - 1); c3 += 1) A(-((n - 1) % 8) + n + c2 - 1, c1 + c3); } diff -Nru isl-0.12.2/test_inputs/codegen/separation_class3.c isl-0.15/test_inputs/codegen/separation_class3.c --- isl-0.12.2/test_inputs/codegen/separation_class3.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/separation_class3.c 2015-04-19 12:02:52.000000000 +0000 @@ -11,10 +11,10 @@ for (int c6 = -2 * c0 + c4 + 4; c6 <= 2 * c0 - c4 + 4; c6 += 1) S_0(c4, c6); } - for (int c4 = max(2 * c0 - 1, 0); c4 <= min(7, 2 * c0); c4 += 1) + for (int c4 = max(0, 2 * c0 - 1); c4 <= min(7, 2 * c0); c4 += 1) for (int c6 = -2 * c0 + c4 + 8; c6 <= 8; c6 += 1) S_0(c4, c6); - if (c0 <= 3 && c0 >= 1) { + if (c0 >= 1 && c0 <= 3) { for (int c2 = 0; c2 <= 1; c2 += 1) for (int c4 = 2 * c0 - 1; c4 <= 2 * c0; c4 += 1) for (int c6 = 2 * c0 + 4 * c2 - c4 + 1; c6 <= -2 * c0 + 4 * c2 + c4 + 3; c6 += 1) diff -Nru isl-0.12.2/test_inputs/codegen/separation_class4.c isl-0.15/test_inputs/codegen/separation_class4.c --- isl-0.12.2/test_inputs/codegen/separation_class4.c 2014-01-12 11:34:14.000000000 +0000 +++ isl-0.15/test_inputs/codegen/separation_class4.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ -for (int c0 = 0; c0 <= 128; c0 += 1) +for (int c0 = 0; c0 <= 128; c0 += 1) { if (c0 <= 127) { if (c0 == 0) { for (int c3 = 0; c3 <= 1; c3 += 1) @@ -6,14 +6,15 @@ S_0(c3, c5); } else for (int c2 = 1; c2 <= 2; c2 += 1) - for (int c3 = max(4 * c0 - 2, 4 * c0 + 6 * c2 - 12); c3 <= min(4 * c0 + 6 * c2 - 7, 4 * c0 + 1); c3 += 1) - for (int c5 = max(4 * c0 - c3 + 57, -4 * c0 + c3 + 58); c5 <= min(-4 * c0 + c3 + 62, 4 * c0 - c3 + 61); c5 += 1) + for (int c3 = max(4 * c0 - 2, 4 * c0 + 6 * c2 - 12); c3 <= min(4 * c0 + 1, 4 * c0 + 6 * c2 - 7); c3 += 1) + for (int c5 = max(4 * c0 - c3 + 57, -4 * c0 + c3 + 58); c5 <= min(4 * c0 - c3 + 61, -4 * c0 + c3 + 62); c5 += 1) S_0(c3, c5); for (int c2 = 1; c2 <= 2; c2 += 1) - for (int c3 = max(4 * c0 + 6 * c2 - 10, 4 * c0); c3 <= min(4 * c0 + 6 * c2 - 5, 4 * c0 + 3); c3 += 1) - for (int c5 = max(4 * c0 - c3 + 62, -4 * c0 + c3 + 59); c5 <= min(4 * c0 - c3 + 66, -4 * c0 + c3 + 63); c5 += 1) + for (int c3 = max(4 * c0, 4 * c0 + 6 * c2 - 10); c3 <= min(4 * c0 + 3, 4 * c0 + 6 * c2 - 5); c3 += 1) + for (int c5 = max(-4 * c0 + c3 + 59, 4 * c0 - c3 + 62); c5 <= min(-4 * c0 + c3 + 63, 4 * c0 - c3 + 66); c5 += 1) S_0(c3, c5); } else for (int c3 = 510; c3 <= 511; c3 += 1) for (int c5 = -c3 + 569; c5 < c3 - 449; c5 += 1) S_0(c3, c5); +} diff -Nru isl-0.12.2/test_inputs/codegen/separation_class.c isl-0.15/test_inputs/codegen/separation_class.c --- isl-0.12.2/test_inputs/codegen/separation_class.c 2013-09-13 17:23:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/separation_class.c 2015-04-19 12:02:52.000000000 +0000 @@ -12,6 +12,6 @@ for (int c0 = 9; c0 <= 10; c0 += 1) for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) for (int c2 = 10 * c0; c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) - for (int c3 = 10 * c1; c3 <= min(-c2 + 100, 10 * c1 + 9); c3 += 1) + for (int c3 = 10 * c1; c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) A(c2, c3); } diff -Nru isl-0.12.2/test_inputs/codegen/shift2.c isl-0.15/test_inputs/codegen/shift2.c --- isl-0.12.2/test_inputs/codegen/shift2.c 2014-01-12 11:34:14.000000000 +0000 +++ isl-0.15/test_inputs/codegen/shift2.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,53 +1,43 @@ for (int c0 = 0; c0 <= 1; c0 += 1) { - for (int c1 = 0; c1 < length - 1; c1 += 32) { - for (int c2 = c1; c2 < length; c2 += 32) { - if (c1 == 0) - for (int c3 = 0; c3 <= min(length, 2 * c2 - 32); c3 += 32) - for (int c5 = 0; c5 <= min(31, length - c2 - 1); c5 += 1) - for (int c6 = max(-c3 + 1, 0); c6 <= min(31, length - c3); c6 += 1) - S_0(c0, c2 + c5, c3 + c6 - 1); - for (int c3 = max(2 * c1, 2 * c2); c3 <= min(2 * c2 + 62, 2 * length - 2); c3 += 32) - for (int c4 = 0; c4 <= min(min(length - c1 - 2, -c1 + c3 / 2 + 14), 31); c4 += 1) { - if (c4 == 0 && c3 == 0 && c2 == 0 && c1 == 0) { - for (int c6 = 1; c6 <= min(31, length); c6 += 1) - S_0(c0, 0, c6 - 1); - } else if (c4 == 0 && c3 == 2 * c2 + 32 && c1 == 0) - for (int c5 = 0; c5 <= 15; c5 += 1) - for (int c6 = 0; c6 <= min(31, length - 2 * c2 - 32); c6 += 1) - S_0(c0, c2 + c5, 2 * c2 + c6 + 31); - for (int c5 = max((-2 * c2 + c3) / 2, c1 - c2 + c4 + 1); c5 <= min(-c2 + c3 / 2 + 15, length - c2 - 1); c5 += 1) { - if (c4 == 0 && c1 == 0) - for (int c6 = max(-c3 + 1, 0); c6 <= min(2 * c2 - c3 + 2 * c5 - 1, length - c3); c6 += 1) - S_0(c0, c2 + c5, c3 + c6 - 1); - S_3(c0, c1 + c4, c2 + c5); - if (c4 == 0 && c1 == 0 && length >= 2 * c2 + 2 * c5) + for (int c2 = 0; c2 <= length; c2 += 32) { + if (length >= c2 + 1) { + for (int c3 = 0; c3 <= length; c3 += 32) { + for (int c5 = 0; c5 <= min(31, length - c2 - 1); c5 += 1) { + for (int c6 = max(0, -c3 + 1); c6 <= min(min(31, length - c3), 2 * c2 - c3 + 2 * c5 - 1); c6 += 1) + S_0(c0, c2 + c5, c3 + c6 - 1); + if (c2 + c5 >= 1 && 2 * c2 + 2 * c5 >= c3 && c3 + 30 >= 2 * c2 + 2 * c5) { + S_3(c0, 0, c2 + c5); + if (length >= 2 * c2 + 2 * c5) S_0(c0, c2 + c5, 2 * c2 + 2 * c5 - 1); - if (c4 == 0 && c1 == 0) - for (int c6 = 2 * c2 - c3 + 2 * c5 + 1; c6 <= min(length - c3, 31); c6 += 1) - S_0(c0, c2 + c5, c3 + c6 - 1); } - if (c4 == 0 && c1 == 0 && c3 + 30 >= 2 * length) + for (int c6 = max(0, 2 * c2 - c3 + 2 * c5 + 1); c6 <= min(31, length - c3); c6 += 1) + S_0(c0, c2 + c5, c3 + c6 - 1); + } + if (length <= 15 && c2 == 0 && c3 == 0) + S_4(c0); + if (c3 >= 2 * c2 && 2 * c2 + 32 >= c3) + for (int c4 = 1; c4 <= min(min(31, length - 2), (c3 / 2) + 14); c4 += 1) + for (int c5 = max((c3 / 2) - c2, -c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1) + S_3(c0, c4, c2 + c5); + } + for (int c3 = max(2 * c2, -(length % 32) + length + 32); c3 <= min(2 * length - 2, 2 * c2 + 62); c3 += 32) + for (int c4 = 0; c4 <= min(31, length - 2); c4 += 1) { + for (int c5 = max((c3 / 2) - c2, -c2 + c4 + 1); c5 <= min(length - c2 - 1, (c3 / 2) - c2 + 15); c5 += 1) + S_3(c0, c4, c2 + c5); + if (c3 + 30 >= 2 * length && c4 == 0) S_4(c0); - if (c4 == 0 && c3 == 2 * c2 && c1 == 0) - for (int c5 = 16; c5 <= min(length - c2 - 1, 31); c5 += 1) - for (int c6 = max(0, -2 * c2 + 1); c6 <= min(31, length - 2 * c2); c6 += 1) - S_0(c0, c2 + c5, 2 * c2 + c6 - 1); } - if (32 * floord(length - 16, 32) + 16 == length && c2 + 16 == length && c1 == 0) + if (c2 + 16 == length && (length - 16) % 32 == 0) S_4(c0); - if (c1 == 0) - for (int c3 = 2 * c2 + 64; c3 <= length; c3 += 32) - for (int c5 = 0; c5 <= 31; c5 += 1) - for (int c6 = 0; c6 <= min(31, length - c3); c6 += 1) - S_0(c0, c2 + c5, c3 + c6 - 1); - } - if (length % 32 == 0 && c1 == 0) + } else if (length == 0) { + S_4(c0); + } else S_4(c0); } - if (length <= 1) - for (int c5 = 0; c5 <= length; c5 += 1) - if (c5 == length) { - S_4(c0); - } else - S_0(c0, 0, 0); + for (int c1 = 32; c1 < length - 1; c1 += 32) + for (int c2 = c1; c2 < length; c2 += 32) + for (int c3 = c2; c3 <= min(length - 1, c2 + 31); c3 += 16) + for (int c4 = 0; c4 <= min(min(31, length - c1 - 2), -c1 + c3 + 14); c4 += 1) + for (int c5 = max(-c2 + c3, c1 - c2 + c4 + 1); c5 <= min(length - c2 - 1, -c2 + c3 + 15); c5 += 1) + S_3(c0, c1 + c4, c2 + c5); } diff -Nru isl-0.12.2/test_inputs/codegen/single_valued.c isl-0.15/test_inputs/codegen/single_valued.c --- isl-0.12.2/test_inputs/codegen/single_valued.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/single_valued.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,2 +1,2 @@ -if (2 * (63 * t1 % 64) + t1 <= 134) +if (2 * ((t1 - 1) % 64) + 8 >= t1) S(-(2 * ((t1 - 1) % 64)) + t1 + 126); diff -Nru isl-0.12.2/test_inputs/codegen/stride5.c isl-0.15/test_inputs/codegen/stride5.c --- isl-0.12.2/test_inputs/codegen/stride5.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/stride5.c 2015-06-02 09:28:10.000000000 +0000 @@ -1,3 +1,3 @@ -if (2 * floord(n, 2) == n) - for (int c0 = (n + 4 * floord(-n - 1, 4) + 4) / 2; c0 <= 100; c0 += 2) +if (n % 2 == 0) + for (int c0 = (n / 2) + 2 * floord(-n - 1, 4) + 2; c0 <= 100; c0 += 2) S(c0); diff -Nru isl-0.12.2/test_inputs/codegen/stride6.c isl-0.15/test_inputs/codegen/stride6.c --- isl-0.12.2/test_inputs/codegen/stride6.c 2013-09-13 17:27:24.000000000 +0000 +++ isl-0.15/test_inputs/codegen/stride6.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,4 +1,4 @@ for (int c1 = -1024; c1 <= 0; c1 += 32) - for (int c2 = max(-((niter - c1) % 32) + niter - c1 - 32, -((niter - 1) % 32) + niter - 1); c2 <= min(niter + 1022, niter - c1 - 1); c2 += 32) - for (int c5 = max(max(niter - c1 - c2 - 32, -c1 - 1023), 0); c5 <= min(min(-c1, niter - c1 - c2 - 1), 31); c5 += 1) + for (int c2 = max(-((niter - 1) % 32) + niter - 1, -((niter - c1) % 32) + niter - c1 - 32); c2 <= min(niter + 1022, niter - c1 - 1); c2 += 32) + for (int c5 = max(max(0, -c1 - 1023), niter - c1 - c2 - 32); c5 <= min(min(31, -c1), niter - c1 - c2 - 1); c5 += 1) S_4(niter - 1, -c1 - c5); diff -Nru isl-0.12.2/test_inputs/codegen/stride7.c isl-0.15/test_inputs/codegen/stride7.c --- isl-0.12.2/test_inputs/codegen/stride7.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/stride7.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,6 @@ +for (int c0 = 2; c0 <= 200; c0 += 64) { + for (int c2 = c0 - 1; c2 <= 120; c2 += 1) + s2(c0, c2); + for (int c2 = 122; c2 <= c0 + 62; c2 += 1) + s4(c0, c2); +} diff -Nru isl-0.12.2/test_inputs/codegen/stride7.in isl-0.15/test_inputs/codegen/stride7.in --- isl-0.12.2/test_inputs/codegen/stride7.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/stride7.in 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,7 @@ +# Check that no redundant guards are introduced +{ s4[a, b] -> [a, 2, b] : exists (e0 = floor((-2 + a)/64): + 64e0 = -2 + a and a <= 200 and b <= 62 + a and b >= 122); + s2[a, b] -> [a, 2, b] : exists (e0 = floor((-2 + a)/64): + 64e0 = -2 + a and a >= 2 and b <= 120 and b >= -1 + a and a <= 100) } +{ : } +{ } diff -Nru isl-0.12.2/test_inputs/codegen/unroll10.c isl-0.15/test_inputs/codegen/unroll10.c --- isl-0.12.2/test_inputs/codegen/unroll10.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll10.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,29 @@ +if (m >= 1 && n >= 1) { + A(0); + if (m >= 2 && n >= 2) { + A(1); + if (m >= 3 && n >= 3) { + A(2); + if (m >= 4 && n >= 4) { + A(3); + if (m >= 5 && n >= 5) { + A(4); + if (m >= 6 && n >= 6) { + A(5); + if (m >= 7 && n >= 7) { + A(6); + if (m >= 8 && n >= 8) { + A(7); + if (m >= 9 && n >= 9) { + A(8); + if (m >= 10 && n >= 10) + A(9); + } + } + } + } + } + } + } + } +} diff -Nru isl-0.12.2/test_inputs/codegen/unroll10.in isl-0.15/test_inputs/codegen/unroll10.in --- isl-0.12.2/test_inputs/codegen/unroll10.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll10.in 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,4 @@ +# Check that all information is taken into account while trying to unroll +[m,n] -> { A[i] -> [i] : 0 <= i < n,m } +[m,n] -> { : m <= 10 or n <= 10 } +{ [i] -> unroll[x] } diff -Nru isl-0.12.2/test_inputs/codegen/unroll10.st isl-0.15/test_inputs/codegen/unroll10.st --- isl-0.12.2/test_inputs/codegen/unroll10.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll10.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +# Check that all information is taken into account while trying to unroll +domain: "[m,n] -> { A[i] : 0 <= i < n,m }" +child: + context: "[m,n] -> { [] : m <= 10 or n <= 10 }" + child: + schedule: "[{ A[i] -> [i] }]" + options: "{ unroll[x] }" diff -Nru isl-0.12.2/test_inputs/codegen/unroll11.c isl-0.15/test_inputs/codegen/unroll11.c --- isl-0.12.2/test_inputs/codegen/unroll11.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll11.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,8 @@ +{ + if (t1 >= 126) + S(0, t1 - 384); + S(0, t1 - 256); + if (t1 >= 126) + S(1, t1 - 384); + S(1, t1 - 256); +} diff -Nru isl-0.12.2/test_inputs/codegen/unroll11.in isl-0.15/test_inputs/codegen/unroll11.in --- isl-0.12.2/test_inputs/codegen/unroll11.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll11.in 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,10 @@ +# Check that the most appropriate lower bound is selected +[t1,t2]->{ S[i,j] -> [i,j] : exists (alpha, beta : + 0 <= i <= 1 && + t1 = j+128alpha && + 0 <= j+2beta < 128 && + 510 <= t2+2beta <= 514 && + 0 <= 2beta - t2 <= 5 +)} +[t1,t2] -> {: 125 <= t1 <= 127 and 254 <= t2 < 257} +{[i,j] -> unroll[x]} diff -Nru isl-0.12.2/test_inputs/codegen/unroll4.c isl-0.15/test_inputs/codegen/unroll4.c --- isl-0.12.2/test_inputs/codegen/unroll4.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll4.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,22 +1,22 @@ { write_shared_A(3, ((t1 + 3) % 4) + 1, ((t2 + 31) % 32) + 1); - if (t1 % 3 == 0 && t2 >= 1 && t2 <= 2) - write_shared_A(3, (-t1 + 12) / 3, t2 + 32); + if (t2 >= 1 && t2 <= 2 && t1 % 3 == 0) + write_shared_A(3, (-t1 / 3) + 4, t2 + 32); { - int c3 = ((t1 + 3) % 4) + 1 >= t2 && t2 >= 2 && t2 <= 33 ? t2 + 32 : ((t2 + 30) % 32) + 2; - if (c3 == t2 + 32 || (c3 == t2 && ((-t1 + 8) % 4) + t2 >= ((t2 + 1) % 2) + 5)) + int c3 = t2 >= 2 && ((t1 + 3) % 4) + 1 >= t2 ? t2 + 32 : ((t2 + 30) % 32) + 2; + if (c3 == t2 + 32 || (c3 == t2 && t2 >= ((t1 + 3) % 4) + ((t2 - 1) % 2) + 2)) write_shared_A(3, ((t1 + 3) % 4) + 5, c3); } - if (t2 >= t1 + 1 && t2 <= 4 && t1 >= 1) + if (t1 >= 1 && t2 >= t1 + 1 && t2 <= 4) write_shared_A(3, t1 + 4, t2 + 32); write_shared_A(4, ((t1 + 3) % 4) + 1, ((t2 + 31) % 32) + 1); - if (t1 % 3 == 0 && t2 >= 1 && t2 <= 2) - write_shared_A(4, (-t1 + 12) / 3, t2 + 32); + if (t2 >= 1 && t2 <= 2 && t1 % 3 == 0) + write_shared_A(4, (-t1 / 3) + 4, t2 + 32); { - int c3 = ((t1 + 3) % 4) + 1 >= t2 && t2 >= 2 && t2 <= 33 ? t2 + 32 : ((t2 + 30) % 32) + 2; - if (c3 == t2 + 32 || (c3 == t2 && ((-t1 + 8) % 4) + t2 >= ((t2 + 1) % 2) + 5)) + int c3 = t2 >= 2 && ((t1 + 3) % 4) + 1 >= t2 ? t2 + 32 : ((t2 + 30) % 32) + 2; + if (c3 == t2 + 32 || (c3 == t2 && t2 >= ((t1 + 3) % 4) + ((t2 - 1) % 2) + 2)) write_shared_A(4, ((t1 + 3) % 4) + 5, c3); } - if (t2 >= t1 + 1 && t2 <= 4 && t1 >= 1) + if (t1 >= 1 && t2 >= t1 + 1 && t2 <= 4) write_shared_A(4, t1 + 4, t2 + 32); } diff -Nru isl-0.12.2/test_inputs/codegen/unroll6.c isl-0.15/test_inputs/codegen/unroll6.c --- isl-0.12.2/test_inputs/codegen/unroll6.c 2014-01-12 10:15:28.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll6.c 2015-04-19 12:02:52.000000000 +0000 @@ -1,8 +1,8 @@ { - if (((-t1 + 128) % 128) + nn >= 128 * g + 130 && 128 * g + 127 >= (-t1 + 128) % 128 && nn >= 128 * g + 6) + if (g >= 0 && nn >= 128 * g + 6 && nn >= ((t1 + 127) % 128) + 128 * g + 3) for (int c1 = 393214; c1 < nn - 1; c1 += 393216) A(c1, ((t1 + 127) % 128) + 128 * g + 1, ((t1 + 127) % 128) + 1); - if (nn >= t1 + 128 * g + 130 && t1 + 128 * g >= -127 && t1 <= 2 && t1 >= 1) + if (t1 >= 1 && t1 <= 2 && nn >= t1 + 128 * g + 130 && t1 + 128 * g >= -127) for (int c1 = 393214; c1 < nn - 1; c1 += 393216) A(c1, t1 + 128 * g + 128, t1 + 128); } diff -Nru isl-0.12.2/test_inputs/codegen/unroll7.c isl-0.15/test_inputs/codegen/unroll7.c --- isl-0.12.2/test_inputs/codegen/unroll7.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll7.c 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,10 @@ +{ + S(0, 0); + S(0, 3); + S(0, 4); + S(1, 1); + S(1, 4); + S(2, 2); + S(3, 3); + S(4, 4); +} diff -Nru isl-0.12.2/test_inputs/codegen/unroll7.in isl-0.15/test_inputs/codegen/unroll7.in --- isl-0.12.2/test_inputs/codegen/unroll7.in 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll7.in 2015-04-19 12:02:52.000000000 +0000 @@ -0,0 +1,5 @@ +# Check that some code is generated. +# Older versions of isl would abort on unknown divs. +{ S[i,j] -> [i,j]: exists (alpha, beta: j=i+4alpha +3beta and 0 <= alpha < 24 and 0 <= beta and 0 <= i,j < 5) } +{ : } +{ [i,j] -> unroll[x] } diff -Nru isl-0.12.2/test_inputs/codegen/unroll8.c isl-0.15/test_inputs/codegen/unroll8.c --- isl-0.12.2/test_inputs/codegen/unroll8.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll8.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,6 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) { + A(c0, 0); + A(c0, 1); + B(c0, 0); + B(c0, 1); +} diff -Nru isl-0.12.2/test_inputs/codegen/unroll8.st isl-0.15/test_inputs/codegen/unroll8.st --- isl-0.12.2/test_inputs/codegen/unroll8.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll8.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,5 @@ +# Check that options are adjusted by shifted stride detection +domain: "{ A[i,j] : 0 <= i < 100 and 0 <= j < 2; B[i,j] : 0 <= i < 100 and 0 <= j < 2 }" +child: + schedule: "[{ A[i,j] -> [2i]; B[i,j] -> [2i+1] }, { A[i,j] -> [j]; B[i,j] -> [j]}]" + options: "{ unroll[1] }" diff -Nru isl-0.12.2/test_inputs/codegen/unroll9.c isl-0.15/test_inputs/codegen/unroll9.c --- isl-0.12.2/test_inputs/codegen/unroll9.c 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll9.c 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +for (int c0 = 0; c0 <= 99; c0 += 1) + for (int c1 = 0; c1 <= 99; c1 += 1) { + A(c1, 0, c0); + A(c1, 1, c0); + B(c1, 0, c0); + B(c1, 1, c0); + } diff -Nru isl-0.12.2/test_inputs/codegen/unroll9.st isl-0.15/test_inputs/codegen/unroll9.st --- isl-0.12.2/test_inputs/codegen/unroll9.st 1970-01-01 00:00:00.000000000 +0000 +++ isl-0.15/test_inputs/codegen/unroll9.st 2015-06-02 09:28:10.000000000 +0000 @@ -0,0 +1,7 @@ +# Check that options are interpreted locally +domain: "{ A[i,j,k] : 0 <= i,k < 100 and 0 <= j < 2; B[i,j,k] : 0 <= i,k < 100 and 0 <= j < 2 }" +child: + schedule: "[{ A[i,j,k] -> [k]; B[i,j,k] -> [k] }]" + child: + schedule: "[{ A[i,j,k] -> [2i]; B[i,j,k] -> [2i+1] }, { A[i,j,k] -> [j]; B[i,j,k] -> [j]}]" + options: "{ unroll[1] }"