[polly] r307090 - Bump isl to isl-0.18-768-g033b61ae

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 4 08:54:11 PDT 2017


Author: grosser
Date: Tue Jul  4 08:54:11 2017
New Revision: 307090

URL: http://llvm.org/viewvc/llvm-project?rev=307090&view=rev
Log:
Bump isl to isl-0.18-768-g033b61ae

Summary: This is a general maintenance update

Reviewers: grosser

Subscribers: srhines, fedor.sergeev, pollydev, llvm-commits

Contributed-by: Maximilian Falkenstein <falkensm at student.ethz.ch>

Differential Revision: https://reviews.llvm.org/D34903

Added:
    polly/trunk/lib/External/isl/extract_key.c
    polly/trunk/lib/External/isl/flow.c
    polly/trunk/lib/External/isl/flow_cmp.c
    polly/trunk/lib/External/isl/flow_test.sh.in
    polly/trunk/lib/External/isl/isl_maybe_map.h
    polly/trunk/lib/External/isl/isl_union_set_private.h
    polly/trunk/lib/External/isl/test_inputs/flow/
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.ai
    polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.flow
    polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/loop.ai
    polly/trunk/lib/External/isl/test_inputs/flow/loop.flow
    polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/may_loop.ai
    polly/trunk/lib/External/isl/test_inputs/flow/may_loop.flow
    polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.ai
    polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.ai
    polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.flow
    polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/no_source.ai
    polly/trunk/lib/External/isl/test_inputs/flow/no_source.flow
    polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/no_source2.ai
    polly/trunk/lib/External/isl/test_inputs/flow/no_source2.flow
    polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.ai
    polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.flow
    polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.ai
    polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.flow
    polly/trunk/lib/External/isl/test_inputs/flow/single_source.ai
    polly/trunk/lib/External/isl/test_inputs/flow/single_source.flow
Modified:
    polly/trunk/lib/External/isl/GIT_HEAD_ID
    polly/trunk/lib/External/isl/Makefile.am
    polly/trunk/lib/External/isl/Makefile.in
    polly/trunk/lib/External/isl/config.guess
    polly/trunk/lib/External/isl/config.sub
    polly/trunk/lib/External/isl/configure
    polly/trunk/lib/External/isl/configure.ac
    polly/trunk/lib/External/isl/doc/user.pod
    polly/trunk/lib/External/isl/imath/imath.c
    polly/trunk/lib/External/isl/imath_wrap/wrap.h
    polly/trunk/lib/External/isl/include/isl/aff.h
    polly/trunk/lib/External/isl/include/isl/flow.h
    polly/trunk/lib/External/isl/include/isl/map.h
    polly/trunk/lib/External/isl/include/isl/schedule.h
    polly/trunk/lib/External/isl/include/isl/set.h
    polly/trunk/lib/External/isl/include/isl/union_map.h
    polly/trunk/lib/External/isl/include/isl/val.h
    polly/trunk/lib/External/isl/isl_aff.c
    polly/trunk/lib/External/isl/isl_aff_private.h
    polly/trunk/lib/External/isl/isl_config.h.in
    polly/trunk/lib/External/isl/isl_convex_hull.c
    polly/trunk/lib/External/isl/isl_dim_map.c
    polly/trunk/lib/External/isl/isl_dim_map.h
    polly/trunk/lib/External/isl/isl_flow.c
    polly/trunk/lib/External/isl/isl_imath.c
    polly/trunk/lib/External/isl/isl_imath.h
    polly/trunk/lib/External/isl/isl_int_gmp.h
    polly/trunk/lib/External/isl/isl_int_imath.h
    polly/trunk/lib/External/isl/isl_int_sioimath.c
    polly/trunk/lib/External/isl/isl_int_sioimath.h
    polly/trunk/lib/External/isl/isl_map.c
    polly/trunk/lib/External/isl/isl_map_private.h
    polly/trunk/lib/External/isl/isl_map_simplify.c
    polly/trunk/lib/External/isl/isl_mat.c
    polly/trunk/lib/External/isl/isl_mat_private.h
    polly/trunk/lib/External/isl/isl_options.c
    polly/trunk/lib/External/isl/isl_options_private.h
    polly/trunk/lib/External/isl/isl_schedule_constraints.c
    polly/trunk/lib/External/isl/isl_schedule_read.c
    polly/trunk/lib/External/isl/isl_scheduler.c
    polly/trunk/lib/External/isl/isl_tab.h
    polly/trunk/lib/External/isl/isl_tab_pip.c
    polly/trunk/lib/External/isl/isl_test.c
    polly/trunk/lib/External/isl/isl_test_int.c
    polly/trunk/lib/External/isl/isl_union_map.c
    polly/trunk/lib/External/isl/isl_val.c
    polly/trunk/lib/External/isl/isl_vec.c
    polly/trunk/lib/External/isl/isl_vec_private.h
    polly/trunk/lib/External/isl/ltmain.sh
    polly/trunk/lib/External/isl/m4/ax_detect_clang.m4
    polly/trunk/test/DependenceInfo/different_schedule_dimensions.ll
    polly/trunk/test/DependenceInfo/do_pluto_matmult.ll
    polly/trunk/test/ScheduleOptimizer/outer_coincidence.ll

Modified: polly/trunk/lib/External/isl/GIT_HEAD_ID
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/GIT_HEAD_ID?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/GIT_HEAD_ID (original)
+++ polly/trunk/lib/External/isl/GIT_HEAD_ID Tue Jul  4 08:54:11 2017
@@ -1 +1 @@
-isl-0.18-679-g6e75a0d
+isl-0.18-768-g033b61ae

Modified: polly/trunk/lib/External/isl/Makefile.am
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/Makefile.am?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/Makefile.am (original)
+++ polly/trunk/lib/External/isl/Makefile.am Tue Jul  4 08:54:11 2017
@@ -11,8 +11,10 @@ lib_LTLIBRARIES = libisl.la
 noinst_PROGRAMS = isl_test isl_polyhedron_sample isl_pip \
 	isl_polyhedron_minimize isl_polytope_scan \
 	isl_polyhedron_detect_equalities isl_cat \
-	isl_closure isl_bound isl_schedule isl_codegen isl_test_int
-TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh isl_test_int
+	isl_closure isl_bound isl_schedule isl_codegen isl_test_int \
+	isl_flow isl_flow_cmp
+TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh isl_test_int \
+	flow_test.sh
 
 if IMATH_FOR_MP
 
@@ -181,6 +183,7 @@ libisl_la_SOURCES = \
 	isl_transitive_closure.c \
 	isl_union_map.c \
 	isl_union_map_private.h \
+	isl_union_set_private.h \
 	isl_val.c \
 	isl_val_private.h \
 	isl_vec_private.h \
@@ -218,6 +221,16 @@ isl_schedule_LDADD = libisl.la @MP_LIBS@
 isl_schedule_SOURCES = \
 	schedule.c
 
+isl_flow_LDFLAGS = @MP_LDFLAGS@
+isl_flow_LDADD = libisl.la @MP_LIBS@
+isl_flow_SOURCES = \
+	flow.c
+
+isl_flow_cmp_LDFLAGS = @MP_LDFLAGS@
+isl_flow_cmp_LDADD = libisl.la @MP_LIBS@
+isl_flow_cmp_SOURCES = \
+	flow_cmp.c
+
 isl_codegen_LDFLAGS = @MP_LDFLAGS@
 isl_codegen_LDADD = libisl.la @MP_LIBS@
 isl_codegen_SOURCES = \
@@ -341,9 +354,11 @@ EXTRA_DIST = \
 	basis_reduction_templ.c \
 	bset_to_bmap.c \
 	bset_from_bmap.c \
+	extract_key.c \
 	isl_list_templ.c \
 	isl_list_templ.h \
 	isl_map_lexopt_templ.c \
+	isl_maybe_map.h \
 	isl_multi_macro.h \
 	isl_multi_templ.c \
 	isl_multi_templ.h \

Modified: polly/trunk/lib/External/isl/Makefile.in
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/Makefile.in?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/Makefile.in (original)
+++ polly/trunk/lib/External/isl/Makefile.in Tue Jul  4 08:54:11 2017
@@ -96,9 +96,10 @@ noinst_PROGRAMS = isl_test$(EXEEXT) isl_
 	isl_polytope_scan$(EXEEXT) \
 	isl_polyhedron_detect_equalities$(EXEEXT) isl_cat$(EXEEXT) \
 	isl_closure$(EXEEXT) isl_bound$(EXEEXT) isl_schedule$(EXEEXT) \
-	isl_codegen$(EXEEXT) isl_test_int$(EXEEXT) $(am__EXEEXT_1)
+	isl_codegen$(EXEEXT) isl_test_int$(EXEEXT) isl_flow$(EXEEXT) \
+	isl_flow_cmp$(EXEEXT) $(am__EXEEXT_1)
 TESTS = isl_test$(EXEEXT) codegen_test.sh pip_test.sh bound_test.sh \
-	isl_test_int$(EXEEXT) $(am__EXEEXT_1)
+	isl_test_int$(EXEEXT) flow_test.sh $(am__EXEEXT_1)
 @IMATH_FOR_MP_TRUE at am__append_1 = isl_test_imath
 @IMATH_FOR_MP_TRUE at am__append_2 = isl_test_imath
 @IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE at am__append_3 = isl_int_sioimath.h \
@@ -138,7 +139,7 @@ am__CONFIG_DISTCLEAN_FILES = config.stat
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = isl_config.h
 CONFIG_CLEAN_FILES = isl_srcdir.c bound_test.sh codegen_test.sh \
-	pip_test.sh
+	pip_test.sh flow_test.sh
 CONFIG_CLEAN_VPATH_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
@@ -211,8 +212,8 @@ am__libisl_la_SOURCES_DIST = mp_get_memo
 	isl_stream_private.h isl_seq.c isl_seq.h isl_tab.c isl_tab.h \
 	isl_tab_pip.c isl_tarjan.c isl_tarjan.h \
 	isl_transitive_closure.c isl_union_map.c \
-	isl_union_map_private.h isl_val.c isl_val_private.h \
-	isl_vec_private.h isl_vec.c isl_version.c \
+	isl_union_map_private.h isl_union_set_private.h isl_val.c \
+	isl_val_private.h isl_vec_private.h isl_vec.c isl_version.c \
 	isl_vertices_private.h isl_vertices.c isl_yaml.h
 @GMP_FOR_MP_TRUE@@NEED_GET_MEMORY_FUNCTIONS_TRUE at am__objects_1 = mp_get_memory_functions.lo
 am__dirstamp = $(am__leading_dot)dirstamp
@@ -280,6 +281,18 @@ isl_codegen_DEPENDENCIES = libisl.la
 isl_codegen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(isl_codegen_LDFLAGS) $(LDFLAGS) -o $@
+am_isl_flow_OBJECTS = flow.$(OBJEXT)
+isl_flow_OBJECTS = $(am_isl_flow_OBJECTS)
+isl_flow_DEPENDENCIES = libisl.la
+isl_flow_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(isl_flow_LDFLAGS) $(LDFLAGS) -o $@
+am_isl_flow_cmp_OBJECTS = flow_cmp.$(OBJEXT)
+isl_flow_cmp_OBJECTS = $(am_isl_flow_cmp_OBJECTS)
+isl_flow_cmp_DEPENDENCIES = libisl.la
+isl_flow_cmp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(isl_flow_cmp_LDFLAGS) $(LDFLAGS) -o $@
 am_isl_pip_OBJECTS = pip.$(OBJEXT)
 isl_pip_OBJECTS = $(am_isl_pip_OBJECTS)
 isl_pip_DEPENDENCIES = libisl.la
@@ -366,14 +379,16 @@ am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libisl_la_SOURCES) $(isl_bound_SOURCES) $(isl_cat_SOURCES) \
 	$(isl_closure_SOURCES) $(isl_codegen_SOURCES) \
-	$(isl_pip_SOURCES) $(isl_polyhedron_detect_equalities_SOURCES) \
+	$(isl_flow_SOURCES) $(isl_flow_cmp_SOURCES) $(isl_pip_SOURCES) \
+	$(isl_polyhedron_detect_equalities_SOURCES) \
 	$(isl_polyhedron_minimize_SOURCES) \
 	$(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \
 	$(isl_schedule_SOURCES) isl_test.c isl_test_imath.c \
 	isl_test_int.c
 DIST_SOURCES = $(am__libisl_la_SOURCES_DIST) $(isl_bound_SOURCES) \
 	$(isl_cat_SOURCES) $(isl_closure_SOURCES) \
-	$(isl_codegen_SOURCES) $(isl_pip_SOURCES) \
+	$(isl_codegen_SOURCES) $(isl_flow_SOURCES) \
+	$(isl_flow_cmp_SOURCES) $(isl_pip_SOURCES) \
 	$(isl_polyhedron_detect_equalities_SOURCES) \
 	$(isl_polyhedron_minimize_SOURCES) \
 	$(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \
@@ -625,10 +640,11 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/bound_test.sh.in \
-	$(srcdir)/codegen_test.sh.in $(srcdir)/isl_config.h.in \
-	$(srcdir)/isl_srcdir.c.in $(srcdir)/pip_test.sh.in AUTHORS \
-	ChangeLog README compile config.guess config.sub depcomp \
-	install-sh ltmain.sh missing test-driver
+	$(srcdir)/codegen_test.sh.in $(srcdir)/flow_test.sh.in \
+	$(srcdir)/isl_config.h.in $(srcdir)/isl_srcdir.c.in \
+	$(srcdir)/pip_test.sh.in AUTHORS ChangeLog README compile \
+	config.guess config.sub depcomp install-sh ltmain.sh missing \
+	test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -958,6 +974,7 @@ libisl_la_SOURCES = \
 	isl_transitive_closure.c \
 	isl_union_map.c \
 	isl_union_map_private.h \
+	isl_union_set_private.h \
 	isl_val.c \
 	isl_val_private.h \
 	isl_vec_private.h \
@@ -991,6 +1008,16 @@ isl_schedule_LDADD = libisl.la @MP_LIBS@
 isl_schedule_SOURCES = \
 	schedule.c
 
+isl_flow_LDFLAGS = @MP_LDFLAGS@
+isl_flow_LDADD = libisl.la @MP_LIBS@
+isl_flow_SOURCES = \
+	flow.c
+
+isl_flow_cmp_LDFLAGS = @MP_LDFLAGS@
+isl_flow_cmp_LDADD = libisl.la @MP_LIBS@
+isl_flow_cmp_SOURCES = \
+	flow_cmp.c
+
 isl_codegen_LDFLAGS = @MP_LDFLAGS@
 isl_codegen_LDADD = libisl.la @MP_LIBS@
 isl_codegen_SOURCES = \
@@ -1115,9 +1142,11 @@ EXTRA_DIST = \
 	basis_reduction_templ.c \
 	bset_to_bmap.c \
 	bset_from_bmap.c \
+	extract_key.c \
 	isl_list_templ.c \
 	isl_list_templ.h \
 	isl_map_lexopt_templ.c \
+	isl_maybe_map.h \
 	isl_multi_macro.h \
 	isl_multi_templ.c \
 	isl_multi_templ.h \
@@ -1230,6 +1259,8 @@ codegen_test.sh: $(top_builddir)/config.
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 pip_test.sh: $(top_builddir)/config.status $(srcdir)/pip_test.sh.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
+flow_test.sh: $(top_builddir)/config.status $(srcdir)/flow_test.sh.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
 
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
@@ -1306,6 +1337,14 @@ isl_codegen$(EXEEXT): $(isl_codegen_OBJE
 	@rm -f isl_codegen$(EXEEXT)
 	$(AM_V_CCLD)$(isl_codegen_LINK) $(isl_codegen_OBJECTS) $(isl_codegen_LDADD) $(LIBS)
 
+isl_flow$(EXEEXT): $(isl_flow_OBJECTS) $(isl_flow_DEPENDENCIES) $(EXTRA_isl_flow_DEPENDENCIES) 
+	@rm -f isl_flow$(EXEEXT)
+	$(AM_V_CCLD)$(isl_flow_LINK) $(isl_flow_OBJECTS) $(isl_flow_LDADD) $(LIBS)
+
+isl_flow_cmp$(EXEEXT): $(isl_flow_cmp_OBJECTS) $(isl_flow_cmp_DEPENDENCIES) $(EXTRA_isl_flow_cmp_DEPENDENCIES) 
+	@rm -f isl_flow_cmp$(EXEEXT)
+	$(AM_V_CCLD)$(isl_flow_cmp_LINK) $(isl_flow_cmp_OBJECTS) $(isl_flow_cmp_LDADD) $(LIBS)
+
 isl_pip$(EXEEXT): $(isl_pip_OBJECTS) $(isl_pip_DEPENDENCIES) $(EXTRA_isl_pip_DEPENDENCIES) 
 	@rm -f isl_pip$(EXEEXT)
 	$(AM_V_CCLD)$(isl_pip_LINK) $(isl_pip_OBJECTS) $(isl_pip_LDADD) $(LIBS)
@@ -1355,6 +1394,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/closure.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/codegen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/flow.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/flow_cmp.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_aff.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_affine_hull.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isl_arg.Plo at am__quote@
@@ -1848,6 +1889,13 @@ isl_test_int.log: isl_test_int$(EXEEXT)
 	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+flow_test.sh.log: flow_test.sh
+	@p='flow_test.sh'; \
+	b='flow_test.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
 isl_test_imath.log: isl_test_imath$(EXEEXT)
 	@p='isl_test_imath$(EXEEXT)'; \

Modified: polly/trunk/lib/External/isl/config.guess
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/config.guess?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/config.guess (original)
+++ polly/trunk/lib/External/isl/config.guess Tue Jul  4 08:54:11 2017
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2016 Free Software Foundation, Inc.
 
-timestamp='2016-04-02'
+timestamp='2016-10-02'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
-	# to ELF recently, or will in the future.
+	# to ELF recently (or will in the future) and ABI.
 	case "${UNAME_MACHINE_ARCH}" in
-	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+	    earm*)
+		os=netbsdelf
+		;;
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
@@ -997,6 +1000,9 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
+    mips64el:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     openrisc*:Linux:*:*)
 	echo or1k-unknown-linux-${LIBC}
 	exit ;;
@@ -1029,6 +1035,9 @@ EOF
     ppcle:Linux:*:*)
 	echo powerpcle-unknown-linux-${LIBC}
 	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
 	exit ;;
@@ -1408,18 +1417,17 @@ esac
 cat >&2 <<EOF
 $0: unable to guess system type
 
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
 
   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches at gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches at gnu.org to
+provide the necessary information to handle your system.
 
 config.guess timestamp = $timestamp
 

Modified: polly/trunk/lib/External/isl/config.sub
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/config.sub?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/config.sub (original)
+++ polly/trunk/lib/External/isl/config.sub Tue Jul  4 08:54:11 2017
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2016 Free Software Foundation, Inc.
 
-timestamp='2016-03-30'
+timestamp='2016-11-04'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -117,7 +117,7 @@ case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -301,6 +301,7 @@ case $basic_machine in
 	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pru \
 	| pyramid \
 	| riscv32 | riscv64 \
 	| rl78 | rx \
@@ -428,6 +429,7 @@ case $basic_machine in
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pru-* \
 	| pyramid-* \
 	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
@@ -643,6 +645,14 @@ case $basic_machine in
 		basic_machine=m68k-bull
 		os=-sysv3
 		;;
+	e500v[12])
+		basic_machine=powerpc-unknown
+		os=$os"spe"
+		;;
+	e500v[12]-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=$os"spe"
+		;;
 	ebmon29k)
 		basic_machine=a29k-amd
 		os=-ebmon
@@ -1022,7 +1032,7 @@ case $basic_machine in
 	ppc-* | ppcbe-*)
 		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppcle | powerpclittle | ppc-le | powerpc-little)
+	ppcle | powerpclittle)
 		basic_machine=powerpcle-unknown
 		;;
 	ppcle-* | powerpclittle-*)
@@ -1032,7 +1042,7 @@ case $basic_machine in
 		;;
 	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+	ppc64le | powerpc64little)
 		basic_machine=powerpc64le-unknown
 		;;
 	ppc64le-* | powerpc64little-*)
@@ -1389,7 +1399,7 @@ case $os in
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
@@ -1399,7 +1409,7 @@ case $os in
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
 	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos*)
+	      | -onefs* | -tirtos* | -phoenix* | -fuchsia*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)

Modified: polly/trunk/lib/External/isl/configure
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/configure?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/configure (original)
+++ polly/trunk/lib/External/isl/configure Tue Jul  4 08:54:11 2017
@@ -19611,6 +19611,21 @@ rm -f conftest*
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#include <clang/Frontend/FrontendOptions.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "IK_C" >/dev/null 2>&1; then :
+
+else
+
+$as_echo "#define IK_C InputKind::C" >>confdefs.h
+
+fi
+rm -f conftest*
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
 	#include <clang/Basic/TargetOptions.h>
 	#include <clang/Lex/PreprocessorOptions.h>
@@ -20006,6 +20021,8 @@ ac_config_files="$ac_config_files codege
 
 ac_config_files="$ac_config_files pip_test.sh"
 
+ac_config_files="$ac_config_files flow_test.sh"
+
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -21201,6 +21218,7 @@ do
     "bound_test.sh") CONFIG_FILES="$CONFIG_FILES bound_test.sh" ;;
     "codegen_test.sh") CONFIG_FILES="$CONFIG_FILES codegen_test.sh" ;;
     "pip_test.sh") CONFIG_FILES="$CONFIG_FILES pip_test.sh" ;;
+    "flow_test.sh") CONFIG_FILES="$CONFIG_FILES flow_test.sh" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
@@ -23202,6 +23220,7 @@ fi ; rm conftest.sed # DONE generate $pk
     "bound_test.sh":F) chmod +x bound_test.sh ;;
     "codegen_test.sh":F) chmod +x codegen_test.sh ;;
     "pip_test.sh":F) chmod +x pip_test.sh ;;
+    "flow_test.sh":F) chmod +x flow_test.sh ;;
 
   esac
 done # for ac_tag

Modified: polly/trunk/lib/External/isl/configure.ac
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/configure.ac?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/configure.ac (original)
+++ polly/trunk/lib/External/isl/configure.ac Tue Jul  4 08:54:11 2017
@@ -137,6 +137,7 @@ fi
 AC_CONFIG_FILES([bound_test.sh], [chmod +x bound_test.sh])
 AC_CONFIG_FILES([codegen_test.sh], [chmod +x codegen_test.sh])
 AC_CONFIG_FILES([pip_test.sh], [chmod +x pip_test.sh])
+AC_CONFIG_FILES([flow_test.sh], [chmod +x flow_test.sh])
 AC_CONFIG_COMMANDS_POST([
 	dnl pass on arguments to subdir configures, but don't
 	dnl add them to config.status

Modified: polly/trunk/lib/External/isl/doc/user.pod
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/doc/user.pod?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/doc/user.pod (original)
+++ polly/trunk/lib/External/isl/doc/user.pod Tue Jul  4 08:54:11 2017
@@ -768,6 +768,8 @@ The following binary operations are avai
 		unsigned long v2);
 	__isl_give isl_val *isl_val_div(__isl_take isl_val *v1,
 		__isl_take isl_val *v2);
+	__isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1,
+		unsigned long v2);
 
 On integer values, we additionally have the following operations.
 
@@ -4661,12 +4663,17 @@ Intersect the set, relation or function
 with the hyperplane where the given
 dimension has the fixed given value.
 
-	__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
-		__isl_take isl_basic_map *bmap,
-		enum isl_dim_type type, unsigned pos, int value);
-	__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
-		__isl_take isl_basic_map *bmap,
-		enum isl_dim_type type, unsigned pos, int value);
+	#include <isl/set.h>
+	__isl_give isl_basic_set *
+	isl_basic_set_lower_bound_val(
+		__isl_take isl_basic_set *bset,
+		enum isl_dim_type type, unsigned pos,
+		__isl_take isl_val *value);
+	__isl_give isl_basic_set *
+	isl_basic_set_upper_bound_val(
+		__isl_take isl_basic_set *bset,
+		enum isl_dim_type type, unsigned pos,
+		__isl_take isl_val *value);
 	__isl_give isl_set *isl_set_lower_bound_si(
 		__isl_take isl_set *set,
 		enum isl_dim_type type, unsigned pos, int value);
@@ -4674,9 +4681,6 @@ dimension has the fixed given value.
 		__isl_take isl_set *set,
 		enum isl_dim_type type, unsigned pos,
 		__isl_take isl_val *value);
-	__isl_give isl_map *isl_map_lower_bound_si(
-		__isl_take isl_map *map,
-		enum isl_dim_type type, unsigned pos, int value);
 	__isl_give isl_set *isl_set_upper_bound_si(
 		__isl_take isl_set *set,
 		enum isl_dim_type type, unsigned pos, int value);
@@ -4684,6 +4688,17 @@ dimension has the fixed given value.
 		__isl_take isl_set *set,
 		enum isl_dim_type type, unsigned pos,
 		__isl_take isl_val *value);
+
+	#include <isl/map.h>
+	__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
+		__isl_take isl_basic_map *bmap,
+		enum isl_dim_type type, unsigned pos, int value);
+	__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
+		__isl_take isl_basic_map *bmap,
+		enum isl_dim_type type, unsigned pos, int value);
+	__isl_give isl_map *isl_map_lower_bound_si(
+		__isl_take isl_map *map,
+		enum isl_dim_type type, unsigned pos, int value);
 	__isl_give isl_map *isl_map_upper_bound_si(
 		__isl_take isl_map *map,
 		enum isl_dim_type type, unsigned pos, int value);
@@ -5831,6 +5846,14 @@ the same (number of) parameters.
 	__isl_give isl_map *isl_map_intersect(
 		__isl_take isl_map *map1,
 		__isl_take isl_map *map2);
+	__isl_give isl_map *
+	isl_map_intersect_domain_factor_range(
+		__isl_take isl_map *map,
+		__isl_take isl_map *factor);
+	__isl_give isl_map *
+	isl_map_intersect_range_factor_range(
+		__isl_take isl_map *map,
+		__isl_take isl_map *factor);
 
 	#include <isl/union_set.h>
 	__isl_give isl_union_set *isl_union_set_intersect_params(
@@ -5853,6 +5876,10 @@ the same (number of) parameters.
 	__isl_give isl_union_map *isl_union_map_intersect(
 		__isl_take isl_union_map *umap1,
 		__isl_take isl_union_map *umap2);
+	__isl_give isl_union_map *
+	isl_union_map_intersect_range_factor_range(
+		__isl_take isl_union_map *umap,
+		__isl_take isl_union_map *factor);
 
 	#include <isl/aff.h>
 	__isl_give isl_pw_aff *isl_pw_aff_intersect_domain(
@@ -8747,29 +8774,31 @@ C<isl_schedule_node_to_str> prints the s
 =head2 Dependence Analysis
 
 C<isl> contains specialized functionality for performing
-array dataflow analysis.  That is, given a I<sink> access relation
-and a collection of possible I<source> access relations,
+array dataflow analysis.  That is, given a I<sink> access relation,
+a collection of possible I<source> accesses and
+a collection of I<kill> accesses,
 C<isl> can compute relations that describe
-for each iteration of the sink access, which iteration
-of which of the source access relations was the last
-to access the same data element before the given iteration
-of the sink access.
+for each iteration of the sink access, which iterations
+of which of the source access relations may have
+accessed the same data element before the given iteration
+of the sink access without any intermediate kill of that data element.
 The resulting dependence relations map source 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>
-accesses, then there will be a (may) dependence from the last
-I<must> access B<and> from any I<may> access that follows
-this last I<must> access, but still precedes the sink access.
-Only dependences originating in a must access and without
-any may accesses between the must access and the sink access
-are considered to be must dependences.
-In particular, if I<all> sources are I<may> accesses,
+If no kills are specified,
 then memory based dependence analysis is performed.
-If, on the other hand, all sources are I<must> accesses,
+If, on the other hand, all sources are also kills,
 then value based dependence analysis is performed.
+If any of the source accesses are marked as being I<must>
+accesses, then they are also treated as kills.
+Furthermore, the specification of must-sources results
+in the computation of must-dependences.
+Only dependences originating in a must access not coscheduled
+with any other access to the same element and without
+any may accesses between the must access and the sink access
+are considered to be must dependences.
 
 =head3 High-level Interface
 
@@ -8795,14 +8824,18 @@ the following functions.
 	isl_union_access_info_from_sink(
 		__isl_take isl_union_map *sink);
 	__isl_give isl_union_access_info *
-	isl_union_access_info_set_must_source(
+	isl_union_access_info_set_kill(
 		__isl_take isl_union_access_info *access,
-		__isl_take isl_union_map *must_source);
+		__isl_take isl_union_map *kill);
 	__isl_give isl_union_access_info *
 	isl_union_access_info_set_may_source(
 		__isl_take isl_union_access_info *access,
 		__isl_take isl_union_map *may_source);
 	__isl_give isl_union_access_info *
+	isl_union_access_info_set_must_source(
+		__isl_take isl_union_access_info *access,
+		__isl_take isl_union_map *must_source);
+	__isl_give isl_union_access_info *
 	isl_union_access_info_set_schedule(
 		__isl_take isl_union_access_info *access,
 		__isl_take isl_schedule *schedule);
@@ -8820,7 +8853,9 @@ the following functions.
 The may sources set by C<isl_union_access_info_set_may_source>
 do not need to include the must sources set by
 C<isl_union_access_info_set_must_source> as a subset.
-The user is free not to call one (or both) of these functions,
+The kills set by C<isl_union_access_info_set_kill> may overlap
+with the may-sources and/or must-sources.
+The user is free not to call one (or more) of these functions,
 in which case the corresponding set is kept to its empty default.
 Similarly, the default schedule initialized by
 C<isl_union_access_info_from_sink> is empty.
@@ -8832,6 +8867,14 @@ the access relations.  In particular, th
 relations are effectively intersected with the domain of the schedule
 and only the resulting accesses are considered by the dependence analysis.
 
+An C<isl_union_access_info> object can be read from input
+using the following function.
+
+	#include <isl/flow.h>
+	__isl_give isl_union_access_info *
+	isl_union_access_info_read_from_file(isl_ctx *ctx,
+		FILE *input);
+
 A representation of the information contained in an object
 of type C<isl_union_access_info> can be obtained using
 
@@ -8941,6 +8984,7 @@ C<sink>, a token C<sink_user> used to id
 access to the user, a callback function for specifying the
 relative order of source and sink accesses, and the number
 of source access relations that will be added.
+
 The callback function has type C<int (*)(void *first, void *second)>.
 The function is called with two user supplied tokens identifying
 either a source or the sink and it should return the shared nesting
@@ -8949,7 +8993,12 @@ In particular, let I<n> be the number of
 the two accesses.  If C<first> precedes C<second> textually,
 then the function should return I<2 * n + 1>; otherwise,
 it should return I<2 * n>.
-The sources can be added to the C<isl_access_info> by performing
+The low-level interface assumes that no sources are coscheduled.
+If the information returned by the callback does not allow
+the relative order to be determined, then one of the sources
+is arbitrarily taken to be executed after the other(s).
+
+The sources can be added to the C<isl_access_info> object by performing
 (at most) C<max_source> calls to C<isl_access_info_add_source>.
 C<must> indicates whether the source is a I<must> access
 or a I<may> access.  Note that a multi-valued access relation
@@ -8960,7 +9009,7 @@ the source access.  The range of the sou
 C<source> should have the same dimension as the range
 of the sink access relation.
 The C<isl_access_info_free> function should usually not be
-called explicitly, because it is called implicitly by
+called explicitly, because it is already called implicitly by
 C<isl_access_info_compute_flow>.
 
 The result of the dependence analysis is collected in an
@@ -9297,6 +9346,10 @@ L</"Schedule Trees">.
 		isl_ctx *ctx, int val);
 	int isl_options_get_schedule_algorithm(
 		isl_ctx *ctx);
+	isl_stat isl_options_set_schedule_carry_self_first(
+		isl_ctx *ctx, int val);
+	int isl_options_get_schedule_carry_self_first(
+		isl_ctx *ctx);
 	isl_stat isl_options_set_schedule_separate_components(
 		isl_ctx *ctx, int val);
 	int isl_options_get_schedule_separate_components(
@@ -9378,7 +9431,7 @@ If this option is set, then we try to co
 constant term is split off from the linear part if the linear parts of
 the scheduling rows for all nodes in the graph have a common non-trivial
 divisor.
-The constant term is then placed in a separate band and the linear
+The constant term is then dropped and the linear
 part is reduced.
 This option is only effective when the Feautrier style scheduler is
 being used, either as the main scheduler or as a fallback for the
@@ -9394,6 +9447,12 @@ For the Feautrier style scheduler, this
 coalescing schedules and then tries to adjust the schedule to avoid
 the coalescing.
 
+=item * schedule_carry_self_first
+
+If this option is set, then the Feautrier style scheduler
+(when used as a fallback for the Pluto-like scheduler) will
+first try to only carry self-dependences.
+
 =item * schedule_separate_components
 
 If this option is set then the function C<isl_schedule_get_map>
@@ -10763,6 +10822,12 @@ is given, then the constant should appea
 Given a polytope, C<isl_polytope_scan> prints
 all integer points in the polytope.
 
+=head2 C<isl_flow>
+
+Given an C<isl_union_access_info> object as input,
+C<isl_flow> prints out the corresponding dependences,
+as computed by C<isl_union_access_info_compute_flow>.
+
 =head2 C<isl_codegen>
 
 Given either a schedule tree or a sequence consisting of

Added: polly/trunk/lib/External/isl/extract_key.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/extract_key.c?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/extract_key.c (added)
+++ polly/trunk/lib/External/isl/extract_key.c Tue Jul  4 08:54:11 2017
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2013      Ecole Normale Superieure
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
+ */
+
+#include <string.h>
+
+/* Extract a mapping key from the token "tok".
+ * Return KEY_ERROR on error, i.e., if "tok" does not
+ * correspond to any known key.
+ */
+static KEY extract_key(__isl_keep isl_stream *s, struct isl_token *tok)
+{
+	int type;
+	char *name;
+	KEY key;
+	isl_ctx *ctx;
+
+	if (!tok)
+		return KEY_ERROR;
+	type = isl_token_get_type(tok);
+	if (type != ISL_TOKEN_IDENT && type != ISL_TOKEN_STRING) {
+		isl_stream_error(s, tok, "expecting key");
+		return KEY_ERROR;
+	}
+
+	ctx = isl_stream_get_ctx(s);
+	name = isl_token_get_str(ctx, tok);
+	if (!name)
+		return KEY_ERROR;
+
+	for (key = 0; key < KEY_END; ++key) {
+		if (!strcmp(name, key_str[key]))
+			break;
+	}
+	free(name);
+
+	if (key >= KEY_END)
+		isl_die(ctx, isl_error_invalid, "unknown key",
+			return KEY_ERROR);
+	return key;
+}
+
+/* Read a key from "s" and return the corresponding enum.
+ * Return KEY_ERROR on error, i.e., if the first token
+ * on the stream does not correspond to any known key.
+ */
+static KEY get_key(__isl_keep isl_stream *s)
+{
+	struct isl_token *tok;
+	KEY key;
+
+	tok = isl_stream_next_token(s);
+	key = extract_key(s, tok);
+	isl_token_free(tok);
+
+	return key;
+}

Added: polly/trunk/lib/External/isl/flow.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/flow.c?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/flow.c (added)
+++ polly/trunk/lib/External/isl/flow.c Tue Jul  4 08:54:11 2017
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017      Sven Verdoolaege
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege.
+ */
+
+/* This program takes an isl_union_access_info object as input and
+ * prints the corresponding dependences.
+ */
+
+#include <isl/options.h>
+#include <isl/printer.h>
+#include <isl/union_map.h>
+#include <isl/flow.h>
+#include <isl/schedule.h>
+
+int main(int argc, char **argv)
+{
+	isl_ctx *ctx;
+	isl_printer *p;
+	isl_union_access_info *access;
+	isl_union_flow *flow;
+	struct isl_options *options;
+
+	options = isl_options_new_with_defaults();
+	argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL);
+	ctx = isl_ctx_alloc_with_options(&isl_options_args, options);
+
+	access = isl_union_access_info_read_from_file(ctx, stdin);
+	flow = isl_union_access_info_compute_flow(access);
+
+	p = isl_printer_to_file(ctx, stdout);
+	p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK);
+	p = isl_printer_print_union_flow(p, flow);
+	isl_printer_free(p);
+
+	isl_union_flow_free(flow);
+
+	isl_ctx_free(ctx);
+
+	return 0;
+}

Added: polly/trunk/lib/External/isl/flow_cmp.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/flow_cmp.c?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/flow_cmp.c (added)
+++ polly/trunk/lib/External/isl/flow_cmp.c Tue Jul  4 08:54:11 2017
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2017      Sven Verdoolaege
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege.
+ */
+
+#include <stdlib.h>
+
+#include <isl/arg.h>
+#include <isl/options.h>
+#include <isl/union_map.h>
+#include <isl/stream.h>
+
+struct options {
+	struct isl_options *isl;
+	char *flow1;
+	char *flow2;
+};
+
+ISL_ARGS_START(struct options, options_args)
+ISL_ARG_CHILD(struct options, isl, "isl", &isl_options_args, "isl options")
+ISL_ARG_ARG(struct options, flow1, "flow1", NULL)
+ISL_ARG_ARG(struct options, flow2, "flow2", NULL)
+ISL_ARGS_END
+
+ISL_ARG_DEF(options, struct options, options_args)
+
+static void die(const char *msg)
+{
+	fprintf(stderr, "%s\n", msg);
+	exit(EXIT_FAILURE);
+}
+
+static FILE *open_or_die(const char *filename)
+{
+	FILE *file;
+
+	file = fopen(filename, "r");
+	if (!file) {
+		fprintf(stderr, "Unable to open %s\n", filename);
+		exit(EXIT_FAILURE);
+	}
+	return file;
+}
+
+#undef BASE
+#define BASE union_map
+#include "read_in_string_templ.c"
+
+/* Given two YAML descriptions of isl_union_flow objects, check whether
+ * they are equivalent.
+ * Return EXIT_SUCCESS if they are and EXIT_FAILURE if they are not
+ * or if anything else went wrong.
+ *
+ * The descriptions are checked field by field, meaning that the fields
+ * are expected to appear in the same order in both inputs.
+ */
+int main(int argc, char **argv)
+{
+	int more;
+	isl_ctx *ctx;
+	struct options *options;
+	FILE *input1, *input2;
+	isl_stream *s1, *s2;
+
+	options = options_new_with_defaults();
+	if (!options)
+		return EXIT_FAILURE;
+
+	ctx = isl_ctx_alloc_with_options(&options_args, options);
+	argc = options_parse(options, argc, argv, ISL_ARG_ALL);
+
+	input1 = open_or_die(options->flow1);
+	input2 = open_or_die(options->flow2);
+	s1 = isl_stream_new_file(ctx, input1);
+	s2 = isl_stream_new_file(ctx, input2);
+
+	if (isl_stream_yaml_read_start_mapping(s1))
+		isl_die(ctx, isl_error_unknown, "arg1 not a YAML mapping",
+			return EXIT_FAILURE);
+	if (isl_stream_yaml_read_start_mapping(s2))
+		isl_die(ctx, isl_error_unknown, "arg2 not a YAML mapping",
+			return EXIT_FAILURE);
+
+	while ((more = isl_stream_yaml_next(s1)) > 0) {
+		int more2;
+		isl_bool equal;
+		isl_union_map *umap1, *umap2;
+
+		more2 = isl_stream_yaml_next(s2);
+		if (more2 < 0)
+			return EXIT_FAILURE;
+		if (!more2)
+			isl_die(ctx, isl_error_unknown, "arg2 shorter",
+				return EXIT_FAILURE);
+		if (isl_stream_eat(s1, ISL_TOKEN_IDENT) < 0)
+			return EXIT_FAILURE;
+		if (isl_stream_eat(s2, ISL_TOKEN_IDENT) < 0)
+			return EXIT_FAILURE;
+		more = isl_stream_yaml_next(s1);
+		more2 = isl_stream_yaml_next(s2);
+		if (more < 0 || more2 < 0)
+			return EXIT_FAILURE;
+		if (!more || !more2)
+			isl_die(ctx, isl_error_unknown, "missing value",
+				return EXIT_FAILURE);
+
+		umap1 = read_union_map(s1);
+		umap2 = read_union_map(s2);
+		equal = isl_union_map_is_equal(umap1, umap2);
+		isl_union_map_free(umap1);
+		isl_union_map_free(umap2);
+		if (equal < 0)
+			return EXIT_FAILURE;
+		if (!equal)
+			die("field not equal");
+	}
+	if (more < 0)
+		return EXIT_FAILURE;
+
+
+	if (isl_stream_yaml_read_end_mapping(s1) < 0) {
+		isl_stream_error(s1, NULL, "unexpected extra elements");
+		return EXIT_FAILURE;
+	}
+	if (isl_stream_yaml_read_end_mapping(s2) < 0) {
+		isl_stream_error(s2, NULL, "unexpected extra elements");
+		return EXIT_FAILURE;
+	}
+
+	isl_stream_free(s1);
+	isl_stream_free(s2);
+	fclose(input1);
+	fclose(input2);
+	isl_ctx_free(ctx);
+
+	return EXIT_SUCCESS;
+}

Added: polly/trunk/lib/External/isl/flow_test.sh.in
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/flow_test.sh.in?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/flow_test.sh.in (added)
+++ polly/trunk/lib/External/isl/flow_test.sh.in Tue Jul  4 08:54:11 2017
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+EXEEXT=@EXEEXT@
+srcdir=@srcdir@
+
+failed=0
+
+for i in $srcdir/test_inputs/flow/*.ai; do
+	echo $i;
+	base=`basename $i .ai`
+	test=test-$base.flow
+	dir=`dirname $i`
+	ref=$dir/$base.flow
+	(./isl_flow$EXEEXT < $i > $test &&
+	./isl_flow_cmp$EXEEXT $ref $test && rm $test) || failed=1
+done
+
+test $failed -eq 0 || exit

Modified: polly/trunk/lib/External/isl/imath/imath.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/imath/imath.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/imath/imath.c (original)
+++ polly/trunk/lib/External/isl/imath/imath.c Tue Jul  4 08:54:11 2017
@@ -993,7 +993,7 @@ mp_result mp_int_expt(mp_int a, mp_small
 {
   mpz_t t;
   mp_result res;
-  unsigned int v = abs(b);
+  unsigned int v = labs(b);
 
   CHECK(c != NULL);
   if (b < 0)
@@ -1025,7 +1025,7 @@ mp_result mp_int_expt_value(mp_small a,
 {
   mpz_t     t;
   mp_result res;
-  unsigned int v = abs(b);
+  unsigned int v = labs(b);
 
   CHECK(c != NULL);
   if (b < 0)
@@ -1635,7 +1635,7 @@ mp_result mp_int_to_int(mp_int z, mp_sma
   }
 
   if (out)
-    *out = (sz == MP_NEG) ? -(mp_small)uv : (mp_small)uv;
+    *out = (mp_small)((sz == MP_NEG) ? -uv : uv);
 
   return MP_OK;
 }
@@ -2511,7 +2511,7 @@ STATIC void     s_qmod(mp_int z, mp_size
 {
   mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT;
   mp_size uz = MP_USED(z);
-  mp_digit mask = (1 << rest) - 1;
+  mp_digit mask = (1u << rest) - 1;
 
   if (start <= uz) {
     MP_USED(z) = start;
@@ -2679,7 +2679,7 @@ STATIC int      s_norm(mp_int a, mp_int
   mp_digit d = b->digits[MP_USED(b) - 1];
   int k = 0;
 
-  while (d < (mp_digit) (1 << (MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */
+  while (d < (1u << (mp_digit)(MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */
     d <<= 1;
     ++k;
   }
@@ -2816,106 +2816,6 @@ STATIC mp_result s_embar(mp_int a, mp_in
   return res;
 }
 
-#if 0
-/*
-  The s_udiv function produces incorrect results. For example, with test
-     div:11141460315522012760862883825:48318382095:0,230584300062375935
-   commenting out the function for now and using s_udiv_knuth instead.
-   STATIC mp_result s_udiv(mp_int a, mp_int b);
-*/
-/* Precondition:  a >= b and b > 0
-   Postcondition: a' = a / b, b' = a % b
- */
-STATIC mp_result s_udiv(mp_int a, mp_int b)
-{
-  mpz_t q, r, t;
-  mp_size ua, ub, qpos = 0;
-  mp_digit *da, btop;
-  mp_result res = MP_OK;
-  int k, skip = 0;
-
-  /* Force signs to positive */
-  MP_SIGN(a) = MP_ZPOS;
-  MP_SIGN(b) = MP_ZPOS;
-
-  /* Normalize, per Knuth */
-  k = s_norm(a, b);
-
-  ua = MP_USED(a); ub = MP_USED(b); btop = b->digits[ub - 1];
-  if ((res = mp_int_init_size(&q, ua)) != MP_OK) return res;
-  if ((res = mp_int_init_size(&t, ua + 1)) != MP_OK) goto CLEANUP;
-
-  da = MP_DIGITS(a);
-  r.digits = da + ua - 1;  /* The contents of r are shared with a */
-  r.used   = 1;
-  r.sign   = MP_ZPOS;
-  r.alloc  = MP_ALLOC(a);
-  ZERO(t.digits, t.alloc);
-
-  /* Solve for quotient digits, store in q.digits in reverse order */
-  while (r.digits >= da) {
-    assert(qpos <= q.alloc);
-
-    if (s_ucmp(b, &r) > 0) {
-      r.digits -= 1;
-      r.used += 1;
-
-      if (++skip > 1 && qpos > 0)
-	q.digits[qpos++] = 0;
-
-      CLAMP(&r);
-    }
-    else {
-      mp_word  pfx = r.digits[r.used - 1];
-      mp_word  qdigit;
-
-      if (r.used > 1 && pfx < btop) {
-	pfx <<= MP_DIGIT_BIT / 2;
-	pfx <<= MP_DIGIT_BIT / 2;
-	pfx |= r.digits[r.used - 2];
-      }
-
-      qdigit = pfx / btop;
-      if (qdigit > MP_DIGIT_MAX) {
-	qdigit = MP_DIGIT_MAX;
-      }
-
-      s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub);
-      t.used = ub + 1; CLAMP(&t);
-      while (s_ucmp(&t, &r) > 0) {
-	--qdigit;
-	(void) mp_int_sub(&t, b, &t); /* cannot fail */
-      }
-
-      s_usub(r.digits, t.digits, r.digits, r.used, t.used);
-      CLAMP(&r);
-
-      q.digits[qpos++] = (mp_digit) qdigit;
-      ZERO(t.digits, t.used);
-      skip = 0;
-    }
-  }
-
-  /* Put quotient digits in the correct order, and discard extra zeroes */
-  q.used = qpos;
-  REV(mp_digit, q.digits, qpos);
-  CLAMP(&q);
-
-  /* Denormalize the remainder */
-  CLAMP(a);
-  if (k != 0)
-    s_qdiv(a, k);
-
-  mp_int_copy(a, b);  /* ok:  0 <= r < b */
-  mp_int_copy(&q, a); /* ok:  q <= a     */
-
-  mp_int_clear(&t);
- CLEANUP:
-  mp_int_clear(&q);
-  return res;
-}
-#endif
-
 /* Division of nonnegative integers
 
    This function implements division algorithm for unsigned multi-precision
@@ -2956,19 +2856,18 @@ STATIC mp_result s_udiv_knuth(mp_int u,
     return MP_OK;
   }
 
-  /************************************************************/
-  /* Algorithm D */
-  /************************************************************/
-  /* The n and m variables are defined as used by Knuth.
+  /* Algorithm D
+
+     The n and m variables are defined as used by Knuth.
      u is an n digit number with digits u_{n-1}..u_0.
      v is an n+m digit number with digits from v_{m+n-1}..v_0.
-     We require that n > 1 and m >= 0 */
+     We require that n > 1 and m >= 0
+   */
   n = MP_USED(v);
   m = MP_USED(u) - n;
-  assert(n >  1);
+  assert(n > 1);
   assert(m >= 0);
 
-  /************************************************************/
   /* D1: Normalize.
      The normalization step provides the necessary condition for Theorem B,
      which states that the quotient estimate for q_j, call it qhat
@@ -2980,7 +2879,8 @@ STATIC mp_result s_udiv_knuth(mp_int u,
       qhat - 2 <= q_j <= qhat.
 
      That is, qhat is always greater than the actual quotient digit q,
-     and it is never more than two larger than the actual quotient digit.  */
+     and it is never more than two larger than the actual quotient digit.
+   */
   k = s_norm(u, v);
 
   /* Extend size of u by one if needed.
@@ -3001,16 +2901,17 @@ STATIC mp_result s_udiv_knuth(mp_int u,
 
      The multiplication in step D4 multiplies qhat * 0v_{n-1}..v_0.  We need to
      add the leading zero to v here to ensure that the multiplication will
-     produce the full n+1 digit result.  */
+     produce the full n+1 digit result.
+   */
   if (!s_pad(v, n+1)) return MP_MEMORY; v->digits[n] = 0;
 
   /* Initialize temporary variables q and t.
      q allocates space for m+1 digits to store the quotient digits
-     t allocates space for n+1 digits to hold the result of q_j*v */
+     t allocates space for n+1 digits to hold the result of q_j*v
+   */
   if ((res = mp_int_init_size(&q, m + 1)) != MP_OK) return res;
   if ((res = mp_int_init_size(&t, n + 1)) != MP_OK) goto CLEANUP;
 
-  /************************************************************/
   /* D2: Initialize j */
   j = m;
   r.digits = MP_DIGITS(u) + j;  /* The contents of r are shared with u */
@@ -3021,7 +2922,6 @@ STATIC mp_result s_udiv_knuth(mp_int u,
 
   /* Calculate the m+1 digits of the quotient result */
   for (; j >= 0; j--) {
-    /************************************************************/
     /* D3: Calculate q' */
     /* r->digits is aligned to position j of the number u */
     mp_word pfx, qhat;
@@ -3038,7 +2938,6 @@ STATIC mp_result s_udiv_knuth(mp_int u,
     if (qhat > MP_DIGIT_MAX)
       qhat = MP_DIGIT_MAX;
 
-    /************************************************************/
     /* D4,D5,D6: Multiply qhat * v and test for a correct value of q
 
        We proceed a bit different than the way described by Knuth. This way is
@@ -3049,7 +2948,8 @@ STATIC mp_result s_udiv_knuth(mp_int u,
        more time before we get a value that is smaller than r.
 
        This way is less efficent than Knuth becuase we do more multiplies, but
-       we do not need to worry about underflow this way.  */
+       we do not need to worry about underflow this way.
+     */
     /* t = qhat * v */
     s_dbmul(MP_DIGITS(v), (mp_digit) qhat, t.digits, n+1); t.used = n + 1;
     CLAMP(&t);
@@ -3072,25 +2972,25 @@ STATIC mp_result s_udiv_knuth(mp_int u,
        digits long. */
     r.used = n + 1;
 
-    /************************************************************/
-    /* D4: Multiply and subtract */
-    /* note: The multiply was completed above so we only need to subtract here.
-     **/
+    /* D4: Multiply and subtract
+
+       Note: The multiply was completed above so we only need to subtract here.
+     */
     s_usub(r.digits, t.digits, r.digits, r.used, t.used);
 
-    /************************************************************/
-    /* D5: Test remainder */
-    /* note: Not needed because we always check that qhat is the correct value
-     *       before performing the subtract.
-     *       Value cast to mp_digit to prevent warning, qhat has been clamped to MP_DIGIT_MAX */
+    /* D5: Test remainder
+
+       Note: Not needed because we always check that qhat is the correct value
+             before performing the subtract.  Value cast to mp_digit to prevent
+             warning, qhat has been clamped to MP_DIGIT_MAX
+     */
     q.digits[j] = (mp_digit)qhat;
 
-    /************************************************************/
-    /* D6: Add back */
-    /* note: Not needed because we always check that qhat is the correct value
-     *       before performing the subtract. */
+    /* D6: Add back
+       Note: Not needed because we always check that qhat is the correct value
+             before performing the subtract.
+     */
 
-    /************************************************************/
     /* D7: Loop on j */
     r.digits--;
     ZERO(t.digits, t.alloc);

Modified: polly/trunk/lib/External/isl/imath_wrap/wrap.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/imath_wrap/wrap.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/imath_wrap/wrap.h (original)
+++ polly/trunk/lib/External/isl/imath_wrap/wrap.h Tue Jul  4 08:54:11 2017
@@ -39,7 +39,6 @@
 #define impz_divisible_p	isl_impz_divisible_p
 #define impz_export	isl_impz_export
 #define impz_fdiv_q	isl_impz_fdiv_q
-#define impz_fdiv_q_ui	isl_impz_fdiv_q_ui
 #define impz_fdiv_r	isl_impz_fdiv_r
 #define impz_gcd	isl_impz_gcd
 #define impz_get_si	isl_impz_get_si

Modified: polly/trunk/lib/External/isl/include/isl/aff.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/aff.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/aff.h (original)
+++ polly/trunk/lib/External/isl/include/isl/aff.h Tue Jul  4 08:54:11 2017
@@ -947,8 +947,8 @@ __isl_give isl_union_pw_aff *isl_multi_u
 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff);
 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma);
-__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
-	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma);
+__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff(
+	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa);
 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
 	__isl_take isl_multi_union_pw_aff *mupa,
 	__isl_take isl_pw_multi_aff *pma);

Modified: polly/trunk/lib/External/isl/include/isl/flow.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/flow.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/flow.h (original)
+++ polly/trunk/lib/External/isl/include/isl/flow.h Tue Jul  4 08:54:11 2017
@@ -1,6 +1,8 @@
 #ifndef ISL_FLOW_H
 #define ISL_FLOW_H
 
+#include <stdio.h>
+
 #include <isl/set_type.h>
 #include <isl/map_type.h>
 #include <isl/union_set_type.h>
@@ -82,6 +84,10 @@ __isl_give isl_union_access_info *isl_un
 	__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_kill(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *kill);
+__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);
@@ -97,6 +103,8 @@ __isl_null isl_union_access_info *isl_un
 isl_ctx *isl_union_access_info_get_ctx(
 	__isl_keep isl_union_access_info *access);
 
+__isl_give isl_union_access_info *isl_union_access_info_read_from_file(
+	isl_ctx *ctx, FILE *input);
 __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(

Modified: polly/trunk/lib/External/isl/include/isl/map.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/map.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/map.h (original)
+++ polly/trunk/lib/External/isl/include/isl/map.h Tue Jul  4 08:54:11 2017
@@ -301,8 +301,8 @@ __isl_export
 __isl_give isl_map *isl_map_union(
 		__isl_take isl_map *map1,
 		__isl_take isl_map *map2);
-struct isl_map *isl_map_union_disjoint(
-			struct isl_map *map1, struct isl_map *map2);
+__isl_give isl_map *isl_map_union_disjoint(
+		__isl_take isl_map *map1, __isl_take isl_map *map2);
 __isl_export
 __isl_give isl_map *isl_map_intersect_domain(
 		__isl_take isl_map *map,
@@ -311,6 +311,10 @@ __isl_export
 __isl_give isl_map *isl_map_intersect_range(
 		__isl_take isl_map *map,
 		__isl_take isl_set *set);
+__isl_give isl_map *isl_map_intersect_domain_factor_range(
+	__isl_take isl_map *map, __isl_take isl_map *factor);
+__isl_give isl_map *isl_map_intersect_range_factor_range(
+	__isl_take isl_map *map, __isl_take isl_map *factor);
 __isl_export
 __isl_give isl_map *isl_map_apply_domain(
 		__isl_take isl_map *map1,

Modified: polly/trunk/lib/External/isl/include/isl/schedule.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/schedule.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/schedule.h (original)
+++ polly/trunk/lib/External/isl/include/isl/schedule.h Tue Jul  4 08:54:11 2017
@@ -47,6 +47,9 @@ int isl_options_get_schedule_serialize_s
 isl_stat isl_options_set_schedule_whole_component(isl_ctx *ctx, int val);
 int isl_options_get_schedule_whole_component(isl_ctx *ctx);
 
+isl_stat isl_options_set_schedule_carry_self_first(isl_ctx *ctx, int val);
+int isl_options_get_schedule_carry_self_first(isl_ctx *ctx);
+
 __isl_give isl_schedule_constraints *isl_schedule_constraints_copy(
 	__isl_keep isl_schedule_constraints *sc);
 __isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain(

Modified: polly/trunk/lib/External/isl/include/isl/set.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/set.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/set.h (original)
+++ polly/trunk/lib/External/isl/include/isl/set.h Tue Jul  4 08:54:11 2017
@@ -152,10 +152,16 @@ __isl_give isl_set *isl_set_fix_si(__isl
 		enum isl_dim_type type, unsigned pos, int value);
 __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
 		enum isl_dim_type type, unsigned pos, int value);
+__isl_give isl_basic_set *isl_basic_set_lower_bound_val(
+	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_val *value);
 __isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set,
 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value);
 __isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set,
 	enum isl_dim_type type, unsigned pos, int value);
+__isl_give isl_basic_set *isl_basic_set_upper_bound_val(
+	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_val *value);
 __isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set,
 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value);
 

Modified: polly/trunk/lib/External/isl/include/isl/union_map.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/union_map.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/union_map.h (original)
+++ polly/trunk/lib/External/isl/include/isl/union_map.h Tue Jul  4 08:54:11 2017
@@ -145,6 +145,8 @@ __isl_give isl_union_map *isl_union_map_
 __isl_export
 __isl_give isl_union_map *isl_union_map_intersect_range(
 	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset);
+__isl_give isl_union_map *isl_union_map_intersect_range_factor_range(
+	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor);
 
 __isl_export
 __isl_give isl_union_map *isl_union_map_subtract_domain(

Modified: polly/trunk/lib/External/isl/include/isl/val.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/val.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/val.h (original)
+++ polly/trunk/lib/External/isl/include/isl/val.h Tue Jul  4 08:54:11 2017
@@ -84,6 +84,7 @@ __isl_give isl_val *isl_val_mul(__isl_ta
 __isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2);
 __isl_export
 __isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2);
+__isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2);
 __isl_export
 __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2);
 __isl_export

Modified: polly/trunk/lib/External/isl/isl_aff.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_aff.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_aff.c (original)
+++ polly/trunk/lib/External/isl/isl_aff.c Tue Jul  4 08:54:11 2017
@@ -3805,6 +3805,64 @@ error:
 
 #undef NO_DOMAIN
 
+/* Construct an isl_multi_aff living in "space" that corresponds
+ * to the affine transformation matrix "mat".
+ */
+__isl_give isl_multi_aff *isl_multi_aff_from_aff_mat(
+	__isl_take isl_space *space, __isl_take isl_mat *mat)
+{
+	isl_ctx *ctx;
+	isl_local_space *ls = NULL;
+	isl_multi_aff *ma = NULL;
+	int n_row, n_col, n_out, total;
+	int i;
+
+	if (!space || !mat)
+		goto error;
+
+	ctx = isl_mat_get_ctx(mat);
+
+	n_row = isl_mat_rows(mat);
+	n_col = isl_mat_cols(mat);
+	if (n_row < 1)
+		isl_die(ctx, isl_error_invalid,
+			"insufficient number of rows", goto error);
+	if (n_col < 1)
+		isl_die(ctx, isl_error_invalid,
+			"insufficient number of columns", goto error);
+	n_out = isl_space_dim(space, isl_dim_out);
+	total = isl_space_dim(space, isl_dim_all);
+	if (1 + n_out != n_row || 2 + total != n_row + n_col)
+		isl_die(ctx, isl_error_invalid,
+			"dimension mismatch", goto error);
+
+	ma = isl_multi_aff_zero(isl_space_copy(space));
+	ls = isl_local_space_from_space(isl_space_domain(space));
+
+	for (i = 0; i < n_row - 1; ++i) {
+		isl_vec *v;
+		isl_aff *aff;
+
+		v = isl_vec_alloc(ctx, 1 + n_col);
+		if (!v)
+			goto error;
+		isl_int_set(v->el[0], mat->row[0][0]);
+		isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col);
+		v = isl_vec_normalize(v);
+		aff = isl_aff_alloc_vec(isl_local_space_copy(ls), v);
+		ma = isl_multi_aff_set_aff(ma, i, aff);
+	}
+
+	isl_local_space_free(ls);
+	isl_mat_free(mat);
+	return ma;
+error:
+	isl_local_space_free(ls);
+	isl_mat_free(mat);
+	isl_multi_aff_free(ma);
+	return NULL;
+}
+
 /* Remove any internal structure of the domain of "ma".
  * If there is any such internal structure in the input,
  * then the name of the corresponding space is also removed.

Modified: polly/trunk/lib/External/isl/isl_aff_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_aff_private.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_aff_private.h (original)
+++ polly/trunk/lib/External/isl/isl_aff_private.h Tue Jul  4 08:54:11 2017
@@ -125,6 +125,9 @@ __isl_give isl_multi_aff *isl_multi_aff_
 __isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
 	__isl_take isl_basic_set *bset);
 
+__isl_give isl_multi_aff *isl_multi_aff_from_aff_mat(
+	__isl_take isl_space *space, __isl_take isl_mat *mat);
+
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_domain_space(
 	__isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_space(

Modified: polly/trunk/lib/External/isl/isl_config.h.in
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_config.h.in?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_config.h.in (original)
+++ polly/trunk/lib/External/isl/isl_config.h.in Tue Jul  4 08:54:11 2017
@@ -130,6 +130,9 @@
 /* Return type of HandleTopLevelDeclReturn */
 #undef HandleTopLevelDeclReturn
 
+/* Define to InputKind::C for newer versions of clang */
+#undef IK_C
+
 /* Define to the sub-directory where libtool stores uninstalled libraries. */
 #undef LT_OBJDIR
 

Modified: polly/trunk/lib/External/isl/isl_convex_hull.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_convex_hull.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_convex_hull.c (original)
+++ polly/trunk/lib/External/isl/isl_convex_hull.c Tue Jul  4 08:54:11 2017
@@ -1346,23 +1346,29 @@ error:
 }
 
 /* Compute the lineality space of a basic set.
- * We currently do not allow the basic set to have any divs.
  * We basically just drop the constants and turn every inequality
  * into an equality.
+ * Any explicit representations of local variables are removed
+ * because they may no longer be valid representations
+ * in the lineality space.
  */
 __isl_give isl_basic_set *isl_basic_set_lineality_space(
 	__isl_take isl_basic_set *bset)
 {
 	int i, k;
 	struct isl_basic_set *lin = NULL;
-	unsigned dim;
+	unsigned n_div, dim;
 
 	if (!bset)
 		goto error;
-	isl_assert(bset->ctx, bset->n_div == 0, goto error);
+	n_div = isl_basic_set_dim(bset, isl_dim_div);
 	dim = isl_basic_set_total_dim(bset);
 
-	lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset), 0, dim, 0);
+	lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset),
+					n_div, dim, 0);
+	for (i = 0; i < n_div; ++i)
+		if (isl_basic_set_alloc_div(lin) < 0)
+			goto error;
 	if (!lin)
 		goto error;
 	for (i = 0; i < bset->n_eq; ++i) {
@@ -1394,9 +1400,9 @@ error:
 }
 
 /* Compute the (linear) hull of the lineality spaces of the basic sets in the
- * "underlying" set "set".
+ * set "set".
  */
-static __isl_give isl_basic_set *uset_combined_lineality_space(
+__isl_give isl_basic_set *isl_set_combined_lineality_space(
 	__isl_take isl_set *set)
 {
 	int i;
@@ -1772,7 +1778,7 @@ static __isl_give isl_basic_set *uset_co
 	if (bounded && set->ctx->opt->convex == ISL_CONVEX_HULL_WRAP)
 		return uset_convex_hull_wrap(set);
 
-	lin = uset_combined_lineality_space(isl_set_copy(set));
+	lin = isl_set_combined_lineality_space(isl_set_copy(set));
 	if (!lin)
 		goto error;
 	if (isl_basic_set_plain_is_universe(lin)) {
@@ -1852,6 +1858,8 @@ static __isl_give isl_basic_set *modulo_
 	convex_hull = isl_basic_set_intersect(convex_hull, affine_hull);
 	return convex_hull;
 error:
+	isl_mat_free(T);
+	isl_mat_free(T2);
 	isl_basic_set_free(affine_hull);
 	isl_set_free(set);
 	return NULL;

Modified: polly/trunk/lib/External/isl/isl_dim_map.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_dim_map.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_dim_map.c (original)
+++ polly/trunk/lib/External/isl/isl_dim_map.c Tue Jul  4 08:54:11 2017
@@ -43,8 +43,7 @@ __isl_give isl_dim_map *isl_dim_map_allo
 }
 
 void isl_dim_map_range(__isl_keep isl_dim_map *dim_map,
-	unsigned dst_pos, unsigned dst_stride,
-	unsigned src_pos, unsigned src_stride,
+	unsigned dst_pos, int dst_stride, unsigned src_pos, int src_stride,
 	unsigned n, int sign)
 {
 	int i;

Modified: polly/trunk/lib/External/isl/isl_dim_map.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_dim_map.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_dim_map.h (original)
+++ polly/trunk/lib/External/isl/isl_dim_map.h Tue Jul  4 08:54:11 2017
@@ -11,8 +11,7 @@ typedef struct isl_dim_map isl_dim_map;
 
 __isl_give isl_dim_map *isl_dim_map_alloc(isl_ctx *ctx, unsigned len);
 void isl_dim_map_range(__isl_keep isl_dim_map *dim_map,
-	unsigned dst_pos, unsigned dst_stride,
-	unsigned src_pos, unsigned src_stride,
+	unsigned dst_pos, int dst_stride, unsigned src_pos, int src_stride,
 	unsigned n, int sign);
 void isl_dim_map_dim_range(__isl_keep isl_dim_map *dim_map,
 	isl_space *dim, enum isl_dim_type type,

Modified: polly/trunk/lib/External/isl/isl_flow.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_flow.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_flow.c (original)
+++ polly/trunk/lib/External/isl/isl_flow.c Tue Jul  4 08:54:11 2017
@@ -23,6 +23,7 @@
 #include <isl/flow.h>
 #include <isl/schedule_node.h>
 #include <isl_sort.h>
+#include <isl/stream.h>
 
 enum isl_restriction_type {
 	isl_restriction_type_empty,
@@ -159,10 +160,15 @@ struct isl_labeled_map {
 	int		must;
 };
 
+typedef int (*isl_access_coscheduled)(void *first, void *second);
+
 /* A structure containing the input for dependence analysis:
  * - a sink
  * - n_must + n_may (<= max_source) sources
  * - a function for determining the relative order of sources and sink
+ * - an optional function "coscheduled" for determining whether sources
+ *   may be coscheduled.  If "coscheduled" is NULL, then the sources
+ *   are assumed not to be coscheduled.
  * The must sources are placed before the may sources.
  *
  * domain_map is an auxiliary map that maps the sink access relation
@@ -177,6 +183,7 @@ struct isl_access_info {
 	isl_map				*domain_map;
 	struct isl_labeled_map		sink;
 	isl_access_level_before		level_before;
+	isl_access_coscheduled		coscheduled;
 
 	isl_access_restrict		restrict_fn;
 	void				*restrict_user;
@@ -840,6 +847,140 @@ static __isl_give isl_map *all_intermedi
 	return map;
 }
 
+/* Given a dependence relation "old_map" between a must-source and the sink,
+ * return a subset of the dependences, augmented with instances
+ * of the source at position "pos" in "acc" that are coscheduled
+ * with the must-source and that access the same element.
+ * That is, if the input lives in a space T -> K, then the output
+ * lives in the space [T -> S] -> K, with S the space of source "pos", and
+ * the domain factor of the domain product is a subset of the input.
+ * The sources are considered to be coscheduled if they have the same values
+ * for the initial "depth" coordinates.
+ *
+ * First construct a dependence relation S -> K and a mapping
+ * between coscheduled sources T -> S.
+ * The second is combined with the original dependence relation T -> K
+ * to form a relation in T -> [S -> K], which is subsequently
+ * uncurried to [T -> S] -> K.
+ * This result is then intersected with the dependence relation S -> K
+ * to form the output.
+ */
+static __isl_give isl_map *coscheduled_source(__isl_keep isl_access_info *acc,
+	__isl_keep isl_map *old_map, int pos, int depth)
+{
+	isl_space *space;
+	isl_set *set_C;
+	isl_map *read_map;
+	isl_map *write_map;
+	isl_map *dep_map;
+	isl_map *equal;
+	isl_map *map;
+
+	set_C = isl_map_range(isl_map_copy(old_map));
+	read_map = isl_map_copy(acc->sink.map);
+	read_map = isl_map_intersect_domain(read_map, set_C);
+	write_map = isl_map_copy(acc->source[pos].map);
+	dep_map = isl_map_domain_product(write_map, read_map);
+	dep_map = isl_set_unwrap(isl_map_domain(dep_map));
+	space = isl_space_join(isl_map_get_space(old_map),
+				isl_space_reverse(isl_map_get_space(dep_map)));
+	equal = isl_map_from_basic_map(isl_basic_map_equal(space, depth));
+	map = isl_map_range_product(equal, isl_map_copy(old_map));
+	map = isl_map_uncurry(map);
+	map = isl_map_intersect_domain_factor_range(map, dep_map);
+
+	return map;
+}
+
+/* After the dependences derived from a must-source have been computed
+ * at a certain level, check if any of the sources of the must-dependences
+ * may be coscheduled with other sources.
+ * If they are any such sources, then there is no way of determining
+ * which of the sources actually comes last and the must-dependences
+ * need to be turned into may-dependences, while dependences from
+ * the other sources need to be added to the may-dependences as well.
+ * "acc" describes the sources and a callback for checking whether
+ * two sources may be coscheduled.  If acc->coscheduled is NULL then
+ * the sources are assumed not to be coscheduled.
+ * "must_rel" and "may_rel" describe the must and may-dependence relations
+ * computed at the current level for the must-sources.  Some of the dependences
+ * may be moved from "must_rel" to "may_rel".
+ * "flow" contains all dependences computed so far (apart from those
+ * in "must_rel" and "may_rel") and may be updated with additional
+ * dependences derived from may-sources.
+ *
+ * In particular, consider all the must-sources with a non-empty
+ * dependence relation in "must_rel".  They are considered in reverse
+ * order because that is the order in which they are considered in the caller.
+ * If any of the must-sources are coscheduled, then the last one
+ * is the one that will have a corresponding dependence relation.
+ * For each must-source i, consider both all the previous must-sources
+ * and all the may-sources.  If any of those may be coscheduled with
+ * must-source i, then compute the coscheduled instances that access
+ * the same memory elements.  The result is a relation [T -> S] -> K.
+ * The projection onto T -> K is a subset of the must-dependence relation
+ * that needs to be turned into may-dependences.
+ * The projection onto S -> K needs to be added to the may-dependences
+ * of source S.
+ * Since a given must-source instance may be coscheduled with several
+ * other source instances, the dependences that need to be turned
+ * into may-dependences are first collected and only actually removed
+ * from the must-dependences after all other sources have been considered.
+ */
+static __isl_give isl_flow *handle_coscheduled(__isl_keep isl_access_info *acc,
+	__isl_keep isl_map **must_rel, __isl_keep isl_map **may_rel,
+	__isl_take isl_flow *flow)
+{
+	int i, j;
+
+	if (!acc->coscheduled)
+		return flow;
+	for (i = acc->n_must - 1; i >= 0; --i) {
+		isl_map *move;
+
+		if (isl_map_plain_is_empty(must_rel[i]))
+			continue;
+		move = isl_map_empty(isl_map_get_space(must_rel[i]));
+		for (j = i - 1; j >= 0; --j) {
+			int depth;
+			isl_map *map, *factor;
+
+			if (!acc->coscheduled(acc->source[i].data,
+						acc->source[j].data))
+				continue;
+			depth = acc->level_before(acc->source[i].data,
+						acc->source[j].data) / 2;
+			map = coscheduled_source(acc, must_rel[i], j, depth);
+			factor = isl_map_domain_factor_range(isl_map_copy(map));
+			may_rel[j] = isl_map_union(may_rel[j], factor);
+			map = isl_map_domain_factor_domain(map);
+			move = isl_map_union(move, map);
+		}
+		for (j = 0; j < acc->n_may; ++j) {
+			int depth, pos;
+			isl_map *map, *factor;
+
+			pos = acc->n_must + j;
+			if (!acc->coscheduled(acc->source[i].data,
+						acc->source[pos].data))
+				continue;
+			depth = acc->level_before(acc->source[i].data,
+						acc->source[pos].data) / 2;
+			map = coscheduled_source(acc, must_rel[i], pos, depth);
+			factor = isl_map_domain_factor_range(isl_map_copy(map));
+			pos = 2 * acc->n_must + j;
+			flow->dep[pos].map = isl_map_union(flow->dep[pos].map,
+							    factor);
+			map = isl_map_domain_factor_domain(map);
+			move = isl_map_union(move, map);
+		}
+		must_rel[i] = isl_map_subtract(must_rel[i], isl_map_copy(move));
+		may_rel[i] = isl_map_union(may_rel[i], move);
+	}
+
+	return flow;
+}
+
 /* Compute dependences for the case where all accesses are "may"
  * accesses, which boils down to computing memory based dependences.
  * The generic algorithm would also work in this case, but it would
@@ -917,7 +1058,12 @@ static __isl_give isl_flow *compute_mem_
  * need to be considered.  These iterations are split into those that
  * haven't been matched to any source access (mustdo) and those that have only
  * been matched to may accesses (maydo).
- * At the end of each level, we also consider the may accesses.
+ * At the end of each level, must-sources and may-sources that are coscheduled
+ * with the sources of the must-dependences at that level are considered.
+ * If any coscheduled instances are found, then corresponding may-dependences
+ * are added and the original must-dependences are turned into may-dependences.
+ * Afterwards, the may accesses that occur after must-dependence sources
+ * are considered.
  * In particular, we consider may accesses that precede the remaining
  * sink iterations, moving elements from mustdo to maydo when appropriate,
  * and may accesses that occur between a must source and a sink of any 
@@ -1004,6 +1150,8 @@ static __isl_give isl_flow *compute_val_
 			intermediate_sources(acc, may_rel, j, level);
 		}
 
+		handle_coscheduled(acc, must_rel, may_rel, res);
+
 		for (j = 0; j < acc->n_may; ++j) {
 			int plevel;
 			isl_map *T;
@@ -1219,11 +1367,28 @@ error:
 	return NULL;
 }
 
+/* The different types of access relations that isl_union_access_info
+ * keeps track of.
+
+ * "isl_access_sink" represents the sink accesses.
+ * "isl_access_must_source" represents the definite source accesses.
+ * "isl_access_may_source" represents the possible source accesses.
+ * "isl_access_kill" represents the kills.
+ *
+ * isl_access_sink is sometimes treated differently and
+ * should therefore appear first.
+ */
+enum isl_access_type {
+	isl_access_sink,
+	isl_access_must_source,
+	isl_access_may_source,
+	isl_access_kill,
+	isl_access_end
+};
+
 /* This structure represents the input for a dependence analysis computation.
  *
- * "sink" represents the sink accesses.
- * "must_source" represents the definite source accesses.
- * "may_source" represents the possible source accesses.
+ * "access" contains the access relations.
  *
  * "schedule" or "schedule_map" represents the execution order.
  * Exactly one of these fields should be NULL.  The other field
@@ -1236,9 +1401,7 @@ error:
  * the "schedule_map" field no longer contains useful information.
  */
 struct isl_union_access_info {
-	isl_union_map *sink;
-	isl_union_map *must_source;
-	isl_union_map *may_source;
+	isl_union_map *access[isl_access_end];
 
 	isl_schedule *schedule;
 	isl_union_map *schedule_map;
@@ -1249,12 +1412,13 @@ struct isl_union_access_info {
 __isl_null isl_union_access_info *isl_union_access_info_free(
 	__isl_take isl_union_access_info *access)
 {
+	enum isl_access_type i;
+
 	if (!access)
 		return NULL;
 
-	isl_union_map_free(access->sink);
-	isl_union_map_free(access->must_source);
-	isl_union_map_free(access->may_source);
+	for (i = isl_access_sink; i < isl_access_end; ++i)
+		isl_union_map_free(access->access[i]);
 	isl_schedule_free(access->schedule);
 	isl_union_map_free(access->schedule_map);
 	free(access);
@@ -1266,46 +1430,98 @@ __isl_null isl_union_access_info *isl_un
  */
 isl_ctx *isl_union_access_info_get_ctx(__isl_keep isl_union_access_info *access)
 {
-	return access ? isl_union_map_get_ctx(access->sink) : NULL;
+	if (!access)
+		return NULL;
+	return isl_union_map_get_ctx(access->access[isl_access_sink]);
 }
 
-/* Create a new isl_union_access_info with the given sink accesses and
- * and no source accesses or schedule information.
+/* Construct an empty (invalid) isl_union_access_info object.
+ * The caller is responsible for setting the sink access relation and
+ * initializing all the other fields, e.g., by calling
+ * isl_union_access_info_init.
+ */
+static __isl_give isl_union_access_info *isl_union_access_info_alloc(
+	isl_ctx *ctx)
+{
+	return isl_calloc_type(ctx, isl_union_access_info);
+}
+
+/* Initialize all the fields of "info", except the sink access relation,
+ * which is assumed to have been set by the caller.
  *
  * By default, we use the schedule field of the isl_union_access_info,
  * but this may be overridden by a call
  * to isl_union_access_info_set_schedule_map.
  */
+static __isl_give isl_union_access_info *isl_union_access_info_init(
+	__isl_take isl_union_access_info *info)
+{
+	isl_space *space;
+	isl_union_map *empty;
+	enum isl_access_type i;
+
+	if (!info)
+		return NULL;
+	if (!info->access[isl_access_sink])
+		return isl_union_access_info_free(info);
+
+	space = isl_union_map_get_space(info->access[isl_access_sink]);
+	empty = isl_union_map_empty(isl_space_copy(space));
+	for (i = isl_access_sink + 1; i < isl_access_end; ++i)
+		if (!info->access[i])
+			info->access[i] = isl_union_map_copy(empty);
+	isl_union_map_free(empty);
+	if (!info->schedule && !info->schedule_map)
+		info->schedule = isl_schedule_empty(isl_space_copy(space));
+	isl_space_free(space);
+
+	for (i = isl_access_sink + 1; i < isl_access_end; ++i)
+		if (!info->access[i])
+			return isl_union_access_info_free(info);
+	if (!info->schedule && !info->schedule_map)
+		return isl_union_access_info_free(info);
+
+	return info;
+}
+
+/* Create a new isl_union_access_info with the given sink accesses and
+ * and no other accesses or schedule information.
+ */
 __isl_give isl_union_access_info *isl_union_access_info_from_sink(
 	__isl_take isl_union_map *sink)
 {
 	isl_ctx *ctx;
-	isl_space *space;
-	isl_union_map *empty;
 	isl_union_access_info *access;
 
 	if (!sink)
 		return NULL;
 	ctx = isl_union_map_get_ctx(sink);
-	access = isl_alloc_type(ctx, isl_union_access_info);
+	access = isl_union_access_info_alloc(ctx);
 	if (!access)
 		goto error;
+	access->access[isl_access_sink] = sink;
+	return isl_union_access_info_init(access);
+error:
+	isl_union_map_free(sink);
+	return NULL;
+}
 
-	space = isl_union_map_get_space(sink);
-	empty = isl_union_map_empty(isl_space_copy(space));
-	access->sink = sink;
-	access->must_source = isl_union_map_copy(empty);
-	access->may_source = empty;
-	access->schedule = isl_schedule_empty(space);
-	access->schedule_map = NULL;
+/* Replace the access relation of type "type" of "info" by "access".
+ */
+static __isl_give isl_union_access_info *isl_union_access_info_set(
+	__isl_take isl_union_access_info *info,
+	enum isl_access_type type, __isl_take isl_union_map *access)
+{
+	if (!info || !access)
+		goto error;
 
-	if (!access->sink || !access->must_source ||
-	    !access->may_source || !access->schedule)
-		return isl_union_access_info_free(access);
+	isl_union_map_free(info->access[type]);
+	info->access[type] = access;
 
-	return access;
+	return info;
 error:
-	isl_union_map_free(sink);
+	isl_union_access_info_free(info);
+	isl_union_map_free(access);
 	return NULL;
 }
 
@@ -1315,17 +1531,8 @@ __isl_give isl_union_access_info *isl_un
 	__isl_take isl_union_access_info *access,
 	__isl_take isl_union_map *must_source)
 {
-	if (!access || !must_source)
-		goto error;
-
-	isl_union_map_free(access->must_source);
-	access->must_source = must_source;
-
-	return access;
-error:
-	isl_union_access_info_free(access);
-	isl_union_map_free(must_source);
-	return NULL;
+	return isl_union_access_info_set(access, isl_access_must_source,
+					must_source);
 }
 
 /* Replace the possible source accesses of "access" by "may_source".
@@ -1334,17 +1541,63 @@ __isl_give isl_union_access_info *isl_un
 	__isl_take isl_union_access_info *access,
 	__isl_take isl_union_map *may_source)
 {
-	if (!access || !may_source)
-		goto error;
+	return isl_union_access_info_set(access, isl_access_may_source,
+					may_source);
+}
 
-	isl_union_map_free(access->may_source);
-	access->may_source = may_source;
+/* Replace the kills of "info" by "kill".
+ */
+__isl_give isl_union_access_info *isl_union_access_info_set_kill(
+	__isl_take isl_union_access_info *info, __isl_take isl_union_map *kill)
+{
+	return isl_union_access_info_set(info, isl_access_kill, kill);
+}
 
-	return access;
-error:
-	isl_union_access_info_free(access);
-	isl_union_map_free(may_source);
-	return NULL;
+/* Return the access relation of type "type" of "info".
+ */
+static __isl_give isl_union_map *isl_union_access_info_get(
+	__isl_keep isl_union_access_info *info, enum isl_access_type type)
+{
+	if (!info)
+		return NULL;
+	return isl_union_map_copy(info->access[type]);
+}
+
+/* Return the definite source accesses of "info".
+ */
+__isl_give isl_union_map *isl_union_access_info_get_must_source(
+	__isl_keep isl_union_access_info *info)
+{
+	return isl_union_access_info_get(info, isl_access_must_source);
+}
+
+/* Return the possible source accesses of "info".
+ */
+__isl_give isl_union_map *isl_union_access_info_get_may_source(
+	__isl_keep isl_union_access_info *info)
+{
+	return isl_union_access_info_get(info, isl_access_may_source);
+}
+
+/* Return the kills of "info".
+ */
+__isl_give isl_union_map *isl_union_access_info_get_kill(
+	__isl_keep isl_union_access_info *info)
+{
+	return isl_union_access_info_get(info, isl_access_kill);
+}
+
+/* Does "info" specify any kills?
+ */
+static isl_bool isl_union_access_has_kill(
+	__isl_keep isl_union_access_info *info)
+{
+	isl_bool empty;
+
+	if (!info)
+		return isl_bool_error;
+	empty = isl_union_map_is_empty(info->access[isl_access_kill]);
+	return isl_bool_not(empty);
 }
 
 /* Replace the schedule of "access" by "schedule".
@@ -1393,15 +1646,15 @@ __isl_give isl_union_access_info *isl_un
 	__isl_keep isl_union_access_info *access)
 {
 	isl_union_access_info *copy;
+	enum isl_access_type i;
 
 	if (!access)
 		return NULL;
 	copy = isl_union_access_info_from_sink(
-				isl_union_map_copy(access->sink));
-	copy = isl_union_access_info_set_must_source(copy,
-				isl_union_map_copy(access->must_source));
-	copy = isl_union_access_info_set_may_source(copy,
-				isl_union_map_copy(access->may_source));
+		    isl_union_map_copy(access->access[isl_access_sink]));
+	for (i = isl_access_sink + 1; i < isl_access_end; ++i)
+		copy = isl_union_access_info_set(copy, i,
+					isl_union_map_copy(access->access[i]));
 	if (access->schedule)
 		copy = isl_union_access_info_set_schedule(copy,
 				isl_schedule_copy(access->schedule));
@@ -1428,26 +1681,76 @@ static __isl_give isl_printer *print_uni
 	return p;
 }
 
+/* An enumeration of the various keys that may appear in a YAML mapping
+ * of an isl_union_access_info object.
+ * The keys for the access relation types are assumed to have the same values
+ * as the access relation types in isl_access_type.
+ */
+enum isl_ai_key {
+	isl_ai_key_error = -1,
+	isl_ai_key_sink = isl_access_sink,
+	isl_ai_key_must_source = isl_access_must_source,
+	isl_ai_key_may_source = isl_access_may_source,
+	isl_ai_key_kill = isl_access_kill,
+	isl_ai_key_schedule_map,
+	isl_ai_key_schedule,
+	isl_ai_key_end
+};
+
+/* Textual representations of the YAML keys for an isl_union_access_info
+ * object.
+ */
+static char *key_str[] = {
+	[isl_ai_key_sink] = "sink",
+	[isl_ai_key_must_source] = "must_source",
+	[isl_ai_key_may_source] = "may_source",
+	[isl_ai_key_kill] = "kill",
+	[isl_ai_key_schedule_map] = "schedule_map",
+	[isl_ai_key_schedule] = "schedule",
+};
+
+/* Print a key-value pair corresponding to the access relation of type "type"
+ * of a YAML mapping of "info" to "p".
+ *
+ * The sink access relation is always printed, but any other access relation
+ * is only printed if it is non-empty.
+ */
+static __isl_give isl_printer *print_access_field(__isl_take isl_printer *p,
+	__isl_keep isl_union_access_info *info, enum isl_access_type type)
+{
+	if (type != isl_access_sink) {
+		isl_bool empty;
+
+		empty = isl_union_map_is_empty(info->access[type]);
+		if (empty < 0)
+			return isl_printer_free(p);
+		if (empty)
+			return p;
+	}
+	return print_union_map_field(p, key_str[type], info->access[type]);
+}
+
 /* 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)
 {
+	enum isl_access_type i;
+
 	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);
+	for (i = isl_access_sink; i < isl_access_end; ++i)
+		p = print_access_field(p, access, i);
 	if (access->schedule) {
-		p = isl_printer_print_str(p, "schedule");
+		p = isl_printer_print_str(p, key_str[isl_ai_key_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",
+		p = print_union_map_field(p, key_str[isl_ai_key_schedule_map],
 						access->schedule_map);
 	}
 	p = isl_printer_yaml_end_mapping(p);
@@ -1476,6 +1779,119 @@ __isl_give char *isl_union_access_info_t
 	return s;
 }
 
+#undef KEY
+#define KEY enum isl_ai_key
+#undef KEY_ERROR
+#define KEY_ERROR isl_ai_key_error
+#undef KEY_END
+#define KEY_END isl_ai_key_end
+#include "extract_key.c"
+
+#undef BASE
+#define BASE union_map
+#include "read_in_string_templ.c"
+
+/* Read an isl_union_access_info object from "s".
+ *
+ * Start off with an empty (invalid) isl_union_access_info object and
+ * then fill up the fields based on the input.
+ * The input needs to contain at least a description of the sink
+ * access relation as well as some form of schedule.
+ * The other access relations are set to empty relations
+ * by isl_union_access_info_init if they are not specified in the input.
+ */
+__isl_give isl_union_access_info *isl_stream_read_union_access_info(
+	isl_stream *s)
+{
+	isl_ctx *ctx;
+	isl_union_access_info *info;
+	int more;
+	int sink_set = 0;
+	int schedule_set = 0;
+
+	if (isl_stream_yaml_read_start_mapping(s))
+		return NULL;
+
+	ctx = isl_stream_get_ctx(s);
+	info = isl_union_access_info_alloc(ctx);
+	while ((more = isl_stream_yaml_next(s)) > 0) {
+		enum isl_ai_key key;
+		isl_union_map *access, *schedule_map;
+		isl_schedule *schedule;
+
+		key = get_key(s);
+		if (isl_stream_yaml_next(s) < 0)
+			return isl_union_access_info_free(info);
+		switch (key) {
+		case isl_ai_key_end:
+		case isl_ai_key_error:
+			return isl_union_access_info_free(info);
+		case isl_ai_key_sink:
+			sink_set = 1;
+		case isl_ai_key_must_source:
+		case isl_ai_key_may_source:
+		case isl_ai_key_kill:
+			access = read_union_map(s);
+			info = isl_union_access_info_set(info, key, access);
+			if (!info)
+				return NULL;
+			break;
+		case isl_ai_key_schedule_map:
+			schedule_set = 1;
+			schedule_map = read_union_map(s);
+			info = isl_union_access_info_set_schedule_map(info,
+								schedule_map);
+			if (!info)
+				return NULL;
+			break;
+		case isl_ai_key_schedule:
+			schedule_set = 1;
+			schedule = isl_stream_read_schedule(s);
+			info = isl_union_access_info_set_schedule(info,
+								schedule);
+			if (!info)
+				return NULL;
+			break;
+		}
+	}
+	if (more < 0)
+		return isl_union_access_info_free(info);
+
+	if (isl_stream_yaml_read_end_mapping(s) < 0) {
+		isl_stream_error(s, NULL, "unexpected extra elements");
+		return isl_union_access_info_free(info);
+	}
+
+	if (!sink_set) {
+		isl_stream_error(s, NULL, "no sink specified");
+		return isl_union_access_info_free(info);
+	}
+
+	if (!schedule_set) {
+		isl_stream_error(s, NULL, "no schedule specified");
+		return isl_union_access_info_free(info);
+	}
+
+	return isl_union_access_info_init(info);
+}
+
+/* Read an isl_union_access_info object from the file "input".
+ */
+__isl_give isl_union_access_info *isl_union_access_info_read_from_file(
+	isl_ctx *ctx, FILE *input)
+{
+	isl_stream *s;
+	isl_union_access_info *access;
+
+	s = isl_stream_new_file(ctx, input);
+	if (!s)
+		return NULL;
+	access = isl_stream_read_union_access_info(s);
+	isl_stream_free(s);
+
+	return access;
+}
+
 /* 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.
@@ -1484,23 +1900,21 @@ static __isl_give isl_union_access_info
 	__isl_take isl_union_access_info *access)
 {
 	isl_space *space;
+	enum isl_access_type i;
 
 	if (!access)
 		return NULL;
 
-	space = isl_union_map_get_space(access->sink);
-	space = isl_space_align_params(space,
-				isl_union_map_get_space(access->must_source));
-	space = isl_space_align_params(space,
-				isl_union_map_get_space(access->may_source));
+	space = isl_union_map_get_space(access->access[isl_access_sink]);
+	for (i = isl_access_sink + 1; i < isl_access_end; ++i)
+		space = isl_space_align_params(space,
+				isl_union_map_get_space(access->access[i]));
 	if (access->schedule_map)
 		space = isl_space_align_params(space,
 				isl_union_map_get_space(access->schedule_map));
-	access->sink = isl_union_map_align_params(access->sink,
-							isl_space_copy(space));
-	access->must_source = isl_union_map_align_params(access->must_source,
-							isl_space_copy(space));
-	access->may_source = isl_union_map_align_params(access->may_source,
+	for (i = isl_access_sink; i < isl_access_end; ++i)
+		access->access[i] =
+			isl_union_map_align_params(access->access[i],
 							isl_space_copy(space));
 	if (!access->schedule_map) {
 		isl_space_free(space);
@@ -1511,8 +1925,9 @@ static __isl_give isl_union_access_info
 			return isl_union_access_info_free(access);
 	}
 
-	if (!access->sink || !access->must_source || !access->may_source)
-		return isl_union_access_info_free(access);
+	for (i = isl_access_sink; i < isl_access_end; ++i)
+		if (!access->access[i])
+			return isl_union_access_info_free(access);
 
 	return access;
 }
@@ -1544,22 +1959,23 @@ isl_union_access_info_introduce_schedule
 	__isl_take isl_union_access_info *access)
 {
 	isl_union_map *sm;
+	enum isl_access_type i;
 
 	if (!access)
 		return NULL;
 
 	sm = isl_union_map_reverse(access->schedule_map);
 	sm = isl_union_map_range_map(sm);
-	access->sink = isl_union_map_apply_range(isl_union_map_copy(sm),
-						access->sink);
-	access->may_source = isl_union_map_apply_range(isl_union_map_copy(sm),
-						access->may_source);
-	access->must_source = isl_union_map_apply_range(isl_union_map_copy(sm),
-						access->must_source);
+	for (i = isl_access_sink; i < isl_access_end; ++i)
+		access->access[i] =
+			isl_union_map_apply_range(isl_union_map_copy(sm),
+						access->access[i]);
 	access->schedule_map = sm;
 
-	if (!access->sink || !access->must_source ||
-	    !access->may_source || !access->schedule_map)
+	for (i = isl_access_sink; i < isl_access_end; ++i)
+		if (!access->access[i])
+			return isl_union_access_info_free(access);
+	if (!access->schedule_map)
 		return isl_union_access_info_free(access);
 
 	return access;
@@ -1939,6 +2355,40 @@ static int before(void *first, void *sec
 	return 2 * n1;
 }
 
+/* Check if the given two accesses may be coscheduled.
+ * If so, return 1.  Otherwise return 0.
+ *
+ * Two accesses may only be coscheduled if the fixed schedule
+ * coordinates have the same values.
+ */
+static int coscheduled(void *first, void *second)
+{
+	struct isl_sched_info *info1 = first;
+	struct isl_sched_info *info2 = second;
+	int n1, n2;
+	int i;
+
+	n1 = isl_vec_size(info1->cst);
+	n2 = isl_vec_size(info2->cst);
+
+	if (n2 < n1)
+		n1 = n2;
+
+	for (i = 0; i < n1; ++i) {
+		int cmp;
+
+		if (!info1->is_cst[i])
+			continue;
+		if (!info2->is_cst[i])
+			continue;
+		cmp = isl_vec_cmp_element(info1->cst, info2->cst, i);
+		if (cmp != 0)
+			return 0;
+	}
+
+	return 1;
+}
+
 /* 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_core.
@@ -1978,6 +2428,7 @@ static isl_stat compute_flow(__isl_take
 	if (!data->sink_info || (data->count && !data->source_info) ||
 	    !data->accesses)
 		goto error;
+	data->accesses->coscheduled = &coscheduled;
 	data->count = 0;
 	data->must = 1;
 	if (isl_union_map_foreach_map(data->must_source,
@@ -2034,6 +2485,69 @@ error:
 	return isl_stat_error;
 }
 
+/* Add the kills of "info" to the must-sources.
+ */
+static __isl_give isl_union_access_info *
+isl_union_access_info_add_kill_to_must_source(
+	__isl_take isl_union_access_info *info)
+{
+	isl_union_map *must, *kill;
+
+	must = isl_union_access_info_get_must_source(info);
+	kill = isl_union_access_info_get_kill(info);
+	must = isl_union_map_union(must, kill);
+	return isl_union_access_info_set_must_source(info, must);
+}
+
+/* Drop dependences from "flow" that purely originate from kills.
+ * That is, only keep those dependences that originate from
+ * the original must-sources "must" and/or the original may-sources "may".
+ * In particular, "must" contains the must-sources from before
+ * the kills were added and "may" contains the may-source from before
+ * the kills were removed.
+ *
+ * The dependences are of the form
+ *
+ *	Source -> [Sink -> Data]
+ *
+ * Only those dependences are kept where the Source -> Data part
+ * is a subset of the original may-sources or must-sources.
+ * Of those, only the must-dependences that intersect with the must-sources
+ * remain must-dependences.
+ * If there is some overlap between the may-sources and the must-sources,
+ * then the may-dependences and must-dependences may also overlap.
+ * This should be fine since the may-dependences are only kept
+ * disjoint from the must-dependences for the isl_union_map_compute_flow
+ * interface.  This interface does not support kills, so it will
+ * not end up calling this function.
+ */
+static __isl_give isl_union_flow *isl_union_flow_drop_kill_source(
+	__isl_take isl_union_flow *flow, __isl_take isl_union_map *must,
+	__isl_take isl_union_map *may)
+{
+	isl_union_map *move;
+
+	if (!flow)
+		goto error;
+	move = isl_union_map_copy(flow->must_dep);
+	move = isl_union_map_intersect_range_factor_range(move,
+				isl_union_map_copy(may));
+	may = isl_union_map_union(may, isl_union_map_copy(must));
+	flow->may_dep = isl_union_map_intersect_range_factor_range(
+				flow->may_dep, may);
+	flow->must_dep = isl_union_map_intersect_range_factor_range(
+				flow->must_dep, must);
+	flow->may_dep = isl_union_map_union(flow->may_dep, move);
+	if (!flow->must_dep || !flow->may_dep)
+		return isl_union_flow_free(flow);
+
+	return flow;
+error:
+	isl_union_map_free(must);
+	isl_union_map_free(may);
+	return NULL;
+}
+
 /* Remove the must accesses from the may accesses.
  *
  * A must access always trumps a may access, so there is no need
@@ -2046,9 +2560,10 @@ static __isl_give isl_union_access_info
 {
 	if (!access)
 		return NULL;
-	access->may_source = isl_union_map_subtract(access->may_source,
-				    isl_union_map_copy(access->must_source));
-	if (!access->may_source)
+	access->access[isl_access_may_source] =
+		isl_union_map_subtract(access->access[isl_access_may_source],
+		    isl_union_map_copy(access->access[isl_access_must_source]));
+	if (!access->access[isl_access_may_source])
 		return isl_union_access_info_free(access);
 
 	return access;
@@ -2077,18 +2592,20 @@ static __isl_give isl_union_flow *comput
 	__isl_take isl_union_access_info *access)
 {
 	struct isl_compute_flow_data data;
+	isl_union_map *sink;
 
 	access = isl_union_access_info_align_params(access);
 	access = isl_union_access_info_introduce_schedule(access);
 	if (!access)
 		return NULL;
 
-	data.must_source = access->must_source;
-	data.may_source = access->may_source;
+	data.must_source = access->access[isl_access_must_source];
+	data.may_source = access->access[isl_access_may_source];
 
-	data.flow = isl_union_flow_alloc(isl_union_map_get_space(access->sink));
+	sink = access->access[isl_access_sink];
+	data.flow = isl_union_flow_alloc(isl_union_map_get_space(sink));
 
-	if (isl_union_map_foreach_map(access->sink, &compute_flow, &data) < 0)
+	if (isl_union_map_foreach_map(sink, &compute_flow, &data) < 0)
 		goto error;
 
 	data.flow = isl_union_flow_drop_schedule(data.flow);
@@ -2218,21 +2735,21 @@ static isl_bool count_sink_source(__isl_
 
 	domain = isl_schedule_node_get_universe_domain(node);
 
-	umap = isl_union_map_copy(data->access->sink);
+	umap = isl_union_map_copy(data->access->access[isl_access_sink]);
 	umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain));
 	data->n_sink += isl_union_map_n_map(umap);
 	isl_union_map_free(umap);
 	if (!umap)
 		r = isl_bool_error;
 
-	umap = isl_union_map_copy(data->access->must_source);
+	umap = isl_union_map_copy(data->access->access[isl_access_must_source]);
 	umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain));
 	data->n_source += isl_union_map_n_map(umap);
 	isl_union_map_free(umap);
 	if (!umap)
 		r = isl_bool_error;
 
-	umap = isl_union_map_copy(data->access->may_source);
+	umap = isl_union_map_copy(data->access->access[isl_access_may_source]);
 	umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain));
 	data->n_source += isl_union_map_n_map(umap);
 	isl_union_map_free(umap);
@@ -2307,7 +2824,7 @@ static isl_bool collect_sink_source(__is
 	prefix = isl_union_map_range_map(prefix);
 
 	data->set_sink = 1;
-	umap = isl_union_map_copy(data->access->sink);
+	umap = isl_union_map_copy(data->access->access[isl_access_sink]);
 	umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap);
 	if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0)
 		r = isl_bool_error;
@@ -2315,7 +2832,7 @@ static isl_bool collect_sink_source(__is
 
 	data->set_sink = 0;
 	data->must = 1;
-	umap = isl_union_map_copy(data->access->must_source);
+	umap = isl_union_map_copy(data->access->access[isl_access_must_source]);
 	umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap);
 	if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0)
 		r = isl_bool_error;
@@ -2323,7 +2840,7 @@ static isl_bool collect_sink_source(__is
 
 	data->set_sink = 0;
 	data->must = 0;
-	umap = isl_union_map_copy(data->access->may_source);
+	umap = isl_union_map_copy(data->access->access[isl_access_may_source]);
 	umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap);
 	if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0)
 		r = isl_bool_error;
@@ -2378,6 +2895,19 @@ static int before_node(void *first, void
 	return 2 * depth + before;
 }
 
+/* Check if the given two accesses may be coscheduled.
+ * If so, return 1.  Otherwise return 0.
+ *
+ * Two accesses may only be coscheduled if they appear in the same leaf.
+ */
+static int coscheduled_node(void *first, void *second)
+{
+	isl_schedule_node *node1 = first;
+	isl_schedule_node *node2 = second;
+
+	return node1 == node2;
+}
+
 /* Add the scheduled sources from "data" that access
  * the same data space as "sink" to "access".
  */
@@ -2448,6 +2978,8 @@ static __isl_give isl_union_flow *comput
 
 	access = isl_access_info_alloc(isl_map_copy(sink->access), sink->node,
 					&before_node, data->n_source);
+	if (access)
+		access->coscheduled = &coscheduled_node;
 	access = add_matching_sources(access, sink, data);
 
 	flow = access_info_compute_flow_core(access);
@@ -2505,6 +3037,7 @@ static __isl_give isl_union_flow *comput
 	struct isl_compute_flow_schedule_data data = { access };
 	int i, n;
 	isl_ctx *ctx;
+	isl_space *space;
 	isl_union_flow *flow;
 
 	ctx = isl_union_access_info_get_ctx(access);
@@ -2527,7 +3060,8 @@ static __isl_give isl_union_flow *comput
 					    &collect_sink_source, &data) < 0)
 		goto error;
 
-	flow = isl_union_flow_alloc(isl_union_map_get_space(access->sink));
+	space = isl_union_map_get_space(access->access[isl_access_sink]);
+	flow = isl_union_flow_alloc(space);
 
 	isl_compute_flow_schedule_data_align_params(&data);
 
@@ -2556,6 +3090,10 @@ error:
  * map domain elements of access->{may,must)_source to
  * domain elements of access->sink.
  *
+ * If any kills have been specified, then they are treated as
+ * must-sources internally.  Any dependence that purely derives
+ * from an original kill is removed from the output.
+ *
  * We check whether the schedule is available as a schedule tree
  * or a schedule map and call the corresponding function to perform
  * the analysis.
@@ -2563,13 +3101,33 @@ error:
 __isl_give isl_union_flow *isl_union_access_info_compute_flow(
 	__isl_take isl_union_access_info *access)
 {
+	isl_bool has_kill;
+	isl_union_map *must = NULL, *may = NULL;
+	isl_union_flow *flow;
+
+	has_kill = isl_union_access_has_kill(access);
+	if (has_kill < 0)
+		goto error;
+	if (has_kill) {
+		must = isl_union_access_info_get_must_source(access);
+		may = isl_union_access_info_get_may_source(access);
+	}
+	access = isl_union_access_info_add_kill_to_must_source(access);
 	access = isl_union_access_info_normalize(access);
 	if (!access)
-		return NULL;
+		goto error;
 	if (access->schedule)
-		return compute_flow_schedule(access);
+		flow = compute_flow_schedule(access);
 	else
-		return compute_flow_union_map(access);
+		flow = compute_flow_union_map(access);
+	if (has_kill)
+		flow = isl_union_flow_drop_kill_source(flow, must, may);
+	return flow;
+error:
+	isl_union_access_info_free(access);
+	isl_union_map_free(must);
+	isl_union_map_free(may);
+	return NULL;
 }
 
 /* Print the information contained in "flow" to "p".
@@ -2584,8 +3142,10 @@ __isl_give isl_printer *isl_printer_prin
 		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);
+	umap = isl_union_flow_get_full_must_dependence(flow);
+	p = print_union_map_field(p, "must_dependence", umap);
+	isl_union_map_free(umap);
+	umap = isl_union_flow_get_full_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);

Modified: polly/trunk/lib/External/isl/isl_imath.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_imath.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_imath.c (original)
+++ polly/trunk/lib/External/isl/isl_imath.c Tue Jul  4 08:54:11 2017
@@ -53,3 +53,31 @@ void isl_imath_submul_ui(mp_int rop, mp_
 
 	mp_int_clear(&temp);
 }
+
+/* Compute the division of lhs by a rhs of type unsigned long, rounding towards
+ * positive infinity (Ceil).
+ */
+void isl_imath_cdiv_q_ui(mp_int rop, mp_int lhs, unsigned long rhs)
+{
+	mpz_t temp;
+	mp_int_init(&temp);
+
+	mp_int_set_uvalue(&temp, rhs);
+	impz_cdiv_q(rop, lhs, &temp);
+
+	mp_int_clear(&temp);
+}
+
+/* Compute the division of lhs by a rhs of type unsigned long, rounding towards
+ * negative infinity (Floor).
+ */
+void isl_imath_fdiv_q_ui(mp_int rop, mp_int lhs, unsigned long rhs)
+{
+	mpz_t temp;
+	mp_int_init(&temp);
+
+	mp_int_set_uvalue(&temp, rhs);
+	impz_fdiv_q(rop, lhs, &temp);
+
+	mp_int_clear(&temp);
+}

Modified: polly/trunk/lib/External/isl/isl_imath.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_imath.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_imath.h (original)
+++ polly/trunk/lib/External/isl/isl_imath.h Tue Jul  4 08:54:11 2017
@@ -6,3 +6,5 @@ int isl_imath_fits_ulong_p(mp_int op);
 int isl_imath_fits_slong_p(mp_int op);
 void isl_imath_addmul_ui(mp_int rop, mp_int op1, unsigned long op2);
 void isl_imath_submul_ui(mp_int rop, mp_int op1, unsigned long op2);
+void isl_imath_cdiv_q_ui(mp_int rop, mp_int op1, unsigned long op2);
+void isl_imath_fdiv_q_ui(mp_int rop, mp_int op1, unsigned long op2);

Modified: polly/trunk/lib/External/isl/isl_int_gmp.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_int_gmp.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_int_gmp.h (original)
+++ polly/trunk/lib/External/isl/isl_int_gmp.h Tue Jul  4 08:54:11 2017
@@ -45,6 +45,7 @@ typedef mpz_t	isl_int;
 #define isl_int_divexact_ui(r,i,j)	mpz_divexact_ui(r,i,j)
 #define isl_int_tdiv_q(r,i,j)	mpz_tdiv_q(r,i,j)
 #define isl_int_cdiv_q(r,i,j)	mpz_cdiv_q(r,i,j)
+#define isl_int_cdiv_q_ui(r,i,j)	mpz_cdiv_q_ui(r,i,j)
 #define isl_int_fdiv_q(r,i,j)	mpz_fdiv_q(r,i,j)
 #define isl_int_fdiv_r(r,i,j)	mpz_fdiv_r(r,i,j)
 #define isl_int_fdiv_q_ui(r,i,j)	mpz_fdiv_q_ui(r,i,j)

Modified: polly/trunk/lib/External/isl/isl_int_imath.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_int_imath.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_int_imath.h (original)
+++ polly/trunk/lib/External/isl/isl_int_imath.h Tue Jul  4 08:54:11 2017
@@ -45,9 +45,10 @@ typedef mp_int isl_int;
 #define isl_int_divexact_ui(r,i,j)	impz_divexact_ui(r,i,j)
 #define isl_int_tdiv_q(r,i,j)	impz_tdiv_q(r,i,j)
 #define isl_int_cdiv_q(r,i,j)	impz_cdiv_q(r,i,j)
+#define isl_int_cdiv_q_ui(r,i,j)	isl_imath_cdiv_q_ui(r,i,j)
 #define isl_int_fdiv_q(r,i,j)	impz_fdiv_q(r,i,j)
 #define isl_int_fdiv_r(r,i,j)	impz_fdiv_r(r,i,j)
-#define isl_int_fdiv_q_ui(r,i,j)	impz_fdiv_q_ui(r,i,j)
+#define isl_int_fdiv_q_ui(r,i,j)	isl_imath_fdiv_q_ui(r,i,j)
 
 #define isl_int_read(r,s)	impz_set_str(r,s,10)
 #define isl_int_sgn(i)		impz_sgn(i)

Modified: polly/trunk/lib/External/isl/isl_int_sioimath.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_int_sioimath.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_int_sioimath.c (original)
+++ polly/trunk/lib/External/isl/isl_int_sioimath.c Tue Jul  4 08:54:11 2017
@@ -154,6 +154,8 @@ extern void isl_sioimath_tdiv_q_ui(isl_s
 	unsigned long rhs);
 extern void isl_sioimath_cdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs,
 	isl_sioimath_src rhs);
+extern void isl_sioimath_cdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
+	unsigned long rhs);
 extern void isl_sioimath_fdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs,
 	isl_sioimath_src rhs);
 extern void isl_sioimath_fdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,

Modified: polly/trunk/lib/External/isl/isl_int_sioimath.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_int_sioimath.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_int_sioimath.h (original)
+++ polly/trunk/lib/External/isl/isl_int_sioimath.h Tue Jul  4 08:54:11 2017
@@ -927,6 +927,31 @@ inline void isl_sioimath_cdiv_q(isl_sioi
 	isl_sioimath_try_demote(dst);
 }
 
+/* Compute the division of lhs by a rhs of type unsigned long, rounding towards
+ * positive infinity (Ceil).
+ */
+inline void isl_sioimath_cdiv_q_ui(isl_sioimath_ptr dst, isl_sioimath_src lhs,
+	unsigned long rhs)
+{
+	isl_sioimath_scratchspace_t lhsscratch, rhsscratch;
+	int32_t lhssmall, q;
+
+	if (isl_sioimath_decode_small(lhs, &lhssmall) && (rhs <= INT32_MAX)) {
+		if (lhssmall >= 0)
+			q = ((int64_t) lhssmall + ((int64_t) rhs - 1)) /
+			    (int64_t) rhs;
+		else
+			q = lhssmall / (int32_t) rhs;
+		isl_sioimath_set_small(dst, q);
+		return;
+	}
+
+	impz_cdiv_q(isl_sioimath_reinit_big(dst),
+	    isl_sioimath_bigarg_src(lhs, &lhsscratch),
+	    isl_sioimath_uiarg_src(rhs, &rhsscratch));
+	isl_sioimath_try_demote(dst);
+}
+
 /* Divide lhs by rhs, rounding to negative infinity (Floor).
  */
 inline void isl_sioimath_fdiv_q(isl_sioimath_ptr dst, isl_sioimath_src lhs,
@@ -1199,6 +1224,7 @@ typedef isl_sioimath isl_int[1];
 #define isl_int_divexact_ui(r, i, j)	isl_sioimath_tdiv_q_ui((r), *(i), j)
 #define isl_int_tdiv_q(r, i, j)		isl_sioimath_tdiv_q((r), *(i), *(j))
 #define isl_int_cdiv_q(r, i, j)		isl_sioimath_cdiv_q((r), *(i), *(j))
+#define isl_int_cdiv_q_ui(r, i, j)	isl_sioimath_cdiv_q_ui((r), *(i), j)
 #define isl_int_fdiv_q(r, i, j)		isl_sioimath_fdiv_q((r), *(i), *(j))
 #define isl_int_fdiv_r(r, i, j)		isl_sioimath_fdiv_r((r), *(i), *(j))
 #define isl_int_fdiv_q_ui(r, i, j)	isl_sioimath_fdiv_q_ui((r), *(i), j)

Modified: polly/trunk/lib/External/isl/isl_map.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_map.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map.c (original)
+++ polly/trunk/lib/External/isl/isl_map.c Tue Jul  4 08:54:11 2017
@@ -6570,6 +6570,56 @@ error:
 	return NULL;
 }
 
+/* Bound the given variable of "bset" from below (or above is "upper"
+ * is set) to "value".
+ */
+static __isl_give isl_basic_set *isl_basic_set_bound(
+	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
+	isl_int value, int upper)
+{
+	return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
+						type, pos, value, upper));
+}
+
+/* Bound the given variable of "bset" from below (or above is "upper"
+ * is set) to "value".
+ */
+static __isl_give isl_basic_set *isl_basic_set_bound_val(
+	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_val *value, int upper)
+{
+	if (!value)
+		goto error;
+	if (!isl_val_is_int(value))
+		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
+			"expecting integer value", goto error);
+	bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
+	isl_val_free(value);
+	return bset;
+error:
+	isl_val_free(value);
+	isl_basic_set_free(bset);
+	return NULL;
+}
+
+/* Bound the given variable of "bset" from below to "value".
+ */
+__isl_give isl_basic_set *isl_basic_set_lower_bound_val(
+	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_val *value)
+{
+	return isl_basic_set_bound_val(bset, type, pos, value, 0);
+}
+
+/* Bound the given variable of "bset" from above to "value".
+ */
+__isl_give isl_basic_set *isl_basic_set_upper_bound_val(
+	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_val *value)
+{
+	return isl_basic_set_bound_val(bset, type, pos, value, 1);
+}
+
 __isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
 {
 	int i;
@@ -7830,6 +7880,63 @@ __isl_give isl_map *isl_map_intersect_do
 						&map_intersect_domain);
 }
 
+/* Given a map "map" in a space [A -> B] -> C and a map "factor"
+ * in the space B -> C, return the intersection.
+ * The parameters are assumed to have been aligned.
+ *
+ * The map "factor" is first extended to a map living in the space
+ * [A -> B] -> C and then a regular intersection is computed.
+ */
+static __isl_give isl_map *map_intersect_domain_factor_range(
+	__isl_take isl_map *map, __isl_take isl_map *factor)
+{
+	isl_space *space;
+	isl_map *ext_factor;
+
+	space = isl_space_domain_factor_domain(isl_map_get_space(map));
+	ext_factor = isl_map_universe(space);
+	ext_factor = isl_map_domain_product(ext_factor, factor);
+	return map_intersect(map, ext_factor);
+}
+
+/* Given a map "map" in a space [A -> B] -> C and a map "factor"
+ * in the space B -> C, return the intersection.
+ */
+__isl_give isl_map *isl_map_intersect_domain_factor_range(
+	__isl_take isl_map *map, __isl_take isl_map *factor)
+{
+	return isl_map_align_params_map_map_and(map, factor,
+					    &map_intersect_domain_factor_range);
+}
+
+/* Given a map "map" in a space A -> [B -> C] and a map "factor"
+ * in the space A -> C, return the intersection.
+ *
+ * The map "factor" is first extended to a map living in the space
+ * A -> [B -> C] and then a regular intersection is computed.
+ */
+static __isl_give isl_map *map_intersect_range_factor_range(
+	__isl_take isl_map *map, __isl_take isl_map *factor)
+{
+	isl_space *space;
+	isl_map *ext_factor;
+
+	space = isl_space_range_factor_domain(isl_map_get_space(map));
+	ext_factor = isl_map_universe(space);
+	ext_factor = isl_map_range_product(ext_factor, factor);
+	return isl_map_intersect(map, ext_factor);
+}
+
+/* Given a map "map" in a space A -> [B -> C] and a map "factor"
+ * in the space A -> C, return the intersection.
+ */
+__isl_give isl_map *isl_map_intersect_range_factor_range(
+	__isl_take isl_map *map, __isl_take isl_map *factor)
+{
+	return isl_map_align_params_map_map_and(map, factor,
+					    &map_intersect_range_factor_range);
+}
+
 static __isl_give isl_map *map_apply_domain(__isl_take isl_map *map1,
 	__isl_take isl_map *map2)
 {
@@ -13336,6 +13443,22 @@ __isl_give isl_set *isl_set_preimage_mul
 	return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
 }
 
+/* Return a copy of the equality constraints of "bset" as a matrix.
+ */
+__isl_give isl_mat *isl_basic_set_extract_equalities(
+	__isl_keep isl_basic_set *bset)
+{
+	isl_ctx *ctx;
+	unsigned total;
+
+	if (!bset)
+		return NULL;
+
+	ctx = isl_basic_set_get_ctx(bset);
+	total = 1 + isl_basic_set_dim(bset, isl_dim_all);
+	return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, total);
+}
+
 /* Are the "n" "coefficients" starting at "first" of the integer division
  * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
  * to each other?

Modified: polly/trunk/lib/External/isl/isl_map_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_map_private.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map_private.h (original)
+++ polly/trunk/lib/External/isl/isl_map_private.h Tue Jul  4 08:54:11 2017
@@ -365,10 +365,13 @@ __isl_give isl_basic_set *isl_basic_set_
 	__isl_take isl_basic_set *bset);
 __isl_give isl_basic_set *isl_basic_set_lineality_space(
 	__isl_take isl_basic_set *bset);
+__isl_give isl_basic_set *isl_set_combined_lineality_space(
+	__isl_take isl_set *set);
 
 __isl_give isl_basic_set *isl_basic_set_set_integral(
 	__isl_take isl_basic_set *bset);
-struct isl_basic_set *isl_basic_set_set_rational(struct isl_basic_set *bset);
+__isl_give isl_basic_set *isl_basic_set_set_rational(
+	__isl_take isl_basic_set *bset);
 __isl_give isl_set *isl_set_set_rational(__isl_take isl_set *set);
 __isl_give isl_basic_map *isl_basic_map_set_rational(
 	__isl_take isl_basic_map *bmap);
@@ -491,8 +494,12 @@ isl_bool isl_map_is_set(__isl_keep isl_m
 isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
 	unsigned dim, isl_int *val);
 
+__isl_give isl_set *isl_set_plain_gist_basic_set(__isl_take isl_set *set,
+	__isl_take isl_basic_set *context);
 __isl_give isl_map *isl_map_plain_gist_basic_map(__isl_take isl_map *map,
 	__isl_take isl_basic_map *context);
+__isl_give isl_map *isl_map_plain_gist(__isl_take isl_map *map,
+	__isl_take isl_map *context);
 
 __isl_give isl_basic_set *isl_basic_set_plain_affine_hull(
 	__isl_take isl_basic_set *bset);
@@ -531,6 +538,9 @@ int isl_basic_set_count_upto(__isl_keep
 	isl_int max, isl_int *count);
 int isl_set_count_upto(__isl_keep isl_set *set, isl_int max, isl_int *count);
 
+__isl_give isl_mat *isl_basic_set_extract_equalities(
+	__isl_keep isl_basic_set *bset);
+
 isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
 	int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
 	unsigned first, unsigned n);

Modified: polly/trunk/lib/External/isl/isl_map_simplify.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_map_simplify.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map_simplify.c (original)
+++ polly/trunk/lib/External/isl/isl_map_simplify.c Tue Jul  4 08:54:11 2017
@@ -3371,6 +3371,34 @@ error:
 	return NULL;
 }
 
+/* Remove the constraints in "context" from "set".
+ * If any of the disjuncts in the result turns out to be the universe,
+ * then return this universe.
+ * "context" is assumed to have explicit representations
+ * for all local variables.
+ */
+__isl_give isl_set *isl_set_plain_gist_basic_set(__isl_take isl_set *set,
+	__isl_take isl_basic_set *context)
+{
+	return set_from_map(isl_map_plain_gist_basic_map(set_to_map(set),
+							bset_to_bmap(context)));
+}
+
+/* Remove the constraints in "context" from "map".
+ * If any of the disjuncts in the result turns out to be the universe,
+ * then return this universe.
+ * "context" is assumed to consist of a single disjunct and
+ * to have explicit representations for all local variables.
+ */
+__isl_give isl_map *isl_map_plain_gist(__isl_take isl_map *map,
+	__isl_take isl_map *context)
+{
+	isl_basic_map *hull;
+
+	hull = isl_map_unshifted_simple_hull(context);
+	return isl_map_plain_gist_basic_map(map, hull);
+}
+
 /* Replace "map" by a universe map in the same space and free "drop".
  */
 static __isl_give isl_map *replace_by_universe(__isl_take isl_map *map,
@@ -3717,13 +3745,24 @@ isl_bool isl_map_plain_is_disjoint(__isl
 }
 
 /* Are "map1" and "map2" disjoint?
+ * The parameters are assumed to have been aligned.
+ *
+ * In particular, check whether all pairs of basic maps are disjoint.
+ */
+static isl_bool isl_map_is_disjoint_aligned(__isl_keep isl_map *map1,
+	__isl_keep isl_map *map2)
+{
+	return all_pairs(map1, map2, &isl_basic_map_is_disjoint);
+}
+
+/* Are "map1" and "map2" disjoint?
  *
  * They are disjoint if they are "obviously disjoint" or if one of them
  * is empty.  Otherwise, they are not disjoint if one of them is universal.
  * If the two inputs are (obviously) equal and not empty, then they are
  * not disjoint.
  * If none of these cases apply, then check if all pairs of basic maps
- * are disjoint.
+ * are disjoint after aligning the parameters.
  */
 isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
 {
@@ -3754,7 +3793,8 @@ isl_bool isl_map_is_disjoint(__isl_keep
 	if (intersect < 0 || intersect)
 		return isl_bool_not(intersect);
 
-	return all_pairs(map1, map2, &isl_basic_map_is_disjoint);
+	return isl_map_align_params_map_map_and_test(map1, map2,
+						&isl_map_is_disjoint_aligned);
 }
 
 /* Are "bmap1" and "bmap2" disjoint?

Modified: polly/trunk/lib/External/isl/isl_mat.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_mat.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_mat.c (original)
+++ polly/trunk/lib/External/isl/isl_mat.c Tue Jul  4 08:54:11 2017
@@ -271,13 +271,22 @@ static isl_stat check_col(__isl_keep isl
 	return isl_stat_ok;
 }
 
-int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v)
+/* Check that "row" is a valid row position for "mat".
+ */
+static isl_stat check_row(__isl_keep isl_mat *mat, int row)
 {
 	if (!mat)
-		return -1;
+		return isl_stat_error;
 	if (row < 0 || row >= mat->n_row)
-		isl_die(mat->ctx, isl_error_invalid, "row out of range",
-			return -1);
+		isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
+			"row out of range", return isl_stat_error);
+	return isl_stat_ok;
+}
+
+int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v)
+{
+	if (check_row(mat, row) < 0)
+		return -1;
 	if (check_col(mat, col) < 0)
 		return -1;
 	isl_int_set(*v, mat->row[row][col]);
@@ -291,14 +300,11 @@ __isl_give isl_val *isl_mat_get_element_
 {
 	isl_ctx *ctx;
 
-	if (!mat)
+	if (check_row(mat, row) < 0)
 		return NULL;
-	ctx = isl_mat_get_ctx(mat);
-	if (row < 0 || row >= mat->n_row)
-		isl_die(ctx, isl_error_invalid, "row out of range",
-			return NULL);
 	if (check_col(mat, col) < 0)
 		return NULL;
+	ctx = isl_mat_get_ctx(mat);
 	return isl_val_int_from_isl_int(ctx, mat->row[row][col]);
 }
 
@@ -306,36 +312,24 @@ __isl_give isl_mat *isl_mat_set_element(
 	int row, int col, isl_int v)
 {
 	mat = isl_mat_cow(mat);
-	if (!mat)
-		return NULL;
-	if (row < 0 || row >= mat->n_row)
-		isl_die(mat->ctx, isl_error_invalid, "row out of range",
-			goto error);
+	if (check_row(mat, row) < 0)
+		return isl_mat_free(mat);
 	if (check_col(mat, col) < 0)
 		return isl_mat_free(mat);
 	isl_int_set(mat->row[row][col], v);
 	return mat;
-error:
-	isl_mat_free(mat);
-	return NULL;
 }
 
 __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat,
 	int row, int col, int v)
 {
 	mat = isl_mat_cow(mat);
-	if (!mat)
-		return NULL;
-	if (row < 0 || row >= mat->n_row)
-		isl_die(mat->ctx, isl_error_invalid, "row out of range",
-			goto error);
+	if (check_row(mat, row) < 0)
+		return isl_mat_free(mat);
 	if (check_col(mat, col) < 0)
 		return isl_mat_free(mat);
 	isl_int_set_si(mat->row[row][col], v);
 	return mat;
-error:
-	isl_mat_free(mat);
-	return NULL;
 }
 
 /* Replace the element at row "row", column "col" of "mat" by "v".
@@ -689,6 +683,109 @@ error:
 	return NULL;
 }
 
+/* Use row "row" of "mat" to eliminate column "col" from all other rows.
+ */
+static __isl_give isl_mat *eliminate(__isl_take isl_mat *mat, int row, int col)
+{
+	int k, nr, nc;
+	isl_ctx *ctx;
+
+	if (!mat)
+		return NULL;
+
+	ctx = isl_mat_get_ctx(mat);
+	nr = isl_mat_rows(mat);
+	nc = isl_mat_cols(mat);
+
+	for (k = 0; k < nr; ++k) {
+		if (k == row)
+			continue;
+		if (isl_int_is_zero(mat->row[k][col]))
+			continue;
+		mat = isl_mat_cow(mat);
+		if (!mat)
+			return NULL;
+		isl_seq_elim(mat->row[k], mat->row[row], col, nc, NULL);
+		isl_seq_normalize(ctx, mat->row[k], nc);
+	}
+
+	return mat;
+}
+
+/* Perform Gaussian elimination on the rows of "mat", but start
+ * from the final row and the final column.
+ * Any zero rows that result from the elimination are removed.
+ *
+ * In particular, for each column from last to first,
+ * look for the last row with a non-zero coefficient in that column,
+ * move it last (but before other rows moved last in previous steps) and
+ * use it to eliminate the column from the other rows.
+ */
+__isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat)
+{
+	int k, row, last, nr, nc;
+
+	if (!mat)
+		return NULL;
+
+	nr = isl_mat_rows(mat);
+	nc = isl_mat_cols(mat);
+
+	last = nc - 1;
+	for (row = nr - 1; row >= 0; --row) {
+		for (; last >= 0; --last) {
+			for (k = row; k >= 0; --k)
+				if (!isl_int_is_zero(mat->row[k][last]))
+					break;
+			if (k >= 0)
+				break;
+		}
+		if (last < 0)
+			break;
+		if (k != row)
+			mat = isl_mat_swap_rows(mat, k, row);
+		if (!mat)
+			return NULL;
+		if (isl_int_is_neg(mat->row[row][last]))
+			mat = isl_mat_row_neg(mat, row);
+		mat = eliminate(mat, row, last);
+		if (!mat)
+			return NULL;
+	}
+	mat = isl_mat_drop_rows(mat, 0, row + 1);
+
+	return mat;
+}
+
+/* Negate the lexicographically negative rows of "mat" such that
+ * all rows in the result are lexicographically non-negative.
+ */
+__isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat)
+{
+	int i, nr, nc;
+
+	if (!mat)
+		return NULL;
+
+	nr = isl_mat_rows(mat);
+	nc = isl_mat_cols(mat);
+
+	for (i = 0; i < nr; ++i) {
+		int pos;
+
+		pos = isl_seq_first_non_zero(mat->row[i], nc);
+		if (pos < 0)
+			continue;
+		if (isl_int_is_nonneg(mat->row[i][pos]))
+			continue;
+		mat = isl_mat_row_neg(mat, i);
+		if (!mat)
+			return NULL;
+	}
+
+	return mat;
+}
+
 struct isl_mat *isl_mat_right_kernel(struct isl_mat *mat)
 {
 	int i, rank;
@@ -1545,6 +1642,21 @@ __isl_give isl_mat *isl_mat_col_neg(__is
 	return mat;
 }
 
+/* Negate row "row" of "mat" and return the result.
+ */
+__isl_give isl_mat *isl_mat_row_neg(__isl_take isl_mat *mat, int row)
+{
+	if (check_row(mat, row) < 0)
+		return isl_mat_free(mat);
+	if (isl_seq_first_non_zero(mat->row[row], mat->n_col) == -1)
+		return mat;
+	mat = isl_mat_cow(mat);
+	if (!mat)
+		return NULL;
+	isl_seq_neg(mat->row[row], mat->row[row], mat->n_col);
+	return mat;
+}
+
 __isl_give isl_mat *isl_mat_unimodular_complete(__isl_take isl_mat *M, int row)
 {
 	int r;
@@ -1720,12 +1832,9 @@ error:
  */
 isl_stat isl_mat_row_gcd(__isl_keep isl_mat *mat, int row, isl_int *gcd)
 {
-	if (!mat)
+	if (check_row(mat, row) < 0)
 		return isl_stat_error;
 
-	if (row < 0 || row >= mat->n_row)
-		isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
-			"row out of range", return isl_stat_error);
 	isl_seq_gcd(mat->row[row], mat->n_col, gcd);
 
 	return isl_stat_ok;

Modified: polly/trunk/lib/External/isl/isl_mat_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_mat_private.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_mat_private.h (original)
+++ polly/trunk/lib/External/isl/isl_mat_private.h Tue Jul  4 08:54:11 2017
@@ -35,12 +35,16 @@ isl_stat isl_mat_sub_transform(isl_int *
 	unsigned first_col, __isl_take isl_mat *mat);
 __isl_give isl_mat *isl_mat_diag(isl_ctx *ctx, unsigned n_row, isl_int d);
 
+__isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat);
+
 __isl_give isl_mat *isl_mat_scale(__isl_take isl_mat *mat, isl_int m);
 __isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row,
 	isl_int m);
 
 __isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row);
 
+__isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat);
+
 int isl_mat_is_scaled_identity(__isl_keep isl_mat *mat);
 
 isl_stat isl_mat_row_gcd(__isl_keep isl_mat *mat, int row, isl_int *gcd);
@@ -51,6 +55,7 @@ void isl_mat_col_submul(struct isl_mat *
 __isl_give isl_mat *isl_mat_col_addmul(__isl_take isl_mat *mat, int dst_col,
 	isl_int f, int src_col);
 __isl_give isl_mat *isl_mat_col_neg(__isl_take isl_mat *mat, int col);
+__isl_give isl_mat *isl_mat_row_neg(__isl_take isl_mat *mat, int row);
 
 int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v);
 __isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat,

Added: polly/trunk/lib/External/isl/isl_maybe_map.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_maybe_map.h?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/isl_maybe_map.h (added)
+++ polly/trunk/lib/External/isl/isl_maybe_map.h Tue Jul  4 08:54:11 2017
@@ -0,0 +1,10 @@
+#ifndef ISL_MAYBE_MAP_H
+#define ISL_MAYBE_MAP_H
+
+#include <isl/map_type.h>
+
+#define ISL_TYPE	isl_map
+#include <isl/maybe_templ.h>
+#undef ISL_TYPE
+
+#endif

Modified: polly/trunk/lib/External/isl/isl_options.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_options.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_options.c (original)
+++ polly/trunk/lib/External/isl/isl_options.c Tue Jul  4 08:54:11 2017
@@ -169,6 +169,8 @@ ISL_ARG_BOOL(struct isl_options, schedul
 ISL_ARG_CHOICE(struct isl_options, schedule_algorithm, 0,
 	"schedule-algorithm", isl_schedule_algorithm_choice,
 	ISL_SCHEDULE_ALGORITHM_ISL, "scheduling algorithm to use")
+ISL_ARG_BOOL(struct isl_options, schedule_carry_self_first, 0,
+	"schedule-carry-self-first", 1, "try and carry self-dependences first")
 ISL_ARG_BOOL(struct isl_options, schedule_serialize_sccs, 0,
 	"schedule-serialize-sccs", 0,
 	"serialize strongly connected components in dependence graph")
@@ -295,6 +297,11 @@ ISL_CTX_GET_CHOICE_DEF(isl_options, stru
 	schedule_algorithm)
 
 ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
+	schedule_carry_self_first)
+ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
+	schedule_carry_self_first)
+
+ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
 	schedule_serialize_sccs)
 ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
 	schedule_serialize_sccs)

Modified: polly/trunk/lib/External/isl/isl_options_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_options_private.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_options_private.h (original)
+++ polly/trunk/lib/External/isl/isl_options_private.h Tue Jul  4 08:54:11 2017
@@ -46,6 +46,7 @@ struct isl_options {
 	int			schedule_separate_components;
 	int			schedule_whole_component;
 	unsigned		schedule_algorithm;
+	int			schedule_carry_self_first;
 	int			schedule_serialize_sccs;
 
 	int			tile_scale_tile_loops;

Modified: polly/trunk/lib/External/isl/isl_schedule_constraints.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_constraints.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_constraints.c (original)
+++ polly/trunk/lib/External/isl/isl_schedule_constraints.c Tue Jul  4 08:54:11 2017
@@ -8,8 +8,6 @@
  * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
  */
 
-#include <string.h>
-
 #include <isl_schedule_constraints.h>
 #include <isl/schedule.h>
 #include <isl/set.h>
@@ -526,58 +524,13 @@ __isl_give isl_printer *isl_printer_prin
 #define BASE schedule_constraints
 #include <print_templ_yaml.c>
 
-/* Extract a mapping key from the token "tok".
- * Return isl_sc_key_error on error, i.e., if "tok" does not
- * correspond to any known key.
- */
-static enum isl_sc_key extract_key(__isl_keep isl_stream *s,
-	struct isl_token *tok)
-{
-	int type;
-	char *name;
-	isl_ctx *ctx;
-	enum isl_sc_key key;
-
-	if (!tok)
-		return isl_sc_key_error;
-	type = isl_token_get_type(tok);
-	if (type != ISL_TOKEN_IDENT && type != ISL_TOKEN_STRING) {
-		isl_stream_error(s, tok, "expecting key");
-		return isl_sc_key_error;
-	}
-
-	ctx = isl_stream_get_ctx(s);
-	name = isl_token_get_str(ctx, tok);
-	if (!name)
-		return isl_sc_key_error;
-
-	for (key = 0; key < isl_sc_key_end; ++key) {
-		if (!strcmp(name, key_str[key]))
-			break;
-	}
-	free(name);
-
-	if (key >= isl_sc_key_end)
-		isl_die(ctx, isl_error_invalid, "unknown key",
-			return isl_sc_key_error);
-	return key;
-}
-
-/* Read a key from "s" and return the corresponding enum.
- * Return isl_sc_key_error on error, i.e., if the first token
- * on the stream does not correspond to any known key.
- */
-static enum isl_sc_key get_key(__isl_keep isl_stream *s)
-{
-	struct isl_token *tok;
-	enum isl_sc_key key;
-
-	tok = isl_stream_next_token(s);
-	key = extract_key(s, tok);
-	isl_token_free(tok);
-
-	return key;
-}
+#undef KEY
+#define KEY enum isl_sc_key
+#undef KEY_ERROR
+#define KEY_ERROR isl_sc_key_error
+#undef KEY_END
+#define KEY_END isl_sc_key_end
+#include "extract_key.c"
 
 #undef BASE
 #define BASE set

Modified: polly/trunk/lib/External/isl/isl_schedule_read.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_read.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_read.c (original)
+++ polly/trunk/lib/External/isl/isl_schedule_read.c Tue Jul  4 08:54:11 2017
@@ -1,5 +1,3 @@
-#include <string.h>
-
 #include <isl/schedule.h>
 #include <isl/stream.h>
 #include <isl_schedule_private.h>
@@ -25,82 +23,38 @@ enum isl_schedule_key {
 	isl_schedule_key_permutable,
 	isl_schedule_key_schedule,
 	isl_schedule_key_sequence,
-	isl_schedule_key_set
+	isl_schedule_key_set,
+	isl_schedule_key_end
 };
 
-/* Extract a mapping key from the token "tok".
- * Return isl_schedule_key_error on error, i.e., if "tok" does not
- * correspond to any known key.
- */
-static enum isl_schedule_key extract_key(__isl_keep isl_stream *s,
-	struct isl_token *tok)
-{
-	int type;
-	char *name;
-	enum isl_schedule_key key;
-	isl_ctx *ctx;
-
-	ctx = isl_stream_get_ctx(s);
-	type = isl_token_get_type(tok);
-	if (type != ISL_TOKEN_IDENT && type != ISL_TOKEN_STRING) {
-		isl_stream_error(s, tok, "expecting key");
-		return isl_schedule_key_error;
-	}
-	name = isl_token_get_str(ctx, tok);
-	if (!strcmp(name, "child"))
-		key = isl_schedule_key_child;
-	else if (!strcmp(name, "coincident"))
-		key = isl_schedule_key_coincident;
-	else if (!strcmp(name, "context"))
-		key = isl_schedule_key_context;
-	else if (!strcmp(name, "contraction"))
-		key = isl_schedule_key_contraction;
-	else if (!strcmp(name, "domain"))
-		key = isl_schedule_key_domain;
-	else if (!strcmp(name, "expansion"))
-		key = isl_schedule_key_expansion;
-	else if (!strcmp(name, "extension"))
-		key = isl_schedule_key_extension;
-	else if (!strcmp(name, "filter"))
-		key = isl_schedule_key_filter;
-	else if (!strcmp(name, "guard"))
-		key = isl_schedule_key_guard;
-	else if (!strcmp(name, "leaf"))
-		key = isl_schedule_key_leaf;
-	else if (!strcmp(name, "mark"))
-		key = isl_schedule_key_mark;
-	else if (!strcmp(name, "options"))
-		key = isl_schedule_key_options;
-	else if (!strcmp(name, "schedule"))
-		key = isl_schedule_key_schedule;
-	else if (!strcmp(name, "sequence"))
-		key = isl_schedule_key_sequence;
-	else if (!strcmp(name, "set"))
-		key = isl_schedule_key_set;
-	else if (!strcmp(name, "permutable"))
-		key = isl_schedule_key_permutable;
-	else
-		isl_die(ctx, isl_error_invalid, "unknown key",
-			key = isl_schedule_key_error);
-	free(name);
-	return key;
-}
-
-/* Read a key from "s" and return the corresponding enum.
- * Return isl_schedule_key_error on error, i.e., if the first token
- * on the stream does not correspond to any known key.
+/* Textual representations of the YAML keys for an isl_schedule object.
  */
-static enum isl_schedule_key get_key(__isl_keep isl_stream *s)
-{
-	struct isl_token *tok;
-	enum isl_schedule_key key;
-
-	tok = isl_stream_next_token(s);
-	key = extract_key(s, tok);
-	isl_token_free(tok);
+static char *key_str[] = {
+	[isl_schedule_key_child] = "child",
+	[isl_schedule_key_coincident] = "coincident",
+	[isl_schedule_key_context] = "context",
+	[isl_schedule_key_contraction] = "contraction",
+	[isl_schedule_key_domain] = "domain",
+	[isl_schedule_key_expansion] = "expansion",
+	[isl_schedule_key_extension] = "extension",
+	[isl_schedule_key_filter] = "filter",
+	[isl_schedule_key_guard] = "guard",
+	[isl_schedule_key_leaf] = "leaf",
+	[isl_schedule_key_mark] = "mark",
+	[isl_schedule_key_options] = "options",
+	[isl_schedule_key_permutable] = "permutable",
+	[isl_schedule_key_schedule] = "schedule",
+	[isl_schedule_key_sequence] = "sequence",
+	[isl_schedule_key_set] = "set",
+};
 
-	return key;
-}
+#undef KEY
+#define KEY enum isl_schedule_key
+#undef KEY_ERROR
+#define KEY_ERROR isl_schedule_key_error
+#undef KEY_END
+#define KEY_END isl_schedule_key_end
+#include "extract_key.c"
 
 static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(
 	__isl_keep isl_stream *s);
@@ -759,6 +713,7 @@ static __isl_give isl_schedule_tree *isl
 	case isl_schedule_key_child:
 		isl_die(isl_stream_get_ctx(s), isl_error_unsupported,
 			"cannot identity node type", return NULL);
+	case isl_schedule_key_end:
 	case isl_schedule_key_error:
 		return NULL;
 	}

Modified: polly/trunk/lib/External/isl/isl_scheduler.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_scheduler.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_scheduler.c (original)
+++ polly/trunk/lib/External/isl/isl_scheduler.c Tue Jul  4 08:54:11 2017
@@ -27,7 +27,7 @@
 #include <isl_mat_private.h>
 #include <isl_vec_private.h>
 #include <isl/set.h>
-#include <isl/union_set.h>
+#include <isl_union_set_private.h>
 #include <isl_seq.h>
 #include <isl_tab.h>
 #include <isl_dim_map.h>
@@ -58,11 +58,12 @@
  *	is defined over the uncompressed domain space
  * rank is the number of linearly independent rows in the linear part
  *	of sched
- * the columns of cmap represent a change of basis for the schedule
- *	coefficients; the first rank columns span the linear part of
- *	the schedule rows
- * cinv is the inverse of cmap.
- * ctrans is the transpose of cmap.
+ * the rows of "vmap" represent a change of basis for the node
+ *	variables; the first rank rows span the linear part of
+ *	the schedule rows; the remaining rows are linearly independent
+ * the rows of "indep" represent linear combinations of the schedule
+ * coefficients that are non-zero when the schedule coefficients are
+ * linearly independent of previously computed schedule rows.
  * start is the first variable in the LP problem in the sequences that
  *	represents the schedule coefficients of this node
  * nvar is the dimension of the domain
@@ -93,6 +94,8 @@
  * schedule coefficients of the (compressed) variables.  If no bound
  * needs to be imposed on a particular variable, then the corresponding
  * value is negative.
+ * If not NULL, then "bounds" contains a non-parametric set
+ * in the compressed space that is bounded by the size in each direction.
  */
 struct isl_sched_node {
 	isl_space *space;
@@ -103,9 +106,8 @@ struct isl_sched_node {
 	isl_mat *sched;
 	isl_map *sched_map;
 	int	 rank;
-	isl_mat *cmap;
-	isl_mat *cinv;
-	isl_mat *ctrans;
+	isl_mat *indep;
+	isl_mat *vmap;
 	int	 start;
 	int	 nvar;
 	int	 nparam;
@@ -116,6 +118,7 @@ struct isl_sched_node {
 	int	*coincident;
 
 	isl_multi_val *sizes;
+	isl_basic_set *bounds;
 	isl_vec *max;
 };
 
@@ -286,7 +289,11 @@ static int is_conditional_validity(struc
  * the construction of the schedule.
  *
  * intra_hmap is a cache, mapping dependence relations to their dual,
- *	for dependences from a node to itself
+ *	for dependences from a node to itself, possibly without
+ *	coefficients for the parameters
+ * intra_hmap_param is a cache, mapping dependence relations to their dual,
+ *	for dependences from a node to itself, including coefficients
+ *	for the parameters
  * inter_hmap is a cache, mapping dependence relations to their dual,
  *	for dependences between distinct nodes
  * if compression is involved then the key for these maps
@@ -336,6 +343,7 @@ static int is_conditional_validity(struc
  */
 struct isl_sched_graph {
 	isl_map_to_basic_set *intra_hmap;
+	isl_map_to_basic_set *intra_hmap_param;
 	isl_map_to_basic_set *inter_hmap;
 
 	struct isl_sched_node *node;
@@ -357,7 +365,7 @@ struct isl_sched_graph {
 	struct isl_hash_table *edge_table[isl_edge_last + 1];
 
 	struct isl_hash_table *node_table;
-	struct isl_region *region;
+	struct isl_trivial_region *region;
 
 	isl_basic_set *lp;
 
@@ -615,11 +623,13 @@ static int graph_alloc(isl_ctx *ctx, str
 	graph->n_edge = n_edge;
 	graph->node = isl_calloc_array(ctx, struct isl_sched_node, graph->n);
 	graph->sorted = isl_calloc_array(ctx, int, graph->n);
-	graph->region = isl_alloc_array(ctx, struct isl_region, graph->n);
+	graph->region = isl_alloc_array(ctx,
+					struct isl_trivial_region, graph->n);
 	graph->edge = isl_calloc_array(ctx,
 					struct isl_sched_edge, graph->n_edge);
 
 	graph->intra_hmap = isl_map_to_basic_set_alloc(ctx, 2 * n_edge);
+	graph->intra_hmap_param = isl_map_to_basic_set_alloc(ctx, 2 * n_edge);
 	graph->inter_hmap = isl_map_to_basic_set_alloc(ctx, 2 * n_edge);
 
 	if (!graph->node || !graph->region || (graph->n_edge && !graph->edge) ||
@@ -637,6 +647,7 @@ static void graph_free(isl_ctx *ctx, str
 	int i;
 
 	isl_map_to_basic_set_free(graph->intra_hmap);
+	isl_map_to_basic_set_free(graph->intra_hmap_param);
 	isl_map_to_basic_set_free(graph->inter_hmap);
 
 	if (graph->node)
@@ -647,12 +658,12 @@ static void graph_free(isl_ctx *ctx, str
 			isl_multi_aff_free(graph->node[i].decompress);
 			isl_mat_free(graph->node[i].sched);
 			isl_map_free(graph->node[i].sched_map);
-			isl_mat_free(graph->node[i].cmap);
-			isl_mat_free(graph->node[i].cinv);
-			isl_mat_free(graph->node[i].ctrans);
+			isl_mat_free(graph->node[i].indep);
+			isl_mat_free(graph->node[i].vmap);
 			if (graph->root)
 				free(graph->node[i].coincident);
 			isl_multi_val_free(graph->node[i].sizes);
+			isl_basic_set_free(graph->node[i].bounds);
 			isl_vec_free(graph->node[i].max);
 		}
 	free(graph->node);
@@ -759,8 +770,9 @@ static isl_stat set_max_coefficient(isl_
 
 /* Set the entries of node->max to the minimum of the schedule_max_coefficient
  * option (if set) and half of the minimum of the sizes in the other
- * dimensions.  If the minimum of the sizes is one, half of the size
- * is zero and this value is reset to one.
+ * dimensions.  Round up when computing the half such that
+ * if the minimum of the sizes is one, half of the size is taken to be one
+ * rather than zero.
  * If the global minimum is unbounded (i.e., if both
  * the schedule_max_coefficient is not set and the sizes in the other
  * dimensions are unbounded), then store a negative value.
@@ -808,11 +820,8 @@ static isl_stat compute_max_coefficient(
 		isl_val_free(size);
 	}
 
-	for (i = 0; i < node->nvar; ++i) {
-		isl_int_fdiv_q_ui(v->el[i], v->el[i], 2);
-		if (isl_int_is_zero(v->el[i]))
-			isl_int_set_si(v->el[i], 1);
-	}
+	for (i = 0; i < node->nvar; ++i)
+		isl_int_cdiv_q_ui(v->el[i], v->el[i], 2);
 
 	node->max = v;
 	return isl_stat_ok;
@@ -1439,6 +1448,75 @@ static int sort_sccs(struct isl_sched_gr
 	return isl_sort(graph->sorted, graph->n, sizeof(int), &cmp_scc, graph);
 }
 
+/* Return a non-parametric set in the compressed space of "node" that is
+ * bounded by the size in each direction
+ *
+ *	{ [x] : -S_i <= x_i <= S_i }
+ *
+ * If S_i is infinity in direction i, then there are no constraints
+ * in that direction.
+ *
+ * Cache the result in node->bounds.
+ */
+static __isl_give isl_basic_set *get_size_bounds(struct isl_sched_node *node)
+{
+	isl_space *space;
+	isl_basic_set *bounds;
+	int i;
+	unsigned nparam;
+
+	if (node->bounds)
+		return isl_basic_set_copy(node->bounds);
+
+	if (node->compressed)
+		space = isl_multi_aff_get_domain_space(node->decompress);
+	else
+		space = isl_space_copy(node->space);
+	nparam = isl_space_dim(space, isl_dim_param);
+	space = isl_space_drop_dims(space, isl_dim_param, 0, nparam);
+	bounds = isl_basic_set_universe(space);
+
+	for (i = 0; i < node->nvar; ++i) {
+		isl_val *size;
+
+		size = isl_multi_val_get_val(node->sizes, i);
+		if (!size)
+			return isl_basic_set_free(bounds);
+		if (!isl_val_is_int(size)) {
+			isl_val_free(size);
+			continue;
+		}
+		bounds = isl_basic_set_upper_bound_val(bounds, isl_dim_set, i,
+							isl_val_copy(size));
+		bounds = isl_basic_set_lower_bound_val(bounds, isl_dim_set, i,
+							isl_val_neg(size));
+	}
+
+	node->bounds = isl_basic_set_copy(bounds);
+	return bounds;
+}
+
+/* Drop some constraints from "delta" that could be exploited
+ * to construct loop coalescing schedules.
+ * In particular, drop those constraint that bound the difference
+ * to the size of the domain.
+ * First project out the parameters to improve the effectiveness.
+ */
+static __isl_give isl_set *drop_coalescing_constraints(
+	__isl_take isl_set *delta, struct isl_sched_node *node)
+{
+	unsigned nparam;
+	isl_basic_set *bounds;
+
+	bounds = get_size_bounds(node);
+
+	nparam = isl_set_dim(delta, isl_dim_param);
+	delta = isl_set_project_out(delta, isl_dim_param, 0, nparam);
+	delta = isl_set_remove_divs(delta);
+	delta = isl_set_plain_gist_basic_set(delta, bounds);
+	return delta;
+}
+
 /* Given a dependence relation R from "node" to itself,
  * construct the set of coefficients of valid constraints for elements
  * in that dependence relation.
@@ -1456,19 +1534,40 @@ static int sort_sccs(struct isl_sched_gr
  * in a set of tuples c_0, c_n, c_x, c_y, and then
  * plugged in (c_0, c_n, c_x, -c_x).
  *
+ * If "need_param" is set, then the resulting coefficients effectively
+ * include coefficients for the parameters c_n.  Otherwise, they may
+ * have been projected out already.
+ * Since the constraints may be different for these two cases,
+ * they are stored in separate caches.
+ * In particular, if no parameter coefficients are required and
+ * the schedule_treat_coalescing option is set, then the parameters
+ * are projected out and some constraints that could be exploited
+ * to construct coalescing schedules are removed before the dual
+ * is computed.
+ *
  * If "node" has been compressed, then the dependence relation
  * is also compressed before the set of coefficients is computed.
  */
 static __isl_give isl_basic_set *intra_coefficients(
 	struct isl_sched_graph *graph, struct isl_sched_node *node,
-	__isl_take isl_map *map)
+	__isl_take isl_map *map, int need_param)
 {
+	isl_ctx *ctx;
 	isl_set *delta;
 	isl_map *key;
 	isl_basic_set *coef;
 	isl_maybe_isl_basic_set m;
+	isl_map_to_basic_set **hmap = &graph->intra_hmap;
+	int treat;
+
+	if (!map)
+		return NULL;
 
-	m = isl_map_to_basic_set_try_get(graph->intra_hmap, map);
+	ctx = isl_map_get_ctx(map);
+	treat = !need_param && isl_options_get_schedule_treat_coalescing(ctx);
+	if (!treat)
+		hmap = &graph->intra_hmap_param;
+	m = isl_map_to_basic_set_try_get(*hmap, map);
 	if (m.valid < 0 || m.valid) {
 		isl_map_free(map);
 		return m.value;
@@ -1481,10 +1580,12 @@ static __isl_give isl_basic_set *intra_c
 		map = isl_map_preimage_range_multi_aff(map,
 				    isl_multi_aff_copy(node->decompress));
 	}
-	delta = isl_set_remove_divs(isl_map_deltas(map));
+	delta = isl_map_deltas(map);
+	if (treat)
+		delta = drop_coalescing_constraints(delta, node);
+	delta = isl_set_remove_divs(delta);
 	coef = isl_set_coefficients(delta);
-	graph->intra_hmap = isl_map_to_basic_set_set(graph->intra_hmap, key,
-					isl_basic_set_copy(coef));
+	*hmap = isl_map_to_basic_set_set(*hmap, key, isl_basic_set_copy(coef));
 
 	return coef;
 }
@@ -1551,17 +1652,54 @@ static int coef_var_offset(__isl_keep is
 	return offset;
 }
 
-/* Return the offset of the coefficients of the variables of "node"
+/* Return the offset of the coefficient of the constant term of "node"
  * within the (I)LP.
  *
  * Within each node, the coefficients have the following order:
+ *	- positive and negative parts of c_i_x
+ *	- c_i_n (if parametric)
  *	- c_i_0
+ */
+static int node_cst_coef_offset(struct isl_sched_node *node)
+{
+	return node->start + 2 * node->nvar + node->nparam;
+}
+
+/* Return the offset of the coefficients of the parameters of "node"
+ * within the (I)LP.
+ *
+ * Within each node, the coefficients have the following order:
+ *	- positive and negative parts of c_i_x
  *	- c_i_n (if parametric)
+ *	- c_i_0
+ */
+static int node_par_coef_offset(struct isl_sched_node *node)
+{
+	return node->start + 2 * node->nvar;
+}
+
+/* Return the offset of the coefficients of the variables of "node"
+ * within the (I)LP.
+ *
+ * Within each node, the coefficients have the following order:
  *	- positive and negative parts of c_i_x
+ *	- c_i_n (if parametric)
+ *	- c_i_0
  */
 static int node_var_coef_offset(struct isl_sched_node *node)
 {
-	return node->start + 1 + node->nparam;
+	return node->start;
+}
+
+/* Return the position of the pair of variables encoding
+ * coefficient "i" of "node".
+ *
+ * The order of these variable pairs is the opposite of
+ * that of the coefficients, with 2 variables per coefficient.
+ */
+static int node_var_coef_pos(struct isl_sched_node *node, int i)
+{
+	return node_var_coef_offset(node) + 2 * (node->nvar - 1 - i);
 }
 
 /* Construct an isl_dim_map for mapping constraints on coefficients
@@ -1570,11 +1708,16 @@ static int node_var_coef_offset(struct i
  * in the input constraints.
  * "s" is the sign of the mapping.
  *
- * The input constraints are given in terms of the coefficients (c_0, c_n, c_x).
+ * The input constraints are given in terms of the coefficients
+ * (c_0, c_x) or (c_0, c_n, c_x).
  * The mapping produced by this function essentially plugs in
+ * (0, c_i_x^+ - c_i_x^-) if s = 1 and
+ * (0, -c_i_x^+ + c_i_x^-) if s = -1 or
  * (0, 0, c_i_x^+ - c_i_x^-) if s = 1 and
  * (0, 0, -c_i_x^+ + c_i_x^-) if s = -1.
  * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart.
+ * Furthermore, the order of these pairs is the opposite of that
+ * of the corresponding coefficients.
  *
  * The caller can extend the mapping to also map the other coefficients
  * (and therefore not plug in 0).
@@ -1591,10 +1734,10 @@ static __isl_give isl_dim_map *intra_dim
 		return NULL;
 
 	total = isl_basic_set_total_dim(graph->lp);
-	pos = node_var_coef_offset(node);
+	pos = node_var_coef_pos(node, 0);
 	dim_map = isl_dim_map_alloc(ctx, total);
-	isl_dim_map_range(dim_map, pos, 2, offset, 1, node->nvar, -s);
-	isl_dim_map_range(dim_map, pos + 1, 2, offset, 1, node->nvar, s);
+	isl_dim_map_range(dim_map, pos, -2, offset, 1, node->nvar, -s);
+	isl_dim_map_range(dim_map, pos + 1, -2, offset, 1, node->nvar, s);
 
 	return dim_map;
 }
@@ -1614,6 +1757,8 @@ static __isl_give isl_dim_map *intra_dim
  * (-c_j_0 + c_i_0, -c_j_n + c_i_n,
  *  c_i_x^+ - c_i_x^-, -(c_j_x^+ - c_j_x^-)) if s = -1.
  * In graph->lp, the c_*^- appear before their c_*^+ counterpart.
+ * Furthermore, the order of these pairs is the opposite of that
+ * of the corresponding coefficients.
  *
  * The caller can further extend the mapping.
  */
@@ -1631,19 +1776,23 @@ static __isl_give isl_dim_map *inter_dim
 	total = isl_basic_set_total_dim(graph->lp);
 	dim_map = isl_dim_map_alloc(ctx, total);
 
-	isl_dim_map_range(dim_map, dst->start, 0, 0, 0, 1, s);
-	isl_dim_map_range(dim_map, dst->start + 1, 1, 1, 1, dst->nparam, s);
-	pos = node_var_coef_offset(dst);
-	isl_dim_map_range(dim_map, pos, 2, offset + src->nvar, 1,
+	pos = node_cst_coef_offset(dst);
+	isl_dim_map_range(dim_map, pos, 0, 0, 0, 1, s);
+	pos = node_par_coef_offset(dst);
+	isl_dim_map_range(dim_map, pos, 1, 1, 1, dst->nparam, s);
+	pos = node_var_coef_pos(dst, 0);
+	isl_dim_map_range(dim_map, pos, -2, offset + src->nvar, 1,
 			  dst->nvar, -s);
-	isl_dim_map_range(dim_map, pos + 1, 2, offset + src->nvar, 1,
+	isl_dim_map_range(dim_map, pos + 1, -2, offset + src->nvar, 1,
 			  dst->nvar, s);
 
-	isl_dim_map_range(dim_map, src->start, 0, 0, 0, 1, -s);
-	isl_dim_map_range(dim_map, src->start + 1, 1, 1, 1, src->nparam, -s);
-	pos = node_var_coef_offset(src);
-	isl_dim_map_range(dim_map, pos, 2, offset, 1, src->nvar, s);
-	isl_dim_map_range(dim_map, pos + 1, 2, offset, 1, src->nvar, -s);
+	pos = node_cst_coef_offset(src);
+	isl_dim_map_range(dim_map, pos, 0, 0, 0, 1, -s);
+	pos = node_par_coef_offset(src);
+	isl_dim_map_range(dim_map, pos, 1, 1, 1, src->nparam, -s);
+	pos = node_var_coef_pos(src, 0);
+	isl_dim_map_range(dim_map, pos, -2, offset, 1, src->nvar, s);
+	isl_dim_map_range(dim_map, pos + 1, -2, offset, 1, src->nvar, -s);
 
 	return dim_map;
 }
@@ -1672,14 +1821,12 @@ static __isl_give isl_basic_set *add_con
  *	= c_i_x (y - x) >= 0
  *
  * for each (x,y) in R.
- * We obtain general constraints on coefficients (c_0, c_n, c_x)
- * of valid constraints for (y - x) and then plug in (0, 0, c_i_x^+ - c_i_x^-),
+ * We obtain general constraints on coefficients (c_0, c_x)
+ * of valid constraints for (y - x) and then plug in (0, c_i_x^+ - c_i_x^-),
  * where c_i_x = c_i_x^+ - c_i_x^-, with c_i_x^+ and c_i_x^- non-negative.
  * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart.
- *
- * Actually, we do not construct constraints for the c_i_x themselves,
- * but for the coefficients of c_i_x written as a linear combination
- * of the columns in node->cmap.
+ * Note that the result of intra_coefficients may also contain
+ * parameter coefficients c_n, in which case 0 is plugged in for them as well.
  */
 static isl_stat add_intra_validity_constraints(struct isl_sched_graph *graph,
 	struct isl_sched_edge *edge)
@@ -1691,12 +1838,10 @@ static isl_stat add_intra_validity_const
 	isl_basic_set *coef;
 	struct isl_sched_node *node = edge->src;
 
-	coef = intra_coefficients(graph, node, map);
+	coef = intra_coefficients(graph, node, map, 0);
 
 	offset = coef_var_offset(coef);
 
-	coef = isl_basic_set_transform_dims(coef, isl_dim_set,
-					    offset, isl_mat_copy(node->cmap));
 	if (!coef)
 		return isl_stat_error;
 
@@ -1718,10 +1863,6 @@ static isl_stat add_intra_validity_const
  * (c_j_0 - c_i_0, c_j_n - c_i_n, -(c_i_x^+ - c_i_x^-), c_j_x^+ - c_j_x^-),
  * where c_* = c_*^+ - c_*^-, with c_*^+ and c_*^- non-negative.
  * In graph->lp, the c_*^- appear before their c_*^+ counterpart.
- *
- * Actually, we do not construct constraints for the c_*_x themselves,
- * but for the coefficients of c_*_x written as a linear combination
- * of the columns in node->cmap.
  */
 static isl_stat add_inter_validity_constraints(struct isl_sched_graph *graph,
 	struct isl_sched_edge *edge)
@@ -1743,10 +1884,6 @@ static isl_stat add_inter_validity_const
 
 	offset = coef_var_offset(coef);
 
-	coef = isl_basic_set_transform_dims(coef, isl_dim_set,
-				offset, isl_mat_copy(src->cmap));
-	coef = isl_basic_set_transform_dims(coef, isl_dim_set,
-				offset + src->nvar, isl_mat_copy(dst->cmap));
 	if (!coef)
 		return isl_stat_error;
 
@@ -1786,10 +1923,6 @@ static isl_stat add_inter_validity_const
  * with each coefficient (except m_0) represented as a pair of non-negative
  * coefficients.
  *
- * Actually, we do not construct constraints for the c_i_x themselves,
- * but for the coefficients of c_i_x written as a linear combination
- * of the columns in node->cmap.
- *
  *
  * If "local" is set, then we add constraints
  *
@@ -1801,6 +1934,8 @@ static isl_stat add_inter_validity_const
  *
  * instead, forcing the dependence distance to be (less than or) equal to 0.
  * That is, we plug in (0, 0, -s * c_i_x),
+ * intra_coefficients is not required to have c_n in its result when
+ * "local" is set.  If they are missing, then (0, -s * c_i_x) is plugged in.
  * Note that dependences marked local are treated as validity constraints
  * by add_all_validity_constraints and therefore also have
  * their distances bounded by 0 from below.
@@ -1816,12 +1951,10 @@ static isl_stat add_intra_proximity_cons
 	isl_basic_set *coef;
 	struct isl_sched_node *node = edge->src;
 
-	coef = intra_coefficients(graph, node, map);
+	coef = intra_coefficients(graph, node, map, !local);
 
 	offset = coef_var_offset(coef);
 
-	coef = isl_basic_set_transform_dims(coef, isl_dim_set,
-					    offset, isl_mat_copy(node->cmap));
 	if (!coef)
 		return isl_stat_error;
 
@@ -1869,10 +2002,6 @@ static isl_stat add_intra_proximity_cons
  * with each coefficient (except m_0, c_*_0 and c_*_n)
  * represented as a pair of non-negative coefficients.
  *
- * Actually, we do not construct constraints for the c_*_x themselves,
- * but for the coefficients of c_*_x written as a linear combination
- * of the columns in node->cmap.
- *
  *
  * If "local" is set (and s = 1), then we add constraints
  *
@@ -1905,10 +2034,6 @@ static isl_stat add_inter_proximity_cons
 
 	offset = coef_var_offset(coef);
 
-	coef = isl_basic_set_transform_dims(coef, isl_dim_set,
-				offset, isl_mat_copy(src->cmap));
-	coef = isl_basic_set_transform_dims(coef, isl_dim_set,
-				offset + src->nvar, isl_mat_copy(dst->cmap));
 	if (!coef)
 		return isl_stat_error;
 
@@ -1926,6 +2051,16 @@ static isl_stat add_inter_proximity_cons
 	return isl_stat_ok;
 }
 
+/* Should the distance over "edge" be forced to zero?
+ * That is, is it marked as a local edge?
+ * If "use_coincidence" is set, then coincidence edges are treated
+ * as local edges.
+ */
+static int force_zero(struct isl_sched_edge *edge, int use_coincidence)
+{
+	return is_local(edge) || (use_coincidence && is_coincidence(edge));
+}
+
 /* Add all validity constraints to graph->lp.
  *
  * An edge that is forced to be local needs to have its dependence
@@ -1943,11 +2078,10 @@ static int add_all_validity_constraints(
 
 	for (i = 0; i < graph->n_edge; ++i) {
 		struct isl_sched_edge *edge = &graph->edge[i];
-		int local;
+		int zero;
 
-		local = is_local(edge) ||
-			(is_coincidence(edge) && use_coincidence);
-		if (!is_validity(edge) && !local)
+		zero = force_zero(edge, use_coincidence);
+		if (!is_validity(edge) && !zero)
 			continue;
 		if (edge->src != edge->dst)
 			continue;
@@ -1957,11 +2091,10 @@ static int add_all_validity_constraints(
 
 	for (i = 0; i < graph->n_edge; ++i) {
 		struct isl_sched_edge *edge = &graph->edge[i];
-		int local;
+		int zero;
 
-		local = is_local(edge) ||
-			(is_coincidence(edge) && use_coincidence);
-		if (!is_validity(edge) && !local)
+		zero = force_zero(edge, use_coincidence);
+		if (!is_validity(edge) && !zero)
 			continue;
 		if (edge->src == edge->dst)
 			continue;
@@ -1991,19 +2124,18 @@ static int add_all_proximity_constraints
 
 	for (i = 0; i < graph->n_edge; ++i) {
 		struct isl_sched_edge *edge = &graph->edge[i];
-		int local;
+		int zero;
 
-		local = is_local(edge) ||
-			(is_coincidence(edge) && use_coincidence);
-		if (!is_proximity(edge) && !local)
+		zero = force_zero(edge, use_coincidence);
+		if (!is_proximity(edge) && !zero)
 			continue;
 		if (edge->src == edge->dst &&
-		    add_intra_proximity_constraints(graph, edge, 1, local) < 0)
+		    add_intra_proximity_constraints(graph, edge, 1, zero) < 0)
 			return -1;
 		if (edge->src != edge->dst &&
-		    add_inter_proximity_constraints(graph, edge, 1, local) < 0)
+		    add_inter_proximity_constraints(graph, edge, 1, zero) < 0)
 			return -1;
-		if (is_validity(edge) || local)
+		if (is_validity(edge) || zero)
 			continue;
 		if (edge->src == edge->dst &&
 		    add_intra_proximity_constraints(graph, edge, -1, 0) < 0)
@@ -2016,6 +2148,18 @@ static int add_all_proximity_constraints
 	return 0;
 }
 
+/* Normalize the rows of "indep" such that all rows are lexicographically
+ * positive and such that each row contains as many final zeros as possible,
+ * given the choice for the previous rows.
+ * Do this by performing elementary row operations.
+ */
+static __isl_give isl_mat *normalize_independent(__isl_take isl_mat *indep)
+{
+	indep = isl_mat_reverse_gauss(indep);
+	indep = isl_mat_lexnonneg_rows(indep);
+	return indep;
+}
+
 /* Compute a basis for the rows in the linear part of the schedule
  * and extend this basis to a full basis.  The remaining rows
  * can then be used to force linear independence from the rows
@@ -2029,14 +2173,22 @@ static int add_all_proximity_constraints
  * with H the Hermite normal form of S.  That is, all but the
  * first rank columns of H are zero and so each row in S is
  * a linear combination of the first rank rows of Q.
- * The matrix Q is then transposed because we will write the
- * coefficients of the next schedule row as a column vector s
- * and express this s as a linear combination s = Q c of the
- * computed basis.
- * Similarly, the matrix U is transposed such that we can
- * compute the coefficients c = U s from a schedule row s.
+ * The matrix Q can be used as a variable transformation
+ * that isolates the directions of S in the first rank rows.
+ * Transposing S U = H yields
+ *
+ *	U^T S^T = H^T
+ *
+ * with all but the first rank rows of H^T zero.
+ * The last rows of U^T are therefore linear combinations
+ * of schedule coefficients that are all zero on schedule
+ * coefficients that are linearly dependent on the rows of S.
+ * At least one of these combinations is non-zero on
+ * linearly independent schedule coefficients.
+ * The rows are normalized to involve as few of the last
+ * coefficients as possible and to have a positive initial value.
  */
-static int node_update_cmap(struct isl_sched_node *node)
+static int node_update_vmap(struct isl_sched_node *node)
 {
 	isl_mat *H, *U, *Q;
 	int n_row = isl_mat_rows(node->sched);
@@ -2045,16 +2197,16 @@ static int node_update_cmap(struct isl_s
 			      1 + node->nparam, node->nvar);
 
 	H = isl_mat_left_hermite(H, 0, &U, &Q);
-	isl_mat_free(node->cmap);
-	isl_mat_free(node->cinv);
-	isl_mat_free(node->ctrans);
-	node->ctrans = isl_mat_copy(Q);
-	node->cmap = isl_mat_transpose(Q);
-	node->cinv = isl_mat_transpose(U);
+	isl_mat_free(node->indep);
+	isl_mat_free(node->vmap);
+	node->vmap = Q;
+	node->indep = isl_mat_transpose(U);
 	node->rank = isl_mat_initial_non_zero_cols(H);
+	node->indep = isl_mat_drop_rows(node->indep, 0, node->rank);
+	node->indep = normalize_independent(node->indep);
 	isl_mat_free(H);
 
-	if (!node->cmap || !node->cinv || !node->ctrans || node->rank < 0)
+	if (!node->indep || !node->vmap || node->rank < 0)
 		return -1;
 	return 0;
 }
@@ -2082,43 +2234,98 @@ static int is_any_validity(struct isl_sc
  */
 static int edge_multiplicity(struct isl_sched_edge *edge, int use_coincidence)
 {
-	if (is_proximity(edge) || is_local(edge))
-		return 2;
-	if (use_coincidence && is_coincidence(edge))
+	if (is_proximity(edge) || force_zero(edge, use_coincidence))
 		return 2;
 	if (is_validity(edge))
 		return 1;
 	return 0;
 }
 
+/* How many times should the constraints in "edge" be counted
+ * as a parametric intra-node constraint?
+ *
+ * Only proximity edges that are not forced zero need
+ * coefficient constraints that include coefficients for parameters.
+ * If the edge is also a validity edge, then only
+ * an upper bound is introduced.  Otherwise, both lower and upper bounds
+ * are introduced.
+ */
+static int parametric_intra_edge_multiplicity(struct isl_sched_edge *edge,
+	int use_coincidence)
+{
+	if (edge->src != edge->dst)
+		return 0;
+	if (!is_proximity(edge))
+		return 0;
+	if (force_zero(edge, use_coincidence))
+		return 0;
+	if (is_validity(edge))
+		return 1;
+	else
+		return 2;
+}
+
+/* Add "f" times the number of equality and inequality constraints of "bset"
+ * to "n_eq" and "n_ineq" and free "bset".
+ */
+static isl_stat update_count(__isl_take isl_basic_set *bset,
+	int f, int *n_eq, int *n_ineq)
+{
+	if (!bset)
+		return isl_stat_error;
+
+	*n_eq += isl_basic_set_n_equality(bset);
+	*n_ineq += isl_basic_set_n_inequality(bset);
+	isl_basic_set_free(bset);
+
+	return isl_stat_ok;
+}
+
 /* Count the number of equality and inequality constraints
  * that will be added for the given map.
  *
+ * The edges that require parameter coefficients are counted separately.
+ *
  * "use_coincidence" is set if we should take into account coincidence edges.
  */
 static isl_stat count_map_constraints(struct isl_sched_graph *graph,
 	struct isl_sched_edge *edge, __isl_take isl_map *map,
 	int *n_eq, int *n_ineq, int use_coincidence)
 {
+	isl_map *copy;
 	isl_basic_set *coef;
 	int f = edge_multiplicity(edge, use_coincidence);
+	int fp = parametric_intra_edge_multiplicity(edge, use_coincidence);
 
 	if (f == 0) {
 		isl_map_free(map);
 		return isl_stat_ok;
 	}
 
-	if (edge->src == edge->dst)
-		coef = intra_coefficients(graph, edge->src, map);
-	else
+	if (edge->src != edge->dst) {
 		coef = inter_coefficients(graph, edge, map);
-	if (!coef)
-		return isl_stat_error;
-	*n_eq += f * isl_basic_set_n_equality(coef);
-	*n_ineq += f * isl_basic_set_n_inequality(coef);
-	isl_basic_set_free(coef);
+		return update_count(coef, f, n_eq, n_ineq);
+	}
 
+	if (fp > 0) {
+		copy = isl_map_copy(map);
+		coef = intra_coefficients(graph, edge->src, copy, 1);
+		if (update_count(coef, fp, n_eq, n_ineq) < 0)
+			goto error;
+	}
+
+	if (f > fp) {
+		copy = isl_map_copy(map);
+		coef = intra_coefficients(graph, edge->src, copy, 0);
+		if (update_count(coef, f - fp, n_eq, n_ineq) < 0)
+			goto error;
+	}
+
+	isl_map_free(map);
 	return isl_stat_ok;
+error:
+	isl_map_free(map);
+	return isl_stat_error;
 }
 
 /* Count the number of equality and inequality constraints
@@ -2172,11 +2379,6 @@ static isl_stat count_bound_constant_con
  *
  * The maximal value of the constant terms is defined by the option
  * "schedule_max_constant_term".
- *
- * Within each node, the coefficients have the following order:
- *	- c_i_0
- *	- c_i_n (if parametric)
- *	- positive and negative parts of c_i_x
  */
 static isl_stat add_bound_constant_constraints(isl_ctx *ctx,
 	struct isl_sched_graph *graph)
@@ -2193,11 +2395,14 @@ static isl_stat add_bound_constant_const
 
 	for (i = 0; i < graph->n; ++i) {
 		struct isl_sched_node *node = &graph->node[i];
+		int pos;
+
 		k = isl_basic_set_alloc_inequality(graph->lp);
 		if (k < 0)
 			return isl_stat_error;
 		isl_seq_clr(graph->lp->ineq[k], 1 + total);
-		isl_int_set_si(graph->lp->ineq[k][1 + node->start], -1);
+		pos = node_cst_coef_offset(node);
+		isl_int_set_si(graph->lp->ineq[k][1 + pos], -1);
 		isl_int_set_si(graph->lp->ineq[k][0], max);
 	}
 
@@ -2240,21 +2445,20 @@ static int count_bound_coefficient_const
  *	-c_n + max >= 0
  *
  * The variables coefficients are, however, not represented directly.
- * Instead, the variables coefficients c_x are written as a linear
- * combination c_x = cmap c_z of some other coefficients c_z,
- * which are in turn encoded as c_z = c_z^+ - c_z^-.
- * Let a_j be the elements of row i of node->cmap, then
+ * Instead, the variable coefficients c_x are written as differences
+ * c_x = c_x^+ - c_x^-.
+ * That is,
  *
  *	-max_i <= c_x_i <= max_i
  *
  * is encoded as
  *
- *	-max_i <= \sum_j a_j (c_z_j^+ - c_z_j^-) <= max_i
+ *	-max_i <= c_x_i^+ - c_x_i^- <= max_i
  *
  * or
  *
- *	-\sum_j a_j (c_z_j^+ - c_z_j^-) + max_i >= 0
- *	\sum_j a_j (c_z_j^+ - c_z_j^-) + max_i >= 0
+ *	-(c_x_i^+ - c_x_i^-) + max_i >= 0
+ *	c_x_i^+ - c_x_i^- + max_i >= 0
  */
 static isl_stat node_add_coefficient_constraints(isl_ctx *ctx,
 	struct isl_sched_graph *graph, struct isl_sched_node *node, int max)
@@ -2274,7 +2478,7 @@ static isl_stat node_add_coefficient_con
 		k = isl_basic_set_alloc_inequality(graph->lp);
 		if (k < 0)
 			return isl_stat_error;
-		dim = 1 + node->start + 1 + j;
+		dim = 1 + node_par_coef_offset(node) + j;
 		isl_seq_clr(graph->lp->ineq[k], 1 + total);
 		isl_int_set_si(graph->lp->ineq[k][dim], -1);
 		isl_int_set_si(graph->lp->ineq[k][0], max);
@@ -2285,17 +2489,13 @@ static isl_stat node_add_coefficient_con
 	if (!ineq)
 		return isl_stat_error;
 	for (i = 0; i < node->nvar; ++i) {
-		int pos = 1 + node_var_coef_offset(node);
+		int pos = 1 + node_var_coef_pos(node, i);
 
 		if (isl_int_is_neg(node->max->el[i]))
 			continue;
 
-		for (j = 0; j < node->nvar; ++j) {
-			isl_int_set(ineq->el[pos + 2 * j],
-					node->cmap->row[i][j]);
-			isl_int_neg(ineq->el[pos + 2 * j + 1],
-					node->cmap->row[i][j]);
-		}
+		isl_int_set_si(ineq->el[pos], 1);
+		isl_int_set_si(ineq->el[pos + 1], -1);
 		isl_int_set(ineq->el[0], node->max->el[i]);
 
 		k = isl_basic_set_alloc_inequality(graph->lp);
@@ -2303,11 +2503,13 @@ static isl_stat node_add_coefficient_con
 			goto error;
 		isl_seq_cpy(graph->lp->ineq[k], ineq->el, 1 + total);
 
-		isl_seq_neg(ineq->el + pos, ineq->el + pos, 2 * node->nvar);
+		isl_seq_neg(ineq->el + pos, ineq->el + pos, 2);
 		k = isl_basic_set_alloc_inequality(graph->lp);
 		if (k < 0)
 			goto error;
 		isl_seq_cpy(graph->lp->ineq[k], ineq->el, 1 + total);
+
+		isl_seq_clr(ineq->el + pos, 2);
 	}
 	isl_vec_free(ineq);
 
@@ -2370,11 +2572,6 @@ static isl_stat add_sum_constraint(struc
 
 /* Add a constraint to graph->lp that equates the value at position
  * "sum_pos" to the sum of the parameter coefficients of all nodes.
- *
- * Within each node, the coefficients have the following order:
- *	- c_i_0
- *	- c_i_n (if parametric)
- *	- positive and negative parts of c_i_x
  */
 static isl_stat add_param_sum_constraint(struct isl_sched_graph *graph,
 	int sum_pos)
@@ -2390,7 +2587,7 @@ static isl_stat add_param_sum_constraint
 	isl_seq_clr(graph->lp->eq[k], 1 + total);
 	isl_int_set_si(graph->lp->eq[k][1 + sum_pos], -1);
 	for (i = 0; i < graph->n; ++i) {
-		int pos = 1 + graph->node[i].start + 1;
+		int pos = 1 + node_par_coef_offset(&graph->node[i]);
 
 		for (j = 0; j < graph->node[i].nparam; ++j)
 			isl_int_set_si(graph->lp->eq[k][pos + j], 1);
@@ -2401,11 +2598,6 @@ static isl_stat add_param_sum_constraint
 
 /* Add a constraint to graph->lp that equates the value at position
  * "sum_pos" to the sum of the variable coefficients of all nodes.
- *
- * Within each node, the coefficients have the following order:
- *	- c_i_0
- *	- c_i_n (if parametric)
- *	- positive and negative parts of c_i_x
  */
 static isl_stat add_var_sum_constraint(struct isl_sched_graph *graph,
 	int sum_pos)
@@ -2451,13 +2643,9 @@ static isl_stat add_var_sum_constraint(s
  *	- sum of positive and negative parts of all c_x coefficients
  *	- positive and negative parts of m_n coefficients
  *	- for each node
- *		- c_i_0
+ *		- positive and negative parts of c_i_x, in opposite order
  *		- c_i_n (if parametric)
- *		- positive and negative parts of c_i_x
- *
- * The c_i_x are not represented directly, but through the columns of
- * node->cmap.  That is, the computed values are for variable t_i_x
- * such that c_i_x = Q t_i_x with Q equal to node->cmap.
+ *		- c_i_0
  *
  * The constraints are those from the edges plus two or three equalities
  * to express the sums.
@@ -2482,7 +2670,7 @@ static isl_stat setup_lp(isl_ctx *ctx, s
 	total = param_pos + 2 * nparam;
 	for (i = 0; i < graph->n; ++i) {
 		struct isl_sched_node *node = &graph->node[graph->sorted[i]];
-		if (node_update_cmap(node) < 0)
+		if (node_update_vmap(node) < 0)
 			return isl_stat_error;
 		node->start = total;
 		total += 1 + node->nparam + 2 * node->nvar;
@@ -2567,19 +2755,49 @@ static int needs_row(struct isl_sched_gr
 	return node->nvar - node->rank >= graph->maxvar - graph->n_row;
 }
 
+/* Construct a non-triviality region with triviality directions
+ * corresponding to the rows of "indep".
+ * The rows of "indep" are expressed in terms of the schedule coefficients c_i,
+ * while the triviality directions are expressed in terms of
+ * pairs of non-negative variables c^+_i - c^-_i, with c^-_i appearing
+ * before c^+_i.  Furthermore,
+ * the pairs of non-negative variables representing the coefficients
+ * are stored in the opposite order.
+ */
+static __isl_give isl_mat *construct_trivial(__isl_keep isl_mat *indep)
+{
+	isl_ctx *ctx;
+	isl_mat *mat;
+	int i, j, n, n_var;
+
+	if (!indep)
+		return NULL;
+
+	ctx = isl_mat_get_ctx(indep);
+	n = isl_mat_rows(indep);
+	n_var = isl_mat_cols(indep);
+	mat = isl_mat_alloc(ctx, n, 2 * n_var);
+	if (!mat)
+		return NULL;
+	for (i = 0; i < n; ++i) {
+		for (j = 0; j < n_var; ++j) {
+			int nj = n_var - 1 - j;
+			isl_int_neg(mat->row[i][2 * nj], indep->row[i][j]);
+			isl_int_set(mat->row[i][2 * nj + 1], indep->row[i][j]);
+		}
+	}
+
+	return mat;
+}
+
 /* Solve the ILP problem constructed in setup_lp.
  * For each node such that all the remaining rows of its schedule
  * need to be non-trivial, we construct a non-triviality region.
  * This region imposes that the next row is independent of previous rows.
- * In particular the coefficients c_i_x are represented by t_i_x
- * variables with c_i_x = Q t_i_x and Q a unimodular matrix such that
- * its first columns span the rows of the previously computed part
- * of the schedule.  The non-triviality region enforces that at least
- * one of the remaining components of t_i_x is non-zero, i.e.,
- * that the new schedule row depends on at least one of the remaining
- * columns of Q.
+ * In particular, the non-triviality region enforces that at least
+ * one of the linear combinations in the rows of node->indep is non-zero.
  */
-static __isl_give isl_vec *solve_lp(struct isl_sched_graph *graph)
+static __isl_give isl_vec *solve_lp(isl_ctx *ctx, struct isl_sched_graph *graph)
 {
 	int i;
 	isl_vec *sol;
@@ -2587,27 +2805,30 @@ static __isl_give isl_vec *solve_lp(stru
 
 	for (i = 0; i < graph->n; ++i) {
 		struct isl_sched_node *node = &graph->node[i];
-		int skip = node->rank;
-		graph->region[i].pos = node_var_coef_offset(node) + 2 * skip;
+		isl_mat *trivial;
+
+		graph->region[i].pos = node_var_coef_offset(node);
 		if (needs_row(graph, node))
-			graph->region[i].len = 2 * (node->nvar - skip);
+			trivial = construct_trivial(node->indep);
 		else
-			graph->region[i].len = 0;
+			trivial = isl_mat_zero(ctx, 0, 0);
+		graph->region[i].trivial = trivial;
 	}
 	lp = isl_basic_set_copy(graph->lp);
 	sol = isl_tab_basic_set_non_trivial_lexmin(lp, 2, graph->n,
 				       graph->region, &check_conflict, graph);
+	for (i = 0; i < graph->n; ++i)
+		isl_mat_free(graph->region[i].trivial);
 	return sol;
 }
 
 /* Extract the coefficients for the variables of "node" from "sol".
  *
- * Within each node, the coefficients have the following order:
- *	- c_i_0
- *	- c_i_n (if parametric)
- *	- positive and negative parts of c_i_x
- *
+ * Each schedule coefficient c_i_x is represented as the difference
+ * between two non-negative variables c_i_x^+ - c_i_x^-.
  * The c_i_x^- appear before their c_i_x^+ counterpart.
+ * Furthermore, the order of these pairs is the opposite of that
+ * of the corresponding coefficients.
  *
  * Return c_i_x = c_i_x^+ - c_i_x^-
  */
@@ -2626,7 +2847,7 @@ static __isl_give isl_vec *extract_var_c
 
 	pos = 1 + node_var_coef_offset(node);
 	for (i = 0; i < node->nvar; ++i)
-		isl_int_sub(csol->el[i],
+		isl_int_sub(csol->el[node->nvar - 1 - i],
 			    sol->el[pos + 2 * i + 1], sol->el[pos + 2 * i]);
 
 	return csol;
@@ -2637,17 +2858,13 @@ static __isl_give isl_vec *extract_var_c
  * The new row is added to the current band.
  * All possibly negative coefficients are encoded as a difference
  * of two non-negative variables, so we need to perform the subtraction
- * here.  Moreover, if use_cmap is set, then the solution does
- * not refer to the actual coefficients c_i_x, but instead to variables
- * t_i_x such that c_i_x = Q t_i_x and Q is equal to node->cmap.
- * In this case, we then also need to perform this multiplication
- * to obtain the values of c_i_x.
+ * here.
  *
  * If coincident is set, then the caller guarantees that the new
  * row satisfies the coincidence constraints.
  */
 static int update_schedule(struct isl_sched_graph *graph,
-	__isl_take isl_vec *sol, int use_cmap, int coincident)
+	__isl_take isl_vec *sol, int coincident)
 {
 	int i, j;
 	isl_vec *csol = NULL;
@@ -2663,7 +2880,7 @@ static int update_schedule(struct isl_sc
 
 	for (i = 0; i < graph->n; ++i) {
 		struct isl_sched_node *node = &graph->node[i];
-		int pos = node->start;
+		int pos;
 		int row = isl_mat_rows(node->sched);
 
 		isl_vec_free(csol);
@@ -2676,14 +2893,13 @@ static int update_schedule(struct isl_sc
 		node->sched = isl_mat_add_rows(node->sched, 1);
 		if (!node->sched)
 			goto error;
-		for (j = 0; j < 1 + node->nparam; ++j)
+		pos = node_cst_coef_offset(node);
+		node->sched = isl_mat_set_element(node->sched,
+					row, 0, sol->el[1 + pos]);
+		pos = node_par_coef_offset(node);
+		for (j = 0; j < node->nparam; ++j)
 			node->sched = isl_mat_set_element(node->sched,
-						row, j, sol->el[1 + pos + j]);
-		if (use_cmap)
-			csol = isl_mat_vec_product(isl_mat_copy(node->cmap),
-						   csol);
-		if (!csol)
-			goto error;
+					row, 1 + j, sol->el[1 + pos + j]);
 		for (j = 0; j < node->nvar; ++j)
 			node->sched = isl_mat_set_element(node->sched,
 					row, 1 + node->nparam + j, csol->el[j]);
@@ -3158,6 +3374,7 @@ static int copy_nodes(struct isl_sched_g
 		dst->node[j].sched_map = isl_map_copy(src->node[i].sched_map);
 		dst->node[j].coincident = src->node[i].coincident;
 		dst->node[j].sizes = isl_multi_val_copy(src->node[i].sizes);
+		dst->node[j].bounds = isl_basic_set_copy(src->node[i].bounds);
 		dst->node[j].max = isl_vec_copy(src->node[i].max);
 		dst->n++;
 
@@ -3255,7 +3472,7 @@ static int compute_maxvar(struct isl_sch
 		struct isl_sched_node *node = &graph->node[i];
 		int nvar;
 
-		if (node_update_cmap(node) < 0)
+		if (node_update_vmap(node) < 0)
 			return -1;
 		nvar = node->nvar + graph->n_row - node->rank;
 		if (nvar > graph->maxvar)
@@ -3524,16 +3741,16 @@ static __isl_give isl_schedule_node *com
 /* Add the constraints "coef" derived from an edge from "node" to itself
  * to graph->lp in order to respect the dependences and to try and carry them.
  * "pos" is the sequence number of the edge that needs to be carried.
- * "coef" represents general constraints on coefficients (c_0, c_n, c_x)
+ * "coef" represents general constraints on coefficients (c_0, c_x)
  * of valid constraints for (y - x) with x and y instances of the node.
  *
  * The constraints added to graph->lp need to enforce
  *
- *	(c_j_0 + c_j_n n + c_j_x y) - (c_j_0 + c_j_n n + c_j_x x)
+ *	(c_j_0 + c_j_x y) - (c_j_0 + c_j_x x)
  *	= c_j_x (y - x) >= e_i
  *
  * for each (x,y) in the dependence relation of the edge.
- * That is, (-e_i, 0, c_j_x) needs to be plugged in for (c_0, c_n, c_x),
+ * That is, (-e_i, c_j_x) needs to be plugged in for (c_0, c_x),
  * taking into account that each coefficient in c_j_x is represented
  * as a pair of non-negative coefficients.
  */
@@ -3558,7 +3775,8 @@ static isl_stat add_intra_constraints(st
 
 /* Add the constraints "coef" derived from an edge from "src" to "dst"
  * to graph->lp in order to respect the dependences and to try and carry them.
- * "pos" is the sequence number of the edge that needs to be carried.
+ * "pos" is the sequence number of the edge that needs to be carried or
+ * -1 if no attempt should be made to carry the dependences.
  * "coef" represents general constraints on coefficients (c_0, c_n, c_x, c_y)
  * of valid constraints for (x, y) with x and y instances of "src" and "dst".
  *
@@ -3566,9 +3784,15 @@ static isl_stat add_intra_constraints(st
  *
  *	(c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= e_i
  *
- * for each (x,y) in the dependence relation of the edge.
+ * for each (x,y) in the dependence relation of the edge or
+ *
+ *	(c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= 0
+ *
+ * if pos is -1.
  * That is,
  * (-e_i + c_k_0 - c_j_0, c_k_n - c_j_n, -c_j_x, c_k_x)
+ * or
+ * (c_k_0 - c_j_0, c_k_n - c_j_n, -c_j_x, c_k_x)
  * needs to be plugged in for (c_0, c_n, c_x, c_y),
  * taking into account that each coefficient in c_j_x and c_k_x is represented
  * as a pair of non-negative coefficients.
@@ -3587,21 +3811,39 @@ static isl_stat add_inter_constraints(st
 	ctx = isl_basic_set_get_ctx(coef);
 	offset = coef_var_offset(coef);
 	dim_map = inter_dim_map(ctx, graph, src, dst, offset, 1);
-	isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1);
+	if (pos >= 0)
+		isl_dim_map_range(dim_map, 3 + pos, 0, 0, 0, 1, -1);
 	graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map);
 
 	return isl_stat_ok;
 }
 
+/* Data structure for keeping track of the data needed
+ * to exploit non-trivial lineality spaces.
+ *
+ * "any_non_trivial" is true if there are any non-trivial lineality spaces.
+ * If "any_non_trivial" is not true, then "equivalent" and "mask" may be NULL.
+ * "equivalent" connects instances to other instances on the same line(s).
+ * "mask" contains the domain spaces of "equivalent".
+ * Any instance set not in "mask" does not have a non-trivial lineality space.
+ */
+struct isl_exploit_lineality_data {
+	isl_bool any_non_trivial;
+	isl_union_map *equivalent;
+	isl_union_set *mask;
+};
+
 /* Data structure collecting information used during the construction
  * of an LP for carrying dependences.
  *
  * "intra" is a sequence of coefficient constraints for intra-node edges.
  * "inter" is a sequence of coefficient constraints for inter-node edges.
+ * "lineality" contains data used to exploit non-trivial lineality spaces.
  */
 struct isl_carry {
 	isl_basic_set_list *intra;
 	isl_basic_set_list *inter;
+	struct isl_exploit_lineality_data lineality;
 };
 
 /* Free all the data stored in "carry".
@@ -3610,6 +3852,8 @@ static void isl_carry_clear(struct isl_c
 {
 	isl_basic_set_list_free(carry->intra);
 	isl_basic_set_list_free(carry->inter);
+	isl_union_map_free(carry->lineality.equivalent);
+	isl_union_set_free(carry->lineality.mask);
 }
 
 /* Return a pointer to the node in "graph" that lives in "space".
@@ -3652,11 +3896,13 @@ static struct isl_sched_node *graph_find
  *
  * "graph" is the schedule constraint graph for which an LP problem
  * is being constructed.
+ * "carry_inter" indicates whether inter-node edges should be carried.
  * "pos" is the position of the next edge that needs to be carried.
  */
 struct isl_add_all_constraints_data {
 	isl_ctx *ctx;
 	struct isl_sched_graph *graph;
+	int carry_inter;
 	int pos;
 };
 
@@ -3666,7 +3912,7 @@ struct isl_add_all_constraints_data {
  *
  * The space of "coef" is of the form
  *
- *	coefficients[[c_cst, c_n] -> S[c_x]]
+ *	coefficients[[c_cst] -> S[c_x]]
  *
  * with S[c_x] the (compressed) space of the node.
  * Extract the node from the space and call add_intra_constraints.
@@ -3686,7 +3932,7 @@ static isl_stat lp_add_intra(__isl_take
 
 /* Add the constraints "coef" derived from an edge from a node j
  * to a node k to data->graph->lp in order to respect the dependences and
- * to try and carry them.
+ * to try and carry them (provided data->carry_inter is set).
  *
  * The space of "coef" is of the form
  *
@@ -3700,6 +3946,7 @@ static isl_stat lp_add_inter(__isl_take
 	struct isl_add_all_constraints_data *data = user;
 	isl_space *space, *dom;
 	struct isl_sched_node *src, *dst;
+	int pos;
 
 	space = isl_basic_set_get_space(coef);
 	space = isl_space_unwrap(isl_space_range(isl_space_unwrap(space)));
@@ -3710,19 +3957,22 @@ static isl_stat lp_add_inter(__isl_take
 	dst = graph_find_compressed_node(data->ctx, data->graph, space);
 	isl_space_free(space);
 
-	return add_inter_constraints(data->graph, src, dst, coef, data->pos++);
+	pos = data->carry_inter ? data->pos++ : -1;
+	return add_inter_constraints(data->graph, src, dst, coef, pos);
 }
 
 /* Add constraints to graph->lp that force all (conditional) validity
  * dependences to be respected and attempt to carry them.
  * "intra" is the sequence of coefficient constraints for intra-node edges.
  * "inter" is the sequence of coefficient constraints for inter-node edges.
+ * "carry_inter" indicates whether inter-node edges should be carried or
+ * only respected.
  */
 static isl_stat add_all_constraints(isl_ctx *ctx, struct isl_sched_graph *graph,
 	__isl_keep isl_basic_set_list *intra,
-	__isl_keep isl_basic_set_list *inter)
+	__isl_keep isl_basic_set_list *inter, int carry_inter)
 {
-	struct isl_add_all_constraints_data data = { ctx, graph };
+	struct isl_add_all_constraints_data data = { ctx, graph, carry_inter };
 
 	data.pos = 0;
 	if (isl_basic_set_list_foreach(intra, &lp_add_intra, &data) < 0)
@@ -3747,11 +3997,7 @@ static isl_stat bset_update_count(__isl_
 {
 	struct isl_sched_count *data = user;
 
-	data->n_eq += isl_basic_set_n_equality(bset);
-	data->n_ineq += isl_basic_set_n_inequality(bset);
-	isl_basic_set_free(bset);
-
-	return isl_stat_ok;
+	return update_count(bset, 1, &data->n_eq, &data->n_ineq);
 }
 
 /* Count the number of equality and inequality constraints
@@ -3786,6 +4032,9 @@ static isl_stat count_all_constraints(__
  * "intra" is the sequence of coefficient constraints for intra-node edges.
  * "inter" is the sequence of coefficient constraints for inter-node edges.
  * "n_edge" is the total number of edges.
+ * "carry_inter" indicates whether inter-node edges should be carried or
+ * only respected.  That is, if "carry_inter" is not set, then
+ * no e_i variables are introduced for the inter-node edges.
  *
  * All variables of the LP are non-negative.  The actual coefficients
  * may be negative, so each coefficient is represented as the difference
@@ -3800,16 +4049,16 @@ static isl_stat count_all_constraints(__
  *	- for each edge
  *		- e_i
  *	- for each node
- *		- c_i_0
+ *		- positive and negative parts of c_i_x, in opposite order
  *		- c_i_n (if parametric)
- *		- positive and negative parts of c_i_x
+ *		- c_i_0
  *
  * The constraints are those from the (validity) edges plus three equalities
  * to express the sums and n_edge inequalities to express e_i <= 1.
  */
 static isl_stat setup_carry_lp(isl_ctx *ctx, struct isl_sched_graph *graph,
 	int n_edge, __isl_keep isl_basic_set_list *intra,
-	__isl_keep isl_basic_set_list *inter)
+	__isl_keep isl_basic_set_list *inter, int carry_inter)
 {
 	int i;
 	int k;
@@ -3857,7 +4106,7 @@ static isl_stat setup_carry_lp(isl_ctx *
 		isl_int_set_si(graph->lp->ineq[k][0], 1);
 	}
 
-	if (add_all_constraints(ctx, graph, intra, inter) < 0)
+	if (add_all_constraints(ctx, graph, intra, inter, carry_inter) < 0)
 		return isl_stat_error;
 
 	return isl_stat_ok;
@@ -3867,43 +4116,29 @@ static __isl_give isl_schedule_node *com
 	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph,
 	int wcc);
 
-/* Comparison function for sorting the statements based on
- * the corresponding value in "r".
- */
-static int smaller_value(const void *a, const void *b, void *data)
-{
-	isl_vec *r = data;
-	const int *i1 = a;
-	const int *i2 = b;
-
-	return isl_int_cmp(r->el[*i1], r->el[*i2]);
-}
-
 /* If the schedule_split_scaled option is set and if the linear
  * parts of the scheduling rows for all nodes in the graphs have
- * a non-trivial common divisor, then split off the remainder of the
- * constant term modulo this common divisor from the linear part.
+ * a non-trivial common divisor, then remove this
+ * common divisor from the linear part.
  * Otherwise, insert a band node directly and continue with
  * the construction of the schedule.
  *
  * If a non-trivial common divisor is found, then
- * the linear part is reduced and the remainder is enforced
- * by a sequence node with the children placed in the order
- * of this remainder.
- * In particular, we assign an scc index based on the remainder and
- * then rely on compute_component_schedule to insert the sequence and
- * to continue the schedule construction on each part.
+ * the linear part is reduced and the remainder is ignored.
+ * The pieces of the graph that are assigned different remainders
+ * form (groups of) strongly connected components within
+ * the scaled down band.  If needed, they can therefore
+ * be ordered along this remainder in a sequence node.
+ * However, this ordering is not enforced here in order to allow
+ * the scheduler to combine some of the strongly connected components.
  */
 static __isl_give isl_schedule_node *split_scaled(
 	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph)
 {
 	int i;
 	int row;
-	int scc;
 	isl_ctx *ctx;
 	isl_int gcd, gcd_i;
-	isl_vec *r;
-	int *order;
 
 	if (!node)
 		return NULL;
@@ -3936,16 +4171,9 @@ static __isl_give isl_schedule_node *spl
 		return compute_next_band(node, graph, 0);
 	}
 
-	r = isl_vec_alloc(ctx, graph->n);
-	order = isl_calloc_array(ctx, int, graph->n);
-	if (!r || !order)
-		goto error;
-
 	for (i = 0; i < graph->n; ++i) {
 		struct isl_sched_node *node = &graph->node[i];
 
-		order[i] = i;
-		isl_int_fdiv_r(r->el[i], node->sched->row[row][0], gcd);
 		isl_int_fdiv_q(node->sched->row[row][0],
 			       node->sched->row[row][0], gcd);
 		isl_int_mul(node->sched->row[row][0],
@@ -3955,35 +4183,10 @@ static __isl_give isl_schedule_node *spl
 			goto error;
 	}
 
-	if (isl_sort(order, graph->n, sizeof(order[0]), &smaller_value, r) < 0)
-		goto error;
-
-	scc = 0;
-	for (i = 0; i < graph->n; ++i) {
-		if (i > 0 && isl_int_ne(r->el[order[i - 1]], r->el[order[i]]))
-			++scc;
-		graph->node[order[i]].scc = scc;
-	}
-	graph->scc = ++scc;
-	graph->weak = 0;
-
 	isl_int_clear(gcd);
-	isl_vec_free(r);
-	free(order);
-
-	if (update_edges(ctx, graph) < 0)
-		return isl_schedule_node_free(node);
-	node = insert_current_band(node, graph, 0);
-	next_band(graph);
 
-	node = isl_schedule_node_child(node, 0);
-	node = compute_component_schedule(node, graph, 0);
-	node = isl_schedule_node_parent(node);
-
-	return node;
+	return compute_next_band(node, graph, 0);
 error:
-	isl_vec_free(r);
-	free(order);
 	isl_int_clear(gcd);
 	return isl_schedule_node_free(node);
 }
@@ -3994,12 +4197,12 @@ error:
  * Return 1 if the solution is trivial, 0 if it is not and -1 on error.
  *
  * Each coefficient is represented as the difference between
- * two non-negative values in "sol".  "sol" has been computed
- * in terms of the original iterators (i.e., without use of cmap).
- * We construct the schedule row s and write it as a linear
- * combination of (linear combinations of) previously computed schedule rows.
- * s = Q c or c = U s.
- * If the final entries of c are all zero, then the solution is trivial.
+ * two non-negative values in "sol".
+ * We construct the schedule row s and check if it is linearly
+ * independent of previously computed schedule rows
+ * by computing T s, with T the linear combinations that are zero
+ * on linearly dependent schedule rows.
+ * If the result consists of all zeros, then the solution is trivial.
  */
 static int is_trivial(struct isl_sched_node *node, __isl_keep isl_vec *sol)
 {
@@ -4012,11 +4215,11 @@ static int is_trivial(struct isl_sched_n
 		return 0;
 
 	node_sol = extract_var_coef(node, sol);
-	node_sol = isl_mat_vec_product(isl_mat_copy(node->cinv), node_sol);
+	node_sol = isl_mat_vec_product(isl_mat_copy(node->indep), node_sol);
 	if (!node_sol)
 		return -1;
 
-	trivial = isl_seq_first_non_zero(node_sol->el + node->rank,
+	trivial = isl_seq_first_non_zero(node_sol->el,
 					node->nvar - node->rank) == -1;
 
 	isl_vec_free(node_sol);
@@ -4026,8 +4229,6 @@ static int is_trivial(struct isl_sched_n
 
 /* Is the schedule row "sol" trivial on any node where it should
  * not be trivial?
- * "sol" has been computed in terms of the original iterators
- * (i.e., without use of cmap).
  * Return 1 if any solution is trivial, 0 if they are not and -1 on error.
  */
 static int is_any_trivial(struct isl_sched_graph *graph,
@@ -4054,7 +4255,7 @@ static int is_any_trivial(struct isl_sch
  * Otherwise, return node->nvar or -1 on error.
  *
  * In particular, look for pairs of coefficients c_i and c_j such that
- * |c_j/c_i| >= size_i, i.e., |c_j| >= |c_i * size_i|.
+ * |c_j/c_i| > ceil(size_i/2), i.e., |c_j| > |c_i * ceil(size_i/2)|.
  * If any such pair is found, then return i.
  * If size_i is infinity, then no check on c_i needs to be performed.
  */
@@ -4084,13 +4285,17 @@ static int find_node_coalescing(struct i
 			isl_val_free(v);
 			continue;
 		}
+		v = isl_val_div_ui(v, 2);
+		v = isl_val_ceil(v);
+		if (!v)
+			goto error;
 		isl_int_mul(max, v->n, csol->el[i]);
 		isl_val_free(v);
 
 		for (j = 0; j < node->nvar; ++j) {
 			if (j == i)
 				continue;
-			if (isl_int_abs_ge(csol->el[j], max))
+			if (isl_int_abs_gt(csol->el[j], max))
 				break;
 		}
 		if (j < node->nvar)
@@ -4127,7 +4332,7 @@ static __isl_give isl_tab_lexmin *zero_o
 	if (!eq)
 		return isl_tab_lexmin_free(tl);
 
-	pos = 1 + node_var_coef_offset(node) + 2 * pos;
+	pos = 1 + node_var_coef_pos(node, pos);
 	isl_int_set_si(eq->el[pos], 1);
 	isl_int_set_si(eq->el[pos + 1], -1);
 	tl = isl_tab_lexmin_add_eq(tl, eq->el);
@@ -4328,6 +4533,237 @@ static __isl_give isl_union_map *add_int
 	return umap;
 }
 
+/* Internal data structure used by union_drop_coalescing_constraints
+ * to collect bounds on all relevant statements.
+ *
+ * "graph" is the schedule constraint graph for which an LP problem
+ * is being constructed.
+ * "bounds" collects the bounds.
+ */
+struct isl_collect_bounds_data {
+	isl_ctx *ctx;
+	struct isl_sched_graph *graph;
+	isl_union_set *bounds;
+};
+
+/* Add the size bounds for the node with instance deltas in "set"
+ * to data->bounds.
+ */
+static isl_stat collect_bounds(__isl_take isl_set *set, void *user)
+{
+	struct isl_collect_bounds_data *data = user;
+	struct isl_sched_node *node;
+	isl_space *space;
+	isl_set *bounds;
+
+	space = isl_set_get_space(set);
+	isl_set_free(set);
+
+	node = graph_find_compressed_node(data->ctx, data->graph, space);
+	isl_space_free(space);
+
+	bounds = isl_set_from_basic_set(get_size_bounds(node));
+	data->bounds = isl_union_set_add_set(data->bounds, bounds);
+
+	return isl_stat_ok;
+}
+
+/* Drop some constraints from "delta" that could be exploited
+ * to construct loop coalescing schedules.
+ * In particular, drop those constraint that bound the difference
+ * to the size of the domain.
+ * Do this for each set/node in "delta" separately.
+ * The parameters are assumed to have been projected out by the caller.
+ */
+static __isl_give isl_union_set *union_drop_coalescing_constraints(isl_ctx *ctx,
+	struct isl_sched_graph *graph, __isl_take isl_union_set *delta)
+{
+	struct isl_collect_bounds_data data = { ctx, graph };
+
+	data.bounds = isl_union_set_empty(isl_space_params_alloc(ctx, 0));
+	if (isl_union_set_foreach_set(delta, &collect_bounds, &data) < 0)
+		data.bounds = isl_union_set_free(data.bounds);
+	delta = isl_union_set_plain_gist(delta, data.bounds);
+
+	return delta;
+}
+
+/* Given a non-trivial lineality space "lineality", add the corresponding
+ * universe set to data->mask and add a map from elements to
+ * other elements along the lines in "lineality" to data->equivalent.
+ * If this is the first time this function gets called
+ * (data->any_non_trivial is still false), then set data->any_non_trivial and
+ * initialize data->mask and data->equivalent.
+ *
+ * In particular, if the lineality space is defined by equality constraints
+ *
+ *	E x = 0
+ *
+ * then construct an affine mapping
+ *
+ *	f : x -> E x
+ *
+ * and compute the equivalence relation of having the same image under f:
+ *
+ *	{ x -> x' : E x = E x' }
+ */
+static isl_stat add_non_trivial_lineality(__isl_take isl_basic_set *lineality,
+	struct isl_exploit_lineality_data *data)
+{
+	isl_mat *eq;
+	isl_space *space;
+	isl_set *univ;
+	isl_multi_aff *ma;
+	isl_multi_pw_aff *mpa;
+	isl_map *map;
+	int n;
+
+	if (!lineality)
+		return isl_stat_error;
+	if (isl_basic_set_dim(lineality, isl_dim_div) != 0)
+		isl_die(isl_basic_set_get_ctx(lineality), isl_error_internal,
+			"local variables not allowed", goto error);
+
+	space = isl_basic_set_get_space(lineality);
+	if (!data->any_non_trivial) {
+		data->equivalent = isl_union_map_empty(isl_space_copy(space));
+		data->mask = isl_union_set_empty(isl_space_copy(space));
+	}
+	data->any_non_trivial = isl_bool_true;
+
+	univ = isl_set_universe(isl_space_copy(space));
+	data->mask = isl_union_set_add_set(data->mask, univ);
+
+	eq = isl_basic_set_extract_equalities(lineality);
+	n = isl_mat_rows(eq);
+	eq = isl_mat_insert_zero_rows(eq, 0, 1);
+	eq = isl_mat_set_element_si(eq, 0, 0, 1);
+	space = isl_space_from_domain(space);
+	space = isl_space_add_dims(space, isl_dim_out, n);
+	ma = isl_multi_aff_from_aff_mat(space, eq);
+	mpa = isl_multi_pw_aff_from_multi_aff(ma);
+	map = isl_multi_pw_aff_eq_map(mpa, isl_multi_pw_aff_copy(mpa));
+	data->equivalent = isl_union_map_add_map(data->equivalent, map);
+
+	isl_basic_set_free(lineality);
+	return isl_stat_ok;
+error:
+	isl_basic_set_free(lineality);
+	return isl_stat_error;
+}
+
+/* Check if the lineality space "set" is non-trivial (i.e., is not just
+ * the origin or, in other words, satisfies a number of equality constraints
+ * that is smaller than the dimension of the set).
+ * If so, extend data->mask and data->equivalent accordingly.
+ *
+ * The input should not have any local variables already, but
+ * isl_set_remove_divs is called to make sure it does not.
+ */
+static isl_stat add_lineality(__isl_take isl_set *set, void *user)
+{
+	struct isl_exploit_lineality_data *data = user;
+	isl_basic_set *hull;
+	int dim, n_eq;
+
+	set = isl_set_remove_divs(set);
+	hull = isl_set_unshifted_simple_hull(set);
+	dim = isl_basic_set_dim(hull, isl_dim_set);
+	n_eq = isl_basic_set_n_equality(hull);
+	if (!hull)
+		return isl_stat_error;
+	if (dim != n_eq)
+		return add_non_trivial_lineality(hull, data);
+	isl_basic_set_free(hull);
+	return isl_stat_ok;
+}
+
+/* Check if the difference set on intra-node schedule constraints "intra"
+ * has any non-trivial lineality space.
+ * If so, then extend the difference set to a difference set
+ * on equivalent elements.  That is, if "intra" is
+ *
+ *	{ y - x : (x,y) \in V }
+ *
+ * and elements are equivalent if they have the same image under f,
+ * then return
+ *
+ *	{ y' - x' : (x,y) \in V and f(x) = f(x') and f(y) = f(y') }
+ *
+ * or, since f is linear,
+ *
+ *	{ y' - x' : (x,y) \in V and f(y - x) = f(y' - x') }
+ *
+ * The results of the search for non-trivial lineality spaces is stored
+ * in "data".
+ */
+static __isl_give isl_union_set *exploit_intra_lineality(
+	__isl_take isl_union_set *intra,
+	struct isl_exploit_lineality_data *data)
+{
+	isl_union_set *lineality;
+	isl_union_set *uset;
+
+	data->any_non_trivial = isl_bool_false;
+	lineality = isl_union_set_copy(intra);
+	lineality = isl_union_set_combined_lineality_space(lineality);
+	if (isl_union_set_foreach_set(lineality, &add_lineality, data) < 0)
+		data->any_non_trivial = isl_bool_error;
+	isl_union_set_free(lineality);
+
+	if (data->any_non_trivial < 0)
+		return isl_union_set_free(intra);
+	if (!data->any_non_trivial)
+		return intra;
+
+	uset = isl_union_set_copy(intra);
+	intra = isl_union_set_subtract(intra, isl_union_set_copy(data->mask));
+	uset = isl_union_set_apply(uset, isl_union_map_copy(data->equivalent));
+	intra = isl_union_set_union(intra, uset);
+
+	intra = isl_union_set_remove_divs(intra);
+
+	return intra;
+}
+
+/* If the difference set on intra-node schedule constraints was found to have
+ * any non-trivial lineality space by exploit_intra_lineality,
+ * as recorded in "data", then extend the inter-node
+ * schedule constraints "inter" to schedule constraints on equivalent elements.
+ * That is, if "inter" is V and
+ * elements are equivalent if they have the same image under f, then return
+ *
+ *	{ (x', y') : (x,y) \in V and f(x) = f(x') and f(y) = f(y') }
+ */
+static __isl_give isl_union_map *exploit_inter_lineality(
+	__isl_take isl_union_map *inter,
+	struct isl_exploit_lineality_data *data)
+{
+	isl_union_map *umap;
+
+	if (data->any_non_trivial < 0)
+		return isl_union_map_free(inter);
+	if (!data->any_non_trivial)
+		return inter;
+
+	umap = isl_union_map_copy(inter);
+	inter = isl_union_map_subtract_range(inter,
+				isl_union_set_copy(data->mask));
+	umap = isl_union_map_apply_range(umap,
+				isl_union_map_copy(data->equivalent));
+	inter = isl_union_map_union(inter, umap);
+	umap = isl_union_map_copy(inter);
+	inter = isl_union_map_subtract_domain(inter,
+				isl_union_set_copy(data->mask));
+	umap = isl_union_map_apply_range(isl_union_map_copy(data->equivalent),
+				umap);
+	inter = isl_union_map_union(inter, umap);
+
+	inter = isl_union_map_remove_divs(inter);
+
+	return inter;
+}
+
 /* For each (conditional) validity edge in "graph",
  * add the corresponding dependence relation using "add"
  * to a collection of dependence relations and return the result.
@@ -4357,6 +4793,17 @@ static __isl_give isl_union_map *collect
 	return umap;
 }
 
+/* Project out all parameters from "uset" and return the result.
+ */
+static __isl_give isl_union_set *union_set_drop_parameters(
+	__isl_take isl_union_set *uset)
+{
+	unsigned nparam;
+
+	nparam = isl_union_set_dim(uset, isl_dim_param);
+	return isl_union_set_project_out(uset, isl_dim_param, 0, nparam);
+}
+
 /* For each dependence relation on a (conditional) validity edge
  * from a node to itself,
  * construct the set of coefficients of valid constraints for elements
@@ -4364,13 +4811,24 @@ static __isl_give isl_union_map *collect
  * If "coincidence" is set, then coincidence edges are considered as well.
  *
  * In particular, for each dependence relation R, constraints
- * on coefficients (c_0, c_n, c_x) are constructed such that
+ * on coefficients (c_0, c_x) are constructed such that
  *
- *	c_0 + c_n n + c_x d >= 0 for each d in delta R = { y - x | (x,y) in R }
+ *	c_0 + c_x d >= 0 for each d in delta R = { y - x | (x,y) in R }
  *
- * This computation is essentially the same as that performed
+ * If the schedule_treat_coalescing option is set, then some constraints
+ * that could be exploited to construct coalescing schedules
+ * are removed before the dual is computed, but after the parameters
+ * have been projected out.
+ * The entire computation is essentially the same as that performed
  * by intra_coefficients, except that it operates on multiple
- * edges together.
+ * edges together and that the parameters are always projected out.
+ *
+ * Additionally, exploit any non-trivial lineality space
+ * in the difference set after removing coalescing constraints and
+ * store the results of the non-trivial lineality space detection in "data".
+ * The procedure is currently run unconditionally, but it is unlikely
+ * to find any non-trivial lineality spaces if no coalescing constraints
+ * have been removed.
  *
  * Note that if a dependence relation is a union of basic maps,
  * then each basic map needs to be treated individually as it may only
@@ -4382,8 +4840,9 @@ static __isl_give isl_union_map *collect
  * In particular, if the same basic map appears as a disjunct
  * in multiple edges, then it only needs to be carried once.
  */
-static __isl_give isl_basic_set_list *collect_intra_validity(
-	struct isl_sched_graph *graph, int coincidence)
+static __isl_give isl_basic_set_list *collect_intra_validity(isl_ctx *ctx,
+	struct isl_sched_graph *graph, int coincidence,
+	struct isl_exploit_lineality_data *data)
 {
 	isl_union_map *intra;
 	isl_union_set *delta;
@@ -4391,7 +4850,11 @@ static __isl_give isl_basic_set_list *co
 
 	intra = collect_validity(graph, &add_intra, coincidence);
 	delta = isl_union_map_deltas(intra);
+	delta = union_set_drop_parameters(delta);
 	delta = isl_union_set_remove_divs(delta);
+	if (isl_options_get_schedule_treat_coalescing(ctx))
+		delta = union_drop_coalescing_constraints(ctx, graph, delta);
+	delta = exploit_intra_lineality(delta, data);
 	list = isl_union_set_get_basic_set_list(delta);
 	isl_union_set_free(delta);
 
@@ -4413,6 +4876,10 @@ static __isl_give isl_basic_set_list *co
  * by inter_coefficients, except that it operates on multiple
  * edges together.
  *
+ * Additionally, exploit any non-trivial lineality space
+ * that may have been discovered by collect_intra_validity
+ * (as stored in "data").
+ *
  * Note that if a dependence relation is a union of basic maps,
  * then each basic map needs to be treated individually as it may only
  * be possible to carry the dependences expressed by some of those
@@ -4424,13 +4891,15 @@ static __isl_give isl_basic_set_list *co
  * in multiple edges, then it only needs to be carried once.
  */
 static __isl_give isl_basic_set_list *collect_inter_validity(
-	struct isl_sched_graph *graph, int coincidence)
+	struct isl_sched_graph *graph, int coincidence,
+	struct isl_exploit_lineality_data *data)
 {
 	isl_union_map *inter;
 	isl_union_set *wrap;
 	isl_basic_set_list *list;
 
 	inter = collect_validity(graph, &add_inter, coincidence);
+	inter = exploit_inter_lineality(inter, data);
 	inter = isl_union_map_remove_divs(inter);
 	wrap = isl_union_map_wrap(inter);
 	list = isl_union_set_get_basic_set_list(wrap);
@@ -4439,6 +4908,36 @@ static __isl_give isl_basic_set_list *co
 }
 
 /* Construct an LP problem for finding schedule coefficients
+ * such that the schedule carries as many of the "n_edge" groups of
+ * dependences as possible based on the corresponding coefficient
+ * constraints and return the lexicographically smallest non-trivial solution.
+ * "intra" is the sequence of coefficient constraints for intra-node edges.
+ * "inter" is the sequence of coefficient constraints for inter-node edges.
+ * If "want_integral" is set, then compute an integral solution
+ * for the coefficients rather than using the numerators
+ * of a rational solution.
+ * "carry_inter" indicates whether inter-node edges should be carried or
+ * only respected.
+ *
+ * If none of the "n_edge" groups can be carried
+ * then return an empty vector.
+ */
+static __isl_give isl_vec *compute_carrying_sol_coef(isl_ctx *ctx,
+	struct isl_sched_graph *graph, int n_edge,
+	__isl_keep isl_basic_set_list *intra,
+	__isl_keep isl_basic_set_list *inter, int want_integral,
+	int carry_inter)
+{
+	isl_basic_set *lp;
+
+	if (setup_carry_lp(ctx, graph, n_edge, intra, inter, carry_inter) < 0)
+		return NULL;
+
+	lp = isl_basic_set_copy(graph->lp);
+	return non_neg_lexmin(graph, lp, n_edge, want_integral);
+}
+
+/* Construct an LP problem for finding schedule coefficients
  * such that the schedule carries as many of the validity dependences
  * as possible and
  * return the lexicographically smallest non-trivial solution.
@@ -4455,33 +4954,51 @@ static __isl_give isl_basic_set_list *co
  * If a fallback solution is being computed, then compute an integral solution
  * for the coefficients rather than using the numerators
  * of a rational solution.
+ *
+ * If a fallback solution is being computed, if there are any intra-node
+ * dependences, and if requested by the user, then first try
+ * to only carry those intra-node dependences.
+ * If this fails to carry any dependences, then try again
+ * with the inter-node dependences included.
  */
 static __isl_give isl_vec *compute_carrying_sol(isl_ctx *ctx,
 	struct isl_sched_graph *graph, int fallback, int coincidence)
 {
 	int n_intra, n_inter;
 	int n_edge;
-	isl_basic_set *lp;
 	struct isl_carry carry = { 0 };
+	isl_vec *sol;
 
-	carry.intra = collect_intra_validity(graph, coincidence);
-	carry.inter = collect_inter_validity(graph, coincidence);
+	carry.intra = collect_intra_validity(ctx, graph, coincidence,
+						&carry.lineality);
+	carry.inter = collect_inter_validity(graph, coincidence,
+						&carry.lineality);
 	if (!carry.intra || !carry.inter)
 		goto error;
 	n_intra = isl_basic_set_list_n_basic_set(carry.intra);
 	n_inter = isl_basic_set_list_n_basic_set(carry.inter);
+
+	if (fallback && n_intra > 0 &&
+	    isl_options_get_schedule_carry_self_first(ctx)) {
+		sol = compute_carrying_sol_coef(ctx, graph, n_intra,
+				carry.intra, carry.inter, fallback, 0);
+		if (!sol || sol->size != 0 || n_inter == 0) {
+			isl_carry_clear(&carry);
+			return sol;
+		}
+		isl_vec_free(sol);
+	}
+
 	n_edge = n_intra + n_inter;
 	if (n_edge == 0) {
 		isl_carry_clear(&carry);
 		return isl_vec_alloc(ctx, 0);
 	}
 
-	if (setup_carry_lp(ctx, graph, n_edge, carry.intra, carry.inter) < 0)
-		goto error;
-
+	sol = compute_carrying_sol_coef(ctx, graph, n_edge,
+				carry.intra, carry.inter, fallback, 1);
 	isl_carry_clear(&carry);
-	lp = isl_basic_set_copy(graph->lp);
-	return non_neg_lexmin(graph, lp, n_edge, fallback);
+	return sol;
 error:
 	isl_carry_clear(&carry);
 	return NULL;
@@ -4548,7 +5065,7 @@ static __isl_give isl_schedule_node *car
 		return compute_component_schedule(node, graph, 1);
 	}
 
-	if (update_schedule(graph, sol, 0, 0) < 0)
+	if (update_schedule(graph, sol, 0) < 0)
 		return isl_schedule_node_free(node);
 	if (trivial)
 		graph->n_row--;
@@ -4909,6 +5426,7 @@ error:
  *	pair of SCCs between which to split)
  * - continue with the next band (assuming the current band has at least
  *	one row)
+ * - if there is more than one SCC left, then split along all SCCs
  * - if outer coincidence needs to be enforced, then try to carry as many
  *	validity or coincidence dependences as possible and
  *	continue with the next band
@@ -4941,6 +5459,8 @@ static __isl_give isl_schedule_node *com
 			return compute_split_schedule(node, graph);
 		if (!empty)
 			return compute_next_band(node, graph, 1);
+		if (graph->scc > 1)
+			return compute_component_schedule(node, graph, 1);
 		if (!initialized && compute_maxvar(graph) < 0)
 			return isl_schedule_node_free(node);
 		if (isl_options_get_schedule_outer_coincidence(ctx))
@@ -5021,7 +5541,7 @@ static isl_stat compute_schedule_wcc_ban
 
 		if (setup_lp(ctx, graph, use_coincidence) < 0)
 			return isl_stat_error;
-		sol = solve_lp(graph);
+		sol = solve_lp(ctx, graph);
 		if (!sol)
 			return isl_stat_error;
 		if (sol->size == 0) {
@@ -5035,7 +5555,7 @@ static isl_stat compute_schedule_wcc_ban
 			return isl_stat_ok;
 		}
 		coincident = !has_coincidence || use_coincidence;
-		if (update_schedule(graph, sol, 1, coincident) < 0)
+		if (update_schedule(graph, sol, coincident) < 0)
 			return isl_stat_error;
 
 		if (!check_conditional)
@@ -5637,7 +6157,7 @@ static int compute_maxvar_max_slack(int
 			struct isl_sched_node *node = &scc->node[j];
 			int slack;
 
-			if (node_update_cmap(node) < 0)
+			if (node_update_vmap(node) < 0)
 				return -1;
 			slack = node->nvar - node->rank;
 			if (slack > max_slack)
@@ -5677,7 +6197,7 @@ static int limit_maxvar_to_slack(int max
 			struct isl_sched_node *node = &scc->node[j];
 			int slack;
 
-			if (node_update_cmap(node) < 0)
+			if (node_update_vmap(node) < 0)
 				return -1;
 			slack = node->nvar - node->rank;
 			if (slack > max_slack) {
@@ -6469,9 +6989,9 @@ static isl_stat compute_weights(struct i
 
 		hull = isl_map_affine_hull(isl_map_copy(edge->map));
 		hull = isl_basic_map_transform_dims(hull, isl_dim_in, 0,
-						    isl_mat_copy(src->ctrans));
+						    isl_mat_copy(src->vmap));
 		hull = isl_basic_map_transform_dims(hull, isl_dim_out, 0,
-						    isl_mat_copy(dst->ctrans));
+						    isl_mat_copy(dst->vmap));
 		hull = isl_basic_map_project_out(hull,
 						isl_dim_in, 0, src->rank);
 		hull = isl_basic_map_project_out(hull,

Modified: polly/trunk/lib/External/isl/isl_tab.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_tab.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_tab.h (original)
+++ polly/trunk/lib/External/isl/isl_tab.h Tue Jul  4 08:54:11 2017
@@ -260,17 +260,19 @@ __isl_give isl_pw_multi_aff *isl_tab_bas
 	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
 	__isl_give isl_set **empty, unsigned flags);
 
-/* An isl_region represents a sequence of consecutive variables.
+/* An isl_trivial_region represents a non-triviality region.
+ * The region is trivial if applying "trivial" to a given sequence
+ * of variables results in a zero vector.
  * pos is the location (starting at 0) of the first variable in the sequence.
  */
-struct isl_region {
+struct isl_trivial_region {
 	int pos;
-	int len;
+	isl_mat *trivial;
 };
 
 __isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin(
 	__isl_take isl_basic_set *bset, int n_op, int n_region,
-	struct isl_region *region,
+	struct isl_trivial_region *region,
 	int (*conflict)(int con, void *user), void *user);
 
 struct isl_tab_lexmin;

Modified: polly/trunk/lib/External/isl/isl_tab_pip.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_tab_pip.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_tab_pip.c (original)
+++ polly/trunk/lib/External/isl/isl_tab_pip.c Tue Jul  4 08:54:11 2017
@@ -1,7 +1,7 @@
 /*
  * Copyright 2008-2009 Katholieke Universiteit Leuven
  * Copyright 2010      INRIA Saclay
- * Copyright 2016      Sven Verdoolaege
+ * Copyright 2016-2017 Sven Verdoolaege
  *
  * Use of this software is governed by the MIT license
  *
@@ -5037,60 +5037,81 @@ error:
 	return isl_stat_error;
 }
 
-/* Check if the given sequence of len variables starting at pos
- * represents a trivial (i.e., zero) solution.
- * The variables are assumed to be non-negative and to come in pairs,
- * with each pair representing a variable of unrestricted sign.
- * The solution is trivial if each such pair in the sequence consists
- * of two identical values, meaning that the variable being represented
- * has value zero.
+/* Extract the subsequence of the sample value of "tab"
+ * starting at "pos" and of length "len".
  */
-static int region_is_trivial(struct isl_tab *tab, int pos, int len)
+static __isl_give isl_vec *extract_sample_sequence(struct isl_tab *tab,
+	int pos, int len)
 {
 	int i;
+	isl_ctx *ctx;
+	isl_vec *v;
 
-	if (len == 0)
-		return 0;
-
-	for (i = 0; i < len; i +=  2) {
-		int neg_row;
-		int pos_row;
-
-		neg_row = tab->var[pos + i].is_row ?
-				tab->var[pos + i].index : -1;
-		pos_row = tab->var[pos + i + 1].is_row ?
-				tab->var[pos + i + 1].index : -1;
-
-		if ((neg_row < 0 ||
-		     isl_int_is_zero(tab->mat->row[neg_row][1])) &&
-		    (pos_row < 0 ||
-		     isl_int_is_zero(tab->mat->row[pos_row][1])))
-			continue;
+	ctx = isl_tab_get_ctx(tab);
+	v = isl_vec_alloc(ctx, len);
+	if (!v)
+		return NULL;
+	for (i = 0; i < len; ++i) {
+		if (!tab->var[pos + i].is_row) {
+			isl_int_set_si(v->el[i], 0);
+		} else {
+			int row;
 
-		if (neg_row < 0 || pos_row < 0)
-			return 0;
-		if (isl_int_ne(tab->mat->row[neg_row][1],
-			       tab->mat->row[pos_row][1]))
-			return 0;
+			row = tab->var[pos + i].index;
+			isl_int_set(v->el[i], tab->mat->row[row][1]);
+		}
 	}
 
-	return 1;
+	return v;
+}
+
+/* Check if the sequence of variables starting at "pos"
+ * represents a trivial solution according to "trivial".
+ * That is, is the result of applying "trivial" to this sequence
+ * equal to the zero vector?
+ */
+static isl_bool region_is_trivial(struct isl_tab *tab, int pos,
+	__isl_keep isl_mat *trivial)
+{
+	int n, len;
+	isl_vec *v;
+	isl_bool is_trivial;
+
+	if (!trivial)
+		return isl_bool_error;
+
+	n = isl_mat_rows(trivial);
+	if (n == 0)
+		return isl_bool_false;
+
+	len = isl_mat_cols(trivial);
+	v = extract_sample_sequence(tab, pos, len);
+	v = isl_mat_vec_product(isl_mat_copy(trivial), v);
+	is_trivial = isl_vec_is_zero(v);
+	isl_vec_free(v);
+
+	return is_trivial;
 }
 
-/* Return the index of the first trivial region or -1 if all regions
- * are non-trivial.
+/* Return the index of the first trivial region, "n_region" if all regions
+ * are non-trivial or -1 in case of error.
  */
 static int first_trivial_region(struct isl_tab *tab,
-	int n_region, struct isl_region *region)
+	int n_region, struct isl_trivial_region *region)
 {
 	int i;
 
 	for (i = 0; i < n_region; ++i) {
-		if (region_is_trivial(tab, region[i].pos, region[i].len))
+		isl_bool trivial;
+		trivial = region_is_trivial(tab, region[i].pos,
+					region[i].trivial);
+		if (trivial < 0)
+			return -1;
+		if (trivial)
 			return i;
 	}
 
-	return -1;
+	return n_region;
 }
 
 /* Check if the solution is optimal, i.e., whether the first
@@ -5160,17 +5181,86 @@ error:
 	return -1;
 }
 
+/* Global internal data for isl_tab_basic_set_non_trivial_lexmin.
+ *
+ * "v" is a pre-allocated vector that can be used for adding
+ * constraints to the tableau.
+ */
+struct isl_trivial_global {
+	isl_vec *v;
+};
+
+/* Fix triviality direction "dir" of the given region to zero.
+ *
+ * This function assumes that at least two more rows and at least
+ * two more elements in the constraint array are available in the tableau.
+ */
+static isl_stat fix_zero(struct isl_tab *tab, struct isl_trivial_region *region,
+	int dir, struct isl_trivial_global *data)
+{
+	int len;
+
+	data->v = isl_vec_clr(data->v);
+	if (!data->v)
+		return isl_stat_error;
+	len = isl_mat_cols(region->trivial);
+	isl_seq_cpy(data->v->el + 1 + region->pos, region->trivial->row[dir],
+		    len);
+	if (add_lexmin_eq(tab, data->v->el) < 0)
+		return isl_stat_error;
+
+	return isl_stat_ok;
+}
+
+/* This function selects case "side" for non-triviality region "region",
+ * assuming all the equality constraints have been imposed already.
+ * In particular, the triviality direction side/2 is made positive
+ * if side is even and made negative if side is odd.
+ *
+ * This function assumes that at least one more row and at least
+ * one more element in the constraint array are available in the tableau.
+ */
+static struct isl_tab *pos_neg(struct isl_tab *tab,
+	struct isl_trivial_region *region,
+	int side, struct isl_trivial_global *data)
+{
+	int len;
+
+	data->v = isl_vec_clr(data->v);
+	if (!data->v)
+		goto error;
+	isl_int_set_si(data->v->el[0], -1);
+	len = isl_mat_cols(region->trivial);
+	if (side % 2 == 0)
+		isl_seq_cpy(data->v->el + 1 + region->pos,
+			    region->trivial->row[side / 2], len);
+	else
+		isl_seq_neg(data->v->el + 1 + region->pos,
+			    region->trivial->row[side / 2], len);
+	return add_lexmin_ineq(tab, data->v->el);
+error:
+	isl_tab_free(tab);
+	return NULL;
+}
+
 /* Local data at each level of the backtracking procedure of
  * isl_tab_basic_set_non_trivial_lexmin.
  *
+ * "update" is set if a solution has been found in the current case
+ * of this level, such that a better solution needs to be enforced
+ * in the next case.
  * "n_zero" is the number of initial coordinates that have already
  * been forced to be zero at this level.
+ * "region" is the non-triviality region considered at this level.
+ * "side" is the index of the current case at this level.
+ * "n" is the number of triviality directions.
  */
 struct isl_trivial {
 	int update;
 	int n_zero;
 	int region;
 	int side;
+	int n;
 	struct isl_tab_undo *snap;
 };
 
@@ -5186,10 +5276,11 @@ struct isl_trivial {
  * that increase the number of initial zeros in this sequence.
  *
  * A solution is non-trivial, if it is non-trivial on each of the
- * specified regions.  Each region represents a sequence of pairs
- * of variables.  A solution is non-trivial on such a region if
- * at least one of these pairs consists of different values, i.e.,
- * such that the non-negative variable represented by the pair is non-zero.
+ * specified regions.  Each region represents a sequence of
+ * triviality directions on a sequence of variables that starts
+ * at a given position.  A solution is non-trivial on such a region if
+ * at least one of the triviality directions is non-zero
+ * on that sequence of variables.
  *
  * Whenever a conflict is encountered, all constraints involved are
  * reported to the caller through a call to "conflict".
@@ -5197,30 +5288,27 @@ struct isl_trivial {
  * We perform a simple branch-and-bound backtracking search.
  * Each level in the search represents an initially trivial region
  * that is forced to be non-trivial.
- * At each level we consider n cases, where n is the length of the region.
- * In terms of the n/2 variables of unrestricted signs being encoded by
- * the region, we consider the cases
- *	x_0 >= 1
- *	x_0 <= -1
- *	x_0 = 0 and x_1 >= 1
- *	x_0 = 0 and x_1 <= -1
- *	x_0 = 0 and x_1 = 0 and x_2 >= 1
- *	x_0 = 0 and x_1 = 0 and x_2 <= -1
+ * At each level we consider 2 * n cases, where n
+ * is the number of triviality directions.
+ * In terms of those n directions v_i, we consider the cases
+ *	v_0 >= 1
+ *	v_0 <= -1
+ *	v_0 = 0 and v_1 >= 1
+ *	v_0 = 0 and v_1 <= -1
+ *	v_0 = 0 and v_1 = 0 and v_2 >= 1
+ *	v_0 = 0 and v_1 = 0 and v_2 <= -1
  *	...
- * The cases are considered in this order, assuming that each pair
- * x_i_a x_i_b represents the value x_i_b - x_i_a.
- * That is, x_0 >= 1 is enforced by adding the constraint
- *	x_0_b - x_0_a >= 1
+ * in this order.
  */
 __isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin(
 	__isl_take isl_basic_set *bset, int n_op, int n_region,
-	struct isl_region *region,
+	struct isl_trivial_region *region,
 	int (*conflict)(int con, void *user), void *user)
 {
-	int i, j;
+	struct isl_trivial_global data = { 0 };
+	int i;
 	int r;
 	isl_ctx *ctx;
-	isl_vec *v = NULL;
 	isl_vec *sol = NULL;
 	struct isl_tab *tab;
 	struct isl_trivial *triv = NULL;
@@ -5238,9 +5326,9 @@ __isl_give isl_vec *isl_tab_basic_set_no
 	tab->conflict = conflict;
 	tab->conflict_user = user;
 
-	v = isl_vec_alloc(ctx, 1 + tab->n_var);
+	data.v = isl_vec_alloc(ctx, 1 + tab->n_var);
 	triv = isl_calloc_array(ctx, struct isl_trivial, n_region);
-	if (!v || (n_region && !triv))
+	if (!data.v || (n_region && !triv))
 		goto error;
 
 	level = 0;
@@ -5256,7 +5344,9 @@ __isl_give isl_vec *isl_tab_basic_set_no
 			if (tab->empty)
 				goto backtrack;
 			r = first_trivial_region(tab, n_region, region);
-			if (r < 0) {
+			if (r < 0)
+				goto error;
+			if (r == n_region) {
 				for (i = 0; i < level; ++i)
 					triv[i].update = 1;
 				isl_vec_free(sol);
@@ -5270,8 +5360,9 @@ __isl_give isl_vec *isl_tab_basic_set_no
 			if (level >= n_region)
 				isl_die(ctx, isl_error_internal,
 					"nesting level too deep", goto error);
+			triv[level].n = isl_mat_rows(region[r].trivial);
 			if (isl_tab_extend_cons(tab,
-					    2 * region[r].len + 2 * n_op) < 0)
+					    2 * triv[level].n + 2 * n_op) < 0)
 				goto error;
 			triv[level].region = r;
 			triv[level].side = 0;
@@ -5283,7 +5374,7 @@ __isl_give isl_vec *isl_tab_basic_set_no
 		side = triv[level].side;
 		base = 2 * (side/2);
 
-		if (side >= region[r].len) {
+		if (side >= 2 * triv[level].n) {
 backtrack:
 			level--;
 			init = 0;
@@ -5301,24 +5392,17 @@ backtrack:
 			triv[level].update = 0;
 		}
 
-		if (side == base && base >= 2) {
-			for (j = base - 2; j < base; ++j) {
-				v = isl_vec_clr(v);
-				isl_int_set_si(v->el[1 + region[r].pos + j], 1);
-				if (add_lexmin_eq(tab, v->el) < 0)
-					goto error;
-			}
-		}
+		if (side == base && base >= 2 &&
+		    fix_zero(tab, &region[r], base / 2 - 1, &data) < 0)
+			goto error;
 
 		triv[level].snap = isl_tab_snap(tab);
 		if (isl_tab_push_basis(tab) < 0)
 			goto error;
 
-		v = isl_vec_clr(v);
-		isl_int_set_si(v->el[0], -1);
-		isl_int_set_si(v->el[1 + region[r].pos + side], -1);
-		isl_int_set_si(v->el[1 + region[r].pos + (side ^ 1)], 1);
-		tab = add_lexmin_ineq(tab, v->el);
+		tab = pos_neg(tab, &region[r], side, &data);
+		if (!tab)
+			goto error;
 
 		triv[level].side++;
 		level++;
@@ -5326,14 +5410,14 @@ backtrack:
 	}
 
 	free(triv);
-	isl_vec_free(v);
+	isl_vec_free(data.v);
 	isl_tab_free(tab);
 	isl_basic_set_free(bset);
 
 	return sol;
 error:
 	free(triv);
-	isl_vec_free(v);
+	isl_vec_free(data.v);
 	isl_tab_free(tab);
 	isl_basic_set_free(bset);
 	isl_vec_free(sol);

Modified: polly/trunk/lib/External/isl/isl_test.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_test.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_test.c (original)
+++ polly/trunk/lib/External/isl/isl_test.c Tue Jul  4 08:54:11 2017
@@ -327,7 +327,7 @@ static int test_bounded(isl_ctx *ctx)
 }
 
 /* Construct the basic set { [i] : 5 <= i <= N } */
-static int test_construction(isl_ctx *ctx)
+static int test_construction_1(isl_ctx *ctx)
 {
 	isl_int v;
 	isl_space *dim;
@@ -363,6 +363,49 @@ static int test_construction(isl_ctx *ct
 	return 0;
 }
 
+/* Construct the basic set { [x] : -100 <= x <= 100 }
+ * using isl_basic_set_{lower,upper}_bound_val and
+ * check that it is equal the same basic set parsed from a string.
+ */
+static int test_construction_2(isl_ctx *ctx)
+{
+	isl_bool equal;
+	isl_val *v;
+	isl_space *space;
+	isl_basic_set *bset1, *bset2;
+
+	v = isl_val_int_from_si(ctx, 100);
+	space = isl_space_set_alloc(ctx, 0, 1);
+	bset1 = isl_basic_set_universe(space);
+	bset1 = isl_basic_set_upper_bound_val(bset1, isl_dim_set, 0,
+						isl_val_copy(v));
+	bset1 = isl_basic_set_lower_bound_val(bset1, isl_dim_set, 0,
+						isl_val_neg(v));
+	bset2 = isl_basic_set_read_from_str(ctx, "{ [x] : -100 <= x <= 100 }");
+	equal = isl_basic_set_is_equal(bset1, bset2);
+	isl_basic_set_free(bset1);
+	isl_basic_set_free(bset2);
+
+	if (equal < 0)
+		return -1;
+	if (!equal)
+		isl_die(ctx, isl_error_unknown,
+			"failed construction", return -1);
+
+	return 0;
+}
+
+/* Basic tests for constructing basic sets.
+ */
+static int test_construction(isl_ctx *ctx)
+{
+	if (test_construction_1(ctx) < 0)
+		return -1;
+	if (test_construction_2(ctx) < 0)
+		return -1;
+	return 0;
+}
+
 static int test_dim(isl_ctx *ctx)
 {
 	const char *str;
@@ -4015,6 +4058,56 @@ static int test_bounded_coefficients_sch
 	return 0;
 }
 
+/* Check that the bounds on the coefficients are respected.
+ * This function checks for a particular output schedule,
+ * but the exact output is not important, only that it does
+ * not contain any coefficients greater than 4.
+ * It is, however, easier to check for a particular output.
+ * This test is only run for the whole component scheduler
+ * because the incremental scheduler produces a slightly different schedule.
+ */
+static int test_bounded_coefficients_schedule_whole(isl_ctx *ctx)
+{
+	const char *domain, *dep, *str;
+	isl_union_set *I;
+	isl_union_map *D;
+	isl_schedule_constraints *sc;
+	isl_schedule *schedule;
+	isl_union_map *sched1, *sched2;
+	isl_bool equal;
+
+	domain = "{ S_4[i, j, k] : 0 <= i < j <= 10 and 0 <= k <= 100; "
+	    "S_2[i, j] : 0 <= i < j <= 10; S_6[i, j] : 0 <= i < j <= 10 }";
+	dep = "{ S_2[0, j] -> S_4[0, j, 0] : 0 < j <= 10; "
+	    "S_4[0, j, 100] -> S_6[0, j] : 0 < j <= 10 }";
+	I = isl_union_set_read_from_str(ctx, domain);
+	D = isl_union_map_read_from_str(ctx, dep);
+	sc = isl_schedule_constraints_on_domain(I);
+	sc = isl_schedule_constraints_set_validity(sc, D);
+	isl_options_set_schedule_max_constant_term(ctx, 10);
+	isl_options_set_schedule_max_coefficient(ctx, 4);
+	schedule = isl_schedule_constraints_compute_schedule(sc);
+	isl_options_set_schedule_max_coefficient(ctx, -1);
+	isl_options_set_schedule_max_constant_term(ctx, -1);
+	sched1 = isl_schedule_get_map(schedule);
+	isl_schedule_free(schedule);
+
+	str = "{ S_4[i, j, k] -> [i, j, 10 - k, 1]; "
+	    "S_2[i, j] -> [0, i, j, 0]; S_6[i, j] -> [0, 10 + i, j, 2] }";
+	sched2 = isl_union_map_read_from_str(ctx, str);
+	equal = isl_union_map_is_equal(sched1, sched2);
+	isl_union_map_free(sched1);
+	isl_union_map_free(sched2);
+
+	if (equal < 0)
+		return -1;
+	if (!equal)
+		isl_die(ctx, isl_error_unknown,
+			"unexpected schedule", return -1);
+
+	return 0;
+}
+
 /* Check that a set of schedule constraints that only allow for
  * a coalescing schedule still produces a schedule even if the user
  * request a non-coalescing schedule.  Earlier versions of isl
@@ -4045,6 +4138,28 @@ static int test_coalescing_schedule(isl_
 	return 0;
 }
 
+/* Check that the scheduler does not perform any needless
+ * compound skewing.  Earlier versions of isl would compute
+ * schedules in terms of transformed schedule coefficients and
+ * would not accurately keep track of the sum of the original
+ * schedule coefficients.  It could then produce the schedule
+ * S[t,i,j,k] -> [t, 2t + i, 2t + i + j, 2t + i + j + k]
+ * for the input below instead of the schedule below.
+ */
+static int test_skewing_schedule(isl_ctx *ctx)
+{
+	const char *D, *V, *P, *S;
+
+	D = "[n] -> { S[t,i,j,k] : 0 <= t,i,j,k < n }";
+	V = "[n] -> { S[t,i,j,k] -> S[t+1,a,b,c] : 0 <= t,i,j,k,a,b,c < n and "
+		"-2 <= a-i <= 2 and -1 <= a-i + b-j <= 1 and "
+		"-1 <= a-i + b-j + c-k <= 1 }";
+	P = "{ }";
+	S = "{ S[t,i,j,k] -> [t, 2t + i, t + i + j, 2t + k] }";
+
+	return test_special_schedule(ctx, D, V, P, S);
+}
+
 int test_schedule(isl_ctx *ctx)
 {
 	const char *D, *W, *R, *V, *P, *S;
@@ -4259,13 +4374,10 @@ int test_schedule(isl_ctx *ctx)
 		"i0 >= 0 and i0 <= 1 and i1 >= 0 and o2 >= -i1 + i2 and "
 		"o2 >= 1 and o2 <= 6 - i1 and i2 >= 1 + i1 }";
 	P = V;
-	S = "{ Stmt_for_body24[i0, i1, i2, i3] -> "
-		"[i0, 5i0 + i1, 6i0 + i1 + i2, 1 + 6i0 + i1 + i2 + i3, 1];"
-	    "Stmt_for_body7[i0, i1, i2] -> [0, 5i0, 6i0 + i1, 6i0 + i2, 0] }";
 
 	treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx);
 	isl_options_set_schedule_treat_coalescing(ctx, 0);
-	if (test_special_schedule(ctx, D, V, P, S) < 0)
+	if (test_has_schedule(ctx, D, V, P) < 0)
 		return -1;
 	isl_options_set_schedule_treat_coalescing(ctx, treat_coalescing);
 
@@ -4275,7 +4387,7 @@ int test_schedule(isl_ctx *ctx)
 		"S_0[i, j] -> S_0[1 + i, j] : i >= 1 and i <= 9 and "
 					     "j >= 1 and j <= 8 }";
 	P = "{ }";
-	S = "{ S_0[i, j] -> [i + j, j] }";
+	S = "{ S_0[i, j] -> [i + j, i] }";
 	ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER;
 	if (test_special_schedule(ctx, D, V, P, S) < 0)
 		return -1;
@@ -4355,6 +4467,8 @@ int test_schedule(isl_ctx *ctx)
 		return -1;
 	if (test_coalescing_schedule(ctx) < 0)
 		return -1;
+	if (test_skewing_schedule(ctx) < 0)
+		return -1;
 
 	return 0;
 }
@@ -4369,6 +4483,8 @@ static int test_schedule_whole(isl_ctx *
 	whole = isl_options_get_schedule_whole_component(ctx);
 	isl_options_set_schedule_whole_component(ctx, 1);
 	r = test_schedule(ctx);
+	if (r >= 0)
+		r = test_bounded_coefficients_schedule_whole(ctx);
 	isl_options_set_schedule_whole_component(ctx, whole);
 
 	return r;

Modified: polly/trunk/lib/External/isl/isl_test_int.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_test_int.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_test_int.c (original)
+++ polly/trunk/lib/External/isl/isl_test_int.c Tue Jul  4 08:54:11 2017
@@ -261,6 +261,9 @@ static void int_test_divexact(isl_int ex
 
 		isl_int_fdiv_q_ui(result, lhs, rhsulong);
 		assert(isl_int_eq(expected, result));
+
+		isl_int_cdiv_q_ui(result, lhs, rhsulong);
+		assert(isl_int_eq(expected, result));
 	}
 
 	isl_int_clear(result);
@@ -358,12 +361,20 @@ static void int_test_fdiv(isl_int expect
 
 static void int_test_cdiv(isl_int expected, isl_int lhs, isl_int rhs)
 {
+	unsigned long rhsulong;
 	isl_int result;
 	isl_int_init(result);
 
 	isl_int_cdiv_q(result, lhs, rhs);
 	assert(isl_int_eq(expected, result));
 
+	if (isl_int_fits_ulong(rhs)) {
+		rhsulong = isl_int_get_ui(rhs);
+
+		isl_int_cdiv_q_ui(result, lhs, rhsulong);
+		assert(isl_int_eq(expected, result));
+	}
+
 	isl_int_clear(result);
 }
 
@@ -561,6 +572,11 @@ struct {
 	{ &int_test_cdiv, "0", "1", "-2" },
 	{ &int_test_cdiv, "1", "-1", "-2" },
 
+	{ &int_test_cdiv, "1073741824", "2147483647", "2" },
+	{ &int_test_cdiv, "1073741824", "2147483648", "2" },
+	{ &int_test_cdiv, "-1073741824", "-2147483648", "2" },
+	{ &int_test_cdiv, "-1073741823", "-2147483647", "2" },
+
 	{ &int_test_tdiv, "0", "1", "2" },
 	{ &int_test_tdiv, "0", "-1", "2" },
 	{ &int_test_tdiv, "0", "1", "-2" },

Modified: polly/trunk/lib/External/isl/isl_union_map.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_union_map.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_union_map.c (original)
+++ polly/trunk/lib/External/isl/isl_union_map.c Tue Jul  4 08:54:11 2017
@@ -23,6 +23,7 @@
 #include <isl/set.h>
 #include <isl_space_private.h>
 #include <isl/union_set.h>
+#include <isl_maybe_map.h>
 #include <isl/deprecated/union_map_int.h>
 
 #include <bset_from_bmap.c>
@@ -348,12 +349,12 @@ isl_bool isl_union_map_space_has_equal_p
 	return isl_space_has_equal_params(umap_space, space);
 }
 
-static int has_dim(const void *entry, const void *val)
+static int has_space(const void *entry, const void *val)
 {
 	isl_map *map = (isl_map *)entry;
-	isl_space *dim = (isl_space *)val;
+	isl_space *space = (isl_space *) val;
 
-	return isl_space_is_equal(map->dim, dim);
+	return isl_space_is_equal(map->dim, space);
 }
 
 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
@@ -386,7 +387,7 @@ __isl_give isl_union_map *isl_union_map_
 
 	hash = isl_space_get_hash(map->dim);
 	entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
-				    &has_dim, map->dim, 1);
+				    &has_space, map->dim, 1);
 	if (!entry)
 		goto error;
 
@@ -537,7 +538,7 @@ __isl_give isl_map *isl_union_map_extrac
 
 	hash = isl_space_get_hash(space);
 	entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
-				    &has_dim, space, 0);
+				    &has_space, space, 0);
 	if (!entry)
 		return isl_map_empty(space);
 	isl_space_free(space);
@@ -566,7 +567,7 @@ isl_bool isl_union_map_contains(__isl_ke
 
 	hash = isl_space_get_hash(space);
 	entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
-				    &has_dim, space, 0);
+				    &has_space, space, 0);
 	return !!entry;
 }
 
@@ -606,45 +607,159 @@ isl_stat isl_union_set_foreach_point(__i
 	return isl_union_set_foreach_set(uset, &foreach_point, &data);
 }
 
+/* Data structure that specifies how gen_bin_op should
+ * construct results from the inputs.
+ *
+ * If "subtract" is set, then a map in the first input is copied to the result
+ * if there is no corresponding map in the second input.
+ * Otherwise, a map in the first input with no corresponding map
+ * in the second input is ignored.
+ * If "filter" is not NULL, then it specifies which maps in the first
+ * input may have a matching map in the second input.
+ * In particular, it makes sure that "match_space" can be called
+ * on the space of the map.
+ * "match_space" specifies how to transform the space of a map
+ * in the first input to the space of the corresponding map
+ * in the second input.
+ * "fn_map" specifies how the matching maps, one from each input,
+ * should be combined to form a map in the result.
+ */
+struct isl_bin_op_control {
+	int subtract;
+	isl_bool (*filter)(__isl_keep isl_map *map);
+	__isl_give isl_space *(*match_space)(__isl_take isl_space *space);
+	__isl_give isl_map *(*fn_map)(__isl_take isl_map *map1,
+		__isl_take isl_map *map2);
+};
+
+/* Internal data structure for gen_bin_op.
+ * "control" specifies how the maps in the result should be constructed.
+ * "umap2" is a pointer to the second argument.
+ * "res" collects the results.
+ */
 struct isl_union_map_gen_bin_data {
+	struct isl_bin_op_control *control;
 	isl_union_map *umap2;
 	isl_union_map *res;
 };
 
-static isl_stat subtract_entry(void **entry, void *user)
+/* Add a copy of "map" to "res" and return the result.
+ */
+static __isl_give isl_union_map *bin_add_map(__isl_take isl_union_map *res,
+	__isl_keep isl_map *map)
+{
+	return isl_union_map_add_map(res, isl_map_copy(map));
+}
+
+/* Combine "map1" and "map2", add the result to "res" and return the result.
+ * Check whether the result is empty before adding it to "res".
+ */
+static __isl_give isl_union_map *bin_add_pair(__isl_take isl_union_map *res,
+	__isl_keep isl_map *map1, __isl_keep isl_map *map2,
+	struct isl_union_map_gen_bin_data *data)
+{
+	isl_bool empty;
+	isl_map *map;
+
+	map = data->control->fn_map(isl_map_copy(map1), isl_map_copy(map2));
+	empty = isl_map_is_empty(map);
+	if (empty < 0 || empty) {
+		isl_map_free(map);
+		if (empty < 0)
+			return isl_union_map_free(res);
+		return res;
+	}
+	return isl_union_map_add_map(res, map);
+}
+
+/* Dummy match_space function that simply returns the input space.
+ */
+static __isl_give isl_space *identity(__isl_take isl_space *space)
+{
+	return space;
+}
+
+/* Look for the map in data->umap2 that corresponds to "map", if any.
+ * Return (isl_bool_true, matching map) if there is one,
+ * (isl_bool_false, NULL) if there is no matching map and
+ * (isl_bool_error, NULL) on error.
+ *
+ * If not NULL, then data->control->filter specifies whether "map"
+ * can have any matching map.  If so,
+ * data->control->match_space specifies which map in data->umap2
+ * corresponds to "map".
+ */
+static __isl_keep isl_maybe_isl_map bin_try_get_match(
+	struct isl_union_map_gen_bin_data *data, __isl_keep isl_map *map)
 {
-	struct isl_union_map_gen_bin_data *data = user;
 	uint32_t hash;
 	struct isl_hash_table_entry *entry2;
-	isl_map *map = *entry;
+	isl_space *space;
+	isl_maybe_isl_map res = { isl_bool_error, NULL };
 
-	hash = isl_space_get_hash(map->dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, map->dim, 0);
-	map = isl_map_copy(map);
-	if (entry2) {
-		int empty;
-		map = isl_map_subtract(map, isl_map_copy(entry2->data));
-
-		empty = isl_map_is_empty(map);
-		if (empty < 0) {
-			isl_map_free(map);
-			return isl_stat_error;
-		}
-		if (empty) {
-			isl_map_free(map);
-			return isl_stat_ok;
-		}
+	if (data->control->filter) {
+		res.valid = data->control->filter(map);
+		if (res.valid < 0 || !res.valid)
+			return res;
+		res.valid = isl_bool_error;
 	}
-	data->res = isl_union_map_add_map(data->res, map);
+
+	space = isl_map_get_space(map);
+	if (data->control->match_space != &identity)
+		space = data->control->match_space(space);
+	if (!space)
+		return res;
+	hash = isl_space_get_hash(space);
+	entry2 = isl_hash_table_find(isl_union_map_get_ctx(data->umap2),
+				     &data->umap2->table, hash,
+				     &has_space, space, 0);
+	isl_space_free(space);
+	res.valid = entry2 != NULL;
+	if (entry2)
+		res.value = entry2->data;
+
+	return res;
+}
+
+/* isl_hash_table_foreach callback for gen_bin_op.
+ * Look for the map in data->umap2 that corresponds
+ * to the map that "entry" points to, apply the binary operation and
+ * add the result to data->res.
+ *
+ * If no corresponding map can be found, then the effect depends
+ * on data->control->subtract.  If it is set, then the current map
+ * is added directly to the result.  Otherwise, it is ignored.
+ */
+static isl_stat gen_bin_entry(void **entry, void *user)
+{
+	struct isl_union_map_gen_bin_data *data = user;
+	isl_map *map = *entry;
+	isl_maybe_isl_map m;
+
+	m = bin_try_get_match(data, map);
+	if (m.valid < 0)
+		return isl_stat_error;
+	if (!m.valid && !data->control->subtract)
+		return isl_stat_ok;
+
+	if (!m.valid)
+		data->res = bin_add_map(data->res, map);
+	else
+		data->res = bin_add_pair(data->res, map, m.value, data);
+	if (!data->res)
+		return isl_stat_error;
 
 	return isl_stat_ok;
 }
 
+/* Apply a binary operation to "umap1" and "umap2" based on "control".
+ * Run over all maps in "umap1" and look for the corresponding map in "umap2"
+ * in gen_bin_entry.
+ */
 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
-	__isl_take isl_union_map *umap2, isl_stat (*fn)(void **, void *))
+	__isl_take isl_union_map *umap2, struct isl_bin_op_control *control)
 {
-	struct isl_union_map_gen_bin_data data = { NULL, NULL };
+	struct isl_union_map_gen_bin_data data = { control, NULL, NULL };
 
 	umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
 	umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
@@ -656,7 +771,7 @@ static __isl_give isl_union_map *gen_bin
 	data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
 				       umap1->table.n);
 	if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
-				   fn, &data) < 0)
+				   &gen_bin_entry, &data) < 0)
 		goto error;
 
 	isl_union_map_free(umap1);
@@ -672,7 +787,13 @@ error:
 __isl_give isl_union_map *isl_union_map_subtract(
 	__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
 {
-	return gen_bin_op(umap1, umap2, &subtract_entry);
+	struct isl_bin_op_control control = {
+		.subtract = 1,
+		.match_space = &identity,
+		.fn_map = &isl_map_subtract,
+	};
+
+	return gen_bin_op(umap1, umap2, &control);
 }
 
 __isl_give isl_union_set *isl_union_set_subtract(
@@ -793,7 +914,7 @@ static isl_stat match_bin_entry(void **e
 
 	hash = isl_space_get_hash(map->dim);
 	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, map->dim, 0);
+				     hash, &has_space, map->dim, 0);
 	if (!entry2)
 		return isl_stat_ok;
 
@@ -921,6 +1042,28 @@ __isl_give isl_union_set *isl_union_set_
 	return isl_union_map_gist(uset, context);
 }
 
+/* For each map in "umap", remove the constraints in the corresponding map
+ * of "context".
+ * Each map in "context" is assumed to consist of a single disjunct and
+ * to have explicit representations for all local variables.
+ */
+__isl_give isl_union_map *isl_union_map_plain_gist(
+	__isl_take isl_union_map *umap, __isl_take isl_union_map *context)
+{
+	return match_bin_op(umap, context, &isl_map_plain_gist);
+}
+
+/* For each set in "uset", remove the constraints in the corresponding set
+ * of "context".
+ * Each set in "context" is assumed to consist of a single disjunct and
+ * to have explicit representations for all local variables.
+ */
+__isl_give isl_union_set *isl_union_set_plain_gist(
+	__isl_take isl_union_set *uset, __isl_take isl_union_set *context)
+{
+	return isl_union_map_plain_gist(uset, context);
+}
+
 static __isl_give isl_map *lex_le_set(__isl_take isl_map *set1,
 	__isl_take isl_map *set2)
 {
@@ -969,40 +1112,17 @@ __isl_give isl_union_map *isl_union_map_
 	return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1));
 }
 
-static isl_stat intersect_domain_entry(void **entry, void *user)
+/* Intersect the domain of "umap" with "uset".
+ */
+static __isl_give isl_union_map *union_map_intersect_domain(
+	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
 {
-	struct isl_union_map_gen_bin_data *data = user;
-	uint32_t hash;
-	struct isl_hash_table_entry *entry2;
-	isl_space *dim;
-	isl_map *map = *entry;
-	isl_bool empty;
-
-	dim = isl_map_get_space(map);
-	dim = isl_space_domain(dim);
-	hash = isl_space_get_hash(dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, dim, 0);
-	isl_space_free(dim);
-	if (!entry2)
-		return isl_stat_ok;
-
-	map = isl_map_copy(map);
-	map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
-
-	empty = isl_map_is_empty(map);
-	if (empty < 0) {
-		isl_map_free(map);
-		return isl_stat_error;
-	}
-	if (empty) {
-		isl_map_free(map);
-		return isl_stat_ok;
-	}
-
-	data->res = isl_union_map_add_map(data->res, map);
+	struct isl_bin_op_control control = {
+		.match_space = &isl_space_domain,
+		.fn_map = &isl_map_intersect_domain,
+	};
 
-	return isl_stat_ok;
+	return gen_bin_op(umap, uset, &control);
 }
 
 /* Intersect the domain of "umap" with "uset".
@@ -1014,50 +1134,8 @@ __isl_give isl_union_map *isl_union_map_
 {
 	if (isl_union_set_is_params(uset))
 		return union_map_intersect_params(umap, uset);
-	return gen_bin_op(umap, uset, &intersect_domain_entry);
-}
-
-/* Remove the elements of data->umap2 from the domain of *entry
- * and add the result to data->res.
- */
-static isl_stat subtract_domain_entry(void **entry, void *user)
-{
-	struct isl_union_map_gen_bin_data *data = user;
-	uint32_t hash;
-	struct isl_hash_table_entry *entry2;
-	isl_space *dim;
-	isl_map *map = *entry;
-	isl_bool empty;
-
-	dim = isl_map_get_space(map);
-	dim = isl_space_domain(dim);
-	hash = isl_space_get_hash(dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, dim, 0);
-	isl_space_free(dim);
-
-	map = isl_map_copy(map);
-
-	if (!entry2) {
-		data->res = isl_union_map_add_map(data->res, map);
-		return isl_stat_ok;
-	}
-
-	map = isl_map_subtract_domain(map, isl_set_copy(entry2->data));
-
-	empty = isl_map_is_empty(map);
-	if (empty < 0) {
-		isl_map_free(map);
-		return isl_stat_error;
-	}
-	if (empty) {
-		isl_map_free(map);
-		return isl_stat_ok;
-	}
-
-	data->res = isl_union_map_add_map(data->res, map);
-
-	return isl_stat_ok;
+	else
+		return union_map_intersect_domain(umap, uset);
 }
 
 /* Remove the elements of "uset" from the domain of "umap".
@@ -1065,50 +1143,13 @@ static isl_stat subtract_domain_entry(vo
 __isl_give isl_union_map *isl_union_map_subtract_domain(
 	__isl_take isl_union_map *umap, __isl_take isl_union_set *dom)
 {
-	return gen_bin_op(umap, dom, &subtract_domain_entry);
-}
-
-/* Remove the elements of data->umap2 from the range of *entry
- * and add the result to data->res.
- */
-static isl_stat subtract_range_entry(void **entry, void *user)
-{
-	struct isl_union_map_gen_bin_data *data = user;
-	uint32_t hash;
-	struct isl_hash_table_entry *entry2;
-	isl_space *space;
-	isl_map *map = *entry;
-	isl_bool empty;
-
-	space = isl_map_get_space(map);
-	space = isl_space_range(space);
-	hash = isl_space_get_hash(space);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, space, 0);
-	isl_space_free(space);
-
-	map = isl_map_copy(map);
-
-	if (!entry2) {
-		data->res = isl_union_map_add_map(data->res, map);
-		return isl_stat_ok;
-	}
-
-	map = isl_map_subtract_range(map, isl_set_copy(entry2->data));
-
-	empty = isl_map_is_empty(map);
-	if (empty < 0) {
-		isl_map_free(map);
-		return isl_stat_error;
-	}
-	if (empty) {
-		isl_map_free(map);
-		return isl_stat_ok;
-	}
-
-	data->res = isl_union_map_add_map(data->res, map);
+	struct isl_bin_op_control control = {
+		.subtract = 1,
+		.match_space = &isl_space_domain,
+		.fn_map = &isl_map_subtract_domain,
+	};
 
-	return isl_stat_ok;
+	return gen_bin_op(umap, dom, &control);
 }
 
 /* Remove the elements of "uset" from the range of "umap".
@@ -1116,39 +1157,26 @@ static isl_stat subtract_range_entry(voi
 __isl_give isl_union_map *isl_union_map_subtract_range(
 	__isl_take isl_union_map *umap, __isl_take isl_union_set *dom)
 {
-	return gen_bin_op(umap, dom, &subtract_range_entry);
+	struct isl_bin_op_control control = {
+		.subtract = 1,
+		.match_space = &isl_space_range,
+		.fn_map = &isl_map_subtract_range,
+	};
+
+	return gen_bin_op(umap, dom, &control);
 }
 
-static isl_stat gist_domain_entry(void **entry, void *user)
+/* Compute the gist of "umap" with respect to the domain "uset".
+ */
+static __isl_give isl_union_map *union_map_gist_domain(
+	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
 {
-	struct isl_union_map_gen_bin_data *data = user;
-	uint32_t hash;
-	struct isl_hash_table_entry *entry2;
-	isl_space *dim;
-	isl_map *map = *entry;
-	isl_bool empty;
-
-	dim = isl_map_get_space(map);
-	dim = isl_space_domain(dim);
-	hash = isl_space_get_hash(dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, dim, 0);
-	isl_space_free(dim);
-	if (!entry2)
-		return isl_stat_ok;
-
-	map = isl_map_copy(map);
-	map = isl_map_gist_domain(map, isl_set_copy(entry2->data));
-
-	empty = isl_map_is_empty(map);
-	if (empty < 0) {
-		isl_map_free(map);
-		return isl_stat_error;
-	}
-
-	data->res = isl_union_map_add_map(data->res, map);
+	struct isl_bin_op_control control = {
+		.match_space = &isl_space_domain,
+		.fn_map = &isl_map_gist_domain,
+	};
 
-	return isl_stat_ok;
+	return gen_bin_op(umap, uset, &control);
 }
 
 /* Compute the gist of "umap" with respect to the domain "uset".
@@ -1160,39 +1188,8 @@ __isl_give isl_union_map *isl_union_map_
 {
 	if (isl_union_set_is_params(uset))
 		return union_map_gist_params(umap, uset);
-	return gen_bin_op(umap, uset, &gist_domain_entry);
-}
-
-static isl_stat gist_range_entry(void **entry, void *user)
-{
-	struct isl_union_map_gen_bin_data *data = user;
-	uint32_t hash;
-	struct isl_hash_table_entry *entry2;
-	isl_space *space;
-	isl_map *map = *entry;
-	isl_bool empty;
-
-	space = isl_map_get_space(map);
-	space = isl_space_range(space);
-	hash = isl_space_get_hash(space);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, space, 0);
-	isl_space_free(space);
-	if (!entry2)
-		return isl_stat_ok;
-
-	map = isl_map_copy(map);
-	map = isl_map_gist_range(map, isl_set_copy(entry2->data));
-
-	empty = isl_map_is_empty(map);
-	if (empty < 0) {
-		isl_map_free(map);
-		return isl_stat_error;
-	}
-
-	data->res = isl_union_map_add_map(data->res, map);
-
-	return isl_stat_ok;
+	else
+		return union_map_gist_domain(umap, uset);
 }
 
 /* Compute the gist of "umap" with respect to the range "uset".
@@ -1200,49 +1197,39 @@ static isl_stat gist_range_entry(void **
 __isl_give isl_union_map *isl_union_map_gist_range(
 	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
 {
-	return gen_bin_op(umap, uset, &gist_range_entry);
+	struct isl_bin_op_control control = {
+		.match_space = &isl_space_range,
+		.fn_map = &isl_map_gist_range,
+	};
+
+	return gen_bin_op(umap, uset, &control);
 }
 
-static isl_stat intersect_range_entry(void **entry, void *user)
+__isl_give isl_union_map *isl_union_map_intersect_range(
+	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
 {
-	struct isl_union_map_gen_bin_data *data = user;
-	uint32_t hash;
-	struct isl_hash_table_entry *entry2;
-	isl_space *dim;
-	isl_map *map = *entry;
-	isl_bool empty;
-
-	dim = isl_map_get_space(map);
-	dim = isl_space_range(dim);
-	hash = isl_space_get_hash(dim);
-	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, dim, 0);
-	isl_space_free(dim);
-	if (!entry2)
-		return isl_stat_ok;
-
-	map = isl_map_copy(map);
-	map = isl_map_intersect_range(map, isl_set_copy(entry2->data));
-
-	empty = isl_map_is_empty(map);
-	if (empty < 0) {
-		isl_map_free(map);
-		return isl_stat_error;
-	}
-	if (empty) {
-		isl_map_free(map);
-		return isl_stat_ok;
-	}
-
-	data->res = isl_union_map_add_map(data->res, map);
+	struct isl_bin_op_control control = {
+		.match_space = &isl_space_range,
+		.fn_map = &isl_map_intersect_range,
+	};
 
-	return isl_stat_ok;
+	return gen_bin_op(umap, uset, &control);
 }
 
-__isl_give isl_union_map *isl_union_map_intersect_range(
-	__isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
+/* Intersect each map in "umap" in a space A -> [B -> C]
+ * with the corresponding map in "factor" in the space A -> C and
+ * collect the results.
+ */
+__isl_give isl_union_map *isl_union_map_intersect_range_factor_range(
+	__isl_take isl_union_map *umap, __isl_take isl_union_map *factor)
 {
-	return gen_bin_op(umap, uset, &intersect_range_entry);
+	struct isl_bin_op_control control = {
+		.filter = &isl_map_range_is_wrapping,
+		.match_space = &isl_space_range_factor_range,
+		.fn_map = &isl_map_intersect_range_factor_range,
+	};
+
+	return gen_bin_op(umap, factor, &control);
 }
 
 struct isl_union_map_bin_data {
@@ -1684,6 +1671,28 @@ __isl_give isl_union_set *isl_union_set_
 	return isl_union_map_affine_hull(uset);
 }
 
+/* Wrapper around isl_set_combined_lineality_space
+ * that returns the combined lineality space in the form of an isl_set
+ * instead of an isl_basic_set.
+ */
+static __isl_give isl_set *combined_lineality_space(__isl_take isl_set *set)
+{
+	return isl_set_from_basic_set(isl_set_combined_lineality_space(set));
+}
+
+/* For each set in "uset", compute the (linear) hull
+ * of the lineality spaces of its basic sets and
+ * collect and return the results.
+ */
+__isl_give isl_union_set *isl_union_set_combined_lineality_space(
+	__isl_take isl_union_set *uset)
+{
+	struct isl_un_op_control control = {
+		.fn_map = &combined_lineality_space,
+	};
+	return un_op(uset, &control);
+}
+
 /* Compute the polyhedral hull of "map" and return the result as an isl_map.
  */
 static __isl_give isl_map *isl_map_polyhedral_hull_map(__isl_take isl_map *map)
@@ -2132,7 +2141,7 @@ static isl_stat is_subset_entry(void **e
 
 	hash = isl_space_get_hash(map->dim);
 	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, map->dim, 0);
+				     hash, &has_space, map->dim, 0);
 	if (!entry2) {
 		int empty = isl_map_is_empty(map);
 		if (empty < 0)
@@ -2249,7 +2258,7 @@ static isl_stat is_disjoint_entry(void *
 
 	hash = isl_space_get_hash(map->dim);
 	entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
-				     hash, &has_dim, map->dim, 0);
+				     hash, &has_space, map->dim, 0);
 	if (!entry2)
 		return isl_stat_ok;
 

Added: polly/trunk/lib/External/isl/isl_union_set_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_union_set_private.h?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/isl_union_set_private.h (added)
+++ polly/trunk/lib/External/isl/isl_union_set_private.h Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+#ifndef ISL_UNION_SET_PRIVATE_H
+#define ISL_UNION_SET_PRIVATE_H
+
+#include <isl/union_set.h>
+
+__isl_give isl_union_set *isl_union_set_combined_lineality_space(
+	__isl_take isl_union_set *uset);
+__isl_give isl_union_set *isl_union_set_plain_gist(
+	__isl_take isl_union_set *uset, __isl_take isl_union_set *context);
+
+#endif

Modified: polly/trunk/lib/External/isl/isl_val.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_val.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_val.c (original)
+++ polly/trunk/lib/External/isl/isl_val.c Tue Jul  4 08:54:11 2017
@@ -916,6 +916,31 @@ error:
 }
 
 /* Divide "v1" by "v2".
+ */
+__isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2)
+{
+	if (!v1)
+		return NULL;
+	if (isl_val_is_nan(v1))
+		return v1;
+	if (v2 == 0)
+		return isl_val_set_nan(v1);
+	if (v2 == 1)
+		return v1;
+	if (isl_val_is_zero(v1))
+		return v1;
+	if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1))
+		return v1;
+	v1 = isl_val_cow(v1);
+	if (!v1)
+		return NULL;
+
+	isl_int_mul_ui(v1->d, v1->d, v2);
+
+	return isl_val_normalize(v1);
+}
+
+/* Divide "v1" by "v2".
  *
  * This is a private copy of isl_val_div for use in the generic
  * isl_multi_*_scale_down_val instantiated for isl_val.

Modified: polly/trunk/lib/External/isl/isl_vec.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_vec.c?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_vec.c (original)
+++ polly/trunk/lib/External/isl/isl_vec.c Tue Jul  4 08:54:11 2017
@@ -328,6 +328,15 @@ int isl_vec_cmp_element(__isl_keep isl_v
 	return isl_int_cmp(vec1->el[pos], vec2->el[pos]);
 }
 
+/* Does "vec" contain only zero elements?
+ */
+isl_bool isl_vec_is_zero(__isl_keep isl_vec *vec)
+{
+	if (!vec)
+		return isl_bool_error;
+	return isl_seq_first_non_zero(vec->el, vec->size) < 0;
+}
+
 isl_bool isl_vec_is_equal(__isl_keep isl_vec *vec1, __isl_keep isl_vec *vec2)
 {
 	if (!vec1 || !vec2)

Modified: polly/trunk/lib/External/isl/isl_vec_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_vec_private.h?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_vec_private.h (original)
+++ polly/trunk/lib/External/isl/isl_vec_private.h Tue Jul  4 08:54:11 2017
@@ -23,6 +23,8 @@ void isl_vec_lcm(struct isl_vec *vec, is
 int isl_vec_get_element(__isl_keep isl_vec *vec, int pos, isl_int *v);
 __isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v);
 
+isl_bool isl_vec_is_zero(__isl_keep isl_vec *vec);
+
 __isl_give isl_vec *isl_vec_expand(__isl_take isl_vec *vec, int pos, int n,
 	int *exp, int expanded);
 

Modified: polly/trunk/lib/External/isl/ltmain.sh
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/ltmain.sh?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/ltmain.sh (original)
+++ polly/trunk/lib/External/isl/ltmain.sh Tue Jul  4 08:54:11 2017
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-1"
+VERSION="2.4.6 Debian-2.4.6-2"
 package_revision=2.4.6
 
 
@@ -1977,7 +1977,7 @@ func_version ()
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.6 Debian-2.4.6-1'
+scriptversion='(GNU libtool) 2.4.6'
 
 
 # func_echo ARG...
@@ -2068,7 +2068,7 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion
+       version:        $progname $scriptversion Debian-2.4.6-2
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 

Modified: polly/trunk/lib/External/isl/m4/ax_detect_clang.m4
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/m4/ax_detect_clang.m4?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/m4/ax_detect_clang.m4 (original)
+++ polly/trunk/lib/External/isl/m4/ax_detect_clang.m4 Tue Jul  4 08:54:11 2017
@@ -130,6 +130,9 @@ AC_EGREP_HEADER([initializeBuiltins],
 	[clang/Basic/Builtins.h], [],
 	[AC_DEFINE([initializeBuiltins], [InitializeBuiltins],
 		[Define to InitializeBuiltins for older versions of clang])])
+AC_EGREP_HEADER([IK_C], [clang/Frontend/FrontendOptions.h], [],
+	 [AC_DEFINE([IK_C], [InputKind::C],
+	    [Define to InputKind::C for newer versions of clang])])
 AC_TRY_COMPILE([
 	#include <clang/Basic/TargetOptions.h>
 	#include <clang/Lex/PreprocessorOptions.h>

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+kill: "{ T[9] -> a[] }"
+schedule:
+  domain: "{ T[i]; S[] }"
+  child:
+    sequence:
+    - filter: "{ T[i] }"
+      child:
+        schedule: "[{ T[i] -> [(i)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[i] -> a[] : 0 <= i < 10 }
+kill: { T[9] -> a[] }
+schedule_map: { T[i] -> [0,i]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+kill: "{ K[] -> a[] }"
+schedule:
+  domain: "{ T[i]; S[]; K[] }"
+  child:
+    sequence:
+    - filter: "{ T[i]; K[] }"
+      child:
+        schedule: "[{ T[i] -> [(i)]; K[] -> [(10)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{  }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[i] -> a[] : 0 <= i < 10 }
+kill: { K[] -> a[] }
+schedule_map: { T[i] -> [0,i]; K[] -> [0,10]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop2.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{  }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+kill: "{ K[] -> a[] }"
+schedule:
+  domain: "{ T[i]; S[]; K[] }"
+  child:
+    sequence:
+    - filter: "{ T[i]; K[] }"
+      child:
+        schedule: "[{ T[i] -> [(i)]; K[] -> [(9)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[i] -> a[] : 0 <= i < 10 }
+kill: { K[] -> a[] }
+schedule_map: { T[i] -> [0,i]; K[] -> [0,9]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_loop3.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+may_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+kill: "{ T[4] -> a[] }"
+schedule:
+  domain: "{ T[i]; S[] }"
+  child:
+    sequence:
+    - filter: "{ T[i] }"
+      child:
+        schedule: "[{ T[i] -> [(i)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+may_source: { T[i] -> a[] : 0 <= i < 10 }
+kill: { T[4] -> a[] }
+schedule_map: { T[i] -> [0,i]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+may_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+kill: "{ T[9] -> a[] }"
+schedule:
+  domain: "{ T[i]; S[] }"
+  child:
+    sequence:
+    - filter: "{ T[i] }"
+      child:
+        schedule: "[{ T[i] -> [(i)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+may_source: { T[i] -> a[] : 0 <= i < 10 }
+kill: { T[9] -> a[] }
+schedule_map: { T[i] -> [0,i]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop2.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+may_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+kill: "{ K[] -> a[] }"
+schedule:
+  domain: "{ T[i]; S[]; K[] }"
+  child:
+    sequence:
+    - filter: "{ T[i]; K[] }"
+      child:
+        schedule: "[{ T[i] -> [(i)]; K[] -> [(4)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+may_source: { T[i] -> a[] : 0 <= i < 10 }
+kill: { K[] -> a[] }
+schedule_map: { T[i] -> [0,i]; K[] -> [0,4]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/kill_may_loop3.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i] -> [S[] -> a[]] : 4 <= i <= 9 }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,10 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+schedule:
+  domain: "{ T[i]; S[] }"
+  child:
+    sequence:
+    - filter: "{ T[i] }"
+      child:
+        schedule: "[{ T[i] -> [(i)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/loop-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/loop.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/loop.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/loop.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/loop.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: { S[] -> a[] }
+must_source: { T[i] -> a[] : 0 <= i < 10 }
+schedule_map: { T[i] -> [0,i]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/loop.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/loop.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/loop.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/loop.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,10 @@
+sink: "{ S[] -> a[] }"
+may_source: "{ T[i] -> a[] : 0 <= i <= 9 }"
+schedule:
+  domain: "{ T[i]; S[] }"
+  child:
+    sequence:
+    - filter: "{ T[i] }"
+      child:
+        schedule: "[{ T[i] -> [(i)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/may_loop-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i] -> [S[] -> a[]] : 0 <= i <= 9 }"
+must_no_source: "{  }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/may_loop.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/may_loop.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/may_loop.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/may_loop.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: { S[] -> a[] }
+may_source: { T[i] -> a[] : 0 <= i < 10 }
+schedule_map: { T[i] -> [0,i]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/may_loop.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/may_loop.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/may_loop.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/may_loop.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i] -> [S[] -> a[]] : 0 <= i <= 9 }"
+must_no_source: "{  }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,11 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[i] -> a[] : 2*floor((i)/2) = i and 0 <= i <= 9 }"
+may_source: "{ T[i] -> a[] : 2*floor((1 + i)/2) = 1 + i and 0 <= i <= 9 }"
+schedule:
+  domain: "{ T[i]; S[] }"
+  child:
+    sequence:
+    - filter: "{ T[i] }"
+      child:
+        schedule: "[{ T[i] -> [(i)] }]"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]]; T[i = 8] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[i] -> a[] : 0 <= i < 10 and i mod 2 = 0 }
+may_source: { T[i] -> a[] : 0 <= i < 10 and i mod 2 = 1 }
+schedule_map: { T[i] -> [0,i]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/mixed_loop.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[i = 9] -> [S[] -> a[]]; T[i = 8] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,10 @@
+sink: "{ [S_2[] -> __pet_ref_4[]] -> a[] }"
+must_source: "{ [S_0[] -> __pet_ref_0[]] -> a[]; [S_2[] -> __pet_ref_3[]] -> b[]; [S_1[] -> __pet_ref_1[]] -> a[]; [S_1[] -> __pet_ref_2[]] -> a[] }"
+may_source: "{ [S_1[] -> __pet_ref_2[]] -> a[]; [S_1[] -> __pet_ref_1[]] -> a[]; [S_2[] -> __pet_ref_3[]] -> b[]; [S_0[] -> __pet_ref_0[]] -> a[] }"
+schedule:
+  domain: "{ [S_1[] -> __pet_ref_1[]]; [S_1[] -> __pet_ref_2[]]; [S_2[] -> __pet_ref_3[]]; [S_0[] -> __pet_ref_0[]]; [S_2[] -> __pet_ref_4[]] }"
+  child:
+    sequence:
+    - filter: "{ [S_0[] -> __pet_ref_0[]] }"
+    - filter: "{ [S_1[] -> __pet_ref_1[]]; [S_1[] -> __pet_ref_2[]] }"
+    - filter: "{ [S_2[] -> __pet_ref_3[]]; [S_2[] -> __pet_ref_4[]] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ [S_1[] -> __pet_ref_2[]] -> [[S_2[] -> __pet_ref_4[]] -> a[]]; [S_1[] -> __pet_ref_1[]] -> [[S_2[] -> __pet_ref_4[]] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,8 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[] -> a[]; U[] -> a[] }"
+schedule:
+  domain: "{ U[]; S[]; T[] }"
+  child:
+    sequence:
+    - filter: "{ T[]; U[] }"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: { S[] -> a[] }
+must_source: { T[] -> a[]; U[] -> a[] }
+schedule_map: { T[] -> [0]; U[] -> [0]; S[] -> [1] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,9 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[] -> a[] }"
+may_source: "{ U[] -> a[] }"
+schedule:
+  domain: "{ U[]; S[]; T[] }"
+  child:
+    sequence:
+    - filter: "{ T[]; U[] }"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source2-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[] -> a[] }
+may_source: { U[] -> a[] }
+schedule_map: { T[] -> [0]; U[] -> [0]; S[] -> [1] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source2.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,13 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[] -> a[]; U[] -> a[] }"
+may_source: "{ V[] -> a[] }"
+schedule:
+  domain: "{ S[]; U[]; T[]; V[] }"
+  child:
+    sequence:
+    - filter: "{ U[]; T[]; V[] }"
+      child:
+        sequence:
+        - filter: "{ T[]; U[] }"
+        - filter: "{ V[] }"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source3-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[] -> a[]; U[] -> a[] }
+may_source: { V[] -> a[] }
+schedule_map: { T[] -> [0,0]; U[] -> [0,0]; V[] -> [0,1]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source3.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; U[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,13 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[] -> a[]; U[] -> a[] }"
+may_source: "{ V[] -> a[] }"
+schedule:
+  domain: "{ S[]; U[]; T[]; V[] }"
+  child:
+    sequence:
+    - filter: "{ U[]; T[]; V[] }"
+      child:
+        sequence:
+        - filter: "{ U[] }"
+        - filter: "{ V[]; T[] }"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source4-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+sink: { S[] -> a[] }
+must_source: { T[] -> a[]; U[] -> a[] }
+may_source: { V[] -> a[] }
+schedule_map: { T[] -> [0,1]; U[] -> [0,0]; V[] -> [0,1]; S[] -> [1,0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/multi_source4.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]]; V[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: "{ S[] -> a[] }"
+schedule:
+  domain: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{  }"
+must_no_source: "{ S[] -> a[] }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,2 @@
+sink: { S[] -> a[] }
+schedule_map: { S[] -> [] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{  }"
+must_no_source: "{ S[] -> a[] }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,8 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[] -> a[] }"
+schedule:
+  domain: "{ S[]; T[] }"
+  child:
+    sequence:
+    - filter: "{ S[] }"
+    - filter: "{ T[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source2-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{  }"
+must_no_source: "{ S[] -> a[] }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source2.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source2.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source2.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source2.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: { S[] -> a[] }
+must_source: { T[] -> a[] }
+schedule_map: { T[] -> [1]; S[] -> [0] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/no_source2.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/no_source2.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/no_source2.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/no_source2.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{  }"
+must_no_source: "{ S[] -> a[] }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,8 @@
+sink: "{ S[] -> a[] }"
+may_source: "{ T[] -> a[] }"
+schedule:
+  domain: "{ S[]; T[] }"
+  child:
+    sequence:
+    - filter: "{ T[] }"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_may_source-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: { S[] -> a[] }
+may_source: { T[] -> a[] }
+schedule_map: { T[] -> [0]; S[] -> [1] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_may_source.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{  }"
+may_dependence: "{ T[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{ S[] -> a[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,8 @@
+sink: "{ S[] -> a[] }"
+must_source: "{ T[] -> a[] }"
+schedule:
+  domain: "{ S[]; T[] }"
+  child:
+    sequence:
+    - filter: "{ T[] }"
+    - filter: "{ S[] }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_source-tree.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{ T[] -> [S[] -> a[]] }"
+may_dependence: "{ T[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_source.ai
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_source.ai?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_source.ai (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_source.ai Tue Jul  4 08:54:11 2017
@@ -0,0 +1,3 @@
+sink: { S[] -> a[] }
+must_source: { T[] -> a[] }
+schedule_map: { T[] -> [0]; S[] -> [1] }

Added: polly/trunk/lib/External/isl/test_inputs/flow/single_source.flow
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/test_inputs/flow/single_source.flow?rev=307090&view=auto
==============================================================================
--- polly/trunk/lib/External/isl/test_inputs/flow/single_source.flow (added)
+++ polly/trunk/lib/External/isl/test_inputs/flow/single_source.flow Tue Jul  4 08:54:11 2017
@@ -0,0 +1,4 @@
+must_dependence: "{ T[] -> [S[] -> a[]] }"
+may_dependence: "{ T[] -> [S[] -> a[]] }"
+must_no_source: "{  }"
+may_no_source: "{  }"

Modified: polly/trunk/test/DependenceInfo/different_schedule_dimensions.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/different_schedule_dimensions.ll?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/test/DependenceInfo/different_schedule_dimensions.ll (original)
+++ polly/trunk/test/DependenceInfo/different_schedule_dimensions.ll Tue Jul  4 08:54:11 2017
@@ -15,7 +15,7 @@
 ; FUNC: RAW dependences:
 ; FUNC-NEXT:   { Stmt_bb9[0] -> Stmt_bb10[0]; [Stmt_bb9[0] -> Stmt_bb9_Write0[]] -> [Stmt_bb10[0] -> Stmt_bb10_Read0[]] }
 ; FUNC-NEXT: WAR dependences:
-; FUNC-NEXT:   { }
+; FUNC-NEXT:   { [Stmt_bb3[0] -> Stmt_bb3_Read0[]] -> [Stmt_bb10[0] -> Stmt_bb10_Write1[]]; Stmt_bb3[0] -> Stmt_bb10[0] }
 ; FUNC-NEXT: WAW dependences:
 ; FUNC-NEXT:   { Stmt_bb3[0] -> Stmt_bb10[0]; [Stmt_bb3[0] -> Stmt_bb3_Write1[]] -> [Stmt_bb10[0] -> Stmt_bb10_Write1[]] }
 ; FUNC-NEXT: Reduction dependences:

Modified: polly/trunk/test/DependenceInfo/do_pluto_matmult.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/do_pluto_matmult.ll?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/test/DependenceInfo/do_pluto_matmult.ll (original)
+++ polly/trunk/test/DependenceInfo/do_pluto_matmult.ll Tue Jul  4 08:54:11 2017
@@ -83,7 +83,7 @@ do.end45:
 ; FUNC-VALUE:      RAW dependences:
 ; FUNC-VALUE-NEXT:     { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Write3[]] -> [Stmt_do_body2[i0, i1, 1 + i2] -> Stmt_do_body2_Read0[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34 }
 ; FUNC-VALUE-NEXT: WAR dependences:
-; FUNC-VALUE-NEXT:     { }
+; FUNC-VALUE-NEXT:     { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Read0[]] -> [Stmt_do_body2[i0, i1, 1 + i2] -> Stmt_do_body2_Write3[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34 }
 ; FUNC-VALUE-NEXT: WAW dependences:
 ; FUNC-VALUE-NEXT:     { [Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2_Write3[]] -> [Stmt_do_body2[i0, i1, 1 + i2] -> Stmt_do_body2_Write3[]] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34; Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : 0 <= i0 <= 35 and 0 <= i1 <= 35 and 0 <= i2 <= 34 }
 

Modified: polly/trunk/test/ScheduleOptimizer/outer_coincidence.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScheduleOptimizer/outer_coincidence.ll?rev=307090&r1=307089&r2=307090&view=diff
==============================================================================
--- polly/trunk/test/ScheduleOptimizer/outer_coincidence.ll (original)
+++ polly/trunk/test/ScheduleOptimizer/outer_coincidence.ll Tue Jul  4 08:54:11 2017
@@ -65,5 +65,5 @@ for.end13:
 ; OUTER-NEXT: for (int c0 = 0; c0 < m + n - 3; c0 += 1)
 ; OUTER-NEXT:   #pragma simd
 ; OUTER-NEXT:   #pragma known-parallel
-; OUTER-NEXT:   for (int c1 = max(0, -m + c0 + 2); c1 <= min(n - 2, c0); c1 += 1)
-; OUTER-NEXT:     Stmt_for_body3(c0 - c1, c1);
+; OUTER-NEXT:   for (int c1 = max(0, -n + c0 + 2); c1 <= min(m - 2, c0); c1 += 1)
+; OUTER-NEXT:     Stmt_for_body3(c1, c0 - c1);




More information about the llvm-commits mailing list