summaryrefslogtreecommitdiffstats
path: root/polly/lib/External
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2016-01-15 15:54:45 +0000
committerMichael Kruse <llvm@meinersbur.de>2016-01-15 15:54:45 +0000
commit959a8dc39f36150072c4b4551af5d01c37cc126b (patch)
tree86759e68c4a481d87f1a303d4fedd3e6738d139d /polly/lib/External
parentf29dfd36bbf2dd234b3c038448b6fd75beb8ade7 (diff)
downloadbcm5719-llvm-959a8dc39f36150072c4b4551af5d01c37cc126b.tar.gz
bcm5719-llvm-959a8dc39f36150072c4b4551af5d01c37cc126b.zip
Update to ISL 0.16.1
llvm-svn: 257898
Diffstat (limited to 'polly/lib/External')
-rw-r--r--polly/lib/External/isl/AUTHORS3
-rw-r--r--polly/lib/External/isl/ChangeLog14
-rw-r--r--polly/lib/External/isl/GIT_HEAD_ID2
-rw-r--r--polly/lib/External/isl/Makefile.am1
-rw-r--r--polly/lib/External/isl/Makefile.in5
-rwxr-xr-xpolly/lib/External/isl/configure37
-rw-r--r--polly/lib/External/isl/configure.ac8
-rw-r--r--polly/lib/External/isl/doc/manual.pdfbin491429 -> 495859 bytes
-rw-r--r--polly/lib/External/isl/doc/user.pod154
-rw-r--r--polly/lib/External/isl/include/isl/aff.h54
-rw-r--r--polly/lib/External/isl/include/isl/aff_type.h20
-rw-r--r--polly/lib/External/isl/include/isl/ctx.h5
-rw-r--r--polly/lib/External/isl/include/isl/flow.h30
-rw-r--r--polly/lib/External/isl/include/isl/map.h6
-rw-r--r--polly/lib/External/isl/include/isl/multi.h4
-rw-r--r--polly/lib/External/isl/include/isl/point.h2
-rw-r--r--polly/lib/External/isl/include/isl/polynomial.h2
-rw-r--r--polly/lib/External/isl/include/isl/schedule.h7
-rw-r--r--polly/lib/External/isl/include/isl/schedule_node.h14
-rw-r--r--polly/lib/External/isl/include/isl/schedule_type.h4
-rw-r--r--polly/lib/External/isl/include/isl/set.h2
-rw-r--r--polly/lib/External/isl/include/isl/space.h3
-rw-r--r--polly/lib/External/isl/include/isl/union_map.h24
-rw-r--r--polly/lib/External/isl/include/isl/union_set.h9
-rw-r--r--polly/lib/External/isl/include/isl/val.h12
-rw-r--r--polly/lib/External/isl/interface/all.h5
-rw-r--r--polly/lib/External/isl/isl_aff.c238
-rw-r--r--polly/lib/External/isl/isl_affine_hull.c3
-rw-r--r--polly/lib/External/isl/isl_ast_codegen.c103
-rw-r--r--polly/lib/External/isl/isl_coalesce.c6
-rw-r--r--polly/lib/External/isl/isl_config.h.in3
-rw-r--r--polly/lib/External/isl/isl_convex_hull.c170
-rw-r--r--polly/lib/External/isl/isl_flow.c251
-rw-r--r--polly/lib/External/isl/isl_input.c193
-rw-r--r--polly/lib/External/isl/isl_local_space.c10
-rw-r--r--polly/lib/External/isl/isl_local_space_private.h2
-rw-r--r--polly/lib/External/isl/isl_map.c510
-rw-r--r--polly/lib/External/isl/isl_map_private.h21
-rw-r--r--polly/lib/External/isl/isl_map_simplify.c380
-rw-r--r--polly/lib/External/isl/isl_mat.c2
-rw-r--r--polly/lib/External/isl/isl_morph.c2
-rw-r--r--polly/lib/External/isl/isl_multi_templ.c2
-rw-r--r--polly/lib/External/isl/isl_output.c493
-rw-r--r--polly/lib/External/isl/isl_output_private.h27
-rw-r--r--polly/lib/External/isl/isl_point.c53
-rw-r--r--polly/lib/External/isl/isl_printer.c14
-rw-r--r--polly/lib/External/isl/isl_printer_private.h11
-rw-r--r--polly/lib/External/isl/isl_schedule.c20
-rw-r--r--polly/lib/External/isl/isl_schedule_node.c152
-rw-r--r--polly/lib/External/isl/isl_schedule_node_private.h4
-rw-r--r--polly/lib/External/isl/isl_scheduler.c465
-rw-r--r--polly/lib/External/isl/isl_space.c39
-rw-r--r--polly/lib/External/isl/isl_tab.c3
-rw-r--r--polly/lib/External/isl/isl_test.c409
-rw-r--r--polly/lib/External/isl/isl_transitive_closure.c2
-rw-r--r--polly/lib/External/isl/isl_union_map.c59
-rw-r--r--polly/lib/External/isl/isl_union_templ.c10
-rw-r--r--polly/lib/External/isl/print_templ.c3
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/cloog/dealII.c26
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/cloog/faber.c21
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/cloog/jacobi-shared.c2
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c4
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/isolate7.c4
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/omega/dagstuhl1-1.c2
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/omega/lefur03-0.c2
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/omega/lefur04-0.c8
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/omega/p.delft2-0.c4
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/omega/ts1d-check0-0.c2
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.c2
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/redundant.c31
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/separate2.c17
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/separation_class2.c4
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/unroll3.c2
-rw-r--r--polly/lib/External/isl/test_inputs/codegen/unroll4.c14
74 files changed, 3313 insertions, 919 deletions
diff --git a/polly/lib/External/isl/AUTHORS b/polly/lib/External/isl/AUTHORS
index a6afd5a1c70..671a2413014 100644
--- a/polly/lib/External/isl/AUTHORS
+++ b/polly/lib/External/isl/AUTHORS
@@ -19,10 +19,11 @@ isl was written by
2012-2014 Ecole Normale Superieure
45 rue d'Ulm, 75230 Paris
France
-2014 INRIA Rocquencourt
+2014-2015 INRIA Rocquencourt
Domaine de Voluceau - Rocquencourt, B.P. 105
78153 Le Chesnay
France
+2015 Polly Labs
Contributions by
diff --git a/polly/lib/External/isl/ChangeLog b/polly/lib/External/isl/ChangeLog
index 828bbe38c0d..7acd66eeac2 100644
--- a/polly/lib/External/isl/ChangeLog
+++ b/polly/lib/External/isl/ChangeLog
@@ -1,3 +1,17 @@
+version: 0.16.1
+date: Thu Jan 14 18:08:06 CET 2016
+changes:
+ - fix bug in simplification
+---
+version: 0.16
+date: Tue Jan 12 09:56:16 CET 2016
+changes:
+ - add 32 bit integer optimization for IMath
+ - minor AST generator improvements
+ - add isl_union_flow_get_full_{may,must}_dependence
+ - minor improvements to Python bindings
+ - minor improvements to set and map printing
+---
version: 0.15
date: Thu Jun 11 12:45:33 CEST 2015
changes:
diff --git a/polly/lib/External/isl/GIT_HEAD_ID b/polly/lib/External/isl/GIT_HEAD_ID
index 2e88dbf0b47..faede1aa4d7 100644
--- a/polly/lib/External/isl/GIT_HEAD_ID
+++ b/polly/lib/External/isl/GIT_HEAD_ID
@@ -1 +1 @@
-isl-0.15-142-gf101714
+isl-0.16.1
diff --git a/polly/lib/External/isl/Makefile.am b/polly/lib/External/isl/Makefile.am
index 63047abced2..887d2c2ff54 100644
--- a/polly/lib/External/isl/Makefile.am
+++ b/polly/lib/External/isl/Makefile.am
@@ -133,6 +133,7 @@ libisl_la_SOURCES = \
isl_options.c \
isl_options_private.h \
isl_output.c \
+ isl_output_private.h \
isl_point_private.h \
isl_point.c \
isl_polynomial_private.h \
diff --git a/polly/lib/External/isl/Makefile.in b/polly/lib/External/isl/Makefile.in
index 2f6a9048e98..ff6125f5eed 100644
--- a/polly/lib/External/isl/Makefile.in
+++ b/polly/lib/External/isl/Makefile.in
@@ -193,8 +193,8 @@ am__libisl_la_SOURCES_DIST = mp_get_memory_functions.c isl_int_gmp.h \
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_output.c isl_output_private.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 \
@@ -888,6 +888,7 @@ libisl_la_SOURCES = \
isl_options.c \
isl_options_private.h \
isl_output.c \
+ isl_output_private.h \
isl_point_private.h \
isl_point.c \
isl_polynomial_private.h \
diff --git a/polly/lib/External/isl/configure b/polly/lib/External/isl/configure
index 90bdc4b334d..80ee8882609 100755
--- a/polly/lib/External/isl/configure
+++ b/polly/lib/External/isl/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for isl 0.15.
+# Generated by GNU Autoconf 2.69 for isl 0.16.1.
#
# Report bugs to <isl-development@googlegroups.com>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='isl'
PACKAGE_TARNAME='isl'
-PACKAGE_VERSION='0.15'
-PACKAGE_STRING='isl 0.15'
+PACKAGE_VERSION='0.16.1'
+PACKAGE_STRING='isl 0.16.1'
PACKAGE_BUGREPORT='isl-development@googlegroups.com'
PACKAGE_URL=''
@@ -1361,7 +1361,7 @@ if test "$ac_init_help" = "long"; then
# 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.15 to adapt to many kinds of systems.
+\`configure' configures isl 0.16.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1431,7 +1431,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of isl 0.15:";;
+ short | recursive ) echo "Configuration of isl 0.16.1:";;
esac
cat <<\_ACEOF
@@ -1556,7 +1556,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-isl configure 0.15
+isl configure 0.16.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2420,7 +2420,7 @@ cat >config.log <<_ACEOF
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.15, which was
+It was created by isl $as_me 0.16.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3284,7 +3284,7 @@ fi
# Define the identity of the package.
PACKAGE='isl'
- VERSION='0.15'
+ VERSION='0.16.1'
cat >>confdefs.h <<_ACEOF
@@ -3417,7 +3417,7 @@ fi
AM_BACKSLASH='\'
-versioninfo=15:0:0
+versioninfo=16:1:1
if test "x$prefix" != "xNONE"; then
prefix_wd=`cd $prefix && pwd`
@@ -18228,6 +18228,21 @@ $as_echo "#define HAVE_ADT_OWNINGPTR_H /**/" >>confdefs.h
fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <clang/Basic/Builtins.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "initializeBuiltins" >/dev/null 2>&1; then :
+
+else
+
+$as_echo "#define initializeBuiltins InitializeBuiltins" >>confdefs.h
+
+fi
+rm -f conftest*
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -19131,7 +19146,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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.15, which was
+This file was extended by isl $as_me 0.16.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -19197,7 +19212,7 @@ _ACEOF
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.15
+isl config.status 0.16.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/polly/lib/External/isl/configure.ac b/polly/lib/External/isl/configure.ac
index c016f6578f3..4de92066abc 100644
--- a/polly/lib/External/isl/configure.ac
+++ b/polly/lib/External/isl/configure.ac
@@ -1,10 +1,10 @@
-AC_INIT([isl], [0.15], [isl-development@googlegroups.com])
+AC_INIT([isl], [0.16.1], [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=15:0:0
+versioninfo=16:1:1
if test "x$prefix" != "xNONE"; then
prefix_wd=`cd $prefix && pwd`
@@ -227,6 +227,10 @@ system)
AC_CHECK_HEADER([llvm/ADT/OwningPtr.h],
[AC_DEFINE([HAVE_ADT_OWNINGPTR_H], [],
[Define if llvm/ADT/OwningPtr.h exists])])
+ AC_EGREP_HEADER([initializeBuiltins],
+ [clang/Basic/Builtins.h], [],
+ [AC_DEFINE([initializeBuiltins], [InitializeBuiltins],
+ [Define to InitializeBuiltins for older versions of clang])])
AC_LANG_POP
CPPFLAGS="$SAVE_CPPFLAGS"
diff --git a/polly/lib/External/isl/doc/manual.pdf b/polly/lib/External/isl/doc/manual.pdf
index 8a01f42b19a..5ef653503bb 100644
--- a/polly/lib/External/isl/doc/manual.pdf
+++ b/polly/lib/External/isl/doc/manual.pdf
Binary files differ
diff --git a/polly/lib/External/isl/doc/user.pod b/polly/lib/External/isl/doc/user.pod
index d6475e4eaad..a78ee9d7d01 100644
--- a/polly/lib/External/isl/doc/user.pod
+++ b/polly/lib/External/isl/doc/user.pod
@@ -988,6 +988,9 @@ of the original object.
__isl_keep isl_qpolynomial *qp);
__isl_give isl_space *isl_qpolynomial_get_space(
__isl_keep isl_qpolynomial *qp);
+ __isl_give isl_space *
+ isl_qpolynomial_fold_get_domain_space(
+ __isl_keep isl_qpolynomial_fold *fold);
__isl_give isl_space *isl_qpolynomial_fold_get_space(
__isl_keep isl_qpolynomial_fold *fold);
__isl_give isl_space *isl_pw_qpolynomial_get_domain_space(
@@ -2128,6 +2131,11 @@ To iterate over all the sets or maps in a union set or map, use
isl_stat (*fn)(__isl_take isl_map *map, void *user),
void *user);
+These functions call the callback function once for each
+(pair of) space(s) for which there are elements in the input.
+The argument to the callback contains all elements in the input
+with that (pair of) space(s).
+
The number of sets or maps in a union set or map can be obtained
from
@@ -2329,6 +2337,8 @@ A singleton set can be created from a point using
__isl_take isl_point *pnt);
__isl_give isl_set *isl_set_from_point(
__isl_take isl_point *pnt);
+ __isl_give isl_union_set *isl_union_set_from_point(
+ __isl_take isl_point *pnt);
and a box can be created from two opposite extremal points using
@@ -2361,12 +2371,14 @@ enumerating and return C<-1> as well.
If the enumeration is performed successfully and to completion,
then C<isl_set_foreach_point> returns C<0>.
-To obtain a single point of a (basic) set, use
+To obtain a single point of a (basic or union) set, use
__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);
+ __isl_give isl_point *isl_union_set_sample_point(
+ __isl_take isl_union_set *uset);
If C<set> does not contain any (integer) points, then the
resulting point will be ``void'', a property that can be
@@ -2728,6 +2740,10 @@ then this space also needs to be a set space.
__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_pw_aff *
+ isl_multi_pw_aff_from_pw_aff_list(
+ __isl_take isl_space *space,
+ __isl_take isl_pw_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,
@@ -3406,6 +3422,9 @@ Objects can be read from input using the following functions.
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_aff *
+ isl_union_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);
@@ -3889,18 +3908,39 @@ i.e., whether both domain and range are nested relations.
=item * Currying
+ #include <isl/space.h>
+ isl_bool isl_space_can_curry(
+ __isl_keep isl_space *space);
+
+ #include <isl/map.h>
isl_bool isl_basic_map_can_curry(
__isl_keep isl_basic_map *bmap);
isl_bool isl_map_can_curry(__isl_keep isl_map *map);
Check whether the domain of the (basic) relation is a wrapped relation.
+ #include <isl/space.h>
+ __isl_give isl_space *isl_space_uncurry(
+ __isl_take isl_space *space);
+
+ #include <isl/map.h>
isl_bool isl_basic_map_can_uncurry(
__isl_keep isl_basic_map *bmap);
isl_bool isl_map_can_uncurry(__isl_keep isl_map *map);
Check whether the range of the (basic) relation is a wrapped relation.
+ #include <isl/space.h>
+ isl_bool isl_space_can_range_curry(
+ __isl_keep isl_space *space);
+
+ #include <isl/map.h>
+ isl_bool isl_map_can_range_curry(
+ __isl_keep isl_map *map);
+
+Check whether the domain of the relation wrapped in the range of
+the input is itself a wrapped relation.
+
=item * Special Values
#include <isl/aff.h>
@@ -4332,10 +4372,11 @@ on a given parameter domain using the following functions.
__isl_give isl_set *isl_set_from_params(
__isl_take isl_set *set);
-=item * Constructing a relation from a set
+=item * Constructing a relation from one or two sets
-Create a relation with the given set as domain or range.
-The range or domain of the created relation is a zero-dimensional
+Create a relation with the given set(s) as domain and/or range.
+If only the domain or the range is specified, then
+the range or domain of the created relation is a zero-dimensional
flat anonymous space.
#include <isl/space.h>
@@ -4359,6 +4400,12 @@ flat anonymous space.
__isl_give isl_map *isl_map_from_range(
__isl_take isl_set *set);
+ #include <isl/union_map.h>
+ __isl_give isl_union_map *
+ isl_union_map_from_domain_and_range(
+ __isl_take isl_union_set *domain,
+ __isl_take isl_union_set *range);
+
#include <isl/val.h>
__isl_give isl_multi_val *isl_multi_val_from_range(
__isl_take isl_multi_val *mv);
@@ -4818,6 +4865,11 @@ per space.
__isl_take isl_basic_map *bmap,
enum isl_dim_type type,
unsigned first, unsigned n);
+ __isl_give isl_basic_map *
+ isl_basic_map_drop_constraints_not_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,
@@ -5146,6 +5198,21 @@ 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<uncurry> functions perform the inverse operation.
+ #include <isl/space.h>
+ __isl_give isl_space *isl_space_range_curry(
+ __isl_take isl_space *space);
+
+ #include <isl/map.h>
+ __isl_give isl_map *isl_map_range_curry(
+ __isl_take isl_map *map);
+
+ #include <isl/union_map.h>
+ __isl_give isl_union_map *isl_union_map_range_curry(
+ __isl_take isl_union_map *umap);
+
+These functions apply the currying to the relation that
+is nested inside the range of the input.
+
=item * Aligning parameters
Change the order of the parameters of the given set, relation
@@ -6322,6 +6389,9 @@ from the result using the following functions.
isl_union_map_domain_factor_range(
__isl_take isl_union_map *umap);
__isl_give isl_union_map *
+ isl_union_map_range_factor_domain(
+ __isl_take isl_union_map *umap);
+ __isl_give isl_union_map *
isl_union_map_range_factor_range(
__isl_take isl_union_map *umap);
@@ -7677,6 +7747,10 @@ 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);
+ __isl_give char *isl_schedule_to_str(
+ __isl_keep isl_schedule *schedule);
+
+C<isl_schedule_to_str> prints the schedule in flow format.
The schedule tree can be traversed through the use of
C<isl_schedule_node> objects that point to a particular
@@ -8183,6 +8257,20 @@ 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 following function can be used to flatten a nested
+sequence.
+
+ #include <isl/schedule_node.h>
+ __isl_give isl_schedule_node *
+ isl_schedule_node_sequence_splice_child(
+ __isl_take isl_schedule_node *node, int pos);
+
+That is, given a sequence node C<node> that has another sequence node
+in its child at position C<pos> (in particular, the child of that filter
+node is a sequence node), attach the children of that other sequence
+node as children of C<node>, replacing the original child at position
+C<pos>.
+
The partial schedule of a band node can be scaled (down) or reduced using
the following functions.
@@ -8265,14 +8353,20 @@ position as the node pointed to by C<node> in the original tree.
#include <isl/schedule_node.h>
__isl_give isl_schedule_node *
+ isl_schedule_node_order_before(
+ __isl_take isl_schedule_node *node,
+ __isl_take isl_union_set *filter);
+ __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<node>
+These functions split the domain elements that reach C<node>
into those that satisfy C<filter> 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
+executed before (in case of C<isl_schedule_node_order_before>)
+or after (in case of C<isl_schedule_node_order_after>)
+those that do not. The order is imposed by
a sequence node, possibly reusing the grandparent of C<node>
on two copies of the subtree attached to the original C<node>.
Both copies are simplified with respect to their filter.
@@ -8325,6 +8419,10 @@ A representation of the schedule node can be printed using
__isl_give isl_printer *isl_printer_print_schedule_node(
__isl_take isl_printer *p,
__isl_keep isl_schedule_node *node);
+ __isl_give char *isl_schedule_node_to_str(
+ __isl_keep isl_schedule_node *node);
+
+C<isl_schedule_node_to_str> prints the schedule node in block format.
=head2 Dependence Analysis
@@ -8337,7 +8435,8 @@ of which of the source access relations was the last
to access the same data element before the given iteration
of the sink access.
The resulting dependence relations map source iterations
-to the corresponding sink iterations.
+to either the corresponding sink iterations or
+pairs of corresponding sink iterations and accessed data elements.
To compute standard flow dependences, the sink should be
a read, while the sources should be writes.
If any of the source accesses are marked as being I<may>
@@ -8410,6 +8509,19 @@ 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.
+A representation of the information contained in an object
+of type C<isl_union_access_info> can be obtained using
+
+ #include <isl/flow.h>
+ __isl_give isl_printer *
+ isl_printer_print_union_access_info(
+ __isl_take isl_printer *p,
+ __isl_keep isl_union_access_info *access);
+ __isl_give char *isl_union_access_info_to_str(
+ __isl_keep isl_union_access_info *access);
+
+C<isl_union_access_info_to_str> prints the information in flow format.
+
The output of C<isl_union_access_info_compute_flow> can be examined
and freed using the following functions.
@@ -8418,6 +8530,12 @@ and freed using the following functions.
__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_full_must_dependence(
+ __isl_keep isl_union_flow *flow);
+ __isl_give isl_union_map *
+ isl_union_flow_get_full_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(
@@ -8430,6 +8548,13 @@ relates domain elements of must sources to domain elements of the sink.
The relation returned by C<isl_union_flow_get_may_dependence>
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<isl_union_flow_get_full_must_dependence>
+relates domain elements of must sources to pairs of domain elements of the sink
+and accessed data elements.
+The relation returned by C<isl_union_flow_get_full_may_dependence>
+relates domain elements of must or may sources to pairs of
+domain elements of the sink and accessed data elements.
+This relation includes the previous relation as a subset.
The relation returned by C<isl_union_flow_get_must_no_source> is the subset
of the sink relation for which no dependences have been found.
The relation returned by C<isl_union_flow_get_may_no_source> is the subset
@@ -8438,6 +8563,18 @@ That is, it contains those sink access that do not contribute to any
of the elements in the relation returned
by C<isl_union_flow_get_must_dependence>.
+A representation of the information contained in an object
+of type C<isl_union_flow> can be obtained using
+
+ #include <isl/flow.h>
+ __isl_give isl_printer *isl_printer_print_union_flow(
+ __isl_take isl_printer *p,
+ __isl_keep isl_union_flow *flow);
+ __isl_give char *isl_union_flow_to_str(
+ __isl_keep isl_union_flow *flow);
+
+C<isl_union_flow_to_str> prints the information in flow format.
+
=head3 Low-level Interface
A lower-level interface is provided by the following functions.
@@ -8729,6 +8866,9 @@ An C<isl_schedule_constraints> object can be inspected
using the following functions.
#include <isl/schedule.h>
+ __isl_give isl_union_set *
+ isl_schedule_constraints_get_domain(
+ __isl_keep isl_schedule_constraints *sc);
__isl_give isl_union_map *
isl_schedule_constraints_get_validity(
__isl_keep isl_schedule_constraints *sc);
diff --git a/polly/lib/External/isl/include/isl/aff.h b/polly/lib/External/isl/include/isl/aff.h
index 432014da152..8c54c9cdcf4 100644
--- a/polly/lib/External/isl/include/isl/aff.h
+++ b/polly/lib/External/isl/include/isl/aff.h
@@ -89,6 +89,7 @@ __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_export
__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
__isl_take isl_aff *aff2);
__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
@@ -121,6 +122,7 @@ __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
__isl_take isl_aff *aff2);
+__isl_overload
__isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
__isl_take isl_multi_aff *ma);
@@ -132,6 +134,7 @@ __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
__isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
__isl_take isl_aff *aff2);
+__isl_constructor
__isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str);
__isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
__isl_keep isl_aff *aff);
@@ -141,6 +144,7 @@ isl_ctx *isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pwaff);
__isl_give isl_space *isl_pw_aff_get_domain_space(__isl_keep isl_pw_aff *pwaff);
__isl_give isl_space *isl_pw_aff_get_space(__isl_keep isl_pw_aff *pwaff);
+__isl_constructor
__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff);
__isl_give isl_pw_aff *isl_pw_aff_empty(__isl_take isl_space *dim);
__isl_give isl_pw_aff *isl_pw_aff_alloc(__isl_take isl_set *set,
@@ -179,6 +183,7 @@ __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_export
__isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
__isl_take isl_pw_aff *pwaff2);
@@ -216,6 +221,7 @@ __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_export
__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_sub(__isl_take isl_pw_aff *pwaff1,
@@ -261,10 +267,13 @@ __isl_give isl_pw_aff *isl_pw_aff_gist(__isl_take isl_pw_aff *pwaff,
__isl_give isl_pw_aff *isl_pw_aff_gist_params(__isl_take isl_pw_aff *pwaff,
__isl_take isl_set *context);
+__isl_overload
__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_aff(
__isl_take isl_pw_aff *pa, __isl_take isl_multi_aff *ma);
+__isl_overload
__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_overload
__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);
@@ -301,6 +310,7 @@ __isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
__isl_take isl_pw_aff *pa2);
+__isl_constructor
__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);
@@ -327,6 +337,7 @@ ISL_DECLARE_MULTI_NEG(aff)
ISL_DECLARE_MULTI_DIMS(aff)
ISL_DECLARE_MULTI_WITH_DOMAIN(aff)
+__isl_constructor
__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);
@@ -340,9 +351,6 @@ __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
__isl_give isl_multi_aff *isl_multi_aff_floor(__isl_take isl_multi_aff *ma);
-__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_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,
@@ -351,6 +359,7 @@ __isl_give isl_multi_aff *isl_multi_aff_gist(__isl_take isl_multi_aff *maff,
__isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
__isl_give isl_local_space **ls);
+__isl_overload
__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2);
@@ -367,6 +376,7 @@ __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);
+__isl_constructor
__isl_give isl_multi_aff *isl_multi_aff_read_from_str(isl_ctx *ctx,
const char *str);
void isl_multi_aff_dump(__isl_keep isl_multi_aff *maff);
@@ -384,8 +394,10 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
__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_constructor
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff(
__isl_take isl_multi_aff *ma);
+__isl_constructor
__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,
@@ -456,12 +468,14 @@ __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_export
__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_export
__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(
@@ -484,10 +498,13 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
__isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
__isl_take isl_multi_aff *ma);
+__isl_export
__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_export
__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_export
__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);
@@ -511,8 +528,10 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist_params(
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist(
__isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set);
+__isl_overload
__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_overload
__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);
@@ -529,6 +548,7 @@ __isl_give isl_printer *isl_printer_print_pw_multi_aff(__isl_take isl_printer *p
__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);
+__isl_constructor
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str(isl_ctx *ctx,
const char *str);
void isl_pw_multi_aff_dump(__isl_keep isl_pw_multi_aff *pma);
@@ -538,6 +558,7 @@ __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_constructor
__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(
@@ -588,6 +609,7 @@ __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_overload
__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,
@@ -616,9 +638,11 @@ __isl_give isl_union_set *isl_union_pw_multi_aff_domain(
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_neg(
__isl_take isl_union_pw_multi_aff *upma);
+__isl_export
__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_export
__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);
@@ -633,6 +657,7 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_down_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);
+__isl_export
__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);
@@ -646,6 +671,7 @@ __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_overload
__isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
__isl_take isl_union_pw_multi_aff *upma);
@@ -657,6 +683,7 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
__isl_take isl_union_map *umap);
+__isl_constructor
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_read_from_str(
isl_ctx *ctx, const char *str);
void isl_union_pw_multi_aff_dump(__isl_keep isl_union_pw_multi_aff *upma);
@@ -665,8 +692,10 @@ __isl_give char *isl_union_pw_multi_aff_to_str(
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity(
__isl_take isl_space *space);
+__isl_constructor
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
__isl_take isl_multi_aff *ma);
+__isl_constructor
__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);
@@ -685,10 +714,13 @@ __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist_params(
isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
__isl_keep isl_multi_pw_aff *mpa2);
+__isl_overload
__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_overload
__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_overload
__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);
@@ -701,6 +733,7 @@ __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_constructor
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
__isl_take isl_pw_multi_aff *pma);
@@ -711,6 +744,7 @@ __isl_give isl_map *isl_multi_pw_aff_lex_lt_map(
__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_constructor
__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(
@@ -743,6 +777,7 @@ __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user(
__isl_give isl_union_pw_aff *isl_union_pw_aff_empty(
__isl_take isl_space *space);
+__isl_constructor
__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(
@@ -752,6 +787,7 @@ __isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
__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_constructor
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
__isl_take isl_union_pw_aff *upa);
@@ -771,8 +807,10 @@ __isl_give isl_union_set *isl_union_pw_aff_domain(
__isl_give isl_union_pw_aff *isl_union_pw_aff_neg(
__isl_take isl_union_pw_aff *upa);
+__isl_export
__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_export
__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(
@@ -785,6 +823,7 @@ __isl_give isl_union_pw_aff *isl_union_pw_aff_gist(
__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_overload
__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);
@@ -819,6 +858,9 @@ __isl_give isl_union_set *isl_union_pw_aff_zero_union_set(
__isl_give isl_union_map *isl_union_map_from_union_pw_aff(
__isl_take isl_union_pw_aff *upa);
+__isl_constructor
+__isl_give isl_union_pw_aff *isl_union_pw_aff_read_from_str(isl_ctx *ctx,
+ const char *str);
__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);
@@ -828,8 +870,10 @@ 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_constructor
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_pw_aff(
__isl_take isl_union_pw_aff *upa);
+__isl_constructor
__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(
@@ -869,6 +913,7 @@ __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_overload
__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,
@@ -878,6 +923,7 @@ __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_export
__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);
@@ -888,6 +934,7 @@ isl_multi_union_pw_aff_from_union_pw_multi_aff(
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
__isl_take isl_union_map *umap);
+__isl_overload
__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
__isl_take isl_multi_union_pw_aff *mupa);
@@ -897,6 +944,7 @@ __isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set(
__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_constructor
__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(
diff --git a/polly/lib/External/isl/include/isl/aff_type.h b/polly/lib/External/isl/include/isl/aff_type.h
index 12daf9431e0..9a618d681df 100644
--- a/polly/lib/External/isl/include/isl/aff_type.h
+++ b/polly/lib/External/isl/include/isl/aff_type.h
@@ -7,36 +7,40 @@
extern "C" {
#endif
-struct isl_aff;
+struct __isl_subclass(isl_multi_aff) __isl_subclass(isl_pw_aff) isl_aff;
typedef struct isl_aff isl_aff;
ISL_DECLARE_LIST(aff)
-struct isl_pw_aff;
+struct __isl_subclass(isl_pw_multi_aff) __isl_subclass(isl_multi_pw_aff)
+ __isl_subclass(isl_union_pw_aff) isl_pw_aff;
typedef struct isl_pw_aff isl_pw_aff;
ISL_DECLARE_LIST(pw_aff)
-struct isl_union_pw_aff;
+struct __isl_subclass(isl_multi_union_pw_aff)
+ __isl_subclass(isl_union_pw_multi_aff) 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;
+struct __isl_subclass(isl_pw_multi_aff) __isl_subclass(isl_multi_pw_aff)
+ isl_multi_aff;
typedef struct isl_multi_aff isl_multi_aff;
-struct isl_pw_multi_aff;
+struct __isl_subclass(isl_union_pw_multi_aff) __isl_subclass(isl_multi_pw_aff)
+ isl_pw_multi_aff;
typedef struct isl_pw_multi_aff isl_pw_multi_aff;
-struct isl_union_pw_multi_aff;
+struct __isl_export 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;
+struct __isl_subclass(isl_multi_union_pw_aff) isl_multi_pw_aff;
typedef struct isl_multi_pw_aff isl_multi_pw_aff;
-struct isl_multi_union_pw_aff;
+struct __isl_export isl_multi_union_pw_aff;
typedef struct isl_multi_union_pw_aff isl_multi_union_pw_aff;
#if defined(__cplusplus)
diff --git a/polly/lib/External/isl/include/isl/ctx.h b/polly/lib/External/isl/include/isl/ctx.h
index 6cd26a1bcbd..bd1f00fdaeb 100644
--- a/polly/lib/External/isl/include/isl/ctx.h
+++ b/polly/lib/External/isl/include/isl/ctx.h
@@ -30,6 +30,9 @@
#ifndef __isl_export
#define __isl_export
#endif
+#ifndef __isl_overload
+#define __isl_overload
+#endif
#ifndef __isl_constructor
#define __isl_constructor
#endif
@@ -80,7 +83,7 @@ enum isl_error {
};
typedef enum {
isl_stat_error = -1,
- isl_stat_ok = 0,
+ isl_stat_ok = 0
} isl_stat;
typedef enum {
isl_bool_error = -1,
diff --git a/polly/lib/External/isl/include/isl/flow.h b/polly/lib/External/isl/include/isl/flow.h
index 0b985667c4b..388d7919bed 100644
--- a/polly/lib/External/isl/include/isl/flow.h
+++ b/polly/lib/External/isl/include/isl/flow.h
@@ -6,6 +6,7 @@
#include <isl/union_set_type.h>
#include <isl/union_map_type.h>
#include <isl/schedule.h>
+#include <isl/printer.h>
#if defined(__cplusplus)
extern "C" {
@@ -64,22 +65,27 @@ 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;
+struct __isl_export isl_union_access_info;
typedef struct isl_union_access_info isl_union_access_info;
-struct isl_union_flow;
+struct __isl_export isl_union_flow;
typedef struct isl_union_flow isl_union_flow;
+__isl_constructor
__isl_give isl_union_access_info *isl_union_access_info_from_sink(
__isl_take isl_union_map *sink);
+__isl_export
__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_export
__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_export
__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_export
__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);
@@ -91,20 +97,40 @@ __isl_null isl_union_access_info *isl_union_access_info_free(
isl_ctx *isl_union_access_info_get_ctx(
__isl_keep isl_union_access_info *access);
+__isl_give isl_printer *isl_printer_print_union_access_info(
+ __isl_take isl_printer *p, __isl_keep isl_union_access_info *access);
+__isl_give char *isl_union_access_info_to_str(
+ __isl_keep isl_union_access_info *access);
+
+__isl_export
__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_export
__isl_give isl_union_map *isl_union_flow_get_must_dependence(
__isl_keep isl_union_flow *flow);
+__isl_export
__isl_give isl_union_map *isl_union_flow_get_may_dependence(
__isl_keep isl_union_flow *flow);
+__isl_export
+__isl_give isl_union_map *isl_union_flow_get_full_must_dependence(
+ __isl_keep isl_union_flow *flow);
+__isl_export
+__isl_give isl_union_map *isl_union_flow_get_full_may_dependence(
+ __isl_keep isl_union_flow *flow);
+__isl_export
__isl_give isl_union_map *isl_union_flow_get_must_no_source(
__isl_keep isl_union_flow *flow);
+__isl_export
__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);
+__isl_give isl_printer *isl_printer_print_union_flow(
+ __isl_take isl_printer *p, __isl_keep isl_union_flow *flow);
+__isl_give char *isl_union_flow_to_str(__isl_keep 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 --git a/polly/lib/External/isl/include/isl/map.h b/polly/lib/External/isl/include/isl/map.h
index 1624159e81b..619a9ce133f 100644
--- a/polly/lib/External/isl/include/isl/map.h
+++ b/polly/lib/External/isl/include/isl/map.h
@@ -552,6 +552,9 @@ 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);
+isl_bool isl_map_can_range_curry(__isl_keep isl_map *map);
+__isl_give isl_map *isl_map_range_curry(__isl_take 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);
@@ -565,6 +568,9 @@ __isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map);
__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_map *isl_basic_map_drop_constraints_not_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);
diff --git a/polly/lib/External/isl/include/isl/multi.h b/polly/lib/External/isl/include/isl/multi.h
index 8d598f7381a..612bafce3c9 100644
--- a/polly/lib/External/isl/include/isl/multi.h
+++ b/polly/lib/External/isl/include/isl/multi.h
@@ -73,9 +73,11 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_range_splice( \
__isl_take isl_multi_##BASE *multi2); \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_flatten_range( \
__isl_take isl_multi_##BASE *multi); \
+__isl_export \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_flat_range_product( \
__isl_take isl_multi_##BASE *multi1, \
__isl_take isl_multi_##BASE *multi2); \
+__isl_export \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_product( \
__isl_take isl_multi_##BASE *multi1, \
__isl_take isl_multi_##BASE *multi2); \
@@ -100,6 +102,7 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_multi_val( \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_mod_multi_val( \
__isl_take isl_multi_##BASE *multi, \
__isl_take isl_multi_val *mv); \
+__isl_export \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_add( \
__isl_take isl_multi_##BASE *multi1, \
__isl_take isl_multi_##BASE *multi2); \
@@ -128,6 +131,7 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_add_dims( \
unsigned n);
#define ISL_DECLARE_MULTI_WITH_DOMAIN(BASE) \
+__isl_export \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_product( \
__isl_take isl_multi_##BASE *multi1, \
__isl_take isl_multi_##BASE *multi2); \
diff --git a/polly/lib/External/isl/include/isl/point.h b/polly/lib/External/isl/include/isl/point.h
index ae295d3bd81..53970d3a520 100644
--- a/polly/lib/External/isl/include/isl/point.h
+++ b/polly/lib/External/isl/include/isl/point.h
@@ -9,7 +9,7 @@
extern "C" {
#endif
-struct isl_point;
+struct __isl_subclass(isl_basic_set) isl_point;
typedef struct isl_point isl_point;
isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt);
diff --git a/polly/lib/External/isl/include/isl/polynomial.h b/polly/lib/External/isl/include/isl/polynomial.h
index 23fb2395e36..5a242950ece 100644
--- a/polly/lib/External/isl/include/isl/polynomial.h
+++ b/polly/lib/External/isl/include/isl/polynomial.h
@@ -284,6 +284,8 @@ 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);
+__isl_give isl_space *isl_qpolynomial_fold_get_domain_space(
+ __isl_keep isl_qpolynomial_fold *fold);
__isl_give isl_space *isl_qpolynomial_fold_get_space(
__isl_keep isl_qpolynomial_fold *fold);
diff --git a/polly/lib/External/isl/include/isl/schedule.h b/polly/lib/External/isl/include/isl/schedule.h
index 4123288e34a..793f253c5b0 100644
--- a/polly/lib/External/isl/include/isl/schedule.h
+++ b/polly/lib/External/isl/include/isl/schedule.h
@@ -63,6 +63,8 @@ __isl_null isl_schedule_constraints *isl_schedule_constraints_free(
isl_ctx *isl_schedule_constraints_get_ctx(
__isl_keep isl_schedule_constraints *sc);
+__isl_give isl_union_set *isl_schedule_constraints_get_domain(
+ __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(
@@ -88,12 +90,14 @@ __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_export
__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_export
__isl_give isl_schedule_node *isl_schedule_get_root(
__isl_keep isl_schedule *schedule);
__isl_give isl_union_set *isl_schedule_get_domain(
@@ -128,6 +132,7 @@ __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_overload
__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff(
__isl_take isl_schedule *schedule,
__isl_take isl_union_pw_multi_aff *upma);
@@ -136,11 +141,13 @@ __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_constructor
__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);
+__isl_give char *isl_schedule_to_str(__isl_keep isl_schedule *schedule);
int isl_schedule_foreach_band(__isl_keep isl_schedule *sched,
int (*fn)(__isl_keep isl_band *band, void *user), void *user);
diff --git a/polly/lib/External/isl/include/isl/schedule_node.h b/polly/lib/External/isl/include/isl/schedule_node.h
index d0dbba90b76..0ddc81f3619 100644
--- a/polly/lib/External/isl/include/isl/schedule_node.h
+++ b/polly/lib/External/isl/include/isl/schedule_node.h
@@ -29,6 +29,7 @@ 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_export
__isl_give isl_schedule *isl_schedule_node_get_schedule(
__isl_keep isl_schedule_node *node);
@@ -64,10 +65,12 @@ __isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor(
__isl_give isl_schedule_node *isl_schedule_node_root(
__isl_take isl_schedule_node *node);
+__isl_export
__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_export
__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(
@@ -83,6 +86,9 @@ isl_bool isl_schedule_node_is_subtree_anchored(
__isl_give isl_schedule_node *isl_schedule_node_group(
__isl_take isl_schedule_node *node, __isl_take isl_id *group_id);
+__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child(
+ __isl_take isl_schedule_node *node, int pos);
+
__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(
@@ -105,8 +111,10 @@ __isl_give isl_union_set *isl_schedule_node_band_get_ast_build_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);
unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node);
+__isl_export
isl_bool isl_schedule_node_band_member_get_coincident(
__isl_keep isl_schedule_node *node, int pos);
+__isl_export
__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(
@@ -157,12 +165,15 @@ __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_export
__isl_give isl_multi_union_pw_aff *
isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(
__isl_keep isl_schedule_node *node);
+__isl_export
__isl_give isl_union_pw_multi_aff *
isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(
__isl_keep isl_schedule_node *node);
+__isl_export
__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(
@@ -197,6 +208,8 @@ __isl_give isl_schedule_node *isl_schedule_node_cut(
__isl_give isl_schedule_node *isl_schedule_node_delete(
__isl_take isl_schedule_node *node);
+__isl_give isl_schedule_node *isl_schedule_node_order_before(
+ __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter);
__isl_give isl_schedule_node *isl_schedule_node_order_after(
__isl_take isl_schedule_node *node, __isl_take isl_union_set *filter);
@@ -215,6 +228,7 @@ __isl_give isl_schedule_node *isl_schedule_node_align_params(
__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);
+__isl_give char *isl_schedule_node_to_str(__isl_keep isl_schedule_node *node);
#if defined(__cplusplus)
}
diff --git a/polly/lib/External/isl/include/isl/schedule_type.h b/polly/lib/External/isl/include/isl/schedule_type.h
index b1e63d61d88..f5a6d4cad91 100644
--- a/polly/lib/External/isl/include/isl/schedule_type.h
+++ b/polly/lib/External/isl/include/isl/schedule_type.h
@@ -20,10 +20,10 @@ enum isl_schedule_node_type {
isl_schedule_node_set
};
-struct isl_schedule_node;
+struct __isl_export isl_schedule_node;
typedef struct isl_schedule_node isl_schedule_node;
-struct isl_schedule;
+struct __isl_export isl_schedule;
typedef struct isl_schedule isl_schedule;
#if defined(__cplusplus)
diff --git a/polly/lib/External/isl/include/isl/set.h b/polly/lib/External/isl/include/isl/set.h
index 73077220f42..e855de13bc3 100644
--- a/polly/lib/External/isl/include/isl/set.h
+++ b/polly/lib/External/isl/include/isl/set.h
@@ -440,7 +440,9 @@ 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);
+__isl_constructor
__isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt);
+__isl_constructor
__isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt);
__isl_give isl_basic_set *isl_basic_set_box_from_points(
__isl_take isl_point *pnt1, __isl_take isl_point *pnt2);
diff --git a/polly/lib/External/isl/include/isl/space.h b/polly/lib/External/isl/include/isl/space.h
index fdcbff1d377..c03a99e774c 100644
--- a/polly/lib/External/isl/include/isl/space.h
+++ b/polly/lib/External/isl/include/isl/space.h
@@ -141,6 +141,9 @@ __isl_give isl_space *isl_space_zip(__isl_take isl_space *dim);
isl_bool isl_space_can_curry(__isl_keep isl_space *space);
__isl_give isl_space *isl_space_curry(__isl_take isl_space *space);
+isl_bool isl_space_can_range_curry(__isl_keep isl_space *space);
+__isl_give isl_space *isl_space_range_curry(__isl_take 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);
diff --git a/polly/lib/External/isl/include/isl/union_map.h b/polly/lib/External/isl/include/isl/union_map.h
index 2dac338abed..b81caef83b9 100644
--- a/polly/lib/External/isl/include/isl/union_map.h
+++ b/polly/lib/External/isl/include/isl/union_map.h
@@ -40,12 +40,17 @@ int isl_union_map_find_dim_by_name(__isl_keep isl_union_map *umap,
__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);
+__isl_export
__isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_map_domain_map(
__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff(
__isl_take isl_union_map *umap);
+__isl_export
__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(
@@ -68,6 +73,7 @@ __isl_give isl_union_map *isl_union_map_simple_hull(
__isl_export
__isl_give isl_union_map *isl_union_map_coalesce(
__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_map_compute_divs(
__isl_take isl_union_map *umap);
__isl_export
@@ -89,24 +95,35 @@ __isl_give isl_union_map *isl_union_map_intersect(
__isl_export
__isl_give isl_union_map *isl_union_map_intersect_params(
__isl_take isl_union_map *umap, __isl_take isl_set *set);
+__isl_export
__isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
__isl_take isl_union_map *umap2);
+__isl_export
__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_export
__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_export
__isl_give isl_union_map *isl_union_map_domain_factor_domain(
__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_map_domain_factor_range(
__isl_take isl_union_map *umap);
+__isl_export
+__isl_give isl_union_map *isl_union_map_range_factor_domain(
+ __isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_map_range_factor_range(
__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_map_factor_domain(
__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_map_factor_range(
__isl_take isl_union_map *umap);
__isl_export
@@ -160,6 +177,7 @@ __isl_give isl_union_map *isl_union_map_preimage_range_union_pw_multi_aff(
__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_export
__isl_give isl_union_map *isl_union_map_from_domain_and_range(
__isl_take isl_union_set *domain, __isl_take isl_union_set *range);
@@ -211,6 +229,7 @@ __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap);
__isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap);
+__isl_overload
__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,
@@ -247,11 +266,16 @@ __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);
+__isl_export
__isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap);
+__isl_export
__isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset);
+__isl_export
__isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_range_curry(
+ __isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_uncurry(__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_align_params(
diff --git a/polly/lib/External/isl/include/isl/union_set.h b/polly/lib/External/isl/include/isl/union_set.h
index 3d818fe9933..65b3a0926c6 100644
--- a/polly/lib/External/isl/include/isl/union_set.h
+++ b/polly/lib/External/isl/include/isl/union_set.h
@@ -46,6 +46,7 @@ __isl_give isl_union_set *isl_union_set_simple_hull(
__isl_export
__isl_give isl_union_set *isl_union_set_coalesce(
__isl_take isl_union_set *uset);
+__isl_export
__isl_give isl_union_set *isl_union_set_compute_divs(
__isl_take isl_union_set *uset);
__isl_export
@@ -55,6 +56,7 @@ __isl_give isl_union_set *isl_union_set_lexmax(__isl_take isl_union_set *uset);
__isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
__isl_take isl_set *set);
+__isl_export
__isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
__isl_take isl_union_set *uset2);
__isl_export
@@ -115,10 +117,17 @@ __isl_give int isl_union_set_contains(__isl_keep isl_union_set *uset,
__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);
+__isl_export
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);
+__isl_export
+__isl_give isl_point *isl_union_set_sample_point(
+ __isl_take isl_union_set *uset);
+
+__isl_constructor
+__isl_give isl_union_set *isl_union_set_from_point(__isl_take isl_point *pnt);
__isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset);
diff --git a/polly/lib/External/isl/include/isl/val.h b/polly/lib/External/isl/include/isl/val.h
index 167244f0993..5595989ac11 100644
--- a/polly/lib/External/isl/include/isl/val.h
+++ b/polly/lib/External/isl/include/isl/val.h
@@ -10,12 +10,12 @@
extern "C" {
#endif
-struct isl_val;
+struct __isl_export isl_val;
typedef struct isl_val isl_val;
ISL_DECLARE_LIST(val)
-struct isl_multi_val;
+struct __isl_export isl_multi_val;
typedef struct isl_multi_val isl_multi_val;
ISL_DECLARE_MULTI(val)
@@ -23,12 +23,19 @@ ISL_DECLARE_MULTI_NEG(val)
ISL_DECLARE_MULTI_DIMS(val)
ISL_DECLARE_MULTI_WITH_DOMAIN(val)
+__isl_export
__isl_give isl_val *isl_val_zero(isl_ctx *ctx);
+__isl_export
__isl_give isl_val *isl_val_one(isl_ctx *ctx);
+__isl_export
__isl_give isl_val *isl_val_negone(isl_ctx *ctx);
+__isl_export
__isl_give isl_val *isl_val_nan(isl_ctx *ctx);
+__isl_export
__isl_give isl_val *isl_val_infty(isl_ctx *ctx);
+__isl_export
__isl_give isl_val *isl_val_neginfty(isl_ctx *ctx);
+__isl_constructor
__isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i);
__isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u);
__isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, size_t n,
@@ -96,6 +103,7 @@ isl_bool isl_val_abs_eq(__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_constructor
__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,
__isl_keep isl_val *v);
diff --git a/polly/lib/External/isl/interface/all.h b/polly/lib/External/isl/interface/all.h
index 46634e2b8db..1c7d1064cee 100644
--- a/polly/lib/External/isl/interface/all.h
+++ b/polly/lib/External/isl/interface/all.h
@@ -1,4 +1,9 @@
+#include <isl/val.h>
+#include <isl/aff.h>
#include <isl/set.h>
#include <isl/map.h>
#include <isl/union_set.h>
#include <isl/union_map.h>
+#include <isl/flow.h>
+#include <isl/schedule.h>
+#include <isl/schedule_node.h>
diff --git a/polly/lib/External/isl/isl_aff.c b/polly/lib/External/isl/isl_aff.c
index 8cebea949f6..b072b956e6a 100644
--- a/polly/lib/External/isl/isl_aff.c
+++ b/polly/lib/External/isl/isl_aff.c
@@ -1242,7 +1242,7 @@ __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
* expression, but we would also need to check that no other divs are
* defined in terms of them.
*/
-__isl_give isl_aff *isl_aff_remove_unused_divs( __isl_take isl_aff *aff)
+__isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff)
{
int pos;
int off;
@@ -4380,58 +4380,198 @@ error:
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
+/* Subtract the initial "n" elements in "ma" with coefficients in "c" and
+ * denominator "denom".
+ * "denom" is allowed to be negative, in which case the actual denominator
+ * is -denom and the expressions are added instead.
+ */
+static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff,
+ __isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom)
+{
+ int i, first;
+ int sign;
+ isl_int d;
+
+ first = isl_seq_first_non_zero(c, n);
+ if (first == -1)
+ return aff;
+
+ sign = isl_int_sgn(denom);
+ isl_int_init(d);
+ isl_int_abs(d, denom);
+ for (i = first; i < n; ++i) {
+ isl_aff *aff_i;
+
+ if (isl_int_is_zero(c[i]))
+ continue;
+ aff_i = isl_multi_aff_get_aff(ma, i);
+ aff_i = isl_aff_scale(aff_i, c[i]);
+ aff_i = isl_aff_scale_down(aff_i, d);
+ if (sign >= 0)
+ aff = isl_aff_sub(aff, aff_i);
+ else
+ aff = isl_aff_add(aff, aff_i);
+ }
+ isl_int_clear(d);
+
+ return aff;
+}
+
+/* Extract an affine expression that expresses the output dimension "pos"
+ * of "bmap" in terms of the parameters and input dimensions from
+ * equality "eq".
+ * Note that this expression may involve integer divisions defined
+ * in terms of parameters and input dimensions.
+ * The equality may also involve references to earlier (but not later)
+ * output dimensions. These are replaced by the corresponding elements
+ * in "ma".
+ *
+ * If the equality is of the form
+ *
+ * f(i) + h(j) + a x + g(i) = 0,
+ *
+ * with f(i) a linear combinations of the parameters and input dimensions,
+ * g(i) a linear combination of integer divisions defined in terms of the same
+ * and h(j) a linear combinations of earlier output dimensions,
+ * then the affine expression is
+ *
+ * (-f(i) - g(i))/a - h(j)/a
+ *
+ * If the equality is of the form
+ *
+ * f(i) + h(j) - a x + g(i) = 0,
+ *
+ * then the affine expression is
+ *
+ * (f(i) + g(i))/a - h(j)/(-a)
+ *
+ *
+ * If "div" refers to an integer division (i.e., it is smaller than
+ * the number of integer divisions), then the equality constraint
+ * does involve an integer division (the one at position "div") that
+ * is defined in terms of output dimensions. However, this integer
+ * division can be eliminated by exploiting a pair of constraints
+ * x >= l and x <= l + n, with n smaller than the coefficient of "div"
+ * in the equality constraint. "ineq" refers to inequality x >= l, i.e.,
+ * -l + x >= 0.
+ * In particular, let
+ *
+ * x = e(i) + m floor(...)
+ *
+ * with e(i) the expression derived above and floor(...) the integer
+ * division involving output dimensions.
+ * From
+ *
+ * l <= x <= l + n,
+ *
+ * we have
+ *
+ * 0 <= x - l <= n
+ *
+ * This means
+ *
+ * e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m
+ * = (e(i) - l) mod m
+ *
+ * Therefore,
+ *
+ * x - l = (e(i) - l) mod m
+ *
+ * or
+ *
+ * x = ((e(i) - l) mod m) + l
+ *
+ * The variable "shift" below contains the expression -l, which may
+ * also involve a linear combination of earlier output dimensions.
+ */
+static __isl_give isl_aff *extract_aff_from_equality(
+ __isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq,
+ __isl_keep isl_multi_aff *ma)
+{
+ unsigned o_out;
+ unsigned n_div, n_out;
+ isl_ctx *ctx;
+ isl_local_space *ls;
+ isl_aff *aff, *shift;
+ isl_val *mod;
+
+ ctx = isl_basic_map_get_ctx(bmap);
+ ls = isl_basic_map_get_local_space(bmap);
+ ls = isl_local_space_domain(ls);
+ aff = isl_aff_alloc(isl_local_space_copy(ls));
+ if (!aff)
+ goto error;
+ o_out = isl_basic_map_offset(bmap, isl_dim_out);
+ n_out = isl_basic_map_dim(bmap, isl_dim_out);
+ n_div = isl_basic_map_dim(bmap, isl_dim_div);
+ if (isl_int_is_neg(bmap->eq[eq][o_out + pos])) {
+ isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out);
+ isl_seq_cpy(aff->v->el + 1 + o_out,
+ bmap->eq[eq] + o_out + n_out, n_div);
+ } else {
+ isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out);
+ isl_seq_neg(aff->v->el + 1 + o_out,
+ bmap->eq[eq] + o_out + n_out, n_div);
+ }
+ if (div < n_div)
+ isl_int_set_si(aff->v->el[1 + o_out + div], 0);
+ isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos]);
+ aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out,
+ bmap->eq[eq][o_out + pos]);
+ if (div < n_div) {
+ shift = isl_aff_alloc(isl_local_space_copy(ls));
+ if (!shift)
+ goto error;
+ isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out);
+ isl_seq_cpy(shift->v->el + 1 + o_out,
+ bmap->ineq[ineq] + o_out + n_out, n_div);
+ isl_int_set_si(shift->v->el[0], 1);
+ shift = subtract_initial(shift, ma, pos,
+ bmap->ineq[ineq] + o_out, ctx->negone);
+ aff = isl_aff_add(aff, isl_aff_copy(shift));
+ mod = isl_val_int_from_isl_int(ctx,
+ bmap->eq[eq][o_out + n_out + div]);
+ mod = isl_val_abs(mod);
+ aff = isl_aff_mod_val(aff, mod);
+ aff = isl_aff_sub(aff, shift);
+ }
+
+ isl_local_space_free(ls);
+ return aff;
+error:
+ isl_local_space_free(ls);
+ isl_aff_free(aff);
+ return NULL;
+}
+
+/* Given a basic map with output dimensions defined
+ * in terms of the parameters input dimensions and earlier
+ * output dimensions using an equality (and possibly a pair on inequalities),
+ * extract an isl_aff that expresses output dimension "pos" in terms
* of the parameters and input dimensions.
* Note that this expression may involve integer divisions defined
* in terms of parameters and input dimensions.
+ * "ma" contains the expressions corresponding to earlier output dimensions.
*
* This function shares some similarities with
* isl_basic_map_has_defining_equality and isl_constraint_get_bound.
*/
static __isl_give isl_aff *extract_isl_aff_from_basic_map(
- __isl_take isl_basic_map *bmap)
+ __isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma)
{
- int eq;
- unsigned offset;
- unsigned n_div;
- isl_local_space *ls;
+ int eq, div, ineq;
isl_aff *aff;
if (!bmap)
return NULL;
- if (isl_basic_map_dim(bmap, isl_dim_out) != 1)
- isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
- "basic map should have a single output dimension",
- goto error);
- eq = isl_basic_map_output_defining_equality(bmap, 0);
+ eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq);
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;
- 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);
+ "unable to find suitable equality", return NULL);
+ aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma);
aff = isl_aff_remove_unused_divs(aff);
return aff;
-error:
- isl_basic_map_free(bmap);
- return NULL;
}
/* Given a basic map where each output dimension is defined
@@ -4453,14 +4593,9 @@ static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
n_out = isl_basic_map_dim(bmap, isl_dim_out);
for (i = 0; i < n_out; ++i) {
- isl_basic_map *bmap_i;
isl_aff *aff;
- bmap_i = isl_basic_map_copy(bmap);
- bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out,
- i + 1, n_out - (1 + i));
- bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out, 0, i);
- aff = extract_isl_aff_from_basic_map(bmap_i);
+ aff = extract_isl_aff_from_basic_map(bmap, i, ma);
ma = isl_multi_aff_set_aff(ma, i, aff);
}
@@ -4488,12 +4623,22 @@ __isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
* 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.
+ *
+ * Remove all constraints involving local variables without
+ * an explicit representation (resulting in the removal of those
+ * local variables) prior to the actual extraction to ensure
+ * that the local spaces in which the resulting affine expressions
+ * are created do not contain any unknown local variables.
+ * Removing such constraints is safe because constraints involving
+ * unknown local variables are not used to determine whether
+ * a basic map is obviously single-valued.
*/
static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
__isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
{
isl_multi_aff *ma;
+ bmap = isl_basic_map_drop_constraint_involving_unknown_divs(bmap);
ma = extract_isl_multi_aff_from_basic_map(bmap);
ma = isl_multi_aff_floor(ma);
return isl_pw_multi_aff_alloc(domain, ma);
@@ -4800,7 +4945,7 @@ static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
*
* We basically plug (1) into "map", resulting in a map with "a"
* in the range instead of "x". The corresponding isl_pw_multi_aff
- * defining "a" is then plugged back into (1) to obtain a definition fro "x".
+ * defining "a" is then plugged back into (1) to obtain a definition for "x".
*
* Specifically, given the input map
*
@@ -4914,8 +5059,8 @@ static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
*
* x = m a + f(..)
*
- * with m greater than 1, a some combination of existentiall quantified
- * variables and f and expression in the parameters and input dimensions.
+ * with m greater than 1, a some combination of existentially quantified
+ * variables and f an expression in the parameters and input dimensions.
* If so, we remove the stride in pw_multi_aff_from_map_stride.
*
* Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
@@ -4924,7 +5069,7 @@ static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
{
int i, j;
- int sv;
+ isl_bool sv;
isl_basic_map *hull;
unsigned n_out;
unsigned o_out;
@@ -4935,7 +5080,8 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
if (!map)
return NULL;
- hull = isl_map_affine_hull(isl_map_copy(map));
+ map = isl_map_detect_equalities(map);
+ hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
sv = isl_basic_map_plain_is_single_valued(hull);
if (sv >= 0 && sv)
return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
diff --git a/polly/lib/External/isl/isl_affine_hull.c b/polly/lib/External/isl/isl_affine_hull.c
index 2632993da8e..3f219016990 100644
--- a/polly/lib/External/isl/isl_affine_hull.c
+++ b/polly/lib/External/isl/isl_affine_hull.c
@@ -652,6 +652,9 @@ __isl_give isl_map *isl_map_drop_constraints_involving_dims(
return isl_map_free(map);
}
+ if (map->n > 1)
+ ISL_F_CLR(map, ISL_MAP_DISJOINT);
+
return map;
}
diff --git a/polly/lib/External/isl/isl_ast_codegen.c b/polly/lib/External/isl/isl_ast_codegen.c
index 8c6c6dc1b87..350a8402165 100644
--- a/polly/lib/External/isl/isl_ast_codegen.c
+++ b/polly/lib/External/isl/isl_ast_codegen.c
@@ -109,6 +109,54 @@ static __isl_give isl_ast_graft *at_each_domain(__isl_take isl_ast_graft *graft,
return graft;
}
+/* Generate a call expression for the single executed
+ * domain element "map" and put a guard around it based its (simplified)
+ * domain. "executed" is the original inverse schedule from which "map"
+ * has been derived. In particular, "map" is either identical to "executed"
+ * or it is the result of gisting "executed" with respect to the build domain.
+ * "executed" is only used if there is an at_each_domain callback.
+ *
+ * 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.
+ * Since all pending constraints not covered by any enforced constraints
+ * will be added as a guard to the graft in create_node_scaled,
+ * even in the eliminated case, the pending constraints
+ * can be considered to have been generated by outer constructs.
+ *
+ * If the user has set an at_each_domain callback, it is called
+ * on the constructed call expression node.
+ */
+static isl_stat add_domain(__isl_take isl_map *executed,
+ __isl_take isl_map *map, struct isl_generate_domain_data *data)
+{
+ isl_ast_build *build;
+ isl_ast_graft *graft;
+ isl_ast_graft_list *list;
+ isl_set *guard, *pending;
+
+ build = isl_ast_build_copy(data->build);
+ pending = isl_ast_build_get_pending(build);
+ build = isl_ast_build_replace_pending_by_guard(build, pending);
+
+ guard = isl_map_domain(isl_map_copy(map));
+ guard = isl_set_compute_divs(guard);
+ guard = isl_set_coalesce(guard);
+ guard = isl_set_gist(guard, isl_ast_build_get_generated(build));
+ guard = isl_ast_build_specialize(build, 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 isl_stat_ok;
+}
+
/* Generate an AST for a single domain based on
* the inverse schedule "executed" and add it to data->list.
*
@@ -127,7 +175,11 @@ static __isl_give isl_ast_graft *at_each_domain(__isl_take isl_ast_graft *graft,
* 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
- * expression usually yields simpler results.
+ * expression usually yields simpler results in cases where the original
+ * map is not obviously single-valued.
+ * If the original map is obviously single-valued, then the gist
+ * operation is skipped.
+ *
* Because we perform the single-valuedness test on the gisted map,
* we may in rare cases fail to recognize that the inverse schedule
* is single-valued. This becomes problematic if this happens
@@ -137,29 +189,13 @@ static __isl_give isl_ast_graft *at_each_domain(__isl_take isl_ast_graft *graft,
* and revert to the ungisted map if the gisted map turns out not to be
* single-valued.
*
- * Otherwise, we generate a call expression for the single executed
- * 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.
+ * Otherwise, call add_domain to generate a call expression (with guard) and
+ * to call the at_each_domain callback, if any.
*/
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, *domain;
+ isl_set *domain;
isl_map *map = NULL;
int empty, sv;
@@ -174,6 +210,12 @@ static isl_stat generate_domain(__isl_take isl_map *executed, void *user)
return isl_stat_ok;
}
+ sv = isl_map_plain_is_single_valued(executed);
+ if (sv < 0)
+ goto error;
+ if (sv)
+ return add_domain(executed, isl_map_copy(executed), data);
+
executed = isl_map_coalesce(executed);
map = isl_map_copy(executed);
map = isl_ast_build_compute_gist_map_domain(data->build, map);
@@ -187,27 +229,8 @@ static isl_stat generate_domain(__isl_take isl_map *executed, void *user)
else
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_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 isl_stat_ok;
+ return add_domain(executed, map, data);
error:
isl_map_free(map);
isl_map_free(executed);
diff --git a/polly/lib/External/isl/isl_coalesce.c b/polly/lib/External/isl/isl_coalesce.c
index a1993d69348..e7a1863fa28 100644
--- a/polly/lib/External/isl/isl_coalesce.c
+++ b/polly/lib/External/isl/isl_coalesce.c
@@ -2153,7 +2153,7 @@ error:
static int add_sub_vars(struct isl_coalesce_info *info,
__isl_keep isl_aff_list *list, int dim, int extra_var)
{
- int i, n;
+ int i, j, n;
isl_space *space;
space = isl_basic_map_get_space(info->bmap);
@@ -2179,8 +2179,8 @@ static int add_sub_vars(struct isl_coalesce_info *info,
return -1;
if (isl_basic_map_alloc_div(info->bmap) < 0)
return -1;
- if (i != n - 1)
- isl_basic_map_swap_div(info->bmap, i, n - 1);
+ for (j = n - 1; j > i; --j)
+ isl_basic_map_swap_div(info->bmap, j - 1, j);
}
return 0;
diff --git a/polly/lib/External/isl/isl_config.h.in b/polly/lib/External/isl/isl_config.h.in
index 58830f3647e..cd98b7308e7 100644
--- a/polly/lib/External/isl/isl_config.h.in
+++ b/polly/lib/External/isl/isl_config.h.in
@@ -197,4 +197,7 @@
/* Define to getResultType for older versions of clang */
#undef getReturnType
+/* Define to InitializeBuiltins for older versions of clang */
+#undef initializeBuiltins
+
#include <isl_config_post.h>
diff --git a/polly/lib/External/isl/isl_convex_hull.c b/polly/lib/External/isl/isl_convex_hull.c
index a61462e62e0..fbd40dc2040 100644
--- a/polly/lib/External/isl/isl_convex_hull.c
+++ b/polly/lib/External/isl/isl_convex_hull.c
@@ -2414,6 +2414,176 @@ __isl_give isl_basic_set *isl_set_unshifted_simple_hull(
return isl_map_unshifted_simple_hull(set);
}
+/* Drop all inequalities from "bmap1" that do not also appear in "bmap2".
+ * A constraint that appears with different constant terms
+ * in "bmap1" and "bmap2" is also kept, with the least restrictive
+ * (i.e., greatest) constant term.
+ * "bmap1" and "bmap2" are assumed to have the same (known)
+ * integer divisions.
+ * The constraints of both "bmap1" and "bmap2" are assumed
+ * to have been sorted using isl_basic_map_sort_constraints.
+ *
+ * Run through the inequality constraints of "bmap1" and "bmap2"
+ * in sorted order.
+ * Each constraint of "bmap1" without a matching constraint in "bmap2"
+ * is removed.
+ * If a match is found, the constraint is kept. If needed, the constant
+ * term of the constraint is adjusted.
+ */
+static __isl_give isl_basic_map *select_shared_inequalities(
+ __isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
+{
+ int i1, i2;
+
+ bmap1 = isl_basic_map_cow(bmap1);
+ if (!bmap1 || !bmap2)
+ return isl_basic_map_free(bmap1);
+
+ i1 = bmap1->n_ineq - 1;
+ i2 = bmap2->n_ineq - 1;
+ while (bmap1 && i1 >= 0 && i2 >= 0) {
+ int cmp;
+
+ cmp = isl_basic_map_constraint_cmp(bmap1, bmap1->ineq[i1],
+ bmap2->ineq[i2]);
+ if (cmp < 0) {
+ --i2;
+ continue;
+ }
+ if (cmp > 0) {
+ if (isl_basic_map_drop_inequality(bmap1, i1) < 0)
+ bmap1 = isl_basic_map_free(bmap1);
+ --i1;
+ continue;
+ }
+ if (isl_int_lt(bmap1->ineq[i1][0], bmap2->ineq[i2][0]))
+ isl_int_set(bmap1->ineq[i1][0], bmap2->ineq[i2][0]);
+ --i1;
+ --i2;
+ }
+ for (; i1 >= 0; --i1)
+ if (isl_basic_map_drop_inequality(bmap1, i1) < 0)
+ bmap1 = isl_basic_map_free(bmap1);
+
+ return bmap1;
+}
+
+/* Drop all equalities from "bmap1" that do not also appear in "bmap2".
+ * "bmap1" and "bmap2" are assumed to have the same (known)
+ * integer divisions.
+ *
+ * Run through the equality constraints of "bmap1" and "bmap2".
+ * Each constraint of "bmap1" without a matching constraint in "bmap2"
+ * is removed.
+ */
+static __isl_give isl_basic_map *select_shared_equalities(
+ __isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
+{
+ int i1, i2;
+ unsigned total;
+
+ bmap1 = isl_basic_map_cow(bmap1);
+ if (!bmap1 || !bmap2)
+ return isl_basic_map_free(bmap1);
+
+ total = isl_basic_map_total_dim(bmap1);
+
+ i1 = bmap1->n_eq - 1;
+ i2 = bmap2->n_eq - 1;
+ while (bmap1 && i1 >= 0 && i2 >= 0) {
+ int last1, last2;
+
+ last1 = isl_seq_last_non_zero(bmap1->eq[i1] + 1, total);
+ last2 = isl_seq_last_non_zero(bmap2->eq[i2] + 1, total);
+ if (last1 > last2) {
+ --i2;
+ continue;
+ }
+ if (last1 < last2) {
+ if (isl_basic_map_drop_equality(bmap1, i1) < 0)
+ bmap1 = isl_basic_map_free(bmap1);
+ --i1;
+ continue;
+ }
+ if (!isl_seq_eq(bmap1->eq[i1], bmap2->eq[i2], 1 + total)) {
+ if (isl_basic_map_drop_equality(bmap1, i1) < 0)
+ bmap1 = isl_basic_map_free(bmap1);
+ }
+ --i1;
+ --i2;
+ }
+ for (; i1 >= 0; --i1)
+ if (isl_basic_map_drop_equality(bmap1, i1) < 0)
+ bmap1 = isl_basic_map_free(bmap1);
+
+ return bmap1;
+}
+
+/* Compute a superset of "bmap1" and "bmap2" that is described
+ * by only the constraints that appear in both "bmap1" and "bmap2".
+ *
+ * First drop constraints that involve unknown integer divisions
+ * since it is not trivial to check whether two such integer divisions
+ * in different basic maps are the same.
+ * Then align the remaining (known) divs and sort the constraints.
+ * Finally drop all inequalities and equalities from "bmap1" that
+ * do not also appear in "bmap2".
+ */
+__isl_give isl_basic_map *isl_basic_map_plain_unshifted_simple_hull(
+ __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
+{
+ bmap1 = isl_basic_map_drop_constraint_involving_unknown_divs(bmap1);
+ bmap2 = isl_basic_map_drop_constraint_involving_unknown_divs(bmap2);
+ bmap2 = isl_basic_map_align_divs(bmap2, bmap1);
+ bmap1 = isl_basic_map_align_divs(bmap1, bmap2);
+ bmap1 = isl_basic_map_gauss(bmap1, NULL);
+ bmap2 = isl_basic_map_gauss(bmap2, NULL);
+ bmap1 = isl_basic_map_sort_constraints(bmap1);
+ bmap2 = isl_basic_map_sort_constraints(bmap2);
+
+ bmap1 = select_shared_inequalities(bmap1, bmap2);
+ bmap1 = select_shared_equalities(bmap1, bmap2);
+
+ isl_basic_map_free(bmap2);
+ bmap1 = isl_basic_map_finalize(bmap1);
+ return bmap1;
+}
+
+/* Compute a superset of the convex hull of "map" that is described
+ * by only the constraints in the constituents of "map".
+ * In particular, the result is composed of constraints that appear
+ * in each of the basic maps of "map"
+ *
+ * Constraints that involve unknown integer divisions are dropped
+ * since it is not trivial to check whether two such integer divisions
+ * in different basic maps are the same.
+ *
+ * The hull is initialized from the first basic map and then
+ * updated with respect to the other basic maps in turn.
+ */
+__isl_give isl_basic_map *isl_map_plain_unshifted_simple_hull(
+ __isl_take isl_map *map)
+{
+ int i;
+ isl_basic_map *hull;
+
+ if (!map)
+ return NULL;
+ if (map->n <= 1)
+ return map_simple_hull_trivial(map);
+ map = isl_map_drop_constraint_involving_unknown_divs(map);
+ hull = isl_basic_map_copy(map->p[0]);
+ for (i = 1; i < map->n; ++i) {
+ isl_basic_map *bmap_i;
+
+ bmap_i = isl_basic_map_copy(map->p[i]);
+ hull = isl_basic_map_plain_unshifted_simple_hull(hull, bmap_i);
+ }
+
+ isl_map_free(map);
+ return hull;
+}
+
/* 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
diff --git a/polly/lib/External/isl/isl_flow.c b/polly/lib/External/isl/isl_flow.c
index 927ce909c3e..b5ae691d844 100644
--- a/polly/lib/External/isl/isl_flow.c
+++ b/polly/lib/External/isl/isl_flow.c
@@ -167,6 +167,8 @@ struct isl_labeled_map {
*
* domain_map is an auxiliary map that maps the sink access relation
* to the domain of this access relation.
+ * This field is only needed when restrict_fn is set and
+ * the field itself is set by isl_access_info_compute_flow.
*
* restrict_fn is a callback that (if not NULL) will be called
* right before any lexicographical maximization.
@@ -1062,18 +1064,17 @@ error:
*
* To deal with multi-valued sink access relations, the sink iteration
* domain is first extended with dimensions that correspond to the data
- * space. After the computation is finished, these extra dimensions are
- * projected out again.
+ * space. However, these extra dimensions are not projected out again.
+ * It is up to the caller to decide whether these dimensions should be kept.
*/
-__isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc)
+static __isl_give isl_flow *access_info_compute_flow_core(
+ __isl_take isl_access_info *acc)
{
- int j;
struct isl_flow *res = NULL;
if (!acc)
return NULL;
- acc->domain_map = isl_map_domain_map(isl_map_copy(acc->sink.map));
acc->sink.map = isl_map_range_map(acc->sink.map);
if (!acc->sink.map)
goto error;
@@ -1084,22 +1085,56 @@ __isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *ac
acc = isl_access_info_sort_sources(acc);
res = compute_val_based_dependences(acc);
}
+ acc = isl_access_info_free(acc);
if (!res)
+ return NULL;
+ if (!res->must_no_source || !res->may_no_source)
goto error;
+ return res;
+error:
+ isl_access_info_free(acc);
+ isl_flow_free(res);
+ return NULL;
+}
+
+/* Given a "sink" access, a list of n "source" accesses,
+ * compute for each iteration of the sink access
+ * and for each element accessed by that iteration,
+ * the source access in the list that last accessed the
+ * element accessed by the sink access before this sink access.
+ * Each access is given as a map from the loop iterators
+ * to the array indices.
+ * The result is a list of n relations between source and sink
+ * iterations and a subset of the domain of the sink access,
+ * corresponding to those iterations that access an element
+ * not previously accessed.
+ *
+ * To deal with multi-valued sink access relations,
+ * access_info_compute_flow_core extends the sink iteration domain
+ * with dimensions that correspond to the data space. These extra dimensions
+ * are projected out from the result of access_info_compute_flow_core.
+ */
+__isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc)
+{
+ int j;
+ struct isl_flow *res;
+
+ if (!acc)
+ return NULL;
+
+ acc->domain_map = isl_map_domain_map(isl_map_copy(acc->sink.map));
+ res = access_info_compute_flow_core(acc);
+ if (!res)
+ return NULL;
for (j = 0; j < res->n_source; ++j) {
- res->dep[j].map = isl_map_apply_range(res->dep[j].map,
- isl_map_copy(acc->domain_map));
+ res->dep[j].map = isl_map_range_factor_domain(res->dep[j].map);
if (!res->dep[j].map)
goto error;
}
- if (!res->must_no_source || !res->may_no_source)
- goto error;
- isl_access_info_free(acc);
return res;
error:
- isl_access_info_free(acc);
isl_flow_free(res);
return NULL;
}
@@ -1368,6 +1403,70 @@ __isl_give isl_union_access_info *isl_union_access_info_copy(
return copy;
}
+/* Print a key-value pair of a YAML mapping to "p",
+ * with key "name" and value "umap".
+ */
+static __isl_give isl_printer *print_union_map_field(__isl_take isl_printer *p,
+ const char *name, __isl_keep isl_union_map *umap)
+{
+ p = isl_printer_print_str(p, name);
+ p = isl_printer_yaml_next(p);
+ p = isl_printer_print_str(p, "\"");
+ p = isl_printer_print_union_map(p, umap);
+ p = isl_printer_print_str(p, "\"");
+ p = isl_printer_yaml_next(p);
+
+ return p;
+}
+
+/* Print the information contained in "access" to "p".
+ * The information is printed as a YAML document.
+ */
+__isl_give isl_printer *isl_printer_print_union_access_info(
+ __isl_take isl_printer *p, __isl_keep isl_union_access_info *access)
+{
+ if (!access)
+ return isl_printer_free(p);
+
+ p = isl_printer_yaml_start_mapping(p);
+ p = print_union_map_field(p, "sink", access->sink);
+ p = print_union_map_field(p, "must_source", access->must_source);
+ p = print_union_map_field(p, "may_source", access->may_source);
+ if (access->schedule) {
+ p = isl_printer_print_str(p, "schedule");
+ p = isl_printer_yaml_next(p);
+ p = isl_printer_print_schedule(p, access->schedule);
+ p = isl_printer_yaml_next(p);
+ } else {
+ p = print_union_map_field(p, "schedule_map",
+ access->schedule_map);
+ }
+ p = isl_printer_yaml_end_mapping(p);
+
+ return p;
+}
+
+/* Return a string representation of the information in "access".
+ * The information is printed in flow format.
+ */
+__isl_give char *isl_union_access_info_to_str(
+ __isl_keep isl_union_access_info *access)
+{
+ isl_printer *p;
+ char *s;
+
+ if (!access)
+ return NULL;
+
+ p = isl_printer_to_str(isl_union_access_info_get_ctx(access));
+ p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW);
+ p = isl_printer_print_union_access_info(p, access);
+ s = isl_printer_get_str(p);
+ isl_printer_free(p);
+
+ return s;
+}
+
/* 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.
@@ -1457,10 +1556,15 @@ isl_union_access_info_introduce_schedule(
return access;
}
-/* This structure epresents the result of a dependence analysis computation.
+/* This structure represents the result of a dependence analysis computation.
*
- * "must_dep" represents the definite dependences.
- * "may_dep" represents the non-definite dependences.
+ * "must_dep" represents the full definite dependences
+ * "may_dep" represents the full non-definite dependences.
+ * Both are of the form
+ *
+ * [Source] -> [[Sink -> Data]]
+ *
+ * (after the schedule dimensions have been projected out).
* "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
@@ -1509,9 +1613,9 @@ void isl_union_flow_dump(__isl_keep isl_union_flow *flow)
isl_union_map_dump(flow->may_no_source);
}
-/* Return the definite dependences in "flow".
+/* Return the full definite dependences in "flow", with accessed elements.
*/
-__isl_give isl_union_map *isl_union_flow_get_must_dependence(
+__isl_give isl_union_map *isl_union_flow_get_full_must_dependence(
__isl_keep isl_union_flow *flow)
{
if (!flow)
@@ -1519,16 +1623,44 @@ __isl_give isl_union_map *isl_union_flow_get_must_dependence(
return isl_union_map_copy(flow->must_dep);
}
+/* Return the full possible dependences in "flow", including the definite
+ * dependences, with accessed elements.
+ */
+__isl_give isl_union_map *isl_union_flow_get_full_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 definite dependences in "flow", without the accessed elements.
+ */
+__isl_give isl_union_map *isl_union_flow_get_must_dependence(
+ __isl_keep isl_union_flow *flow)
+{
+ isl_union_map *dep;
+
+ if (!flow)
+ return NULL;
+ dep = isl_union_map_copy(flow->must_dep);
+ return isl_union_map_range_factor_domain(dep);
+}
+
/* Return the possible dependences in "flow", including the definite
- * dependences.
+ * dependences, without the accessed elements.
*/
__isl_give isl_union_map *isl_union_flow_get_may_dependence(
__isl_keep isl_union_flow *flow)
{
+ isl_union_map *dep;
+
if (!flow)
return NULL;
- return isl_union_map_union(isl_union_map_copy(flow->must_dep),
+ dep = isl_union_map_union(isl_union_map_copy(flow->must_dep),
isl_union_map_copy(flow->may_dep));
+ return isl_union_map_range_factor_domain(dep);
}
/* Return the non-definite dependences in "flow".
@@ -1614,6 +1746,20 @@ error:
* 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.
+ *
+ * In particular, the dependences computed by access_info_compute_flow_core
+ * are of the form
+ *
+ * [S -> D] -> [[S' -> D'] -> A]
+ *
+ * The schedule dimensions are projected out by first currying the range,
+ * resulting in
+ *
+ * [S -> D] -> [S' -> [D' -> A]]
+ *
+ * and then computing the factor range
+ *
+ * D -> [D' -> A]
*/
static __isl_give isl_union_flow *isl_union_flow_drop_schedule(
__isl_take isl_union_flow *flow)
@@ -1621,7 +1767,9 @@ static __isl_give isl_union_flow *isl_union_flow_drop_schedule(
if (!flow)
return NULL;
+ flow->must_dep = isl_union_map_range_curry(flow->must_dep);
flow->must_dep = isl_union_map_factor_range(flow->must_dep);
+ flow->may_dep = isl_union_map_range_curry(flow->may_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);
@@ -1754,7 +1902,7 @@ static int before(void *first, void *second)
/* Given a sink access, look for all the source accesses that access
* the same array and perform dataflow analysis on them using
- * isl_access_info_compute_flow.
+ * isl_access_info_compute_flow_core.
*/
static isl_stat compute_flow(__isl_take isl_map *map, void *user)
{
@@ -1801,7 +1949,7 @@ static isl_stat compute_flow(__isl_take isl_map *map, void *user)
&collect_matching_array, data) < 0)
goto error;
- flow = isl_access_info_compute_flow(data->accesses);
+ flow = access_info_compute_flow_core(data->accesses);
data->accesses = NULL;
if (!flow)
@@ -2233,6 +2381,19 @@ error:
/* Given a scheduled sink access relation "sink", compute the corresponding
* dependences on the sources in "data" and add the computed dependences
* to "uf".
+ *
+ * The dependences computed by access_info_compute_flow_core are of the form
+ *
+ * [S -> I] -> [[S' -> I'] -> A]
+ *
+ * The schedule dimensions are projected out by first currying the range,
+ * resulting in
+ *
+ * [S -> I] -> [S' -> [I' -> A]]
+ *
+ * and then computing the factor range
+ *
+ * I -> [I' -> A]
*/
static __isl_give isl_union_flow *compute_single_flow(
__isl_take isl_union_flow *uf, struct isl_scheduled_access *sink,
@@ -2250,7 +2411,7 @@ static __isl_give isl_union_flow *compute_single_flow(
&before_node, data->n_source);
access = add_matching_sources(access, sink, data);
- flow = isl_access_info_compute_flow(access);
+ flow = access_info_compute_flow_core(access);
if (!flow)
return isl_union_flow_free(uf);
@@ -2264,7 +2425,8 @@ static __isl_give isl_union_flow *compute_single_flow(
for (i = 0; i < flow->n_source; ++i) {
isl_union_map *dep;
- map = isl_map_factor_range(isl_map_copy(flow->dep[i].map));
+ map = isl_map_range_curry(isl_map_copy(flow->dep[i].map));
+ map = isl_map_factor_range(map);
dep = isl_union_map_from_map(map);
if (flow->dep[i].must)
uf->must_dep = isl_union_map_union(uf->must_dep, dep);
@@ -2371,6 +2533,51 @@ __isl_give isl_union_flow *isl_union_access_info_compute_flow(
return compute_flow_union_map(access);
}
+/* Print the information contained in "flow" to "p".
+ * The information is printed as a YAML document.
+ */
+__isl_give isl_printer *isl_printer_print_union_flow(
+ __isl_take isl_printer *p, __isl_keep isl_union_flow *flow)
+{
+ isl_union_map *umap;
+
+ if (!flow)
+ return isl_printer_free(p);
+
+ p = isl_printer_yaml_start_mapping(p);
+ p = print_union_map_field(p, "must_dependence", flow->must_dep);
+ umap = isl_union_flow_get_may_dependence(flow);
+ p = print_union_map_field(p, "may_dependence", umap);
+ isl_union_map_free(umap);
+ p = print_union_map_field(p, "must_no_source", flow->must_no_source);
+ umap = isl_union_flow_get_may_no_source(flow);
+ p = print_union_map_field(p, "may_no_source", umap);
+ isl_union_map_free(umap);
+ p = isl_printer_yaml_end_mapping(p);
+
+ return p;
+}
+
+/* Return a string representation of the information in "flow".
+ * The information is printed in flow format.
+ */
+__isl_give char *isl_union_flow_to_str(__isl_keep isl_union_flow *flow)
+{
+ isl_printer *p;
+ char *s;
+
+ if (!flow)
+ return NULL;
+
+ p = isl_printer_to_str(isl_union_flow_get_ctx(flow));
+ p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW);
+ p = isl_printer_print_union_flow(p, flow);
+ s = isl_printer_get_str(p);
+ isl_printer_free(p);
+
+ return s;
+}
+
/* Given a collection of "sink" and "source" accesses,
* compute for each iteration of a sink access
* and for each element accessed by that iteration,
diff --git a/polly/lib/External/isl/isl_input.c b/polly/lib/External/isl/isl_input.c
index 99cf7e418f5..7238127051f 100644
--- a/polly/lib/External/isl/isl_input.c
+++ b/polly/lib/External/isl/isl_input.c
@@ -658,10 +658,28 @@ error:
return NULL;
}
+/* Is "type" the type of a comparison operator between lists
+ * of affine expressions?
+ */
+static int is_list_comparator_type(int type)
+{
+ switch (type) {
+ case ISL_TOKEN_LEX_LT:
+ case ISL_TOKEN_LEX_GT:
+ case ISL_TOKEN_LEX_LE:
+ case ISL_TOKEN_LEX_GE:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static int is_comparator(struct isl_token *tok)
{
if (!tok)
return 0;
+ if (is_list_comparator_type(tok->type))
+ return 1;
switch (tok->type) {
case ISL_TOKEN_LT:
@@ -1426,6 +1444,81 @@ static __isl_give isl_map *read_map_tuple(__isl_keep isl_stream *s,
return map_from_tuple(tuple, map, type, v, rational);
}
+/* Given two equal-length lists of piecewise affine expression with the space
+ * of "set" as domain, construct a set in the same space that expresses
+ * that "left" and "right" satisfy the comparison "type".
+ *
+ * A space is constructed of the same dimension as the number of elements
+ * in the two lists. The comparison is then expressed in a map from
+ * this space to itself and wrapped into a set. Finally the two lists
+ * of piecewise affine expressions are plugged into this set.
+ *
+ * Let S be the space of "set" and T the constructed space.
+ * The lists are first changed into two isl_multi_pw_affs in S -> T and
+ * then combined into an isl_multi_pw_aff in S -> [T -> T],
+ * while the comparison is first expressed in T -> T, then [T -> T]
+ * and finally in S.
+ */
+static __isl_give isl_set *list_cmp(__isl_keep isl_set *set, int type,
+ __isl_take isl_pw_aff_list *left, __isl_take isl_pw_aff_list *right)
+{
+ isl_space *space;
+ int n;
+ isl_multi_pw_aff *mpa1, *mpa2;
+
+ if (!set || !left || !right)
+ goto error;
+
+ space = isl_set_get_space(set);
+ n = isl_pw_aff_list_n_pw_aff(left);
+ space = isl_space_from_domain(space);
+ space = isl_space_add_dims(space, isl_dim_out, n);
+ mpa1 = isl_multi_pw_aff_from_pw_aff_list(isl_space_copy(space), left);
+ mpa2 = isl_multi_pw_aff_from_pw_aff_list(isl_space_copy(space), right);
+ mpa1 = isl_multi_pw_aff_range_product(mpa1, mpa2);
+
+ space = isl_space_range(space);
+ switch (type) {
+ case ISL_TOKEN_LEX_LT:
+ set = isl_map_wrap(isl_map_lex_lt(space));
+ break;
+ case ISL_TOKEN_LEX_GT:
+ set = isl_map_wrap(isl_map_lex_gt(space));
+ break;
+ case ISL_TOKEN_LEX_LE:
+ set = isl_map_wrap(isl_map_lex_le(space));
+ break;
+ case ISL_TOKEN_LEX_GE:
+ set = isl_map_wrap(isl_map_lex_ge(space));
+ break;
+ default:
+ isl_multi_pw_aff_free(mpa1);
+ isl_space_free(space);
+ isl_die(isl_set_get_ctx(set), isl_error_internal,
+ "unhandled list comparison type", return NULL);
+ }
+ set = isl_set_preimage_multi_pw_aff(set, mpa1);
+ return set;
+error:
+ isl_pw_aff_list_free(left);
+ isl_pw_aff_list_free(right);
+ return NULL;
+}
+
+/* Construct constraints of the form
+ *
+ * a op b
+ *
+ * where a is an element in "left", op is an operator of type "type" and
+ * b is an element in "right", add the constraints to "set" and return
+ * the result.
+ * "rational" is set if the constraints should be treated as
+ * a rational constraints.
+ *
+ * If "type" is the type of a comparison operator between lists
+ * of affine expressions, then a single (compound) constraint
+ * is constructed by list_cmp instead.
+ */
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,
@@ -1439,7 +1532,9 @@ static __isl_give isl_set *construct_constraints(
left = isl_pw_aff_list_set_rational(left);
right = isl_pw_aff_list_set_rational(right);
}
- if (type == ISL_TOKEN_LE)
+ if (is_list_comparator_type(type))
+ cond = list_cmp(set, type, left, right);
+ else if (type == ISL_TOKEN_LE)
cond = isl_pw_aff_list_le_set(left, right);
else if (type == ISL_TOKEN_GE)
cond = isl_pw_aff_list_ge_set(left, right);
@@ -1455,11 +1550,32 @@ static __isl_give isl_set *construct_constraints(
return isl_set_intersect(set, cond);
}
+/* Read a constraint from "s", add it to "map" and return the result.
+ * "v" contains a description of the identifiers parsed so far.
+ * "rational" is set if the constraint should be treated as
+ * a rational constraint.
+ * The constraint read from "s" may be applied to multiple pairs
+ * of affine expressions and may be chained.
+ * In particular, a list of affine expressions is read, followed
+ * by a comparison operator and another list of affine expressions.
+ * The comparison operator is then applied to each pair of elements
+ * in the two lists and the results are added to "map".
+ * However, if the operator expects two lists of affine expressions,
+ * then it is applied directly to those lists and the two lists
+ * are required to have the same length.
+ * If the next token is another comparison operator, then another
+ * list of affine expressions is read and the process repeats.
+ *
+ * The processing is performed on a wrapped copy of "map" because
+ * an affine expression cannot have a binary relation as domain.
+ */
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;
+ struct isl_token *tok;
+ int type;
isl_pw_aff_list *list1 = NULL, *list2 = NULL;
+ int n1, n2;
isl_set *set;
set = isl_map_wrap(map);
@@ -1471,17 +1587,23 @@ static __isl_give isl_map *add_constraint(__isl_keep isl_stream *s,
isl_stream_error(s, tok, "missing operator");
if (tok)
isl_stream_push_token(s, tok);
- tok = NULL;
goto error;
}
+ type = tok->type;
+ isl_token_free(tok);
for (;;) {
list2 = accept_affine_list(s, isl_set_get_space(set), v);
if (!list2)
goto error;
+ n1 = isl_pw_aff_list_n_pw_aff(list1);
+ n2 = isl_pw_aff_list_n_pw_aff(list2);
+ if (is_list_comparator_type(type) && n1 != n2) {
+ isl_stream_error(s, NULL,
+ "list arguments not of same size");
+ goto error;
+ }
- set = construct_constraints(set, tok->type, list1, list2,
- rational);
- isl_token_free(tok);
+ set = construct_constraints(set, type, list1, list2, rational);
isl_pw_aff_list_free(list1);
list1 = list2;
@@ -1491,13 +1613,13 @@ static __isl_give isl_map *add_constraint(__isl_keep isl_stream *s,
isl_stream_push_token(s, tok);
break;
}
+ type = tok->type;
+ isl_token_free(tok);
}
isl_pw_aff_list_free(list1);
return isl_set_unwrap(set);
error:
- if (tok)
- isl_token_free(tok);
isl_pw_aff_list_free(list1);
isl_pw_aff_list_free(list2);
isl_set_free(set);
@@ -3588,6 +3710,61 @@ static __isl_give isl_union_pw_aff *read_union_pw_aff_with_dom(
return upa;
}
+/* Read an isl_union_pw_aff from "s".
+ *
+ * First check if there are any paramters, then read in the opening brace
+ * and use read_union_pw_aff_with_dom to read in the body of
+ * the isl_union_pw_aff. Finally, read the closing brace.
+ */
+__isl_give isl_union_pw_aff *isl_stream_read_union_pw_aff(
+ __isl_keep isl_stream *s)
+{
+ struct vars *v;
+ isl_set *dom;
+ isl_union_pw_aff *upa = 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;
+
+ upa = read_union_pw_aff_with_dom(s, isl_set_copy(dom), v);
+
+ if (isl_stream_eat(s, '}'))
+ goto error;
+
+ vars_free(v);
+ isl_set_free(dom);
+ return upa;
+error:
+ vars_free(v);
+ isl_set_free(dom);
+ isl_union_pw_aff_free(upa);
+ return NULL;
+}
+
+/* Read an isl_union_pw_aff from "str".
+ */
+__isl_give isl_union_pw_aff *isl_union_pw_aff_read_from_str(isl_ctx *ctx,
+ const char *str)
+{
+ isl_union_pw_aff *upa;
+ isl_stream *s = isl_stream_new_str(ctx, str);
+ if (!s)
+ return NULL;
+ upa = isl_stream_read_union_pw_aff(s);
+ isl_stream_free(s);
+ return upa;
+}
+
/* This function is called for each element in a tuple inside
* isl_stream_read_multi_union_pw_aff.
*
diff --git a/polly/lib/External/isl/isl_local_space.c b/polly/lib/External/isl/isl_local_space.c
index 7b3347cffac..7c06b59d2ab 100644
--- a/polly/lib/External/isl/isl_local_space.c
+++ b/polly/lib/External/isl/isl_local_space.c
@@ -740,18 +740,20 @@ int isl_local_space_div_is_known(__isl_keep isl_local_space *ls, int div)
return !isl_int_is_zero(ls->div->row[div][0]);
}
-int isl_local_space_divs_known(__isl_keep isl_local_space *ls)
+/* Does "ls" have an explicit representation for all local variables?
+ */
+isl_bool isl_local_space_divs_known(__isl_keep isl_local_space *ls)
{
int i;
if (!ls)
- return -1;
+ return isl_bool_error;
for (i = 0; i < ls->div->n_row; ++i)
if (isl_int_is_zero(ls->div->row[i][0]))
- return 0;
+ return isl_bool_false;
- return 1;
+ return isl_bool_true;
}
__isl_give isl_local_space *isl_local_space_domain(
diff --git a/polly/lib/External/isl/isl_local_space_private.h b/polly/lib/External/isl/isl_local_space_private.h
index 4d7e69ff2b5..5d5330500f7 100644
--- a/polly/lib/External/isl/isl_local_space_private.h
+++ b/polly/lib/External/isl/isl_local_space_private.h
@@ -32,7 +32,7 @@ unsigned isl_local_space_offset(__isl_keep isl_local_space *ls,
__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_bool isl_local_space_divs_known(__isl_keep isl_local_space *ls);
__isl_give isl_local_space *isl_local_space_substitute_equalities(
__isl_take isl_local_space *ls, __isl_take isl_basic_set *eq);
diff --git a/polly/lib/External/isl/isl_map.c b/polly/lib/External/isl/isl_map.c
index b3c5c02922b..f92dd616697 100644
--- a/polly/lib/External/isl/isl_map.c
+++ b/polly/lib/External/isl/isl_map.c
@@ -322,6 +322,38 @@ __isl_give isl_local_space *isl_basic_set_get_local_space(
return isl_basic_map_get_local_space(bset);
}
+/* For each known div d = floor(f/m), add the constraints
+ *
+ * f - m d >= 0
+ * -(f-(n-1)) + m d >= 0
+ *
+ * Do not finalize the result.
+ */
+static __isl_give 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);
+ }
+
+ return bmap;
+}
+
__isl_give isl_basic_map *isl_basic_map_from_local_space(
__isl_take isl_local_space *ls)
{
@@ -340,11 +372,9 @@ __isl_give isl_basic_map *isl_basic_map_from_local_space(
if (isl_basic_map_alloc_div(bmap) < 0)
goto error;
- for (i = 0; i < n_div; ++i) {
+ for (i = 0; i < n_div; ++i)
isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
- if (isl_basic_map_add_div_constraints(bmap, i) < 0)
- goto error;
- }
+ bmap = add_known_div_constraints(bmap);
isl_local_space_free(ls);
return bmap;
@@ -4441,11 +4471,13 @@ int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div)
*
* f - m d >= 0
* -(f-(n-1)) + m d >= 0
+ *
+ * Remove duplicate constraints in case of some these div constraints
+ * already appear in "bmap".
*/
__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)
@@ -4453,17 +4485,8 @@ __isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
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 = add_known_div_constraints(bmap);
bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL, 0);
bmap = isl_basic_map_finalize(bmap);
return bmap;
@@ -4703,6 +4726,11 @@ struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
}
+/* Replace the space of "bmap" by "space".
+ *
+ * If the space of "bmap" is identical to "space" (including the identifiers
+ * of the input and output dimensions), then simply return the original input.
+ */
__isl_give isl_basic_map *isl_basic_map_reset_space(
__isl_take isl_basic_map *bmap, __isl_take isl_space *space)
{
@@ -4711,6 +4739,12 @@ __isl_give isl_basic_map *isl_basic_map_reset_space(
if (!bmap)
goto error;
equal = isl_space_is_equal(bmap->dim, space);
+ if (equal >= 0 && equal)
+ equal = isl_space_match(bmap->dim, isl_dim_in,
+ space, isl_dim_in);
+ if (equal >= 0 && equal)
+ equal = isl_space_match(bmap->dim, isl_dim_out,
+ space, isl_dim_out);
if (equal < 0)
goto error;
if (equal) {
@@ -6886,30 +6920,47 @@ error:
return NULL;
}
-int isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
+/* Does local variable "div" of "bmap" have an explicit representation?
+ */
+isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
+{
+ if (!bmap)
+ return isl_bool_error;
+ if (div < 0 || div >= isl_basic_map_dim(bmap, isl_dim_div))
+ isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
+ "position out of bounds", return isl_bool_error);
+ return !isl_int_is_zero(bmap->div[div][0]);
+}
+
+/* Does "bmap" have an explicit representation for all local variables?
+ */
+isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
{
int i;
unsigned off;
if (!bmap)
- return -1;
+ return isl_bool_error;
off = isl_space_dim(bmap->dim, isl_dim_all);
for (i = 0; i < bmap->n_div; ++i) {
- if (isl_int_is_zero(bmap->div[i][0]))
- return 0;
+ if (!isl_basic_map_div_is_known(bmap, i))
+ return isl_bool_false;
isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
- return -1);
+ return isl_bool_error);
}
- return 1;
+ return isl_bool_true;
}
-static int map_divs_known(__isl_keep isl_map *map)
+/* Do all basic maps in "map" have an explicit representation
+ * for all local variables?
+ */
+isl_bool isl_map_divs_known(__isl_keep isl_map *map)
{
int i;
if (!map)
- return -1;
+ return isl_bool_error;
for (i = 0; i < map->n; ++i) {
int known = isl_basic_map_divs_known(map->p[i]);
@@ -6917,7 +6968,7 @@ static int map_divs_known(__isl_keep isl_map *map)
return known;
}
- return 1;
+ return isl_bool_true;
}
/* If bmap contains any unknown divs, then compute explicit
@@ -6962,7 +7013,7 @@ struct isl_map *isl_map_compute_divs(struct isl_map *map)
if (map->n == 0)
return map;
- known = map_divs_known(map);
+ known = isl_map_divs_known(map);
if (known < 0) {
isl_map_free(map);
return NULL;
@@ -8789,8 +8840,23 @@ int isl_set_plain_dim_has_fixed_lower_bound(__isl_keep isl_set *set,
return fixed;
}
-/* uset_gist depends on constraints without existentially quantified
+/* Return -1 if the constraint "c1" should be sorted before "c2"
+ * and 1 if it should be sorted after "c2".
+ * Return 0 if the two constraints are the same (up to the constant term).
+ *
+ * In particular, if a constraint involves later variables than another
+ * then it is sorted after this other constraint.
+ * uset_gist depends on constraints without existentially quantified
* variables sorting first.
+ *
+ * For constraints that have the same latest variable, those
+ * with the same coefficient for this latest variable (first in absolute value
+ * and then in actual value) are grouped together.
+ * This is useful for detecting pairs of constraints that can
+ * be chained in their printed representation.
+ *
+ * Finally, within a group, constraints are sorted according to
+ * their coefficients (excluding the constant term).
*/
static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
{
@@ -8798,6 +8864,7 @@ static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
isl_int **c2 = (isl_int **) p2;
int l1, l2;
unsigned size = *(unsigned *) arg;
+ int cmp;
l1 = isl_seq_last_non_zero(*c1 + 1, size);
l2 = isl_seq_last_non_zero(*c2 + 1, size);
@@ -8805,11 +8872,33 @@ static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
if (l1 != l2)
return l1 - l2;
+ cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
+ if (cmp != 0)
+ return cmp;
+ cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
+ if (cmp != 0)
+ return -cmp;
+
return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
}
-static struct isl_basic_map *isl_basic_map_sort_constraints(
- struct isl_basic_map *bmap)
+/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
+ * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
+ * and 0 if the two constraints are the same (up to the constant term).
+ */
+int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
+ isl_int *c1, isl_int *c2)
+{
+ unsigned total;
+
+ if (!bmap)
+ return -2;
+ total = isl_basic_map_total_dim(bmap);
+ return sort_constraint_cmp(&c1, &c2, &total);
+}
+
+__isl_give isl_basic_map *isl_basic_map_sort_constraints(
+ __isl_take isl_basic_map *bmap)
{
unsigned total;
@@ -10302,18 +10391,126 @@ static int div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
return 0;
}
+/* Return the first integer division of "bmap" in the range
+ * [first, first + n[ that may depend on any output dimensions and
+ * that has a non-zero coefficient in "c" (where the first coefficient
+ * in "c" corresponds to integer division "first").
+ */
+static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
+ isl_int *c, int first, int n)
+{
+ int k;
+
+ if (!bmap)
+ return -1;
+
+ for (k = first; k < first + n; ++k) {
+ if (isl_int_is_zero(c[k]))
+ continue;
+ if (div_may_involve_output(bmap, k))
+ return k;
+ }
+
+ return first + n;
+}
+
+/* Look for a pair of inequality constraints in "bmap" of the form
+ *
+ * -l + i >= 0 or i >= l
+ * and
+ * n + l - i >= 0 or i <= l + n
+ *
+ * with n < "m" and i the output dimension at position "pos".
+ * (Note that n >= 0 as otherwise the two constraints would conflict.)
+ * Furthermore, "l" is only allowed to involve parameters, input dimensions
+ * and earlier output dimensions, as well as integer divisions that do
+ * not involve any of the output dimensions.
+ *
+ * Return the index of the first inequality constraint or bmap->n_ineq
+ * if no such pair can be found.
+ */
+static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
+ int pos, isl_int m)
+{
+ int i, j;
+ isl_ctx *ctx;
+ unsigned total;
+ unsigned n_div, o_div;
+ unsigned n_out, o_out;
+ int less;
+
+ if (!bmap)
+ return -1;
+
+ ctx = isl_basic_map_get_ctx(bmap);
+ total = 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);
+ n_div = isl_basic_map_dim(bmap, isl_dim_div);
+ o_div = isl_basic_map_offset(bmap, isl_dim_div);
+ for (i = 0; i < bmap->n_ineq; ++i) {
+ if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one))
+ continue;
+ if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
+ n_out - (pos + 1)) != -1)
+ continue;
+ if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
+ 0, n_div) < n_div)
+ continue;
+ for (j = i + 1; j < bmap->n_ineq; ++j) {
+ if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],
+ ctx->one))
+ continue;
+ if (!isl_seq_is_neg(bmap->ineq[i] + 1,
+ bmap->ineq[j] + 1, total))
+ continue;
+ break;
+ }
+ if (j >= bmap->n_ineq)
+ continue;
+ isl_int_add(bmap->ineq[i][0],
+ bmap->ineq[i][0], bmap->ineq[j][0]);
+ less = isl_int_abs_lt(bmap->ineq[i][0], m);
+ isl_int_sub(bmap->ineq[i][0],
+ bmap->ineq[i][0], bmap->ineq[j][0]);
+ if (!less)
+ continue;
+ if (isl_int_is_one(bmap->ineq[i][o_out + pos]))
+ return i;
+ else
+ return j;
+ }
+
+ return bmap->n_ineq;
+}
+
/* 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.
+ * In this case, *div is set to the number of integer divisions and
+ * *ineq is set to the number of inequality constraints (provided
+ * div and ineq are not NULL).
+ *
+ * The equality may also involve a single integer division involving
+ * the output dimensions (typically only output dimension "pos") as
+ * long as the coefficient of output dimension "pos" is 1 or -1 and
+ * there is a pair of constraints i >= l and i <= l + n, with i referring
+ * to output dimension "pos", l an expression involving only earlier
+ * dimensions and n smaller than the coefficient of the integer division
+ * in the equality. In this case, the output dimension can be defined
+ * in terms of a modulo expression that does not involve the integer division.
+ * *div is then set to this single integer division and
+ * *ineq is set to the index of constraint i >= l.
+ *
* 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 pos, int *div, int *ineq)
{
- int j, k;
+ int j, k, l;
unsigned n_out, o_out;
unsigned n_div, o_div;
@@ -10325,20 +10522,37 @@ int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
n_div = isl_basic_map_dim(bmap, isl_dim_div);
o_div = isl_basic_map_offset(bmap, isl_dim_div);
+ if (ineq)
+ *ineq = bmap->n_ineq;
+ if (div)
+ *div = n_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;
- }
+ k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
+ 0, n_div);
if (k >= n_div)
return j;
+ if (!isl_int_is_one(bmap->eq[j][o_out + pos]) &&
+ !isl_int_is_negone(bmap->eq[j][o_out + pos]))
+ continue;
+ if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
+ k + 1, n_div - (k+1)) < n_div)
+ continue;
+ l = find_modulo_constraint_pair(bmap, pos,
+ bmap->eq[j][o_div + k]);
+ if (l < 0)
+ return -1;
+ if (l >= bmap->n_ineq)
+ continue;
+ if (div)
+ *div = k;
+ if (ineq)
+ *ineq = l;
+ return j;
}
return bmap->n_eq;
@@ -10362,7 +10576,8 @@ isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
for (i = 0; i < n_out; ++i) {
int eq;
- eq = isl_basic_map_output_defining_equality(bmap, i);
+ eq = isl_basic_map_output_defining_equality(bmap, i,
+ NULL, NULL);
if (eq < 0)
return isl_bool_error;
if (eq >= bmap->n_eq)
@@ -10582,6 +10797,35 @@ isl_bool isl_set_is_wrapping(__isl_keep isl_set *set)
return isl_space_is_wrapping(set->dim);
}
+/* Modify the space of "map" through a call to "change".
+ * If "can_change" is set (not NULL), then first call it to check
+ * if the modification is allowed, printing the error message "cannot_change"
+ * if it is not.
+ */
+static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
+ isl_bool (*can_change)(__isl_keep isl_map *map),
+ const char *cannot_change,
+ __isl_give isl_space *(*change)(__isl_take isl_space *space))
+{
+ isl_bool ok;
+ isl_space *space;
+
+ if (!map)
+ return NULL;
+
+ ok = can_change ? can_change(map) : isl_bool_true;
+ if (ok < 0)
+ return isl_map_free(map);
+ if (!ok)
+ isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,
+ return isl_map_free(map));
+
+ space = change(isl_map_get_space(map));
+ map = isl_map_reset_space(map, space);
+
+ return map;
+}
+
/* Is the domain of "map" a wrapped relation?
*/
isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
@@ -10620,27 +10864,11 @@ error:
return NULL;
}
+/* Given a map A -> B, return the set (A -> B).
+ */
__isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
{
- int i;
-
- map = isl_map_cow(map);
- if (!map)
- return NULL;
-
- for (i = 0; i < map->n; ++i) {
- map->p[i] = (isl_basic_map *)isl_basic_map_wrap(map->p[i]);
- if (!map->p[i])
- goto error;
- }
- map->dim = isl_space_wrap(map->dim);
- if (!map->dim)
- goto error;
-
- return (isl_set *)map;
-error:
- isl_map_free(map);
- return NULL;
+ return isl_map_change_space(map, NULL, NULL, &isl_space_wrap);
}
__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
@@ -10661,35 +10889,13 @@ error:
return NULL;
}
+/* Given a set (A -> B), return the map A -> B.
+ * Error out if "set" is not of the form (A -> B).
+ */
__isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
{
- int i;
-
- if (!set)
- return NULL;
-
- if (!isl_set_is_wrapping(set))
- isl_die(set->ctx, isl_error_invalid, "not a wrapping set",
- goto error);
-
- set = isl_set_cow(set);
- if (!set)
- return NULL;
-
- for (i = 0; i < set->n; ++i) {
- set->p[i] = (isl_basic_set *)isl_basic_set_unwrap(set->p[i]);
- if (!set->p[i])
- goto error;
- }
-
- set->dim = isl_space_unwrap(set->dim);
- if (!set->dim)
- goto error;
-
- return (isl_map *)set;
-error:
- isl_set_free(set);
- return NULL;
+ return isl_map_change_space(set, &isl_set_is_wrapping,
+ "not a wrapping set", &isl_space_unwrap);
}
__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
@@ -10826,33 +11032,17 @@ error:
return NULL;
}
+/* Remove any internal structure from the spaces of domain and range of "map".
+ */
__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
{
- int i;
-
if (!map)
return NULL;
if (!map->dim->nested[0] && !map->dim->nested[1])
return map;
- map = isl_map_cow(map);
- if (!map)
- return NULL;
-
- for (i = 0; i < map->n; ++i) {
- map->p[i] = isl_basic_map_flatten(map->p[i]);
- if (!map->p[i])
- goto error;
- }
- map->dim = isl_space_flatten(map->dim);
- if (!map->dim)
- goto error;
-
- return map;
-error:
- isl_map_free(map);
- return NULL;
+ return isl_map_change_space(map, NULL, NULL, &isl_space_flatten);
}
__isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
@@ -10873,62 +11063,30 @@ __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
return map;
}
+/* Remove any internal structure from the space of the domain of "map".
+ */
__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
{
- int i;
-
if (!map)
return NULL;
if (!map->dim->nested[0])
return map;
- map = isl_map_cow(map);
- if (!map)
- return NULL;
-
- for (i = 0; i < map->n; ++i) {
- map->p[i] = isl_basic_map_flatten_domain(map->p[i]);
- if (!map->p[i])
- goto error;
- }
- map->dim = isl_space_flatten_domain(map->dim);
- if (!map->dim)
- goto error;
-
- return map;
-error:
- isl_map_free(map);
- return NULL;
+ return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_domain);
}
+/* Remove any internal structure from the space of the range of "map".
+ */
__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
{
- int i;
-
if (!map)
return NULL;
if (!map->dim->nested[1])
return map;
- map = isl_map_cow(map);
- if (!map)
- return NULL;
-
- for (i = 0; i < map->n; ++i) {
- map->p[i] = isl_basic_map_flatten_range(map->p[i]);
- if (!map->p[i])
- goto error;
- }
- map->dim = isl_space_flatten_range(map->dim);
- if (!map->dim)
- goto error;
-
- return map;
-error:
- isl_map_free(map);
- return NULL;
+ return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_range);
}
/* Reorder the dimensions of "bmap" according to the given dim_map
@@ -11305,6 +11463,7 @@ __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
bmap->dim = isl_space_zip(bmap->dim);
if (!bmap->dim)
goto error;
+ bmap = isl_basic_map_mark_final(bmap);
return bmap;
error:
isl_basic_map_free(bmap);
@@ -11385,6 +11544,7 @@ __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
bmap->dim = isl_space_curry(bmap->dim);
if (!bmap->dim)
goto error;
+ bmap = isl_basic_map_mark_final(bmap);
return bmap;
error:
isl_basic_map_free(bmap);
@@ -11396,33 +11556,30 @@ error:
*/
__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
{
- int i;
-
- if (!map)
- return NULL;
-
- if (!isl_map_can_curry(map))
- isl_die(map->ctx, isl_error_invalid, "map cannot be curried",
- goto error);
+ return isl_map_change_space(map, &isl_map_can_curry,
+ "map cannot be curried", &isl_space_curry);
+}
- map = isl_map_cow(map);
+/* Can isl_map_range_curry be applied to "map"?
+ * That is, does it have a nested relation in its range,
+ * the domain of which is itself a nested relation?
+ */
+isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
+{
if (!map)
- return NULL;
-
- for (i = 0; i < map->n; ++i) {
- map->p[i] = isl_basic_map_curry(map->p[i]);
- if (!map->p[i])
- goto error;
- }
+ return isl_bool_error;
- map->dim = isl_space_curry(map->dim);
- if (!map->dim)
- goto error;
+ return isl_space_can_range_curry(map->dim);
+}
- return map;
-error:
- isl_map_free(map);
- return NULL;
+/* Given a map A -> ((B -> C) -> D), return the corresponding map
+ * A -> (B -> (C -> D)).
+ */
+__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
+{
+ return isl_map_change_space(map, &isl_map_can_range_curry,
+ "map range cannot be curried",
+ &isl_space_range_curry);
}
/* Can we apply isl_basic_map_uncurry to "bmap"?
@@ -11466,6 +11623,7 @@ __isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
bmap->dim = isl_space_uncurry(bmap->dim);
if (!bmap->dim)
return isl_basic_map_free(bmap);
+ bmap = isl_basic_map_mark_final(bmap);
return bmap;
}
@@ -11474,30 +11632,8 @@ __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)
{
- int i;
-
- if (!map)
- return NULL;
-
- if (!isl_map_can_uncurry(map))
- isl_die(map->ctx, isl_error_invalid, "map cannot be uncurried",
- return isl_map_free(map));
-
- map = isl_map_cow(map);
- if (!map)
- return NULL;
-
- for (i = 0; i < map->n; ++i) {
- map->p[i] = isl_basic_map_uncurry(map->p[i]);
- if (!map->p[i])
- return isl_map_free(map);
- }
-
- map->dim = isl_space_uncurry(map->dim);
- if (!map->dim)
- return isl_map_free(map);
-
- return map;
+ return isl_map_change_space(map, &isl_map_can_uncurry,
+ "map cannot be uncurried", &isl_space_uncurry);
}
/* Construct a basic map mapping the domain of the affine expression
diff --git a/polly/lib/External/isl/isl_map_private.h b/polly/lib/External/isl/isl_map_private.h
index 1a36ac670c3..df44fb02beb 100644
--- a/polly/lib/External/isl/isl_map_private.h
+++ b/polly/lib/External/isl/isl_map_private.h
@@ -128,6 +128,8 @@ __isl_give isl_basic_set *isl_basic_set_simplify(
__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_mark_final(
+ __isl_take isl_basic_map *bmap);
__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,
@@ -271,6 +273,10 @@ struct isl_basic_map *isl_basic_map_gauss(
struct isl_basic_map *bmap, int *progress);
struct isl_basic_set *isl_basic_set_gauss(
struct isl_basic_set *bset, int *progress);
+int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
+ isl_int *c1, isl_int *c2);
+__isl_give isl_basic_map *isl_basic_map_sort_constraints(
+ __isl_take isl_basic_map *bmap);
__isl_give isl_basic_set *isl_basic_set_sort_constraints(
__isl_take isl_basic_set *bset);
int isl_basic_map_plain_cmp(const __isl_keep isl_basic_map *bmap1,
@@ -291,6 +297,10 @@ __isl_give isl_basic_set_list *isl_basic_map_list_underlying_set(
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);
+__isl_give isl_basic_map *isl_basic_map_drop_constraint_involving_unknown_divs(
+ __isl_take isl_basic_map *bmap);
+__isl_give isl_map *isl_map_drop_constraint_involving_unknown_divs(
+ __isl_take isl_map *map);
__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving(
__isl_take isl_basic_set *bset, unsigned first, unsigned n);
__isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset,
@@ -397,7 +407,9 @@ __isl_give isl_basic_map *isl_basic_map_from_local_space(
__isl_give isl_basic_set *isl_basic_set_expand_divs(
__isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp);
-int isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap);
+isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div);
+isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap);
+isl_bool isl_map_divs_known(__isl_keep isl_map *map);
__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_set *bset);
__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap);
@@ -436,6 +448,11 @@ 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_map *isl_map_plain_gist_basic_map(__isl_take isl_map *map,
+ __isl_take isl_basic_map *context);
+
+__isl_give isl_basic_map *isl_map_plain_unshifted_simple_hull(
+ __isl_take isl_map *map);
__isl_give isl_basic_set *isl_basic_set_plain_affine_hull(
__isl_take isl_basic_set *bset);
__isl_give isl_basic_map *isl_basic_map_plain_affine_hull(
@@ -454,7 +471,7 @@ 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);
+ int pos, int *div, int *ineq);
__isl_give isl_basic_map *isl_basic_map_reduce_coefficients(
__isl_take isl_basic_map *bmap);
diff --git a/polly/lib/External/isl/isl_map_simplify.c b/polly/lib/External/isl/isl_map_simplify.c
index 52daf2944a4..62260c11a63 100644
--- a/polly/lib/External/isl/isl_map_simplify.c
+++ b/polly/lib/External/isl/isl_map_simplify.c
@@ -1610,15 +1610,28 @@ static struct isl_basic_map *remove_redundant_divs(struct isl_basic_map *bmap)
return bmap;
}
-struct isl_basic_map *isl_basic_map_finalize(struct isl_basic_map *bmap)
+/* Mark "bmap" as final, without checking for obviously redundant
+ * integer divisions. This function should be used when "bmap"
+ * is known not to involve any such integer divisions.
+ */
+__isl_give isl_basic_map *isl_basic_map_mark_final(
+ __isl_take isl_basic_map *bmap)
{
- bmap = remove_redundant_divs(bmap);
if (!bmap)
return NULL;
ISL_F_SET(bmap, ISL_BASIC_SET_FINAL);
return bmap;
}
+/* Mark "bmap" as final, after removing obviously redundant integer divisions.
+ */
+struct isl_basic_map *isl_basic_map_finalize(struct isl_basic_map *bmap)
+{
+ bmap = remove_redundant_divs(bmap);
+ bmap = isl_basic_map_mark_final(bmap);
+ return bmap;
+}
+
struct isl_basic_set *isl_basic_set_finalize(struct isl_basic_set *bset)
{
return (struct isl_basic_set *)
@@ -1830,6 +1843,86 @@ __isl_give isl_basic_set *isl_basic_set_eliminate(
return isl_basic_map_eliminate(bset, type, first, n);
}
+/* Remove all constraints from "bmap" that reference any unknown local
+ * variables (directly or indirectly).
+ *
+ * Dropping all constraints on a local variable will make it redundant,
+ * so it will get removed implicitly by
+ * isl_basic_map_drop_constraints_involving_dims. Some other local
+ * variables may also end up becoming redundant if they only appear
+ * in constraints together with the unknown local variable.
+ * Therefore, start over after calling
+ * isl_basic_map_drop_constraints_involving_dims.
+ */
+__isl_give isl_basic_map *isl_basic_map_drop_constraint_involving_unknown_divs(
+ __isl_take isl_basic_map *bmap)
+{
+ isl_bool known;
+ int i, n_div, o_div;
+
+ known = isl_basic_map_divs_known(bmap);
+ if (known < 0)
+ return isl_basic_map_free(bmap);
+ if (known)
+ return bmap;
+
+ n_div = isl_basic_map_dim(bmap, isl_dim_div);
+ o_div = isl_basic_map_offset(bmap, isl_dim_div) - 1;
+
+ for (i = 0; i < n_div; ++i) {
+ known = isl_basic_map_div_is_known(bmap, i);
+ if (known < 0)
+ return isl_basic_map_free(bmap);
+ if (known)
+ continue;
+ bmap = remove_dependent_vars(bmap, o_div + i);
+ bmap = isl_basic_map_drop_constraints_involving_dims(bmap,
+ isl_dim_div, i, 1);
+ if (!bmap)
+ return NULL;
+ n_div = isl_basic_map_dim(bmap, isl_dim_div);
+ i = -1;
+ }
+
+ return bmap;
+}
+
+/* Remove all constraints from "map" that reference any unknown local
+ * variables (directly or indirectly).
+ *
+ * Since constraints may get dropped from the basic maps,
+ * they may no longer be disjoint from each other.
+ */
+__isl_give isl_map *isl_map_drop_constraint_involving_unknown_divs(
+ __isl_take isl_map *map)
+{
+ int i;
+ isl_bool known;
+
+ known = isl_map_divs_known(map);
+ if (known < 0)
+ return isl_map_free(map);
+ if (known)
+ return map;
+
+ map = isl_map_cow(map);
+ if (!map)
+ return NULL;
+
+ for (i = 0; i < map->n; ++i) {
+ map->p[i] =
+ isl_basic_map_drop_constraint_involving_unknown_divs(
+ map->p[i]);
+ if (!map->p[i])
+ return isl_map_free(map);
+ }
+
+ if (map->n > 1)
+ ISL_F_CLR(map, ISL_MAP_DISJOINT);
+
+ return map;
+}
+
/* Don't assume equalities are in order, because align_divs
* may have changed the order of the divs.
*/
@@ -2842,6 +2935,230 @@ error:
return NULL;
}
+/* Drop all inequalities from "bmap" that also appear in "context".
+ * "context" is assumed to have only known local variables and
+ * the initial local variables of "bmap" are assumed to be the same
+ * as those of "context".
+ * The constraints of both "bmap" and "context" are assumed
+ * to have been sorted using isl_basic_map_sort_constraints.
+ *
+ * Run through the inequality constraints of "bmap" and "context"
+ * in sorted order.
+ * If a constraint of "bmap" involves variables not in "context",
+ * then it cannot appear in "context".
+ * If a matching constraint is found, it is removed from "bmap".
+ */
+static __isl_give isl_basic_map *drop_inequalities(
+ __isl_take isl_basic_map *bmap, __isl_keep isl_basic_map *context)
+{
+ int i1, i2;
+ unsigned total, extra;
+
+ if (!bmap || !context)
+ return isl_basic_map_free(bmap);
+
+ total = isl_basic_map_total_dim(context);
+ extra = isl_basic_map_total_dim(bmap) - total;
+
+ i1 = bmap->n_ineq - 1;
+ i2 = context->n_ineq - 1;
+ while (bmap && i1 >= 0 && i2 >= 0) {
+ int cmp;
+
+ if (isl_seq_first_non_zero(bmap->ineq[i1] + 1 + total,
+ extra) != -1) {
+ --i1;
+ continue;
+ }
+ cmp = isl_basic_map_constraint_cmp(context, bmap->ineq[i1],
+ context->ineq[i2]);
+ if (cmp < 0) {
+ --i2;
+ continue;
+ }
+ if (cmp > 0) {
+ --i1;
+ continue;
+ }
+ if (isl_int_eq(bmap->ineq[i1][0], context->ineq[i2][0])) {
+ bmap = isl_basic_map_cow(bmap);
+ if (isl_basic_map_drop_inequality(bmap, i1) < 0)
+ bmap = isl_basic_map_free(bmap);
+ }
+ --i1;
+ --i2;
+ }
+
+ return bmap;
+}
+
+/* Drop all equalities from "bmap" that also appear in "context".
+ * "context" is assumed to have only known local variables and
+ * the initial local variables of "bmap" are assumed to be the same
+ * as those of "context".
+ *
+ * Run through the equality constraints of "bmap" and "context"
+ * in sorted order.
+ * If a constraint of "bmap" involves variables not in "context",
+ * then it cannot appear in "context".
+ * If a matching constraint is found, it is removed from "bmap".
+ */
+static __isl_give isl_basic_map *drop_equalities(
+ __isl_take isl_basic_map *bmap, __isl_keep isl_basic_map *context)
+{
+ int i1, i2;
+ unsigned total, extra;
+
+ if (!bmap || !context)
+ return isl_basic_map_free(bmap);
+
+ total = isl_basic_map_total_dim(context);
+ extra = isl_basic_map_total_dim(bmap) - total;
+
+ i1 = bmap->n_eq - 1;
+ i2 = context->n_eq - 1;
+
+ while (bmap && i1 >= 0 && i2 >= 0) {
+ int last1, last2;
+
+ if (isl_seq_first_non_zero(bmap->eq[i1] + 1 + total,
+ extra) != -1)
+ break;
+ last1 = isl_seq_last_non_zero(bmap->eq[i1] + 1, total);
+ last2 = isl_seq_last_non_zero(context->eq[i2] + 1, total);
+ if (last1 > last2) {
+ --i2;
+ continue;
+ }
+ if (last1 < last2) {
+ --i1;
+ continue;
+ }
+ if (isl_seq_eq(bmap->eq[i1], context->eq[i2], 1 + total)) {
+ bmap = isl_basic_map_cow(bmap);
+ if (isl_basic_map_drop_equality(bmap, i1) < 0)
+ bmap = isl_basic_map_free(bmap);
+ }
+ --i1;
+ --i2;
+ }
+
+ return bmap;
+}
+
+/* Remove the constraints in "context" from "bmap".
+ * "context" is assumed to have explicit representations
+ * for all local variables.
+ *
+ * First align the divs of "bmap" to those of "context" and
+ * sort the constraints. Then drop all constraints from "bmap"
+ * that appear in "context".
+ */
+__isl_give isl_basic_map *isl_basic_map_plain_gist(
+ __isl_take isl_basic_map *bmap, __isl_take isl_basic_map *context)
+{
+ isl_bool done, known;
+
+ done = isl_basic_map_is_universe(context);
+ if (done == isl_bool_false)
+ done = isl_basic_map_is_universe(bmap);
+ if (done == isl_bool_false)
+ done = isl_basic_map_plain_is_empty(context);
+ if (done == isl_bool_false)
+ done = isl_basic_map_plain_is_empty(bmap);
+ if (done < 0)
+ goto error;
+ if (done) {
+ isl_basic_map_free(context);
+ return bmap;
+ }
+ known = isl_basic_map_divs_known(context);
+ if (known < 0)
+ goto error;
+ if (!known)
+ isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
+ "context has unknown divs", goto error);
+
+ bmap = isl_basic_map_align_divs(bmap, context);
+ bmap = isl_basic_map_gauss(bmap, NULL);
+ bmap = isl_basic_map_sort_constraints(bmap);
+ context = isl_basic_map_sort_constraints(context);
+
+ bmap = drop_inequalities(bmap, context);
+ bmap = drop_equalities(bmap, context);
+
+ isl_basic_map_free(context);
+ bmap = isl_basic_map_finalize(bmap);
+ return bmap;
+error:
+ isl_basic_map_free(bmap);
+ isl_basic_map_free(context);
+ return NULL;
+}
+
+/* Replace "map" by the disjunct at position "pos" and free "context".
+ */
+static __isl_give isl_map *replace_by_disjunct(__isl_take isl_map *map,
+ int pos, __isl_take isl_basic_map *context)
+{
+ isl_basic_map *bmap;
+
+ bmap = isl_basic_map_copy(map->p[pos]);
+ isl_map_free(map);
+ isl_basic_map_free(context);
+ return isl_map_from_basic_map(bmap);
+}
+
+/* Remove the constraints in "context" from "map".
+ * If any of the disjuncts in the result turns out to be the universe,
+ * the return this universe.
+ * "context" is assumed to have explicit representations
+ * for all local variables.
+ */
+__isl_give isl_map *isl_map_plain_gist_basic_map(__isl_take isl_map *map,
+ __isl_take isl_basic_map *context)
+{
+ int i;
+ isl_bool univ, known;
+
+ univ = isl_basic_map_is_universe(context);
+ if (univ < 0)
+ goto error;
+ if (univ) {
+ isl_basic_map_free(context);
+ return map;
+ }
+ known = isl_basic_map_divs_known(context);
+ if (known < 0)
+ goto error;
+ if (!known)
+ isl_die(isl_map_get_ctx(map), isl_error_invalid,
+ "context has unknown divs", goto error);
+
+ map = isl_map_cow(map);
+ if (!map)
+ goto error;
+ for (i = 0; i < map->n; ++i) {
+ map->p[i] = isl_basic_map_plain_gist(map->p[i],
+ isl_basic_map_copy(context));
+ univ = isl_basic_map_is_universe(map->p[i]);
+ if (univ < 0)
+ goto error;
+ if (univ && map->n > 1)
+ return replace_by_disjunct(map, i, context);
+ }
+
+ isl_basic_map_free(context);
+ ISL_F_CLR(map, ISL_MAP_NORMALIZED);
+ if (map->n > 1)
+ ISL_F_CLR(map, ISL_MAP_DISJOINT);
+ return map;
+error:
+ isl_map_free(map);
+ isl_basic_map_free(context);
+ return NULL;
+}
+
/* Return a map that has the same intersection with "context" as "map"
* and that is as "simple" as possible.
*
@@ -3233,6 +3550,13 @@ isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
return isl_map_is_disjoint(set1, set2);
}
+/* Is "v" equal to 0, 1 or -1?
+ */
+static int is_zero_or_one(isl_int v)
+{
+ return isl_int_is_zero(v) || isl_int_is_one(v) || isl_int_is_negone(v);
+}
+
/* 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.
@@ -3258,6 +3582,8 @@ isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
*
* e + f (a + m b) >= 0
*
+ * Furthermore, in the constraints that only contain b, the coefficient
+ * of b should be equal to 1 or -1.
* If so, we return b so that "a + m b" can be replaced by
* a single div "c = a + m b".
*/
@@ -3314,8 +3640,11 @@ static int div_find_coalesce(struct isl_basic_map *bmap, int *pairs,
int valid;
if (j == l || j == u)
continue;
- if (isl_int_is_zero(bmap->ineq[j][1 + dim + div]))
- continue;
+ if (isl_int_is_zero(bmap->ineq[j][1 + dim + div])) {
+ if (is_zero_or_one(bmap->ineq[j][1 + dim + i]))
+ continue;
+ break;
+ }
if (isl_int_is_zero(bmap->ineq[j][1 + dim + i]))
break;
isl_int_mul(bmap->ineq[j][1 + dim + div],
@@ -3487,8 +3816,8 @@ error:
return NULL;
}
-/* Given a pair of divs div1 and div2 such that, expect for the lower bound l
- * and the upper bound u, div1 always occurs together with div2 in the form
+/* Given a pair of divs div1 and div2 such that, except for the lower bound l
+ * and the upper bound u, div1 always occurs together with div2 in the form
* (div1 + m div2), where m is the constant range on the variable div1
* allowed by l and u, replace the pair div1 and div2 by a single
* div that is equal to div1 + m div2.
@@ -3496,6 +3825,7 @@ error:
* The new div will appear in the location that contains div2.
* We need to modify all constraints that contain
* div2 = (div - div1) / m
+ * The coefficient of div2 is known to be equal to 1 or -1.
* (If a constraint does not contain div2, it will also not contain div1.)
* If the constraint also contains div1, then we know they appear
* as f (div1 + m div2) and we can simply replace (div1 + m div2) by div,
@@ -3512,20 +3842,19 @@ error:
*
* A lower bound on div2
*
- * n div2 + t >= 0
+ * div2 + t >= 0
*
* can be replaced by
*
- * (n * (m div 2 + div1) + m t + n f)/g >= 0
+ * m div2 + div1 + m t + f >= 0
*
- * with g = gcd(m,n).
* An upper bound
*
- * -n div2 + t >= 0
+ * -div2 + t >= 0
*
* can be replaced by
*
- * (-n * (m div2 + div1) + m t + n f')/g >= 0
+ * -(m div2 + div1) + m t + f' >= 0
*
* These constraint are those that we would obtain from eliminating
* div1 using Fourier-Motzkin.
@@ -3536,17 +3865,16 @@ error:
static struct isl_basic_map *coalesce_divs(struct isl_basic_map *bmap,
unsigned div1, unsigned div2, unsigned l, unsigned u)
{
- isl_int a;
- isl_int b;
+ isl_ctx *ctx;
isl_int m;
unsigned dim, total;
int i;
+ ctx = isl_basic_map_get_ctx(bmap);
+
dim = isl_space_dim(bmap->dim, isl_dim_all);
total = 1 + dim + bmap->n_div;
- isl_int_init(a);
- isl_int_init(b);
isl_int_init(m);
isl_int_add(m, bmap->ineq[l][0], bmap->ineq[u][0]);
isl_int_add_ui(m, m, 1);
@@ -3556,26 +3884,18 @@ static struct isl_basic_map *coalesce_divs(struct isl_basic_map *bmap,
continue;
if (isl_int_is_zero(bmap->ineq[i][1 + dim + div2]))
continue;
- if (isl_int_is_zero(bmap->ineq[i][1 + dim + div1])) {
- isl_int_gcd(b, m, bmap->ineq[i][1 + dim + div2]);
- isl_int_divexact(a, m, b);
- isl_int_divexact(b, bmap->ineq[i][1 + dim + div2], b);
- if (isl_int_is_pos(b)) {
- isl_seq_combine(bmap->ineq[i], a, bmap->ineq[i],
- b, bmap->ineq[l], total);
- } else {
- isl_int_neg(b, b);
- isl_seq_combine(bmap->ineq[i], a, bmap->ineq[i],
- b, bmap->ineq[u], total);
- }
- }
+ if (isl_int_is_zero(bmap->ineq[i][1 + dim + div1]))
+ if (isl_int_is_pos(bmap->ineq[i][1 + dim + div2]))
+ isl_seq_combine(bmap->ineq[i], m, bmap->ineq[i],
+ ctx->one, bmap->ineq[l], total);
+ else
+ isl_seq_combine(bmap->ineq[i], m, bmap->ineq[i],
+ ctx->one, bmap->ineq[u], total);
isl_int_set(bmap->ineq[i][1 + dim + div2],
bmap->ineq[i][1 + dim + div1]);
isl_int_set_si(bmap->ineq[i][1 + dim + div1], 0);
}
- isl_int_clear(a);
- isl_int_clear(b);
isl_int_clear(m);
if (l > u) {
isl_basic_map_drop_inequality(bmap, l);
diff --git a/polly/lib/External/isl/isl_mat.c b/polly/lib/External/isl/isl_mat.c
index f859601e5c7..0cb67723a47 100644
--- a/polly/lib/External/isl/isl_mat.c
+++ b/polly/lib/External/isl/isl_mat.c
@@ -1123,7 +1123,7 @@ static int preimage(struct isl_ctx *ctx, isl_int **q, unsigned n,
* M the matrix mat.
*
* If there are fewer variables x' then there are x, then we perform
- * the transformation in place, which that, in principle,
+ * the transformation in place, which means that, in principle,
* this frees up some extra variables as the number
* of columns remains constant, but we would have to extend
* the div array too as the number of rows in this array is assumed
diff --git a/polly/lib/External/isl/isl_morph.c b/polly/lib/External/isl/isl_morph.c
index 9c14c80a466..92215af667f 100644
--- a/polly/lib/External/isl/isl_morph.c
+++ b/polly/lib/External/isl/isl_morph.c
@@ -398,7 +398,7 @@ static __isl_give isl_basic_set *copy_equalities(__isl_keep isl_basic_set *bset,
k = isl_basic_set_alloc_equality(eq);
if (k < 0)
goto error;
- isl_seq_cpy(eq->eq[k], bset->eq[first + k], 1 + total);
+ isl_seq_cpy(eq->eq[k], bset->eq[first + i], 1 + total);
}
return eq;
diff --git a/polly/lib/External/isl/isl_multi_templ.c b/polly/lib/External/isl/isl_multi_templ.c
index 4fac96ba35c..f8924dd80ff 100644
--- a/polly/lib/External/isl/isl_multi_templ.c
+++ b/polly/lib/External/isl/isl_multi_templ.c
@@ -1248,7 +1248,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_multi_val)(
multi = FN(MULTI(BASE),cow)(multi);
if (!multi)
- return NULL;
+ goto error;
for (i = 0; i < multi->n; ++i) {
isl_val *v;
diff --git a/polly/lib/External/isl/isl_output.c b/polly/lib/External/isl/isl_output.c
index 26ef5472bc8..a0a578779bc 100644
--- a/polly/lib/External/isl/isl_output.c
+++ b/polly/lib/External/isl/isl_output.c
@@ -30,6 +30,7 @@
#include <isl_val_private.h>
#include <isl/ast_build.h>
#include <isl_sort.h>
+#include <isl_output_private.h>
static const char *s_to[2] = { " -> ", " \\to " };
static const char *s_and[2] = { " and ", " \\wedge " };
@@ -174,7 +175,10 @@ static int count_same_name(__isl_keep isl_space *dim,
return count;
}
-static __isl_give isl_printer *print_name(__isl_keep isl_space *dim,
+/* Print the name of the variable of type "type" and position "pos"
+ * in "space" to "p".
+ */
+static __isl_give isl_printer *print_name(__isl_keep isl_space *space,
__isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
int latex)
{
@@ -182,7 +186,8 @@ static __isl_give isl_printer *print_name(__isl_keep isl_space *dim,
char buffer[20];
int primes;
- name = type == isl_dim_div ? NULL : isl_space_get_dim_name(dim, type, pos);
+ name = type == isl_dim_div ? NULL
+ : isl_space_get_dim_name(space, type, pos);
if (!name) {
const char *prefix;
@@ -190,14 +195,14 @@ static __isl_give isl_printer *print_name(__isl_keep isl_space *dim,
prefix = s_param_prefix[latex];
else if (type == isl_dim_div)
prefix = s_div_prefix[latex];
- else if (isl_space_is_set(dim) || type == isl_dim_in)
+ else if (isl_space_is_set(space) || type == isl_dim_in)
prefix = s_input_prefix[latex];
else
prefix = s_output_prefix[latex];
snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
name = buffer;
}
- primes = count_same_name(dim, name == buffer ? isl_dim_div : type,
+ primes = count_same_name(space, name == buffer ? isl_dim_div : type,
pos, name);
p = isl_printer_print_str(p, name);
while (primes-- > 0)
@@ -229,10 +234,27 @@ static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos)
return type;
}
+/* Can the div expression of the integer division at position "row" of "div"
+ * be printed?
+ * In particular, are the div expressions available and does the selected
+ * variable have a known explicit representation?
+ * Furthermore, the Omega format does not allow and div expressions
+ * to be printed.
+ */
+static isl_bool can_print_div_expr(__isl_keep isl_printer *p,
+ __isl_keep isl_mat *div, int pos)
+{
+ if (p->output_format == ISL_FORMAT_OMEGA)
+ return isl_bool_false;
+ if (!div)
+ return isl_bool_false;
+ return !isl_int_is_zero(div->row[pos][0]);
+}
+
static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
__isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
-static __isl_give isl_printer *print_term(__isl_keep isl_space *dim,
+static __isl_give isl_printer *print_term(__isl_keep isl_space *space,
__isl_keep isl_mat *div,
isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)
{
@@ -242,9 +264,8 @@ static __isl_give isl_printer *print_term(__isl_keep isl_space *dim,
if (pos == 0)
return isl_printer_print_isl_int(p, c);
- type = pos2type(dim, &pos);
- print_div_def = type == isl_dim_div && div &&
- !isl_int_is_zero(div->row[pos][0]);
+ type = pos2type(space, &pos);
+ print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos);
if (isl_int_is_one(c))
;
@@ -256,9 +277,9 @@ static __isl_give isl_printer *print_term(__isl_keep isl_space *dim,
p = isl_printer_print_str(p, "*");
}
if (print_div_def)
- p = print_div(dim, div, pos, p);
+ p = print_div(space, div, pos, p);
else
- p = print_name(dim, p, type, pos, latex);
+ p = print_name(space, p, type, pos, latex);
return p;
}
@@ -291,34 +312,18 @@ static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
return p;
}
+/* Print an affine expression "c" corresponding to a constraint in "bmap"
+ * to "p", with the variable names taken from "space" and
+ * the integer division definitions taken from "div".
+ */
static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
- __isl_keep isl_space *dim, __isl_take isl_printer *p, isl_int *c)
+ __isl_keep isl_space *space, __isl_keep isl_mat *div,
+ __isl_take isl_printer *p, isl_int *c)
{
unsigned len = 1 + isl_basic_map_total_dim(bmap);
- return print_affine_of_len(dim, NULL, p, c, len);
+ return print_affine_of_len(space, div, p, c, len);
}
-/* 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;
-
- isl_space *space;
- enum isl_dim_type type;
-};
-
/* 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,
@@ -407,20 +412,20 @@ static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
return p;
}
-static __isl_give isl_printer *print_space(__isl_keep isl_space *dim,
+__isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,
__isl_take isl_printer *p, int rational,
struct isl_print_space_data *data)
{
if (rational && !data->latex)
p = isl_printer_print_str(p, "rat: ");
- if (isl_space_is_params(dim))
+ if (isl_space_is_params(space))
;
- else if (isl_space_is_set(dim))
- p = print_tuple(dim, p, isl_dim_set, data);
+ else if (isl_space_is_set(space))
+ p = print_tuple(space, p, isl_dim_set, data);
else {
- p = print_tuple(dim, p, isl_dim_in, data);
+ p = print_tuple(space, p, isl_dim_in, data);
p = isl_printer_print_str(p, s_to[data->latex]);
- p = print_tuple(dim, p, isl_dim_out, data);
+ p = print_tuple(space, p, isl_dim_out, data);
}
return p;
@@ -440,8 +445,91 @@ static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_space *dim,
return p;
}
+/* Does the inequality constraint following "i" in "bmap"
+ * have an opposite value for the same last coefficient?
+ * "last" is the position of the last coefficient of inequality "i".
+ * If the next constraint is a div constraint, then it is ignored
+ * since div constraints are not printed.
+ */
+static int next_is_opposite(__isl_keep isl_basic_map *bmap, int i, int last)
+{
+ unsigned total = isl_basic_map_total_dim(bmap);
+ unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
+
+ if (i + 1 >= bmap->n_ineq)
+ return 0;
+ if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)
+ return 0;
+ if (last >= o_div &&
+ isl_basic_map_is_div_constraint(bmap, bmap->ineq[i + 1],
+ last - o_div))
+ return 0;
+ return isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&
+ !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]);
+}
+
+/* Return a string representation of the operator used when
+ * printing a constraint where the LHS is greater than or equal to the LHS
+ * (sign > 0) or smaller than or equal to the LHS (sign < 0).
+ * If "strict" is set, then return the strict version of the comparison
+ * operator.
+ */
+static const char *constraint_op(int sign, int strict, int latex)
+{
+ if (strict)
+ return sign < 0 ? "<" : ">";
+ if (sign < 0)
+ return s_le[latex];
+ else
+ return s_ge[latex];
+}
+
+/* Print one side of a constraint "c" from "bmap" to "p", with
+ * the variable names taken from "space" and the integer division definitions
+ * taken from "div".
+ * "last" is the position of the last non-zero coefficient.
+ * Let c' be the result of zeroing out this coefficient, then
+ * the partial constraint
+ *
+ * c' op
+ *
+ * is printed.
+ * "first_constraint" is set if this is the first constraint
+ * in the conjunction.
+ */
+static __isl_give isl_printer *print_half_constraint(struct isl_basic_map *bmap,
+ __isl_keep isl_space *space, __isl_keep isl_mat *div,
+ __isl_take isl_printer *p, isl_int *c, int last, const char *op,
+ int first_constraint, int latex)
+{
+ if (!first_constraint)
+ p = isl_printer_print_str(p, s_and[latex]);
+
+ isl_int_set_si(c[last], 0);
+ p = print_affine(bmap, space, div, p, c);
+
+ p = isl_printer_print_str(p, " ");
+ p = isl_printer_print_str(p, op);
+ p = isl_printer_print_str(p, " ");
+
+ return p;
+}
+
+/* Print a constraint "c" from "bmap" to "p", with the variable names
+ * taken from "space" and the integer division definitions taken from "div".
+ * "last" is the position of the last non-zero coefficient, which is
+ * moreover assumed to be negative.
+ * Let c' be the result of zeroing out this coefficient, then
+ * the constraint is printed in the form
+ *
+ * -c[last] op c'
+ *
+ * "first_constraint" is set if this is the first constraint
+ * in the conjunction.
+ */
static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
- __isl_keep isl_space *dim, __isl_take isl_printer *p,
+ __isl_keep isl_space *space, __isl_keep isl_mat *div,
+ __isl_take isl_printer *p,
isl_int *c, int last, const char *op, int first_constraint, int latex)
{
if (!first_constraint)
@@ -449,24 +537,74 @@ static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
isl_int_abs(c[last], c[last]);
- p = print_term(dim, NULL, c[last], last, p, latex);
+ p = print_term(space, div, c[last], last, p, latex);
p = isl_printer_print_str(p, " ");
p = isl_printer_print_str(p, op);
p = isl_printer_print_str(p, " ");
isl_int_set_si(c[last], 0);
- p = print_affine(bmap, dim, p, c);
+ p = print_affine(bmap, space, div, p, c);
return p;
}
+/* Print the constraints of "bmap" to "p".
+ * The names of the variables are taken from "space" and
+ * the integer division definitions are taken from "div".
+ * Div constraints are only printed in "dump" mode.
+ * The constraints are sorted prior to printing (except in "dump" mode).
+ *
+ * If x is the last variable with a non-zero coefficient,
+ * then a lower bound
+ *
+ * f - a x >= 0
+ *
+ * is printed as
+ *
+ * a x <= f
+ *
+ * while an upper bound
+ *
+ * f + a x >= 0
+ *
+ * is printed as
+ *
+ * a x >= -f
+ *
+ * If the next constraint has an opposite sign for the same last coefficient,
+ * then it is printed as
+ *
+ * f >= a x
+ *
+ * or
+ *
+ * -f <= a x
+ *
+ * instead. In fact, the "a x" part is not printed explicitly, but
+ * reused from the next constraint, which is therefore treated as
+ * a first constraint in the conjunction.
+ *
+ * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and
+ * the comparison operator is replaced by the strict variant.
+ * Essentially, ">= 1" is replaced by "> 0".
+ */
static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
- __isl_keep isl_space *dim, __isl_take isl_printer *p, int latex)
+ __isl_keep isl_space *space, __isl_keep isl_mat *div,
+ __isl_take isl_printer *p, int latex)
{
int i;
- struct isl_vec *c;
+ isl_vec *c = NULL;
+ int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
unsigned total = isl_basic_map_total_dim(bmap);
+ unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
+ int first = 1;
+
+ bmap = isl_basic_map_copy(bmap);
+ if (!p->dump)
+ bmap = isl_basic_map_sort_constraints(bmap);
+ if (!bmap)
+ goto error;
c = isl_vec_alloc(bmap->ctx, 1 + total);
if (!c)
@@ -484,29 +622,48 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
else
isl_seq_neg(c->el, bmap->eq[i], 1 + total);
- p = print_constraint(bmap, dim, p, c->el, l,
- "=", i == bmap->n_eq - 1, latex);
+ p = print_constraint(bmap, space, div, p, c->el, l,
+ "=", first, latex);
+ first = 0;
}
for (i = 0; i < bmap->n_ineq; ++i) {
int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
+ int strict;
int s;
const char *op;
if (l < 0)
continue;
+ if (!p->dump && l >= o_div &&
+ isl_basic_map_is_div_constraint(bmap, bmap->ineq[i],
+ l - o_div))
+ continue;
s = isl_int_sgn(bmap->ineq[i][l]);
+ strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
if (s < 0)
isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
else
isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
- op = s < 0 ? s_le[latex] : s_ge[latex];
- p = print_constraint(bmap, dim, p, c->el, l,
- op, !bmap->n_eq && !i, latex);
+ if (strict)
+ isl_int_set_si(c->el[0], 0);
+ if (!p->dump && next_is_opposite(bmap, i, l)) {
+ op = constraint_op(-s, strict, latex);
+ p = print_half_constraint(bmap, space, div, p, c->el, l,
+ op, first, latex);
+ first = 1;
+ } else {
+ op = constraint_op(s, strict, latex);
+ p = print_constraint(bmap, space, div, p, c->el, l,
+ op, first, latex);
+ first = 0;
+ }
}
+ isl_basic_map_free(bmap);
isl_vec_free(c);
return p;
error:
+ isl_basic_map_free(bmap);
isl_vec_free(c);
isl_printer_free(p);
return NULL;
@@ -530,13 +687,17 @@ static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
return 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).
+/* Print a comma separated list of div names, except those that have
+ * a definition that can be printed.
+ * If "print_defined_divs" is set, then those div names are printed
+ * as well, along with their definitions.
*/
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)
+ __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex,
+ int print_defined_divs)
{
int i;
+ int first = 1;
unsigned n_div;
if (!p || !space || !div)
@@ -545,11 +706,13 @@ static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,
n_div = isl_mat_rows(div);
for (i = 0; i < n_div; ++i) {
- if (i)
+ if (!print_defined_divs && can_print_div_expr(p, div, i))
+ continue;
+ if (!first)
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]))
+ first = 0;
+ if (!can_print_div_expr(p, div, i))
continue;
p = isl_printer_print_str(p, " = ");
p = print_div(space, div, i, p);
@@ -558,22 +721,52 @@ static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,
return p;
}
+/* Does printing "bmap" require an "exists" clause?
+ * That is, are there any local variables without an explicit representation?
+ */
+static isl_bool need_exists(__isl_keep isl_printer *p,
+ __isl_keep isl_basic_map *bmap, __isl_keep isl_mat *div)
+{
+ int i;
+
+ if (!p || !bmap)
+ return isl_bool_error;
+ if (bmap->n_div == 0)
+ return isl_bool_false;
+ for (i = 0; i < bmap->n_div; ++i)
+ if (!can_print_div_expr(p, div, i))
+ return isl_bool_true;
+ return isl_bool_false;
+}
+
+/* Print the constraints of "bmap" to "p".
+ * The names of the variables are taken from "space".
+ * "latex" is set if the constraints should be printed in LaTeX format.
+ * Do not print inline explicit div representations in "dump" mode.
+ */
static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
__isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
{
- if (bmap->n_div > 0) {
- isl_mat *div;
+ isl_mat *div;
+ isl_bool exists;
- div = isl_basic_map_get_divs(bmap);
+ div = isl_basic_map_get_divs(bmap);
+ if (p->dump)
+ exists = bmap->n_div > 0;
+ else
+ exists = need_exists(p, bmap, div);
+ if (exists >= 0 && exists) {
p = isl_printer_print_str(p, s_open_exists[latex]);
- p = print_div_list(p, space, div, latex);
- isl_mat_free(div);
+ p = print_div_list(p, space, div, latex, p->dump);
p = isl_printer_print_str(p, ": ");
}
- p = print_constraints(bmap, space, p, latex);
+ if (p->dump)
+ div = isl_mat_free(div);
+ p = print_constraints(bmap, space, div, p, latex);
+ isl_mat_free(div);
- if (bmap->n_div > 0)
+ if (exists >= 0 && exists)
p = isl_printer_print_str(p, s_close_exists[latex]);
return p;
}
@@ -658,22 +851,22 @@ static __isl_give isl_printer *isl_basic_map_print_isl(
p = isl_printer_print_str(p, " -> ");
}
p = isl_printer_print_str(p, "{ ");
- p = print_space(bmap->dim, p, rational, &data);
+ p = isl_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, " }");
return p;
}
-static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
- __isl_take isl_printer *p, int latex)
+/* Print the disjuncts of a map (or set) "map" to "p".
+ * 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_disjuncts_core(__isl_keep isl_map *map,
+ __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
{
int i;
- if (isl_map_plain_is_universe(map))
- return p;
-
- p = isl_printer_print_str(p, s_such_that[latex]);
if (map->n == 0)
p = isl_printer_print_str(p, "1 = 0");
for (i = 0; i < map->n; ++i) {
@@ -681,25 +874,96 @@ static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
p = isl_printer_print_str(p, s_or[latex]);
if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
p = isl_printer_print_str(p, "(");
- p = print_disjunct(map->p[i], map->dim, p, latex);
+ p = print_disjunct(map->p[i], space, p, latex);
if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
p = isl_printer_print_str(p, ")");
}
return p;
}
+/* Print the disjuncts of a map (or set) "map" to "p".
+ * The names of the variables are taken from "space".
+ * "hull" describes constraints shared by all disjuncts of "map".
+ * "latex" is set if the constraints should be printed in LaTeX format.
+ *
+ * Print the disjuncts as a conjunction of "hull" and
+ * the result of removing the constraints of "hull" from "map".
+ * If this result turns out to be the universe, then simply print "hull".
+ */
+static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map,
+ __isl_keep isl_space *space, __isl_take isl_basic_map *hull,
+ __isl_take isl_printer *p, int latex)
+{
+ isl_bool is_universe;
+
+ p = print_disjunct(hull, space, p, latex);
+ map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);
+ is_universe = isl_map_plain_is_universe(map);
+ if (is_universe < 0)
+ goto error;
+ if (!is_universe) {
+ p = isl_printer_print_str(p, s_and[latex]);
+ p = isl_printer_print_str(p, "(");
+ p = print_disjuncts_core(map, space, p, latex);
+ p = isl_printer_print_str(p, ")");
+ }
+ isl_map_free(map);
+
+ return p;
+error:
+ isl_map_free(map);
+ isl_printer_free(p);
+ return NULL;
+}
+
+/* Print the disjuncts of a map (or set) "map" to "p".
+ * The names of the variables are taken from "space".
+ * "latex" is set if the constraints should be printed in LaTeX format.
+ *
+ * If there are at least two disjuncts and "dump" mode is not turned out,
+ * check for any shared constraints among all disjuncts.
+ * If there are any, then print them separately in print_disjuncts_in_hull.
+ */
+static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
+ __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
+{
+ if (isl_map_plain_is_universe(map))
+ return p;
+
+ p = isl_printer_print_str(p, s_such_that[latex]);
+
+ if (!p->dump && map->n >= 2) {
+ isl_basic_map *hull;
+ isl_bool is_universe;
+
+ hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));
+ is_universe = isl_basic_map_is_universe(hull);
+ if (is_universe < 0)
+ p = isl_printer_free(p);
+ else if (!is_universe)
+ return print_disjuncts_in_hull(map, space, hull,
+ p, latex);
+ isl_basic_map_free(hull);
+ }
+
+ return print_disjuncts_core(map, space, p, latex);
+}
+
/* Print the disjuncts of a map (or set).
+ * The names of the variables are taken from "space".
+ * "latex" is set if the constraints should be printed in LaTeX format.
+ *
* If the map turns out to be a universal parameter domain, then
* we need to print the colon. Otherwise, the output looks identical
* to the empty set.
*/
static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
- __isl_take isl_printer *p, int latex)
+ __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
{
if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
return isl_printer_print_str(p, s_such_that[latex]);
else
- return print_disjuncts(map, p, latex);
+ return print_disjuncts(map, space, p, latex);
}
struct isl_aff_split {
@@ -890,7 +1154,7 @@ static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p,
}
static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
- struct isl_aff_split *split, int n)
+ struct isl_aff_split *split, int n, __isl_keep isl_space *space)
{
struct isl_print_space_data data = { 0 };
int i;
@@ -898,18 +1162,15 @@ static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
data.print_dim = &print_dim_eq;
for (i = 0; i < n; ++i) {
- isl_space *dim;
-
if (!split[i].map)
break;
- dim = split[i].map->dim;
rational = split[i].map->n > 0 &&
ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
if (i)
p = isl_printer_print_str(p, "; ");
data.user = split[i].aff;
- p = print_space(dim, p, rational, &data);
- p = print_disjuncts_map(split[i].map, p, 0);
+ p = isl_print_space(space, p, rational, &data);
+ p = print_disjuncts_map(split[i].map, space, p, 0);
}
return p;
@@ -922,15 +1183,15 @@ static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
struct isl_aff_split *split = NULL;
int rational;
- if (map->n > 0)
+ if (!p->dump && map->n > 0)
split = split_aff(map);
if (split) {
- p = print_split_map(p, split, map->n);
+ p = print_split_map(p, split, map->n, map->dim);
} else {
rational = map->n > 0 &&
ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
- p = print_space(map->dim, p, rational, &data);
- p = print_disjuncts_map(map, p, 0);
+ p = isl_print_space(map->dim, p, rational, &data);
+ p = print_disjuncts_map(map, map->dim, p, 0);
}
free_split(split, map->n);
return p;
@@ -964,8 +1225,8 @@ static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
p = isl_printer_print_str(p, s_open_set[1]);
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_print_space(map->dim, p, 0, &data);
+ p = print_disjuncts_map(map, map->dim, p, 1);
p = isl_printer_print_str(p, s_close_set[1]);
return p;
@@ -1335,7 +1596,7 @@ static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
}
p = isl_printer_print_str(p, "{ ");
if (!isl_space_is_params(qp->dim)) {
- p = print_space(qp->dim, p, 0, &data);
+ p = isl_print_space(qp->dim, p, 0, &data);
p = isl_printer_print_str(p, " -> ");
}
p = print_qpolynomial(p, qp);
@@ -1449,14 +1710,18 @@ static __isl_give isl_printer *isl_pwqp_print_isl_body(
int i = 0;
for (i = 0; i < pwqp->n; ++i) {
+ isl_space *space;
+
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, &data);
+ space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp);
+ if (!isl_space_is_params(space)) {
+ p = isl_print_space(space, p, 0, &data);
p = isl_printer_print_str(p, " -> ");
}
p = print_qpolynomial(p, pwqp->p[i].qp);
- p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 0);
+ p = print_disjuncts((isl_map *)pwqp->p[i].set, space, p, 0);
+ isl_space_free(space);
}
return p;
@@ -1512,14 +1777,18 @@ static __isl_give isl_printer *isl_pwf_print_isl_body(
int i = 0;
for (i = 0; i < pwf->n; ++i) {
+ isl_space *space;
+
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, &data);
+ space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold);
+ if (!isl_space_is_params(space)) {
+ p = isl_print_space(space, p, 0, &data);
p = isl_printer_print_str(p, " -> ");
}
p = qpolynomial_fold_print(pwf->p[i].fold, p);
- p = print_disjuncts((isl_map *)pwf->p[i].set, p, 0);
+ p = print_disjuncts((isl_map *)pwf->p[i].set, space, p, 0);
+ isl_space_free(space);
}
return p;
@@ -1970,23 +2239,23 @@ error:
}
static __isl_give isl_printer *isl_printer_print_space_isl(
- __isl_take isl_printer *p, __isl_keep isl_space *dim)
+ __isl_take isl_printer *p, __isl_keep isl_space *space)
{
struct isl_print_space_data data = { 0 };
- if (!dim)
+ if (!space)
goto error;
- if (isl_space_dim(dim, isl_dim_param) > 0) {
- p = print_tuple(dim, p, isl_dim_param, &data);
+ if (isl_space_dim(space, isl_dim_param) > 0) {
+ p = print_tuple(space, p, isl_dim_param, &data);
p = isl_printer_print_str(p, " -> ");
}
p = isl_printer_print_str(p, "{ ");
- if (isl_space_is_params(dim))
+ if (isl_space_is_params(space))
p = isl_printer_print_str(p, s_such_that[0]);
else
- p = print_space(dim, p, 0, &data);
+ p = isl_print_space(space, p, 0, &data);
p = isl_printer_print_str(p, " }");
return p;
@@ -2024,12 +2293,12 @@ __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
p = isl_printer_print_str(p, " -> ");
}
p = isl_printer_print_str(p, "{ ");
- p = print_space(ls->dim, p, 0, &data);
+ p = isl_print_space(ls->dim, p, 0, &data);
n_div = isl_local_space_dim(ls, isl_dim_div);
if (n_div > 0) {
p = isl_printer_print_str(p, " : ");
p = isl_printer_print_str(p, s_open_exists[0]);
- p = print_div_list(p, ls->dim, ls->div, 0);
+ p = print_div_list(p, ls->dim, ls->div, 0, 1);
p = isl_printer_print_str(p, s_close_exists[0]);
} else if (isl_space_is_params(ls->dim))
p = isl_printer_print_str(p, s_such_that[0]);
@@ -2113,10 +2382,14 @@ static __isl_give isl_printer *print_pw_aff_body(
return isl_printer_free(p);
for (i = 0; i < pa->n; ++i) {
+ isl_space *space;
+
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);
+ space = isl_aff_get_domain_space(pa->p[i].aff);
+ p = print_disjuncts((isl_map *)pa->p[i].set, space, p, 0);
+ isl_space_free(space);
}
return p;
@@ -2405,7 +2678,7 @@ static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
data.print_dim = &print_dim_ma;
data.user = maff;
- return print_space(maff->space, p, 0, &data);
+ return isl_print_space(maff->space, p, 0, &data);
}
static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
@@ -2453,10 +2726,14 @@ static __isl_give isl_printer *print_pw_multi_aff_body(
goto error;
for (i = 0; i < pma->n; ++i) {
+ isl_space *space;
+
if (i)
p = isl_printer_print_str(p, "; ");
p = print_multi_aff(p, pma->p[i].maff);
- p = print_disjuncts((isl_map *)pma->p[i].set, p, 0);
+ space = isl_multi_aff_get_domain_space(pma->p[i].maff);
+ p = print_disjuncts((isl_map *)pma->p[i].set, space, p, 0);
+ isl_space_free(space);
}
return p;
error:
@@ -2631,10 +2908,14 @@ static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,
if (need_parens)
p = isl_printer_print_str(p, "(");
for (i = 0; i < pa->n; ++i) {
+ isl_space *space;
+
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);
+ space = isl_aff_get_domain_space(pa->p[i].aff);
+ p = print_disjuncts(pa->p[i].set, space, p, 0);
+ isl_space_free(space);
}
if (need_parens)
p = isl_printer_print_str(p, ")");
@@ -2659,7 +2940,7 @@ static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *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_print_space(mpa->space, p, 0, &data);
p = isl_printer_print_str(p, " }");
return p;
}
@@ -2711,7 +2992,7 @@ static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *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_print_space(mv->space, p, 0, &data);
p = isl_printer_print_str(p, " }");
return p;
}
@@ -2771,7 +3052,7 @@ static __isl_give isl_printer *print_multi_union_pw_aff_isl(
data.print_dim = &print_union_pw_aff_dim;
data.user = mupa;
- p = print_space(space, p, 0, &data);
+ p = isl_print_space(space, p, 0, &data);
isl_space_free(space);
return p;
diff --git a/polly/lib/External/isl/isl_output_private.h b/polly/lib/External/isl/isl_output_private.h
new file mode 100644
index 00000000000..2e4701dda62
--- /dev/null
+++ b/polly/lib/External/isl/isl_output_private.h
@@ -0,0 +1,27 @@
+#include <isl/space.h>
+#include <isl/printer.h>
+
+/* Internal data structure for isl_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;
+
+ isl_space *space;
+ enum isl_dim_type type;
+};
+
+__isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,
+ __isl_take isl_printer *p, int rational,
+ struct isl_print_space_data *data);
diff --git a/polly/lib/External/isl/isl_point.c b/polly/lib/External/isl/isl_point.c
index a78662fea9b..3e832a8e3c5 100644
--- a/polly/lib/External/isl/isl_point.c
+++ b/polly/lib/External/isl/isl_point.c
@@ -1,12 +1,14 @@
#include <isl_map_private.h>
#include <isl_point_private.h>
#include <isl/set.h>
+#include <isl/union_set.h>
#include <isl_sample.h>
#include <isl_scan.h>
#include <isl_seq.h>
#include <isl_space_private.h>
#include <isl_val_private.h>
#include <isl_vec_private.h>
+#include <isl_output_private.h>
#include <isl/deprecated/point_int.h>
isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt)
@@ -445,6 +447,24 @@ __isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt)
return isl_set_from_basic_set(bset);
}
+/* Construct a union set, containing the single element "pnt".
+ * If "pnt" is void, then return an empty union set.
+ */
+__isl_give isl_union_set *isl_union_set_from_point(__isl_take isl_point *pnt)
+{
+ if (!pnt)
+ return NULL;
+ if (isl_point_is_void(pnt)) {
+ isl_space *space;
+
+ space = isl_point_get_space(pnt);
+ isl_point_free(pnt);
+ return isl_union_set_empty(space);
+ }
+
+ return isl_union_set_from_set(isl_set_from_point(pnt));
+}
+
__isl_give isl_basic_set *isl_basic_set_box_from_points(
__isl_take isl_point *pnt1, __isl_take isl_point *pnt2)
{
@@ -537,9 +557,26 @@ __isl_give isl_set *isl_set_box_from_points(__isl_take isl_point *pnt1,
return isl_set_from_basic_set(bset);
}
+/* Print the coordinate at position "pos" of the point "pnt".
+ */
+static __isl_give isl_printer *print_coordinate(__isl_take isl_printer *p,
+ struct isl_print_space_data *data, unsigned pos)
+{
+ isl_point *pnt = data->user;
+
+ p = isl_printer_print_isl_int(p, pnt->vec->el[1 + pos]);
+ if (!isl_int_is_one(pnt->vec->el[0])) {
+ p = isl_printer_print_str(p, "/");
+ p = isl_printer_print_isl_int(p, pnt->vec->el[0]);
+ }
+
+ return p;
+}
+
__isl_give isl_printer *isl_printer_print_point(
__isl_take isl_printer *p, __isl_keep isl_point *pnt)
{
+ struct isl_print_space_data data = { 0 };
int i;
unsigned nparam;
unsigned dim;
@@ -573,16 +610,10 @@ __isl_give isl_printer *isl_printer_print_point(
p = isl_printer_print_str(p, "]");
p = isl_printer_print_str(p, " -> ");
}
- p = isl_printer_print_str(p, "[");
- for (i = 0; i < dim; ++i) {
- if (i)
- p = isl_printer_print_str(p, ", ");
- p = isl_printer_print_isl_int(p, pnt->vec->el[1 + nparam + i]);
- if (!isl_int_is_one(pnt->vec->el[0])) {
- p = isl_printer_print_str(p, "/");
- p = isl_printer_print_isl_int(p, pnt->vec->el[0]);
- }
- }
- p = isl_printer_print_str(p, "]");
+ data.print_dim = &print_coordinate;
+ data.user = pnt;
+ p = isl_printer_print_str(p, "{ ");
+ p = isl_print_space(pnt->dim, p, 0, &data);
+ p = isl_printer_print_str(p, " }");
return p;
}
diff --git a/polly/lib/External/isl/isl_printer.c b/polly/lib/External/isl/isl_printer.c
index a0b3823ec0d..0c9b75ae2e4 100644
--- a/polly/lib/External/isl/isl_printer.c
+++ b/polly/lib/External/isl/isl_printer.c
@@ -384,6 +384,20 @@ int isl_printer_get_output_format(__isl_keep isl_printer *p)
return p->output_format;
}
+/* Keep track of whether the printing to "p" is being performed from
+ * an isl_*_dump function as specified by "dump".
+ */
+__isl_give isl_printer *isl_printer_set_dump(__isl_take isl_printer *p,
+ int dump)
+{
+ if (!p)
+ return NULL;
+
+ p->dump = dump;
+
+ return p;
+}
+
/* 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,
diff --git a/polly/lib/External/isl/isl_printer_private.h b/polly/lib/External/isl/isl_printer_private.h
index 29f3db57d36..7af8aae65da 100644
--- a/polly/lib/External/isl/isl_printer_private.h
+++ b/polly/lib/External/isl/isl_printer_private.h
@@ -1,3 +1,6 @@
+#ifndef ISL_PRINTER_PRIVATE_H
+#define ISL_PRINTER_PRIVATE_H
+
#include <isl/printer.h>
#include <isl_yaml.h>
@@ -5,6 +8,8 @@ struct isl_printer_ops;
/* A printer to a file or a string.
*
+ * "dump" is set if the printing is performed from an isl_*_dump function.
+ *
* 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.
@@ -22,6 +27,7 @@ struct isl_printer {
char *buf;
int indent;
int output_format;
+ int dump;
char *indent_prefix;
char *prefix;
char *suffix;
@@ -32,3 +38,8 @@ struct isl_printer {
int yaml_size;
enum isl_yaml_state *yaml_state;
};
+
+__isl_give isl_printer *isl_printer_set_dump(__isl_take isl_printer *p,
+ int dump);
+
+#endif
diff --git a/polly/lib/External/isl/isl_schedule.c b/polly/lib/External/isl/isl_schedule.c
index 76510c8cbbf..6d98af37785 100644
--- a/polly/lib/External/isl/isl_schedule.c
+++ b/polly/lib/External/isl/isl_schedule.c
@@ -1132,3 +1132,23 @@ void isl_schedule_dump(__isl_keep isl_schedule *schedule)
isl_printer_free(printer);
}
+
+/* Return a string representation of "schedule".
+ * Print the schedule in flow format.
+ */
+__isl_give char *isl_schedule_to_str(__isl_keep isl_schedule *schedule)
+{
+ isl_printer *printer;
+ char *s;
+
+ if (!schedule)
+ return NULL;
+
+ printer = isl_printer_to_str(isl_schedule_get_ctx(schedule));
+ printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_FLOW);
+ printer = isl_printer_print_schedule(printer, schedule);
+ s = isl_printer_get_str(printer);
+ isl_printer_free(printer);
+
+ return s;
+}
diff --git a/polly/lib/External/isl/isl_schedule_node.c b/polly/lib/External/isl/isl_schedule_node.c
index 3272ed15195..7c369e774d2 100644
--- a/polly/lib/External/isl/isl_schedule_node.c
+++ b/polly/lib/External/isl/isl_schedule_node.c
@@ -772,7 +772,7 @@ __isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map(
* there is also a filter ancestor that filters out all the extended
* domain elements.
*
- * Essentially, this functions intersected the domain of the output
+ * Essentially, this function intersects 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.
@@ -2088,6 +2088,39 @@ error:
return NULL;
}
+/* Intersect the filter of filter node "node" with "filter".
+ *
+ * If the filter of the node is already a subset of "filter",
+ * then leave the node unchanged.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_filter_intersect_filter(
+ __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter)
+{
+ isl_union_set *node_filter = NULL;
+ isl_bool subset;
+
+ if (!node || !filter)
+ goto error;
+
+ node_filter = isl_schedule_node_filter_get_filter(node);
+ subset = isl_union_set_is_subset(node_filter, filter);
+ if (subset < 0)
+ goto error;
+ if (subset) {
+ isl_union_set_free(node_filter);
+ isl_union_set_free(filter);
+ return node;
+ }
+ node_filter = isl_union_set_intersect(node_filter, filter);
+ node = isl_schedule_node_filter_set_filter(node, node_filter);
+ return node;
+error:
+ isl_schedule_node_free(node);
+ isl_union_set_free(node_filter);
+ 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(
@@ -2138,6 +2171,50 @@ error:
return NULL;
}
+/* Given a sequence node "node", with a child at position "pos" that
+ * is also a sequence node, attach the children of that node directly
+ * as children of "node" at that position, replacing the original child.
+ *
+ * The filters of these children are intersected with the filter
+ * of the child at position "pos".
+ */
+__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child(
+ __isl_take isl_schedule_node *node, int pos)
+{
+ int i, n;
+ isl_union_set *filter;
+ isl_schedule_node *child;
+ isl_schedule_tree *tree;
+
+ if (!node)
+ return NULL;
+ 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", isl_schedule_node_free(node));
+ node = isl_schedule_node_child(node, pos);
+ node = isl_schedule_node_child(node, 0);
+ 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", isl_schedule_node_free(node));
+ child = isl_schedule_node_copy(node);
+ node = isl_schedule_node_parent(node);
+ filter = isl_schedule_node_filter_get_filter(node);
+ n = isl_schedule_node_n_children(child);
+ for (i = 0; i < n; ++i) {
+ child = isl_schedule_node_child(child, i);
+ child = isl_schedule_node_filter_intersect_filter(child,
+ isl_union_set_copy(filter));
+ child = isl_schedule_node_parent(child);
+ }
+ isl_union_set_free(filter);
+ tree = isl_schedule_node_get_tree(child);
+ isl_schedule_node_free(child);
+ node = isl_schedule_node_parent(node);
+ node = isl_schedule_node_sequence_splice(node, pos, tree);
+
+ return node;
+}
+
/* 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
@@ -2418,6 +2495,8 @@ __isl_give isl_schedule_node *isl_schedule_node_insert_mark(
* 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.
+ * Each copy of the original subtree is simplified with respect
+ * to the corresponding filter.
*/
static __isl_give isl_schedule_node *isl_schedule_node_insert_children(
__isl_take isl_schedule_node *node,
@@ -2439,11 +2518,16 @@ static __isl_give isl_schedule_node *isl_schedule_node_insert_children(
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_node *node_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);
+ node_i = isl_schedule_node_copy(node);
+ node_i = isl_schedule_node_gist(node_i,
+ isl_union_set_copy(filter));
+ tree = isl_schedule_node_get_tree(node_i);
+ isl_schedule_node_free(node_i);
tree = isl_schedule_tree_insert_filter(tree, filter);
list = isl_schedule_tree_list_add(list, tree);
}
@@ -4206,7 +4290,8 @@ __isl_give isl_schedule_node *isl_schedule_node_graft_after(
/* 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.
+ * executed before or after the second subset, depending on the value
+ * of "before".
* 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.
@@ -4217,8 +4302,9 @@ __isl_give isl_schedule_node *isl_schedule_node_graft_after(
* 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)
+static __isl_give isl_schedule_node *isl_schedule_node_order_before_or_after(
+ __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter,
+ int before)
{
enum isl_schedule_node_type ancestors[] =
{ isl_schedule_node_filter, isl_schedule_node_sequence };
@@ -4262,9 +4348,14 @@ __isl_give isl_schedule_node *isl_schedule_node_order_after(
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);
+ if (before) {
+ tree1 = isl_schedule_tree_sequence_pair(tree2, tree1);
+ node = graft_or_splice(node, tree1, 1);
+ } else {
+ tree1 = isl_schedule_tree_sequence_pair(tree1, tree2);
+ node = graft_or_splice(node, tree1, 0);
+ }
return node;
error:
@@ -4274,6 +4365,32 @@ error:
return NULL;
}
+/* 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 before 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.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_order_before(
+ __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter)
+{
+ return isl_schedule_node_order_before_or_after(node, filter, 1);
+}
+
+/* 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.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_order_after(
+ __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter)
+{
+ return isl_schedule_node_order_before_or_after(node, filter, 0);
+}
+
/* Reset the user pointer on all identifiers of parameters and tuples
* in the schedule node "node".
*/
@@ -4428,3 +4545,24 @@ void isl_schedule_node_dump(__isl_keep isl_schedule_node *node)
isl_printer_free(printer);
}
+
+/* Return a string representation of "node".
+ * Print the schedule node in block format as it would otherwise
+ * look identical to the entire schedule.
+ */
+__isl_give char *isl_schedule_node_to_str(__isl_keep isl_schedule_node *node)
+{
+ isl_printer *printer;
+ char *s;
+
+ if (!node)
+ return NULL;
+
+ printer = isl_printer_to_str(isl_schedule_node_get_ctx(node));
+ printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK);
+ printer = isl_printer_print_schedule_node(printer, node);
+ s = isl_printer_get_str(printer);
+ isl_printer_free(printer);
+
+ return s;
+}
diff --git a/polly/lib/External/isl/isl_schedule_node_private.h b/polly/lib/External/isl/isl_schedule_node_private.h
index d6c33340728..17f74d75b21 100644
--- a/polly/lib/External/isl/isl_schedule_node_private.h
+++ b/polly/lib/External/isl/isl_schedule_node_private.h
@@ -3,6 +3,7 @@
#include <isl/schedule_node.h>
#include <isl_schedule_band.h>
+#include <isl_schedule_tree.h>
/* An isl_schedule_node points to a particular location in a schedule tree.
*
@@ -42,6 +43,9 @@ __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_gist(
+ __isl_take isl_schedule_node *node, __isl_take isl_union_set *context);
+
__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_domain_gist_params(
diff --git a/polly/lib/External/isl/isl_scheduler.c b/polly/lib/External/isl/isl_scheduler.c
index 156eb419310..a214e1c3452 100644
--- a/polly/lib/External/isl/isl_scheduler.c
+++ b/polly/lib/External/isl/isl_scheduler.c
@@ -45,7 +45,8 @@ enum isl_edge_type {
isl_edge_condition,
isl_edge_conditional_validity,
isl_edge_proximity,
- isl_edge_last = isl_edge_proximity
+ isl_edge_last = isl_edge_proximity,
+ isl_edge_local
};
/* The constraints that need to be satisfied by a schedule on "domain".
@@ -267,6 +268,17 @@ isl_ctx *isl_schedule_constraints_get_ctx(
return sc ? isl_union_set_get_ctx(sc->domain) : NULL;
}
+/* Return the domain of "sc".
+ */
+__isl_give isl_union_set *isl_schedule_constraints_get_domain(
+ __isl_keep isl_schedule_constraints *sc)
+{
+ if (!sc)
+ return NULL;
+
+ return isl_union_set_copy(sc->domain);
+}
+
/* Return the validity constraints of "sc".
*/
__isl_give isl_union_map *isl_schedule_constraints_get_validity(
@@ -468,6 +480,8 @@ static int node_scc_at_least(struct isl_sched_node *node, int scc)
* If these fields are NULL, then they represent the empty relation.
* src is the source node
* dst is the sink node
+ *
+ * types is a bit vector containing the types of this edge.
* 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
@@ -490,17 +504,96 @@ struct isl_sched_edge {
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;
+ unsigned types;
int start;
int end;
};
+/* Is "edge" marked as being of type "type"?
+ */
+static int is_type(struct isl_sched_edge *edge, enum isl_edge_type type)
+{
+ return ISL_FL_ISSET(edge->types, 1 << type);
+}
+
+/* Mark "edge" as being of type "type".
+ */
+static void set_type(struct isl_sched_edge *edge, enum isl_edge_type type)
+{
+ ISL_FL_SET(edge->types, 1 << type);
+}
+
+/* No longer mark "edge" as being of type "type"?
+ */
+static void clear_type(struct isl_sched_edge *edge, enum isl_edge_type type)
+{
+ ISL_FL_CLR(edge->types, 1 << type);
+}
+
+/* Is "edge" marked as a validity edge?
+ */
+static int is_validity(struct isl_sched_edge *edge)
+{
+ return is_type(edge, isl_edge_validity);
+}
+
+/* Mark "edge" as a validity edge.
+ */
+static void set_validity(struct isl_sched_edge *edge)
+{
+ set_type(edge, isl_edge_validity);
+}
+
+/* Is "edge" marked as a proximity edge?
+ */
+static int is_proximity(struct isl_sched_edge *edge)
+{
+ return is_type(edge, isl_edge_proximity);
+}
+
+/* Is "edge" marked as a local edge?
+ */
+static int is_local(struct isl_sched_edge *edge)
+{
+ return is_type(edge, isl_edge_local);
+}
+
+/* Mark "edge" as a local edge.
+ */
+static void set_local(struct isl_sched_edge *edge)
+{
+ set_type(edge, isl_edge_local);
+}
+
+/* No longer mark "edge" as a local edge.
+ */
+static void clear_local(struct isl_sched_edge *edge)
+{
+ clear_type(edge, isl_edge_local);
+}
+
+/* Is "edge" marked as a coincidence edge?
+ */
+static int is_coincidence(struct isl_sched_edge *edge)
+{
+ return is_type(edge, isl_edge_coincidence);
+}
+
+/* Is "edge" marked as a condition edge?
+ */
+static int is_condition(struct isl_sched_edge *edge)
+{
+ return is_type(edge, isl_edge_condition);
+}
+
+/* Is "edge" marked as a conditional validity edge?
+ */
+static int is_conditional_validity(struct isl_sched_edge *edge)
+{
+ return is_type(edge, isl_edge_conditional_validity);
+}
+
/* Internal information about the dependence graph used during
* the construction of the schedule.
*
@@ -534,7 +627,9 @@ struct isl_sched_edge {
* 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
+ * sets of dependences; however, for each type there is only
+ * a single edge between a given pair of source and sink space
+ * in the entire graph
*
* node_table contains pointers into the node array, hashed on the space
*
@@ -1058,23 +1153,17 @@ struct isl_extract_edge_data {
};
/* 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,
+static int merge_edge(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;
+ edge1->types |= edge2->types;
isl_map_free(edge2->map);
- if (type == isl_edge_condition) {
+ if (is_condition(edge2)) {
if (!edge1->tagged_condition)
edge1->tagged_condition = edge2->tagged_condition;
else
@@ -1083,7 +1172,7 @@ static int merge_edge(enum isl_edge_type type, struct isl_sched_edge *edge1,
edge2->tagged_condition);
}
- if (type == isl_edge_conditional_validity) {
+ if (is_conditional_validity(edge2)) {
if (!edge1->tagged_validity)
edge1->tagged_validity = edge2->tagged_validity;
else
@@ -1092,9 +1181,9 @@ static int merge_edge(enum isl_edge_type type, struct isl_sched_edge *edge1,
edge2->tagged_validity);
}
- if (type == isl_edge_condition && !edge1->tagged_condition)
+ if (is_condition(edge2) && !edge1->tagged_condition)
return -1;
- if (type == isl_edge_conditional_validity && !edge1->tagged_validity)
+ if (is_conditional_validity(edge2) && !edge1->tagged_validity)
return -1;
return 0;
@@ -1173,6 +1262,38 @@ static __isl_give isl_map *map_intersect_domains(__isl_take isl_map *tagged,
return tagged;
}
+/* Return a pointer to the node that lives in the domain space of "map"
+ * or NULL if there is no such node.
+ */
+static struct isl_sched_node *find_domain_node(isl_ctx *ctx,
+ struct isl_sched_graph *graph, __isl_keep isl_map *map)
+{
+ struct isl_sched_node *node;
+ isl_space *space;
+
+ space = isl_space_domain(isl_map_get_space(map));
+ node = graph_find_node(ctx, graph, space);
+ isl_space_free(space);
+
+ return node;
+}
+
+/* Return a pointer to the node that lives in the range space of "map"
+ * or NULL if there is no such node.
+ */
+static struct isl_sched_node *find_range_node(isl_ctx *ctx,
+ struct isl_sched_graph *graph, __isl_keep isl_map *map)
+{
+ struct isl_sched_node *node;
+ isl_space *space;
+
+ space = isl_space_range(isl_map_get_space(map));
+ node = graph_find_node(ctx, graph, space);
+ isl_space_free(space);
+
+ return node;
+}
+
/* 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
@@ -1202,7 +1323,6 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
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;
@@ -1216,12 +1336,8 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
}
}
- 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);
+ src = find_domain_node(ctx, graph, map);
+ dst = find_range_node(ctx, graph, map);
if (!src || !dst) {
isl_map_free(map);
@@ -1240,30 +1356,16 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
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].types = 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;
+ set_type(&graph->edge[graph->n_edge], data->type);
+ if (data->type == isl_edge_condition)
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;
+ if (data->type == isl_edge_conditional_validity)
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) {
@@ -1274,12 +1376,70 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
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)
+ if (merge_edge(edge, &graph->edge[graph->n_edge]) < 0)
return -1;
return graph_edge_table_add(ctx, graph, data->type, edge);
}
+/* Initialize the schedule graph "graph" from the schedule constraints "sc".
+ *
+ * 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.
+ * Note that this intersection is only performed locally here.
+ */
+static isl_stat graph_init(struct isl_sched_graph *graph,
+ __isl_keep isl_schedule_constraints *sc)
+{
+ isl_ctx *ctx;
+ isl_union_set *domain;
+ struct isl_extract_edge_data data;
+ enum isl_edge_type i;
+ isl_stat r;
+
+ if (!sc)
+ return isl_stat_error;
+
+ ctx = isl_schedule_constraints_get_ctx(sc);
+
+ domain = isl_schedule_constraints_get_domain(sc);
+ graph->n = isl_union_set_n_set(domain);
+ isl_union_set_free(domain);
+
+ if (graph_alloc(ctx, graph, graph->n,
+ isl_schedule_constraints_n_map(sc)) < 0)
+ return isl_stat_error;
+
+ if (compute_max_row(graph, sc) < 0)
+ return isl_stat_error;
+ graph->root = 1;
+ graph->n = 0;
+ domain = isl_schedule_constraints_get_domain(sc);
+ 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)
+ return isl_stat_error;
+ if (graph_init_table(ctx, graph) < 0)
+ return isl_stat_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)
+ return isl_stat_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)
+ return isl_stat_error;
+ }
+
+ return isl_stat_ok;
+}
+
/* Check whether there is any dependence from node[j] to node[i]
* or from node[i] to node[j].
*/
@@ -1821,8 +1981,9 @@ static int add_all_validity_constraints(struct isl_sched_graph *graph,
struct isl_sched_edge *edge= &graph->edge[i];
int local;
- local = edge->local || (edge->coincidence && use_coincidence);
- if (!edge->validity && !local)
+ local = is_local(edge) ||
+ (is_coincidence(edge) && use_coincidence);
+ if (!is_validity(edge) && !local)
continue;
if (edge->src != edge->dst)
continue;
@@ -1834,8 +1995,9 @@ static int add_all_validity_constraints(struct isl_sched_graph *graph,
struct isl_sched_edge *edge = &graph->edge[i];
int local;
- local = edge->local || (edge->coincidence && use_coincidence);
- if (!edge->validity && !local)
+ local = is_local(edge) ||
+ (is_coincidence(edge) && use_coincidence);
+ if (!is_validity(edge) && !local)
continue;
if (edge->src == edge->dst)
continue;
@@ -1867,8 +2029,9 @@ static int add_all_proximity_constraints(struct isl_sched_graph *graph,
struct isl_sched_edge *edge= &graph->edge[i];
int local;
- local = edge->local || (edge->coincidence && use_coincidence);
- if (!edge->proximity && !local)
+ local = is_local(edge) ||
+ (is_coincidence(edge) && use_coincidence);
+ if (!is_proximity(edge) && !local)
continue;
if (edge->src == edge->dst &&
add_intra_proximity_constraints(graph, edge, 1, local) < 0)
@@ -1876,7 +2039,7 @@ static int add_all_proximity_constraints(struct isl_sched_graph *graph,
if (edge->src != edge->dst &&
add_inter_proximity_constraints(graph, edge, 1, local) < 0)
return -1;
- if (edge->validity || local)
+ if (is_validity(edge) || local)
continue;
if (edge->src == edge->dst &&
add_intra_proximity_constraints(graph, edge, -1, 0) < 0)
@@ -1951,15 +2114,15 @@ static int node_update_cmap(struct isl_sched_node *node)
static int edge_multiplicity(struct isl_sched_edge *edge, int carry,
int use_coincidence)
{
- if (carry && !edge->validity && !edge->conditional_validity)
+ if (carry && !is_validity(edge) && !is_conditional_validity(edge))
return 0;
if (carry)
return 1;
- if (edge->proximity || edge->local)
+ if (is_proximity(edge) || is_local(edge))
return 2;
- if (use_coincidence && edge->coincidence)
+ if (use_coincidence && is_coincidence(edge))
return 2;
- if (edge->validity)
+ if (is_validity(edge))
return 1;
return 0;
}
@@ -2230,7 +2393,7 @@ static int check_conflict(int con, void *user)
return 0;
for (i = 0; i < graph->n_edge; ++i) {
- if (!graph->edge[i].validity)
+ if (!is_validity(&graph->edge[i]))
continue;
if (graph->edge[i].src == graph->edge[i].dst)
continue;
@@ -2628,9 +2791,9 @@ static int unconditionalize_adjacent_validity(struct isl_sched_graph *graph,
int adjacent;
isl_union_map *validity;
- if (!graph->edge[i].conditional_validity)
+ if (!is_conditional_validity(&graph->edge[i]))
continue;
- if (graph->edge[i].validity)
+ if (is_validity(&graph->edge[i]))
continue;
validity = graph->edge[i].tagged_validity;
@@ -2642,7 +2805,7 @@ static int unconditionalize_adjacent_validity(struct isl_sched_graph *graph,
if (!adjacent)
continue;
- graph->edge[i].validity = 1;
+ set_validity(&graph->edge[i]);
}
isl_union_set_free(condition_source);
@@ -2680,9 +2843,9 @@ static int update_edges(isl_ctx *ctx, struct isl_sched_graph *graph)
isl_union_set *uset;
isl_union_map *umap;
- if (!graph->edge[i].condition)
+ if (!is_condition(&graph->edge[i]))
continue;
- if (graph->edge[i].local)
+ if (is_local(&graph->edge[i]))
continue;
local = is_condition_false(&graph->edge[i]);
if (local < 0)
@@ -2776,7 +2939,7 @@ static __isl_give isl_union_set_list *extract_sccs(isl_ctx *ctx,
}
/* 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.
+ * 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)
@@ -2866,7 +3029,7 @@ static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
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)
+ if (is_validity(edge) || is_conditional_validity(edge))
isl_die(ctx, isl_error_internal,
"backward (conditional) validity edge",
return -1);
@@ -2882,12 +3045,7 @@ static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *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->edge[dst->n_edge].types = edge->types;
dst->n_edge++;
if (edge->tagged_condition && !tagged_condition)
@@ -2941,9 +3099,7 @@ static __isl_give isl_schedule_node *compute_schedule_wcc(
/* 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".
+ * that satisfy edge_pred.
* 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
@@ -2954,14 +3110,21 @@ static __isl_give isl_schedule_node *compute_schedule_wcc(
*/
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,
+ struct isl_sched_graph *graph,
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 i, n = 0, n_edge = 0;
int t;
+ for (i = 0; i < graph->n; ++i)
+ if (node_pred(&graph->node[i], data))
+ ++n;
+ for (i = 0; i < graph->n_edge; ++i)
+ if (edge_pred(&graph->edge[i], data))
+ ++n_edge;
if (graph_alloc(ctx, &split, n, n_edge) < 0)
goto error;
if (copy_nodes(&split, graph, node_pred, data) < 0)
@@ -3036,8 +3199,10 @@ static int reset_band(struct isl_sched_graph *graph)
/* 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"
+ * SCCs. The split is enforced by a sequence node inserted at position "node"
* in the schedule tree. Return the updated schedule node.
+ * If either of these two parts consists of a sequence, then it is spliced
+ * into the sequence containing the two parts.
*
* The current band is reset. It would be possible to reuse
* the previously computed rows as the first rows in the next
@@ -3047,7 +3212,7 @@ static int reset_band(struct isl_sched_graph *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;
+ int is_seq;
isl_ctx *ctx;
isl_union_set_list *filters;
@@ -3057,42 +3222,32 @@ static __isl_give isl_schedule_node *compute_split_schedule(
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, 1);
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 = compute_sub_schedule(node, ctx, graph,
&node_scc_at_least, &edge_src_scc_at_least,
graph->src_scc + 1, 0);
+ is_seq = isl_schedule_node_get_type(node) == isl_schedule_node_sequence;
+ node = isl_schedule_node_parent(node);
+ node = isl_schedule_node_parent(node);
+ if (is_seq)
+ node = isl_schedule_node_sequence_splice_child(node, 1);
+ node = isl_schedule_node_child(node, 0);
+ node = isl_schedule_node_child(node, 0);
+ node = compute_sub_schedule(node, ctx, graph,
+ &node_scc_at_most, &edge_dst_scc_at_most,
+ graph->src_scc, 0);
+ is_seq = isl_schedule_node_get_type(node) == isl_schedule_node_sequence;
node = isl_schedule_node_parent(node);
node = isl_schedule_node_parent(node);
+ if (is_seq)
+ node = isl_schedule_node_sequence_splice_child(node, 0);
return node;
}
@@ -3303,7 +3458,7 @@ static int add_all_constraints(struct isl_sched_graph *graph)
for (i = 0; i < graph->n_edge; ++i) {
struct isl_sched_edge *edge= &graph->edge[i];
- if (!edge->validity && !edge->conditional_validity)
+ if (!is_validity(edge) && !is_conditional_validity(edge))
continue;
for (j = 0; j < edge->map->n; ++j) {
@@ -3668,6 +3823,11 @@ static int is_any_trivial(struct isl_sched_graph *graph,
/* Construct a schedule row for each node such that as many dependences
* as possible are carried and then continue with the next band.
*
+ * Note that despite the fact that the problem is solved using a rational
+ * solver, the solution is guaranteed to be integral.
+ * Specifically, the dependence distance lower bounds e_i (and therefore
+ * also their sum) are integers. See Lemma 5 of [1].
+ *
* 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.
@@ -3684,6 +3844,10 @@ static int is_any_trivial(struct isl_sched_graph *graph,
* 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.
+ *
+ * [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 *carry_dependences(
__isl_take isl_schedule_node *node, struct isl_sched_graph *graph)
@@ -3802,8 +3966,8 @@ static int has_validity_edges(struct isl_sched_graph *graph)
return -1;
if (empty)
continue;
- if (graph->edge[i].validity ||
- graph->edge[i].conditional_validity)
+ if (is_validity(&graph->edge[i]) ||
+ is_conditional_validity(&graph->edge[i]))
return 1;
}
@@ -3846,8 +4010,8 @@ 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;
+ if (is_condition(&graph->edge[i]))
+ clear_local(&graph->edge[i]);
}
/* Does "graph" have both condition and conditional validity edges?
@@ -3859,9 +4023,9 @@ static int need_condition_check(struct isl_sched_graph *graph)
int any_conditional_validity = 0;
for (i = 0; i < graph->n_edge; ++i) {
- if (graph->edge[i].condition)
+ if (is_condition(&graph->edge[i]))
any_condition = 1;
- if (graph->edge[i].conditional_validity)
+ if (is_conditional_validity(&graph->edge[i]))
any_conditional_validity = 1;
}
@@ -3875,7 +4039,7 @@ 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)
+ if (is_coincidence(&graph->edge[i]))
return 1;
return 0;
@@ -3943,9 +4107,9 @@ static int has_adjacent_true_conditions(struct isl_sched_graph *graph,
int adjacent, local;
isl_union_map *condition;
- if (!graph->edge[i].condition)
+ if (!is_condition(&graph->edge[i]))
continue;
- if (graph->edge[i].local)
+ if (is_local(&graph->edge[i]))
continue;
condition = graph->edge[i].tagged_condition;
@@ -3958,7 +4122,7 @@ static int has_adjacent_true_conditions(struct isl_sched_graph *graph,
if (!adjacent)
continue;
- graph->edge[i].local = 1;
+ set_local(&graph->edge[i]);
local = is_condition_false(&graph->edge[i]);
if (local < 0)
@@ -3998,7 +4162,7 @@ static int has_violated_conditional_constraint(isl_ctx *ctx,
isl_union_map *umap;
int violated;
- if (!graph->edge[i].conditional_validity)
+ if (!is_conditional_validity(&graph->edge[i]))
continue;
violated = is_violated(graph, i);
@@ -4182,8 +4346,7 @@ 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;
+ int component;
isl_ctx *ctx;
isl_union_set_list *filters;
@@ -4198,19 +4361,9 @@ static __isl_give isl_schedule_node *compute_component_schedule(
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 = compute_sub_schedule(node, ctx, graph,
&node_scc_exactly,
&edge_scc_exactly, component, wcc);
node = isl_schedule_node_parent(node);
@@ -4267,12 +4420,6 @@ static __isl_give isl_schedule_node *compute_schedule(isl_schedule_node *node,
* 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)
@@ -4282,65 +4429,29 @@ __isl_give isl_schedule *isl_schedule_constraints_compute_schedule(
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;
+ domain = isl_schedule_constraints_get_domain(sc);
+ if (isl_union_set_n_set(domain) == 0) {
+ isl_schedule_constraints_free(sc);
+ return isl_schedule_from_domain(domain);
}
- node = isl_schedule_node_from_domain(isl_union_set_copy(sc->domain));
+ if (graph_init(&graph, sc) < 0)
+ domain = isl_union_set_free(domain);
+
+ node = isl_schedule_node_from_domain(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
diff --git a/polly/lib/External/isl/isl_space.c b/polly/lib/External/isl/isl_space.c
index 78e25a3bd2c..2e1b1e19458 100644
--- a/polly/lib/External/isl/isl_space.c
+++ b/polly/lib/External/isl/isl_space.c
@@ -2281,6 +2281,45 @@ error:
return NULL;
}
+/* Can isl_space_range_curry be applied to "space"?
+ * That is, does it have a nested relation in its range,
+ * the domain of which is itself a nested relation?
+ */
+isl_bool isl_space_can_range_curry(__isl_keep isl_space *space)
+{
+ isl_bool can;
+
+ if (!space)
+ return isl_bool_error;
+ can = isl_space_range_is_wrapping(space);
+ if (can < 0 || !can)
+ return can;
+ return isl_space_can_curry(space->nested[1]);
+}
+
+/* Given a space A -> ((B -> C) -> D), return the corresponding space
+ * A -> (B -> (C -> D)).
+ */
+__isl_give isl_space *isl_space_range_curry(__isl_take isl_space *space)
+{
+ if (!space)
+ return NULL;
+
+ if (!isl_space_can_range_curry(space))
+ isl_die(isl_space_get_ctx(space), isl_error_invalid,
+ "space range cannot be curried",
+ return isl_space_free(space));
+
+ space = isl_space_cow(space);
+ if (!space)
+ return NULL;
+ space->nested[1] = isl_space_curry(space->nested[1]);
+ if (!space->nested[1])
+ return isl_space_free(space);
+
+ return space;
+}
+
/* Can we apply isl_space_uncurry to "space"?
* That is, does it have a nested relation in its range?
*/
diff --git a/polly/lib/External/isl/isl_tab.c b/polly/lib/External/isl/isl_tab.c
index 3d9bd92fcce..908b79349fb 100644
--- a/polly/lib/External/isl/isl_tab.c
+++ b/polly/lib/External/isl/isl_tab.c
@@ -1883,6 +1883,7 @@ int isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq)
}
if (tab->cone) {
isl_int_init(cst);
+ isl_int_set_si(cst, 0);
isl_int_swap(ineq[0], cst);
}
r = isl_tab_add_row(tab, ineq);
@@ -2064,6 +2065,7 @@ int isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
if (tab->cone) {
isl_int_init(cst);
+ isl_int_set_si(cst, 0);
isl_int_swap(eq[0], cst);
}
r = isl_tab_add_row(tab, eq);
@@ -2363,6 +2365,7 @@ struct isl_tab *isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset,
tab->cone = 1;
isl_int_init(cst);
+ isl_int_set_si(cst, 0);
for (i = 0; i < bset->n_eq; ++i) {
isl_int_swap(bset->eq[i][offset], cst);
if (offset > 0) {
diff --git a/polly/lib/External/isl/isl_test.c b/polly/lib/External/isl/isl_test.c
index 26f7e0293e3..a7d6c9ba42f 100644
--- a/polly/lib/External/isl/isl_test.c
+++ b/polly/lib/External/isl/isl_test.c
@@ -119,8 +119,82 @@ static int test_parse_multi_val(isl_ctx *ctx, const char *str)
return mv ? 0 : -1;
}
+/* Pairs of binary relation representations that should represent
+ * the same binary relations.
+ */
+struct {
+ const char *map1;
+ const char *map2;
+} parse_map_equal_tests[] = {
+ { "{ [x,y] : [([x/2]+y)/3] >= 1 }",
+ "{ [x, y] : 2y >= 6 - x }" },
+ { "{ [x,y] : x <= min(y, 2*y+3) }",
+ "{ [x,y] : x <= y, 2*y + 3 }" },
+ { "{ [x,y] : x >= min(y, 2*y+3) }",
+ "{ [x, y] : (y <= x and y >= -3) or (2y <= -3 + x and y <= -4) }" },
+ { "[n] -> { [c1] : c1>=0 and c1<=floord(n-4,3) }",
+ "[n] -> { [c1] : c1 >= 0 and 3c1 <= -4 + n }" },
+ { "{ [i,j] -> [i] : i < j; [i,j] -> [j] : j <= i }",
+ "{ [i,j] -> [min(i,j)] }" },
+ { "{ [i,j] : i != j }",
+ "{ [i,j] : i < j or i > j }" },
+ { "{ [i,j] : (i+1)*2 >= j }",
+ "{ [i, j] : j <= 2 + 2i }" },
+ { "{ [i] -> [i > 0 ? 4 : 5] }",
+ "{ [i] -> [5] : i <= 0; [i] -> [4] : i >= 1 }" },
+ { "[N=2,M] -> { [i=[(M+N)/4]] }",
+ "[N, M] -> { [i] : N = 2 and 4i <= 2 + M and 4i >= -1 + M }" },
+ { "{ [x] : x >= 0 }",
+ "{ [x] : x-0 >= 0 }" },
+ { "{ [i] : ((i > 10)) }",
+ "{ [i] : i >= 11 }" },
+ { "{ [i] -> [0] }",
+ "{ [i] -> [0 * i] }" },
+ { "{ [a] -> [b] : (not false) }",
+ "{ [a] -> [b] : true }" },
+ { "{ [i] : i/2 <= 5 }",
+ "{ [i] : i <= 10 }" },
+ { "{Sym=[n] [i] : i <= n }",
+ "[n] -> { [i] : i <= n }" },
+ { "{ [*] }",
+ "{ [a] }" },
+ { "{ [i] : 2*floor(i/2) = i }",
+ "{ [i] : exists a : i = 2 a }" },
+ { "{ [a] -> [b] : a = 5 implies b = 5 }",
+ "{ [a] -> [b] : a != 5 or b = 5 }" },
+ { "{ [a] -> [a - 1 : a > 0] }",
+ "{ [a] -> [a - 1] : a > 0 }" },
+ { "{ [a] -> [a - 1 : a > 0; a : a <= 0] }",
+ "{ [a] -> [a - 1] : a > 0; [a] -> [a] : a <= 0 }" },
+ { "{ [a] -> [(a) * 2 : a >= 0; 0 : a < 0] }",
+ "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" },
+ { "{ [a] -> [(a * 2) : a >= 0; 0 : a < 0] }",
+ "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" },
+ { "{ [a] -> [(a * 2 : a >= 0); 0 : a < 0] }",
+ "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" },
+ { "{ [a] -> [(a * 2 : a >= 0; 0 : a < 0)] }",
+ "{ [a] -> [2a] : a >= 0; [a] -> [0] : a < 0 }" },
+ { "{ [a,b] -> [i,j] : a,b << i,j }",
+ "{ [a,b] -> [i,j] : a < i or (a = i and b < j) }" },
+ { "{ [a,b] -> [i,j] : a,b <<= i,j }",
+ "{ [a,b] -> [i,j] : a < i or (a = i and b <= j) }" },
+ { "{ [a,b] -> [i,j] : a,b >> i,j }",
+ "{ [a,b] -> [i,j] : a > i or (a = i and b > j) }" },
+ { "{ [a,b] -> [i,j] : a,b >>= i,j }",
+ "{ [a,b] -> [i,j] : a > i or (a = i and b >= j) }" },
+ { "{ [n] -> [i] : exists (a, b, c: 8b <= i - 32a and "
+ "8b >= -7 + i - 32 a and b >= 0 and b <= 3 and "
+ "8c < n - 32a and i < n and c >= 0 and "
+ "c <= 3 and c >= -4a) }",
+ "{ [n] -> [i] : 0 <= i < n }" },
+ { "{ [x] -> [] : exists (a, b: 0 <= a <= 1 and 0 <= b <= 3 and "
+ "2b <= x - 8a and 2b >= -1 + x - 8a) }",
+ "{ [x] -> [] : 0 <= x <= 15 }" },
+};
+
int test_parse(struct isl_ctx *ctx)
{
+ int i;
isl_map *map, *map2;
const char *str, *str2;
@@ -145,18 +219,12 @@ int test_parse(struct isl_ctx *ctx)
test_parse_map(ctx, "{ [p1, y1, y2] -> [2, y1, y2] : "
"p1 = 1 && (y1 <= y2 || y2 = 0) }");
- str = "{ [x,y] : [([x/2]+y)/3] >= 1 }";
- str2 = "{ [x, y] : 2y >= 6 - x }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- if (test_parse_map_equal(ctx, "{ [x,y] : x <= min(y, 2*y+3) }",
- "{ [x,y] : x <= y, 2*y + 3 }") < 0)
- return -1;
- str = "{ [x, y] : (y <= x and y >= -3) or (2y <= -3 + x and y <= -4) }";
- if (test_parse_map_equal(ctx, "{ [x,y] : x >= min(y, 2*y+3) }",
- str) < 0)
- return -1;
+ for (i = 0; i < ARRAY_SIZE(parse_map_equal_tests); ++i) {
+ str = parse_map_equal_tests[i].map1;
+ str2 = parse_map_equal_tests[i].map2;
+ if (test_parse_map_equal(ctx, str, str2) < 0)
+ return -1;
+ }
str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}";
map = isl_map_read_from_str(ctx, str);
@@ -177,103 +245,11 @@ int test_parse(struct isl_ctx *ctx)
isl_map_free(map);
isl_map_free(map2);
- str = "[n] -> { [c1] : c1>=0 and c1<=floord(n-4,3) }";
- str2 = "[n] -> { [c1] : c1 >= 0 and 3c1 <= -4 + n }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [i,j] -> [i] : i < j; [i,j] -> [j] : j <= i }";
- str2 = "{ [i,j] -> [min(i,j)] }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [i,j] : i != j }";
- str2 = "{ [i,j] : i < j or i > j }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [i,j] : (i+1)*2 >= j }";
- str2 = "{ [i, j] : j <= 2 + 2i }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [i] -> [i > 0 ? 4 : 5] }";
- str2 = "{ [i] -> [5] : i <= 0; [i] -> [4] : i >= 1 }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "[N=2,M] -> { [i=[(M+N)/4]] }";
- str2 = "[N, M] -> { [i] : N = 2 and 4i <= 2 + M and 4i >= -1 + M }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [x] : x >= 0 }";
- str2 = "{ [x] : x-0 >= 0 }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [i] : ((i > 10)) }";
- str2 = "{ [i] : i >= 11 }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
- str = "{ [i] -> [0] }";
- str2 = "{ [i] -> [0 * i] }";
- if (test_parse_map_equal(ctx, str, str2) < 0)
- return -1;
-
test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }");
test_parse_map(ctx, "{ S1[i] -> [([i/10]),i%10] : 0 <= i <= 45 }");
test_parse_pwaff(ctx, "{ [i] -> [i + 1] : i > 0; [a] -> [a] : a < 0 }");
test_parse_pwqp(ctx, "{ [x] -> ([(x)/2] * [(x)/3]) }");
- if (test_parse_map_equal(ctx, "{ [a] -> [b] : (not false) }",
- "{ [a] -> [b] : true }") < 0)
- return -1;
-
- if (test_parse_map_equal(ctx, "{ [i] : i/2 <= 5 }",
- "{ [i] : i <= 10 }") < 0)
- return -1;
-
- if (test_parse_map_equal(ctx, "{Sym=[n] [i] : i <= n }",
- "[n] -> { [i] : i <= n }") < 0)
- return -1;
-
- if (test_parse_map_equal(ctx, "{ [*] }", "{ [a] }") < 0)
- return -1;
-
- if (test_parse_map_equal(ctx, "{ [i] : 2*floor(i/2) = i }",
- "{ [i] : exists a : i = 2 a }") < 0)
- return -1;
-
- if (test_parse_map_equal(ctx, "{ [a] -> [b] : a = 5 implies b = 5 }",
- "{ [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;
}
@@ -1105,6 +1081,49 @@ int test_affine_hull(struct isl_ctx *ctx)
return 0;
}
+/* Pairs of maps and the corresponding expected results of
+ * isl_map_plain_unshifted_simple_hull.
+ */
+struct {
+ const char *map;
+ const char *hull;
+} plain_unshifted_simple_hull_tests[] = {
+ { "{ [i] -> [j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }",
+ "{ [i] -> [j] : i >= 1 }" },
+ { "{ [n] -> [i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or "
+ "(j mod 4 = 2 and k mod 6 = n) }",
+ "{ [n] -> [i,j,k] : j mod 4 = 2 }" },
+};
+
+/* Basic tests for isl_map_plain_unshifted_simple_hull.
+ */
+static int test_plain_unshifted_simple_hull(isl_ctx *ctx)
+{
+ int i;
+ isl_map *map;
+ isl_basic_map *hull, *expected;
+ isl_bool equal;
+
+ for (i = 0; i < ARRAY_SIZE(plain_unshifted_simple_hull_tests); ++i) {
+ const char *str;
+ str = plain_unshifted_simple_hull_tests[i].map;
+ map = isl_map_read_from_str(ctx, str);
+ str = plain_unshifted_simple_hull_tests[i].hull;
+ expected = isl_basic_map_read_from_str(ctx, str);
+ hull = isl_map_plain_unshifted_simple_hull(map);
+ equal = isl_basic_map_is_equal(hull, expected);
+ isl_basic_map_free(hull);
+ isl_basic_map_free(expected);
+ if (equal < 0)
+ return -1;
+ if (!equal)
+ isl_die(ctx, isl_error_unknown, "unexpected hull",
+ return -1);
+ }
+
+ return 0;
+}
+
static int test_simple_hull(struct isl_ctx *ctx)
{
const char *str;
@@ -1126,6 +1145,9 @@ static int test_simple_hull(struct isl_ctx *ctx)
isl_die(ctx, isl_error_unknown, "Empty set should be detected",
return -1);
+ if (test_plain_unshifted_simple_hull(ctx) < 0)
+ return -1;
+
return 0;
}
@@ -1258,6 +1280,55 @@ void test_gist_case(struct isl_ctx *ctx, const char *name)
fclose(input);
}
+/* Inputs to isl_map_plain_gist_basic_map, along with the expected output.
+ */
+struct {
+ const char *map;
+ const char *context;
+ const char *gist;
+} plain_gist_tests[] = {
+ { "{ [i] -> [j] : i >= 1 and j >= 1 or i >= 2 and j <= 10 }",
+ "{ [i] -> [j] : i >= 1 }",
+ "{ [i] -> [j] : j >= 1 or i >= 2 and j <= 10 }" },
+ { "{ [n] -> [i,j,k] : (i mod 3 = 2 and j mod 4 = 2) or "
+ "(j mod 4 = 2 and k mod 6 = n) }",
+ "{ [n] -> [i,j,k] : j mod 4 = 2 }",
+ "{ [n] -> [i,j,k] : (i mod 3 = 2) or (k mod 6 = n) }" },
+ { "{ [i] -> [j] : i > j and (exists a,b : i <= 2a + 5b <= 2) }",
+ "{ [i] -> [j] : i > j }",
+ "{ [i] -> [j] : exists a,b : i <= 2a + 5b <= 2 }" },
+};
+
+/* Basic tests for isl_map_plain_gist_basic_map.
+ */
+static int test_plain_gist(isl_ctx *ctx)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(plain_gist_tests); ++i) {
+ const char *str;
+ int equal;
+ isl_map *map, *gist;
+ isl_basic_map *context;
+
+ map = isl_map_read_from_str(ctx, plain_gist_tests[i].map);
+ str = plain_gist_tests[i].context;
+ context = isl_basic_map_read_from_str(ctx, str);
+ map = isl_map_plain_gist_basic_map(map, context);
+ gist = isl_map_read_from_str(ctx, plain_gist_tests[i].gist);
+ equal = isl_map_is_equal(map, gist);
+ isl_map_free(map);
+ isl_map_free(gist);
+ if (equal < 0)
+ return -1;
+ if (!equal)
+ isl_die(ctx, isl_error_unknown,
+ "incorrect gist result", return -1);
+ }
+
+ return 0;
+}
+
struct {
const char *set;
const char *context;
@@ -1397,6 +1468,9 @@ static int test_gist(struct isl_ctx *ctx)
isl_map_free(map1); return -1);
isl_map_free(map1);
+ if (test_plain_gist(ctx) < 0)
+ return -1;
+
return 0;
}
@@ -1658,6 +1732,10 @@ struct {
"32e0 <= 31 + i0)) or "
"i0 >= 0 }" },
{ 1, "{ [a, b, c] : 2b = 1 + a and 2c = 2 + a; [0, 0, 0] }" },
+ { 1, "{ [a, a, b, c] : 32*floor((a)/32) = a and 2*floor((b)/2) = b and "
+ "2*floor((c)/2) = c and 0 <= a <= 192;"
+ "[224, 224, b, c] : 2*floor((b)/2) = b and 2*floor((c)/2) = c }"
+ },
};
/* A specialized coalescing test case that would result
@@ -1722,13 +1800,55 @@ static int test_coalesce(struct isl_ctx *ctx)
return 0;
}
-static int test_closure(isl_ctx *ctx)
+/* Construct a representation of the graph on the right of Figure 1
+ * in "Computing the Transitive Closure of a Union of
+ * Affine Integer Tuple Relations".
+ */
+static __isl_give isl_map *cocoa_fig_1_right_graph(isl_ctx *ctx)
{
- const char *str;
isl_set *dom;
isl_map *up, *right;
+
+ dom = isl_set_read_from_str(ctx,
+ "{ [x,y] : x >= 0 and -2 x + 3 y >= 0 and x <= 3 and "
+ "2 x - 3 y + 3 >= 0 }");
+ right = isl_map_read_from_str(ctx,
+ "{ [x,y] -> [x2,y2] : x2 = x + 1 and y2 = y }");
+ up = isl_map_read_from_str(ctx,
+ "{ [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 }");
+ right = isl_map_intersect_domain(right, isl_set_copy(dom));
+ right = isl_map_intersect_range(right, isl_set_copy(dom));
+ up = isl_map_intersect_domain(up, isl_set_copy(dom));
+ up = isl_map_intersect_range(up, dom);
+ return isl_map_union(up, right);
+}
+
+/* Construct a representation of the power of the graph
+ * on the right of Figure 1 in "Computing the Transitive Closure of
+ * a Union of Affine Integer Tuple Relations".
+ */
+static __isl_give isl_map *cocoa_fig_1_right_power(isl_ctx *ctx)
+{
+ return isl_map_read_from_str(ctx,
+ "{ [1] -> [[0,0] -> [0,1]]; [2] -> [[0,0] -> [1,1]]; "
+ " [1] -> [[0,1] -> [1,1]]; [1] -> [[2,2] -> [3,2]]; "
+ " [2] -> [[2,2] -> [3,3]]; [1] -> [[3,2] -> [3,3]] }");
+}
+
+/* Construct a representation of the transitive closure of the graph
+ * on the right of Figure 1 in "Computing the Transitive Closure of
+ * a Union of Affine Integer Tuple Relations".
+ */
+static __isl_give isl_map *cocoa_fig_1_right_tc(isl_ctx *ctx)
+{
+ return isl_set_unwrap(isl_map_range(cocoa_fig_1_right_power(ctx)));
+}
+
+static int test_closure(isl_ctx *ctx)
+{
+ const char *str;
isl_map *map, *map2;
- int exact;
+ int exact, equal;
/* COCOA example 1 */
map = isl_map_read_from_str(ctx,
@@ -1837,28 +1957,27 @@ static int test_closure(isl_ctx *ctx)
isl_map_free(map2);
isl_map_free(map);
- /* COCOA Fig.1 right */
- dom = isl_set_read_from_str(ctx,
- "{ [x,y] : x >= 0 and -2 x + 3 y >= 0 and x <= 3 and "
- "2 x - 3 y + 3 >= 0 }");
- right = isl_map_read_from_str(ctx,
- "{ [x,y] -> [x2,y2] : x2 = x + 1 and y2 = y }");
- up = isl_map_read_from_str(ctx,
- "{ [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 }");
- right = isl_map_intersect_domain(right, isl_set_copy(dom));
- right = isl_map_intersect_range(right, isl_set_copy(dom));
- up = isl_map_intersect_domain(up, isl_set_copy(dom));
- up = isl_map_intersect_range(up, dom);
- map = isl_map_union(up, right);
+ map = cocoa_fig_1_right_graph(ctx);
map = isl_map_transitive_closure(map, &exact);
assert(exact);
- map2 = isl_map_read_from_str(ctx,
- "{ [0,0] -> [0,1]; [0,0] -> [1,1]; [0,1] -> [1,1]; "
- " [2,2] -> [3,2]; [2,2] -> [3,3]; [3,2] -> [3,3] }");
+ map2 = cocoa_fig_1_right_tc(ctx);
assert(isl_map_is_equal(map, map2));
isl_map_free(map2);
isl_map_free(map);
+ map = cocoa_fig_1_right_graph(ctx);
+ map = isl_map_power(map, &exact);
+ map2 = cocoa_fig_1_right_power(ctx);
+ equal = isl_map_is_equal(map, map2);
+ isl_map_free(map2);
+ isl_map_free(map);
+ if (equal < 0)
+ return -1;
+ if (!exact)
+ isl_die(ctx, isl_error_unknown, "power not exact", return -1);
+ if (!equal)
+ isl_die(ctx, isl_error_unknown, "unexpected power", return -1);
+
/* COCOA Theorem 1 counter example */
map = isl_map_read_from_str(ctx,
"{ [i,j] -> [i2,j2] : i = 0 and 0 <= j and j <= 1 and "
@@ -4834,6 +4953,9 @@ const char *set_conversion_tests[] = {
"[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)] }",
+ "[a, b] -> { [c, d] : (4*floor((-a + c)/4) = -a + c and "
+ "32*floor((-b + d)/32) = -b + d and 5 <= c <= 8 and "
+ "-3 + c <= d <= 28 + c) }",
};
/* Check that converting from isl_set to isl_pw_multi_aff and back
@@ -4866,32 +4988,41 @@ static int test_set_conversion(isl_ctx *ctx)
return 0;
}
+const char *conversion_tests[] = {
+ "{ [a, b, c, d] -> s0[a, b, e, f] : "
+ "exists (e0 = [(a - 2c)/3], e1 = [(-4 + b - 5d)/9], "
+ "e2 = [(-d + f)/9]: 3e0 = a - 2c and 9e1 = -4 + b - 5d and "
+ "9e2 = -d + f and f >= 0 and f <= 8 and 9e >= -5 - 2a and "
+ "9e <= -2 - 2a) }",
+ "{ [a, b] -> [c] : exists (e0 = floor((-a - b + c)/5): "
+ "5e0 = -a - b + c and c >= -a and c <= 4 - a) }",
+ "{ [a, b] -> [c] : exists d : 18 * d = -3 - a + 2c and 1 <= c <= 3 }",
+};
+
/* Check that converting from isl_map to isl_pw_multi_aff and back
* to isl_map produces the original isl_map.
*/
static int test_map_conversion(isl_ctx *ctx)
{
- const char *str;
+ int i;
isl_map *map1, *map2;
isl_pw_multi_aff *pma;
int equal;
- str = "{ [a, b, c, d] -> s0[a, b, e, f] : "
- "exists (e0 = [(a - 2c)/3], e1 = [(-4 + b - 5d)/9], "
- "e2 = [(-d + f)/9]: 3e0 = a - 2c and 9e1 = -4 + b - 5d and "
- "9e2 = -d + f and f >= 0 and f <= 8 and 9e >= -5 - 2a and "
- "9e <= -2 - 2a) }";
- map1 = isl_map_read_from_str(ctx, str);
- pma = isl_pw_multi_aff_from_map(isl_map_copy(map1));
- map2 = isl_map_from_pw_multi_aff(pma);
- equal = isl_map_is_equal(map1, map2);
- isl_map_free(map1);
- isl_map_free(map2);
+ for (i = 0; i < ARRAY_SIZE(conversion_tests); ++i) {
+ map1 = isl_map_read_from_str(ctx, conversion_tests[i]);
+ pma = isl_pw_multi_aff_from_map(isl_map_copy(map1));
+ map2 = isl_map_from_pw_multi_aff(pma);
+ 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, "bad conversion", return -1);
+ if (equal < 0)
+ return -1;
+ if (!equal)
+ isl_die(ctx, isl_error_unknown, "bad conversion",
+ return -1);
+ }
return 0;
}
diff --git a/polly/lib/External/isl/isl_transitive_closure.c b/polly/lib/External/isl/isl_transitive_closure.c
index f031f67acfd..7ef84d48716 100644
--- a/polly/lib/External/isl/isl_transitive_closure.c
+++ b/polly/lib/External/isl/isl_transitive_closure.c
@@ -1608,7 +1608,7 @@ static __isl_give isl_map *floyd_warshall_with_groups(__isl_take isl_space *dim,
floyd_warshall_iterate(grid, n, exact);
- app = isl_map_empty(isl_map_get_space(map));
+ app = isl_map_empty(isl_map_get_space(grid[0][0]));
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j)
diff --git a/polly/lib/External/isl/isl_union_map.c b/polly/lib/External/isl/isl_union_map.c
index 2cae0bc447b..cf616c9e3dc 100644
--- a/polly/lib/External/isl/isl_union_map.c
+++ b/polly/lib/External/isl/isl_union_map.c
@@ -2087,6 +2087,31 @@ __isl_give isl_union_map *isl_union_map_domain_factor_range(
return cond_un_op(umap, &domain_factor_range_entry);
}
+/* If "map" is of the form A -> [B -> C], then add A -> B to "res".
+ */
+static isl_stat range_factor_domain_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_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 -> B and collect the results.
+ */
+__isl_give isl_union_map *isl_union_map_range_factor_domain(
+ __isl_take isl_union_map *umap)
+{
+ return cond_un_op(umap, &range_factor_domain_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)
@@ -2419,6 +2444,14 @@ __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
return (isl_basic_set *)isl_union_map_sample(uset);
}
+/* Return an element in "uset" in the form of an isl_point.
+ * Return a void isl_point if "uset" is empty.
+ */
+__isl_give isl_point *isl_union_set_sample_point(__isl_take isl_union_set *uset)
+{
+ return isl_basic_set_sample_point(isl_union_set_sample(uset));
+}
+
struct isl_forall_data {
isl_bool res;
isl_bool (*fn)(__isl_keep isl_map *map);
@@ -2930,6 +2963,32 @@ __isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap)
return cond_un_op(umap, &curry_entry);
}
+/* If *entry is of the form A -> ((B -> C) -> D), then apply
+ * isl_map_range_curry to it and add the result to *res.
+ */
+static isl_stat range_curry_entry(void **entry, void *user)
+{
+ isl_map *map = *entry;
+ isl_union_map **res = user;
+
+ if (!isl_map_can_range_curry(map))
+ return isl_stat_ok;
+
+ map = isl_map_range_curry(isl_map_copy(map));
+ *res = isl_union_map_add_map(*res, map);
+
+ return isl_stat_ok;
+}
+
+/* Given a union map, take the maps of the form A -> ((B -> C) -> D) and
+ * return the union of the corresponding maps A -> (B -> (C -> D)).
+ */
+__isl_give isl_union_map *isl_union_map_range_curry(
+ __isl_take isl_union_map *umap)
+{
+ return cond_un_op(umap, &range_curry_entry);
+}
+
static isl_stat lift_entry(void **entry, void *user)
{
isl_set *set = *entry;
diff --git a/polly/lib/External/isl/isl_union_templ.c b/polly/lib/External/isl/isl_union_templ.c
index 463b7bddd0f..66bbd2b02f0 100644
--- a/polly/lib/External/isl/isl_union_templ.c
+++ b/polly/lib/External/isl/isl_union_templ.c
@@ -220,8 +220,11 @@ static __isl_give UNION *FN(UNION,alloc_same_size_on_space)(__isl_keep UNION *u,
__isl_take isl_space *space)
{
if (!u)
- space = isl_space_free(space);
+ goto error;
return FN(UNION,alloc)(space, u->type, u->table.n);
+error:
+ isl_space_free(space);
+ return NULL;
}
#else
/* Allocate a UNION with the same size as "u" and with space "space".
@@ -230,8 +233,11 @@ static __isl_give UNION *FN(UNION,alloc_same_size_on_space)(__isl_keep UNION *u,
__isl_take isl_space *space)
{
if (!u)
- space = isl_space_free(space);
+ goto error;
return FN(UNION,alloc)(space, u->table.n);
+error:
+ isl_space_free(space);
+ return NULL;
}
#endif
diff --git a/polly/lib/External/isl/print_templ.c b/polly/lib/External/isl/print_templ.c
index f147fdc5480..d6b0db76bd1 100644
--- a/polly/lib/External/isl/print_templ.c
+++ b/polly/lib/External/isl/print_templ.c
@@ -1,3 +1,5 @@
+#include <isl_printer_private.h>
+
#define xCAT(A,B) A ## B
#define CAT(A,B) xCAT(A,B)
#undef TYPE
@@ -12,6 +14,7 @@ void FN(TYPE,dump)(__isl_keep TYPE *obj)
if (!obj)
return;
p = isl_printer_to_file(FN(TYPE,get_ctx)(obj), stderr);
+ p = isl_printer_set_dump(p, 1);
p = FN(isl_printer_print,BASE)(p, obj);
p = isl_printer_end_line(p);
isl_printer_free(p);
diff --git a/polly/lib/External/isl/test_inputs/codegen/cloog/dealII.c b/polly/lib/External/isl/test_inputs/codegen/cloog/dealII.c
index 939a804a9c7..99ac53ee39a 100644
--- a/polly/lib/External/isl/test_inputs/codegen/cloog/dealII.c
+++ b/polly/lib/External/isl/test_inputs/codegen/cloog/dealII.c
@@ -1,32 +1,18 @@
{
- 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) {
+ for (int c0 = 0; c0 <= min(min(T_2 - 1, T_67 - 1), T_66); c0 += 1) {
S1(c0);
S2(c0);
}
- for (int c0 = max(1, T_66 + 1); c0 < min(T_2, T_67); c0 += 1)
+ for (int c0 = max(0, 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) {
+ for (int c0 = T_67; c0 <= min(T_2 - 1, T_66); c0 += 1) {
S1(c0);
S2(c0);
}
- for (int c0 = max(max(1, T_67), T_66 + 1); c0 < T_2; c0 += 1)
+ for (int c0 = max(T_67, T_66 + 1); c0 < T_2; c0 += 1)
S1(c0);
- 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)
+ for (int c0 = T_2; c0 <= min(T_67 - 1, T_66); c0 += 1)
S2(c0);
- if (T_2 == 0 && T_67 == 0 && T_66 >= 0)
+ if (T_2 == 0 && T_67 == 0)
S1(0);
}
diff --git a/polly/lib/External/isl/test_inputs/codegen/cloog/faber.c b/polly/lib/External/isl/test_inputs/codegen/cloog/faber.c
index ab54229b829..984dafcf70c 100644
--- a/polly/lib/External/isl/test_inputs/codegen/cloog/faber.c
+++ b/polly/lib/External/isl/test_inputs/codegen/cloog/faber.c
@@ -85,17 +85,10 @@
for (int c2 = max(c1 + 24, -2 * c1 + 30); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1)
S1(c0, c1, c2);
}
- if (c0 >= 70 && c0 % 14 >= 9) {
+ if (c0 >= 70 && c0 % 14 >= 9)
for (int c2 = max(c0 / 14 + 19, -((3 * c0 + 14) / 14) + c0 / 14 + 44); c2 <= -((3 * c0 + 17) / 14) + c0 / 14 + 51; 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 = -((3 * c0 + 14) / 14) + c0 / 14 + 44; c2 <= -((3 * c0 + 17) / 14) + c0 / 14 + 51; c2 += 1)
- S1(c0, c0 / 14 - 5, c2);
- }
- for (int c1 = (c0 + 5) / 14 - 5; c1 < 0; c1 += 1) {
+ for (int c1 = c0 / 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)
@@ -104,21 +97,21 @@
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)
+ for (int c2 = max(c1, -2 * c1 + 6); c2 <= min(c1 + 5, -2 * c1 + 24); c2 += 1)
+ S9(c0, c1, c2);
+ for (int c2 = c1 + 6; c2 <= min((2 * c1 + 1) / 5 + 7, (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)
+ if (c1 <= 3)
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)
+ for (int c2 = max(max(c1 + 6, c1 - (6 * c0 + 91) / 77 + 16), (2 * c1 + 1) / 5 + 9); 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);
diff --git a/polly/lib/External/isl/test_inputs/codegen/cloog/jacobi-shared.c b/polly/lib/External/isl/test_inputs/codegen/cloog/jacobi-shared.c
index 50840a86877..0deb1064fd2 100644
--- a/polly/lib/External/isl/test_inputs/codegen/cloog/jacobi-shared.c
+++ b/polly/lib/External/isl/test_inputs/codegen/cloog/jacobi-shared.c
@@ -1,3 +1,3 @@
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);
+ S1(g1 + c0 - 1, -((g2 - t1 + 32) % 32) + g2 + 31);
diff --git a/polly/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c b/polly/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
index 42547118e11..f9e59c1c873 100644
--- a/polly/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
+++ b/polly/lib/External/isl/test_inputs/codegen/cloog/reservoir-liu-zhuge1.c
@@ -1,7 +1,7 @@
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);
+ S2((c0 + 3) / 3 - 1, c0 % 3);
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) {
@@ -9,7 +9,7 @@ if (M >= 0 && N >= 0)
S2((c0 - c1 - 2) / 3, c1 + 2);
}
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);
+ S1((-N + c0 - 1) / 3 + 2, ((-N + c0 - 1) % 3) + N - 1);
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)
diff --git a/polly/lib/External/isl/test_inputs/codegen/isolate7.c b/polly/lib/External/isl/test_inputs/codegen/isolate7.c
index 95ea699334e..d41ce090127 100644
--- a/polly/lib/External/isl/test_inputs/codegen/isolate7.c
+++ b/polly/lib/External/isl/test_inputs/codegen/isolate7.c
@@ -14,9 +14,9 @@
}
for (int c1 = 0; c1 < n; c1 += 32) {
if (n >= c1 + 32) {
- for (int c2 = 0; c2 < n % 32; c2 += 1)
+ for (int c2 = 0; c2 < (n + 32) % 32; c2 += 1)
for (int c3 = 0; c3 <= 31; c3 += 1)
- S_1(-((n - 1) % 32) + n + c2 - 1, c1 + c3);
+ S_1(-((n + 32) % 32) + n + c2, c1 + c3);
} else
for (int c2 = 0; c2 < n - c1; c2 += 1) {
for (int c3 = 0; c3 < n - c1; c3 += 1)
diff --git a/polly/lib/External/isl/test_inputs/codegen/omega/dagstuhl1-1.c b/polly/lib/External/isl/test_inputs/codegen/omega/dagstuhl1-1.c
index a3e4458f146..98953fbde27 100644
--- a/polly/lib/External/isl/test_inputs/codegen/omega/dagstuhl1-1.c
+++ b/polly/lib/External/isl/test_inputs/codegen/omega/dagstuhl1-1.c
@@ -1,2 +1,2 @@
for (int c0 = 0; c0 <= 99; c0 += 1)
- s0(c0, c0 % 10, (c0 + 10) / 10 - 1);
+ s0(c0, c0 % 10, c0 / 10);
diff --git a/polly/lib/External/isl/test_inputs/codegen/omega/lefur03-0.c b/polly/lib/External/isl/test_inputs/codegen/omega/lefur03-0.c
index 05ac73f3a44..e809849cd27 100644
--- a/polly/lib/External/isl/test_inputs/codegen/omega/lefur03-0.c
+++ b/polly/lib/External/isl/test_inputs/codegen/omega/lefur03-0.c
@@ -1,5 +1,5 @@
for (int c0 = 0; c0 <= 3; c0 += 1)
- for (int c1 = max(2 * c0 - 3, c0 / 2); c1 <= min(3, c0 + 1); c1 += 1)
+ for (int c1 = max(0, 2 * c0 - 3); c1 <= min(3, c0 + c0 / 2 + 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)
diff --git a/polly/lib/External/isl/test_inputs/codegen/omega/lefur04-0.c b/polly/lib/External/isl/test_inputs/codegen/omega/lefur04-0.c
index 72ecbe49f62..749fa020dd5 100644
--- a/polly/lib/External/isl/test_inputs/codegen/omega/lefur04-0.c
+++ b/polly/lib/External/isl/test_inputs/codegen/omega/lefur04-0.c
@@ -1,8 +1,8 @@
for (int c0 = 0; c0 <= 3; c0 += 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(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), c2 - (c2 + 3) / 3), c3 - (c3 + 3) / 3), c1 - (c1 - 2 * c3 + 5) / 5); c5 <= min(min(c1 + 1, c3), -c2 + 2 * c3 - (c2 + 3) / 3 + 2); c5 += 1)
+ for (int c1 = max(0, 2 * c0 - 3); c1 <= min(c0 + 1, -c0 + 6); c1 += 1)
+ for (int c2 = c0; c2 <= min(min(3, 2 * c0 - c1 + 1), c0 + c0 / 2 + 1); 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 + 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 --git a/polly/lib/External/isl/test_inputs/codegen/omega/p.delft2-0.c b/polly/lib/External/isl/test_inputs/codegen/omega/p.delft2-0.c
index ad5a4cab0d6..1740e4fe8a5 100644
--- a/polly/lib/External/isl/test_inputs/codegen/omega/p.delft2-0.c
+++ b/polly/lib/External/isl/test_inputs/codegen/omega/p.delft2-0.c
@@ -4,7 +4,7 @@ if (P1 >= 0 && P1 <= 3 && P2 >= 0 && P2 <= 3)
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);
+ s0(P1 - 1, P2, c2, c3, ((5 * P1 + 2 * c2 + 9) % 9) + 1, -4 * P2 + 2 * c3 - 9 * floord(-4 * P2 + 2 * c3, 9));
} else if (P1 == 0 && c0 == 3 && c2 % 4 == 0)
- s0(3, P2, c2, c3, (-c2 / 4) + 3, (-4 * P2 + 2 * c3 + 9) % 9);
+ s0(3, P2, c2, c3, (-c2 / 4) + 3, -4 * P2 + 2 * c3 - 9 * floord(-4 * P2 + 2 * c3, 9));
}
diff --git a/polly/lib/External/isl/test_inputs/codegen/omega/ts1d-check0-0.c b/polly/lib/External/isl/test_inputs/codegen/omega/ts1d-check0-0.c
index 5cf4bc9f5c8..484bd1f6854 100644
--- a/polly/lib/External/isl/test_inputs/codegen/omega/ts1d-check0-0.c
+++ b/polly/lib/External/isl/test_inputs/codegen/omega/ts1d-check0-0.c
@@ -8,6 +8,6 @@
s2(2, 1000 * c1 + c3 + 1, 0, -1000 * c1 + c2 - c3 - 1, 1);
}
if (2 * T >= c2 + 1 && 1000 * c1 + 999 >= c2)
- s1(2, -(c2 % 2) + c2, 0, c2 % 2, 1);
+ s1(2, ((c2 + 1) % 2) + c2 - 1, 0, -((c2 + 1) % 2) + 1, 1);
}
}
diff --git a/polly/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.c b/polly/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.c
index d7fa3cd8a37..94559693fd9 100644
--- a/polly/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.c
+++ b/polly/lib/External/isl/test_inputs/codegen/pldi2012/figure8_b.c
@@ -3,6 +3,6 @@
s1(c0);
s0(c0 + 2);
}
- if (n >= 2 && n % 4 >= 2)
+ if (n >= 1 && n % 4 >= 2)
s1(-(n % 4) + n + 2);
}
diff --git a/polly/lib/External/isl/test_inputs/codegen/redundant.c b/polly/lib/External/isl/test_inputs/codegen/redundant.c
index 809692ed380..ab9b4686118 100644
--- a/polly/lib/External/isl/test_inputs/codegen/redundant.c
+++ b/polly/lib/External/isl/test_inputs/codegen/redundant.c
@@ -1,19 +1,18 @@
-for (int c0 = 0; c0 <= 2; c0 += 1)
- for (int c1 = max(0, b0 - 4 * c0 - 1); c1 <= 1; c1 += 1) {
- if (b0 >= 1 && 4 * c0 + c1 >= 1)
- for (int c2 = 1; c2 <= 2; c2 += 1) {
- if (c2 == 2) {
+for (int c0 = 0; c0 <= 2; c0 += 1) {
+ if (b0 <= 1) {
+ for (int c1 = 0; c1 <= 1; c1 += 1) {
+ if (b0 == 1 && 4 * c0 + c1 >= 1)
+ for (int c2 = 1; c2 <= 2; c2 += 1)
for (int c3 = 1; c3 <= 14; c3 += 1)
- write(c0, c1, 8 * b0 - 3, c3);
- } else if (c1 == 1) {
+ write(c0, c1, c2 + 3, c3);
+ for (int c2 = max(max(3, -8 * b0 + 6), 8 * c0 - 12); c2 <= min(7, 8 * c0 + 6); c2 += 1)
+ if (4 * c0 + c1 >= 2 * floord(2 * c1 + c2 - 5, 4) + 1 && 2 * ((2 * c1 + c2 - 1) / 4) + 7 >= 4 * c0 + c1 && 2 * c1 + c2 >= 4 * ((2 * c1 + c2 - 1) / 4) + 2 && ((-2 * c1 - c2 + 8) % 4) + 2 * c2 <= 14)
for (int c3 = 1; c3 <= 14; c3 += 1)
- write(c0, 1, 8 * b0 - 4, c3);
- } else
- for (int c3 = 1; c3 <= 14; c3 += 1)
- write(c0, 0, 8 * b0 - 4, c3);
- }
- for (int c2 = max(max(3, -8 * b0 + 6), 8 * c0 - 12); c2 <= min(min(7, -8 * b0 + 17), 8 * c0 + 6); c2 += 1)
- if (4 * c0 + c1 >= 2 * floord(2 * c1 + c2 - 5, 4) + 1 && 2 * ((2 * c1 + c2 - 1) / 4) + 7 >= 4 * c0 + c1 && 2 * c1 + c2 >= 4 * ((2 * c1 + c2 - 1) / 4) + 2 && ((-2 * c1 - c2 + 8) % 4) + 2 * c2 <= 14)
+ write(c0, c1, 8 * b0 + c2 - 5, c3);
+ }
+ } else
+ for (int c1 = max(0, -4 * c0 + 1); c1 <= 1; c1 += 1)
+ for (int c2 = 1; c2 <= 2; c2 += 1)
for (int c3 = 1; c3 <= 14; c3 += 1)
- write(c0, c1, 8 * b0 + c2 - 5, c3);
- }
+ write(c0, c1, c2 + 11, c3);
+}
diff --git a/polly/lib/External/isl/test_inputs/codegen/separate2.c b/polly/lib/External/isl/test_inputs/codegen/separate2.c
index 469c894a945..76ee58d96e6 100644
--- a/polly/lib/External/isl/test_inputs/codegen/separate2.c
+++ b/polly/lib/External/isl/test_inputs/codegen/separate2.c
@@ -1,9 +1,8 @@
-if ((length - 1) % 16 <= 14)
- for (int c0 = 0; c0 <= 1; c0 += 1)
- for (int c5 = 0; c5 <= 31; c5 += 1)
- for (int c6 = max(0, 2 * ((length - 1) % 16) + 2 * c5 - 60); c6 <= 30; c6 += 1) {
- if (2 * length + c6 >= 2 * ((length - 1) % 16) + 4 && 2 * ((length - 1) % 16) >= c6 && 2 * ((length - 1) % 16) + 2 * c5 >= c6 && c6 + 62 >= 2 * ((length - 1) % 16) + 2 * c5 && 2 * ((length - 1) % 16) + 2 * c5 == 2 * ((length - 1) % 32) + c6 && (2 * c5 - c6) % 32 == 0)
- S_3(c0, 0, (c6 / 2) - ((length - 1) % 16) + length - 1);
- if (length <= 15 && length >= c5 + 1 && c6 >= 1 && length >= c6)
- S_0(c0, c5, c6 - 1);
- }
+for (int c0 = 0; c0 <= 1; c0 += 1)
+ for (int c5 = 0; c5 <= 31; c5 += 1)
+ for (int c6 = max(0, 2 * (length % 16) + 2 * c5 - 62); c6 <= 30; c6 += 1) {
+ if (2 * length + c6 >= 2 * (length % 16) + 2 && c6 + 62 >= 2 * (length % 16) + 2 * c5 && 2 * (length % 16) >= c6 + 2 && 2 * (length % 16) + 2 * c5 >= c6 && 2 * (length % 32) + c6 == 2 * (length % 16) + 2 * c5 && (2 * c5 - c6) % 32 == 0)
+ S_3(c0, 0, (c6 / 2) - (length % 16) + length);
+ if (length <= 15 && length >= c5 + 1 && c6 >= 1 && length >= c6)
+ S_0(c0, c5, c6 - 1);
+ }
diff --git a/polly/lib/External/isl/test_inputs/codegen/separation_class2.c b/polly/lib/External/isl/test_inputs/codegen/separation_class2.c
index 0fdbc3238e3..80be0a73211 100644
--- a/polly/lib/External/isl/test_inputs/codegen/separation_class2.c
+++ b/polly/lib/External/isl/test_inputs/codegen/separation_class2.c
@@ -6,10 +6,10 @@
A(c0 + c2, c1 + c3);
for (int c2 = 0; c2 <= 7; c2 += 1)
for (int c3 = 0; c3 < n % 8; c3 += 1)
- A(c0 + c2, -((n - 1) % 8) + n + c3 - 1);
+ A(c0 + c2, -(n % 8) + n + c3);
}
for (int c1 = 0; c1 < n; c1 += 8)
for (int c2 = 0; c2 < n % 8; c2 += 1)
for (int c3 = 0; c3 <= min(7, n - c1 - 1); c3 += 1)
- A(-((n - 1) % 8) + n + c2 - 1, c1 + c3);
+ A(-(n % 8) + n + c2, c1 + c3);
}
diff --git a/polly/lib/External/isl/test_inputs/codegen/unroll3.c b/polly/lib/External/isl/test_inputs/codegen/unroll3.c
index 95a30ba7ccc..f6f390d3dd2 100644
--- a/polly/lib/External/isl/test_inputs/codegen/unroll3.c
+++ b/polly/lib/External/isl/test_inputs/codegen/unroll3.c
@@ -1,2 +1,2 @@
if ((t1 + 121) % 128 <= 123)
- write_shared_A(((t1 + 125) % 128) - 3);
+ write_shared_A(((t1 + 121) % 128) + 1);
diff --git a/polly/lib/External/isl/test_inputs/codegen/unroll4.c b/polly/lib/External/isl/test_inputs/codegen/unroll4.c
index c5dea636135..30b2ba8efa8 100644
--- a/polly/lib/External/isl/test_inputs/codegen/unroll4.c
+++ b/polly/lib/External/isl/test_inputs/codegen/unroll4.c
@@ -2,21 +2,15 @@
write_shared_A(3, ((t1 + 3) % 4) + 1, ((t2 + 31) % 32) + 1);
if (t2 >= 1 && t2 <= 2 && t1 % 3 == 0)
write_shared_A(3, (-t1 / 3) + 4, t2 + 32);
- {
- int c3 = t2 >= 2 && ((t1 + 3) % 4) + 1 >= t2 ? t2 + 32 : ((t2 + 30) % 32) + 2;
- if (c3 == t2 + 32 || t2 >= ((t1 + 3) % 4) + ((t2 + 1) % 2) + 2)
- write_shared_A(3, ((t1 + 3) % 4) + 5, c3);
- }
+ if ((t1 >= 1 && t1 <= 2 && t2 >= 3 && t2 <= 4) || ((-((t1 + 3) % 4) + t2 + 30) % 32) + t1 >= -4 * ((-t1 + 4) / 4) + 4)
+ write_shared_A(3, ((t1 + 3) % 4) + 5, -((((t1 + 3) % 4) - t2 + 33) % 32) + t1 + 4 * ((-t1 + 4) / 4) + 32);
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 (t2 >= 1 && t2 <= 2 && t1 % 3 == 0)
write_shared_A(4, (-t1 / 3) + 4, t2 + 32);
- {
- int c3 = t2 >= 2 && ((t1 + 3) % 4) + 1 >= t2 ? t2 + 32 : ((t2 + 30) % 32) + 2;
- if (c3 == t2 + 32 || t2 >= ((t1 + 3) % 4) + ((t2 + 1) % 2) + 2)
- write_shared_A(4, ((t1 + 3) % 4) + 5, c3);
- }
+ if ((t1 >= 1 && t1 <= 2 && t2 >= 3 && t2 <= 4) || ((-((t1 + 3) % 4) + t2 + 30) % 32) + t1 >= -4 * ((-t1 + 4) / 4) + 4)
+ write_shared_A(4, ((t1 + 3) % 4) + 5, -((((t1 + 3) % 4) - t2 + 33) % 32) + t1 + 4 * ((-t1 + 4) / 4) + 32);
if (t1 >= 1 && t2 >= t1 + 1 && t2 <= 4)
write_shared_A(4, t1 + 4, t2 + 32);
}
OpenPOWER on IntegriCloud