[polly] r304686 - Update isl to isl-0.18-679-g6e75a0d

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 4 12:13:11 PDT 2017


Author: grosser
Date: Sun Jun  4 14:13:10 2017
New Revision: 304686

URL: http://llvm.org/viewvc/llvm-project?rev=304686&view=rev
Log:
Update isl to isl-0.18-679-g6e75a0d

This is a regular maintenance update

Modified:
    polly/trunk/lib/External/isl/GIT_HEAD_ID
    polly/trunk/lib/External/isl/doc/user.pod
    polly/trunk/lib/External/isl/include/isl/list.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/union_set.h
    polly/trunk/lib/External/isl/isl_farkas.c
    polly/trunk/lib/External/isl/isl_list_templ.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_union_map.c

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/GIT_HEAD_ID (original)
+++ polly/trunk/lib/External/isl/GIT_HEAD_ID Sun Jun  4 14:13:10 2017
@@ -1 +1 @@
-isl-0.18-662-g17e172e
+isl-0.18-679-g6e75a0d

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/doc/user.pod (original)
+++ polly/trunk/lib/External/isl/doc/user.pod Sun Jun  4 14:13:10 2017
@@ -2116,15 +2116,26 @@ has a unique value when the values of th
 Alternatively, the existentially quantified variables can be removed
 using the following functions, which compute an overapproximation.
 
+	#include <isl/set.h>
 	__isl_give isl_basic_set *isl_basic_set_remove_divs(
 		__isl_take isl_basic_set *bset);
-	__isl_give isl_basic_map *isl_basic_map_remove_divs(
-		__isl_take isl_basic_map *bmap);
 	__isl_give isl_set *isl_set_remove_divs(
 		__isl_take isl_set *set);
+
+	#include <isl/map.h>
+	__isl_give isl_basic_map *isl_basic_map_remove_divs(
+		__isl_take isl_basic_map *bmap);
 	__isl_give isl_map *isl_map_remove_divs(
 		__isl_take isl_map *map);
 
+	#include <isl/union_set.h>
+	__isl_give isl_union_set *isl_union_set_remove_divs(
+		__isl_take isl_union_set *bset);
+
+	#include <isl/union_map.h>
+	__isl_give isl_union_map *isl_union_map_remove_divs(
+		__isl_take isl_union_map *bmap);
+
 It is also possible to only remove those divs that are defined
 in terms of a given range of dimensions or only those for which
 no explicit representation is known.
@@ -2221,11 +2232,17 @@ from
 	int isl_map_n_basic_map(__isl_keep isl_map *map);
 
 It is also possible to obtain a list of basic sets from a set
+or union set
 
 	#include <isl/set.h>
 	__isl_give isl_basic_set_list *isl_set_get_basic_set_list(
 		__isl_keep isl_set *set);
 
+	#include <isl/union_set.h>
+	__isl_give isl_basic_set_list *
+	isl_union_set_get_basic_set_list(
+		__isl_keep isl_union_set *uset);
+
 The returned list can be manipulated using the functions in L<"Lists">.
 
 To iterate over the constraints of a basic set or map, use
@@ -5148,8 +5165,12 @@ Fourier-Motzkin elimination, but this ma
 in future.  In particular, future implementations may use different
 dualization algorithms or skip the elimination step.
 
+	#include <isl/set.h>
 	__isl_give isl_basic_set *isl_basic_set_coefficients(
 		__isl_take isl_basic_set *bset);
+	__isl_give isl_basic_set_list *
+	isl_basic_set_list_coefficients(
+		__isl_take isl_basic_set_list *list);
 	__isl_give isl_basic_set *isl_set_coefficients(
 		__isl_take isl_set *set);
 	__isl_give isl_union_set *isl_union_set_coefficients(
@@ -7460,6 +7481,11 @@ Lists can be created, copied, modified a
 	__isl_give isl_set_list *isl_set_list_concat(
 		__isl_take isl_set_list *list1,
 		__isl_take isl_set_list *list2);
+	__isl_give isl_set_list *isl_set_list_map(
+		__isl_take isl_set_list *list,
+		__isl_give isl_set *(*fn)(__isl_take isl_set *el,
+			void *user),
+		void *user);
 	__isl_give isl_set_list *isl_set_list_sort(
 		__isl_take isl_set_list *list,
 		int (*cmp)(__isl_keep isl_set *a,

Modified: polly/trunk/lib/External/isl/include/isl/list.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/list.h?rev=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/list.h (original)
+++ polly/trunk/lib/External/isl/include/isl/list.h Sun Jun  4 14:13:10 2017
@@ -50,6 +50,11 @@ __isl_give struct isl_##EL##_list *isl_#
 isl_stat isl_##EL##_list_foreach(__isl_keep isl_##EL##_list *list,	\
 	isl_stat (*fn)(__isl_take struct isl_##EL *el, void *user),	\
 	void *user);							\
+__isl_give isl_##EL##_list *isl_##EL##_list_map(			\
+	__isl_take isl_##EL##_list *list,				\
+	__isl_give isl_##EL * (*fn)(__isl_take isl_##EL *el,		\
+		void *user),						\
+	void *user);							\
 __isl_give isl_##EL##_list *isl_##EL##_list_sort(			\
 	__isl_take isl_##EL##_list *list,				\
 	int (*cmp)(__isl_keep struct isl_##EL *a,			\

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/set.h (original)
+++ polly/trunk/lib/External/isl/include/isl/set.h Sun Jun  4 14:13:10 2017
@@ -489,6 +489,8 @@ __isl_give isl_mat *isl_basic_set_reduce
 
 __isl_give isl_basic_set *isl_basic_set_coefficients(
 	__isl_take isl_basic_set *bset);
+__isl_give isl_basic_set_list *isl_basic_set_list_coefficients(
+	__isl_take isl_basic_set_list *list);
 __isl_give isl_basic_set *isl_set_coefficients(__isl_take isl_set *set);
 __isl_give isl_basic_set *isl_basic_set_solutions(
 	__isl_take isl_basic_set *bset);

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/union_map.h (original)
+++ polly/trunk/lib/External/isl/include/isl/union_map.h Sun Jun  4 14:13:10 2017
@@ -194,6 +194,8 @@ __isl_give isl_union_map *isl_union_set_
 __isl_give isl_union_map *isl_union_map_project_out(
 	__isl_take isl_union_map *umap,
 	enum isl_dim_type type, unsigned first, unsigned n);
+__isl_give isl_union_map *isl_union_map_remove_divs(
+	__isl_take isl_union_map *bmap);
 
 __isl_export
 isl_bool isl_union_map_is_empty(__isl_keep isl_union_map *umap);

Modified: polly/trunk/lib/External/isl/include/isl/union_set.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/union_set.h?rev=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/union_set.h (original)
+++ polly/trunk/lib/External/isl/include/isl/union_set.h Sun Jun  4 14:13:10 2017
@@ -91,6 +91,8 @@ __isl_give isl_union_set *isl_union_set_
 __isl_give isl_union_set *isl_union_set_project_out(
 	__isl_take isl_union_set *uset,
 	enum isl_dim_type type, unsigned first, unsigned n);
+__isl_give isl_union_set *isl_union_set_remove_divs(
+	__isl_take isl_union_set *bset);
 
 isl_bool isl_union_set_is_params(__isl_keep isl_union_set *uset);
 __isl_export
@@ -114,6 +116,8 @@ int isl_union_set_n_set(__isl_keep isl_u
 __isl_export
 isl_stat isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
 	isl_stat (*fn)(__isl_take isl_set *set, void *user), void *user);
+__isl_give isl_basic_set_list *isl_union_set_get_basic_set_list(
+	__isl_keep isl_union_set *uset);
 isl_bool isl_union_set_contains(__isl_keep isl_union_set *uset,
 	__isl_keep isl_space *space);
 __isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset,

Modified: polly/trunk/lib/External/isl/isl_farkas.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_farkas.c?rev=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_farkas.c (original)
+++ polly/trunk/lib/External/isl/isl_farkas.c Sun Jun  4 14:13:10 2017
@@ -371,6 +371,24 @@ __isl_give isl_basic_set *isl_set_coeffi
 	return coeff;
 }
 
+/* Wrapper around isl_basic_set_coefficients for use
+ * as a isl_basic_set_list_map callback.
+ */
+static __isl_give isl_basic_set *coefficients_wrap(
+	__isl_take isl_basic_set *bset, void *user)
+{
+	return isl_basic_set_coefficients(bset);
+}
+
+/* Replace the elements of "list" by the result of applying
+ * isl_basic_set_coefficients to them.
+ */
+__isl_give isl_basic_set_list *isl_basic_set_list_coefficients(
+	__isl_take isl_basic_set_list *list)
+{
+	return isl_basic_set_list_map(list, &coefficients_wrap, NULL);
+}
+
 /* Construct a basic set containing the elements that satisfy all
  * affine constraints whose coefficient tuples are
  * contained in the given set.

Modified: polly/trunk/lib/External/isl/isl_list_templ.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_list_templ.c?rev=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_list_templ.c (original)
+++ polly/trunk/lib/External/isl/isl_list_templ.c Sun Jun  4 14:13:10 2017
@@ -2,6 +2,7 @@
  * Copyright 2008-2009 Katholieke Universiteit Leuven
  * Copyright 2011      INRIA Saclay
  * Copyright 2012-2013 Ecole Normale Superieure
+ * Copyright 2017      Sven Verdoolaege
  *
  * Use of this software is governed by the MIT license
  *
@@ -130,6 +131,18 @@ static __isl_give LIST(EL) *FN(LIST(EL),
 	return res;
 }
 
+/* Check that "index" is a valid position in "list".
+ */
+static isl_stat FN(LIST(EL),check_index)(__isl_keep LIST(EL) *list, int index)
+{
+	if (!list)
+		return isl_stat_error;
+	if (index < 0 || index >= list->n)
+		isl_die(FN(LIST(EL),get_ctx)(list), isl_error_invalid,
+			"index out of bounds", return isl_stat_error);
+	return isl_stat_ok;
+}
+
 __isl_give LIST(EL) *FN(LIST(EL),add)(__isl_take LIST(EL) *list,
 	__isl_take struct EL *el)
 {
@@ -239,11 +252,8 @@ int FN(FN(LIST(EL),n),BASE)(__isl_keep L
 
 __isl_give EL *FN(FN(LIST(EL),get),BASE)(__isl_keep LIST(EL) *list, int index)
 {
-	if (!list)
+	if (FN(LIST(EL),check_index)(list, index) < 0)
 		return NULL;
-	if (index < 0 || index >= list->n)
-		isl_die(list->ctx, isl_error_invalid,
-			"index out of bounds", return NULL);
 	return FN(EL,copy)(list->p[index]);
 }
 
@@ -254,9 +264,8 @@ __isl_give LIST(EL) *FN(FN(LIST(EL),set)
 {
 	if (!list || !el)
 		goto error;
-	if (index < 0 || index >= list->n)
-		isl_die(list->ctx, isl_error_invalid,
-			"index out of bounds", goto error);
+	if (FN(LIST(EL),check_index)(list, index) < 0)
+		goto error;
 	if (list->p[index] == el) {
 		FN(EL,free)(el);
 		return list;
@@ -273,6 +282,40 @@ error:
 	return NULL;
 }
 
+/* Return the element at position "index" of "list".
+ * This may be either a copy or the element itself
+ * if there is only one reference to "list".
+ * This allows the element to be modified inplace
+ * if both the list and the element have only a single reference.
+ * The caller is not allowed to modify "list" between
+ * this call to isl_list_*_take_* and a subsequent call
+ * to isl_list_*_restore_*.
+ * The only exception is that isl_list_*_free can be called instead.
+ */
+static __isl_give EL *FN(FN(LIST(EL),take),BASE)(__isl_keep LIST(EL) *list,
+	int index)
+{
+	EL *el;
+
+	if (FN(LIST(EL),check_index)(list, index) < 0)
+		return NULL;
+	if (list->ref != 1)
+		return FN(FN(LIST(EL),get),BASE)(list, index);
+	el = list->p[index];
+	list->p[index] = NULL;
+	return el;
+}
+
+/* Set the element at position "index" of "list" to "el",
+ * where the position may be empty due to a previous call
+ * to isl_list_*_take_*.
+ */
+static __isl_give LIST(EL) *FN(FN(LIST(EL),restore),BASE)(
+	__isl_take LIST(EL) *list, int index, __isl_take EL *el)
+{
+	return FN(FN(LIST(EL),set),BASE)(list, index, el);
+}
+
 isl_stat FN(LIST(EL),foreach)(__isl_keep LIST(EL) *list,
 	isl_stat (*fn)(__isl_take EL *el, void *user), void *user)
 {
@@ -292,6 +335,29 @@ isl_stat FN(LIST(EL),foreach)(__isl_keep
 	return isl_stat_ok;
 }
 
+/* Replace each element in "list" by the result of calling "fn"
+ * on the element.
+ */
+__isl_give LIST(EL) *FN(LIST(EL),map)(__isl_keep LIST(EL) *list,
+	__isl_give EL *(*fn)(__isl_take EL *el, void *user), void *user)
+{
+	int i, n;
+
+	if (!list)
+		return NULL;
+
+	n = list->n;
+	for (i = 0; i < n; ++i) {
+		EL *el = FN(FN(LIST(EL),take),BASE)(list, i);
+		if (!el)
+			return FN(LIST(EL),free)(list);
+		el = fn(el, user);
+		list = FN(FN(LIST(EL),restore),BASE)(list, i, el);
+	}
+
+	return list;
+}
+
 /* Internal data structure for isl_*_list_sort.
  *
  * "cmp" is the original comparison function.
@@ -461,6 +527,26 @@ error:
 	return NULL;
 }
 
+/* Append the elements of "list2" to "list1", where "list1" is known
+ * to have only a single reference and enough room to hold
+ * the extra elements.
+ */
+static __isl_give LIST(EL) *FN(LIST(EL),concat_inplace)(
+	__isl_take LIST(EL) *list1, __isl_take LIST(EL) *list2)
+{
+	int i;
+
+	for (i = 0; i < list2->n; ++i)
+		list1 = FN(LIST(EL),add)(list1, FN(EL,copy)(list2->p[i]));
+	FN(LIST(EL),free)(list2);
+	return list1;
+}
+
+/* Concatenate "list1" and "list2".
+ * If "list1" has only one reference and has enough room
+ * for the elements of "list2", the add the elements to "list1" itself.
+ * Otherwise, create a new list to store the result.
+ */
 __isl_give LIST(EL) *FN(LIST(EL),concat)(__isl_take LIST(EL) *list1,
 	__isl_take LIST(EL) *list2)
 {
@@ -471,6 +557,9 @@ __isl_give LIST(EL) *FN(LIST(EL),concat)
 	if (!list1 || !list2)
 		goto error;
 
+	if (list1->ref == 1 && list1->n + list2->n <= list1->size)
+		return FN(LIST(EL),concat_inplace)(list1, list2);
+
 	ctx = FN(LIST(EL),get_ctx)(list1);
 	res = FN(LIST(EL),alloc)(ctx, list1->n + list2->n);
 	for (i = 0; i < list1->n; ++i)

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_scheduler.c (original)
+++ polly/trunk/lib/External/isl/isl_scheduler.c Sun Jun  4 14:13:10 2017
@@ -3,6 +3,7 @@
  * Copyright 2012-2014 Ecole Normale Superieure
  * Copyright 2015-2016 Sven Verdoolaege
  * Copyright 2016      INRIA Paris
+ * Copyright 2017      Sven Verdoolaege
  *
  * Use of this software is governed by the MIT license
  *
@@ -1586,6 +1587,9 @@ static __isl_give isl_dim_map *intra_dim
 	unsigned total;
 	isl_dim_map *dim_map;
 
+	if (!node)
+		return NULL;
+
 	total = isl_basic_set_total_dim(graph->lp);
 	pos = node_var_coef_offset(node);
 	dim_map = isl_dim_map_alloc(ctx, total);
@@ -1621,6 +1625,9 @@ static __isl_give isl_dim_map *inter_dim
 	unsigned total;
 	isl_dim_map *dim_map;
 
+	if (!src || !dst)
+		return NULL;
+
 	total = isl_basic_set_total_dim(graph->lp);
 	dim_map = isl_dim_map_alloc(ctx, total);
 
@@ -2061,11 +2068,7 @@ static int is_any_validity(struct isl_sc
 
 /* How many times should we count the constraints in "edge"?
  *
- * If carry is set, then we are counting the number of
- * (validity or conditional validity) constraints that will be added
- * in setup_carry_lp and we count each edge exactly once.
- *
- * Otherwise, we count as follows
+ * We count as follows
  * validity		-> 1 (>= 0)
  * validity+proximity	-> 2 (>= 0 and upper bound)
  * proximity		-> 2 (lower and upper bound)
@@ -2077,11 +2080,8 @@ static int is_any_validity(struct isl_sc
  * If "use_coincidence" is set, then we treat coincidence edges as local edges.
  * Otherwise, we ignore them.
  */
-static int edge_multiplicity(struct isl_sched_edge *edge, int carry,
-	int use_coincidence)
+static int edge_multiplicity(struct isl_sched_edge *edge, int use_coincidence)
 {
-	if (carry)
-		return 1;
 	if (is_proximity(edge) || is_local(edge))
 		return 2;
 	if (use_coincidence && is_coincidence(edge))
@@ -2098,10 +2098,10 @@ static int edge_multiplicity(struct isl_
  */
 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 carry, int use_coincidence)
+	int *n_eq, int *n_ineq, int use_coincidence)
 {
 	isl_basic_set *coef;
-	int f = edge_multiplicity(edge, carry, use_coincidence);
+	int f = edge_multiplicity(edge, use_coincidence);
 
 	if (f == 0) {
 		isl_map_free(map);
@@ -2143,7 +2143,7 @@ static int count_constraints(struct isl_
 		isl_map *map = isl_map_copy(edge->map);
 
 		if (count_map_constraints(graph, edge, map, n_eq, n_ineq,
-					    0, use_coincidence) < 0)
+					    use_coincidence) < 0)
 			return -1;
 	}
 
@@ -3521,165 +3521,260 @@ static __isl_give isl_schedule_node *com
 	return node;
 }
 
-/* Add constraints to graph->lp that force the dependence "map" (which
- * is part of the dependence relation of "edge")
- * to be respected and attempt to carry it, where the edge is one from
- * a node j to itself.  "pos" is the sequence number of the given map.
- * That is, add constraints that enforce
+/* 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)
+ * 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_x (y - x) >= e_i
  *
- * for each (x,y) in R.
- * We obtain general constraints on coefficients (c_0, c_n, c_x)
- * of valid constraints for (y - x) and then plug in (-e_i, 0, c_j_x),
- * with each coefficient in c_j_x represented as a pair of non-negative
- * coefficients.
+ * 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),
+ * taking into account that each coefficient in c_j_x is represented
+ * as a pair of non-negative coefficients.
  */
-static int add_intra_constraints(struct isl_sched_graph *graph,
-	struct isl_sched_edge *edge, __isl_take isl_map *map, int pos)
+static isl_stat add_intra_constraints(struct isl_sched_graph *graph,
+	struct isl_sched_node *node, __isl_take isl_basic_set *coef, int pos)
 {
 	int offset;
-	isl_ctx *ctx = isl_map_get_ctx(map);
+	isl_ctx *ctx;
 	isl_dim_map *dim_map;
-	isl_basic_set *coef;
-	struct isl_sched_node *node = edge->src;
 
-	coef = intra_coefficients(graph, node, map);
 	if (!coef)
-		return -1;
+		return isl_stat_error;
 
+	ctx = isl_basic_set_get_ctx(coef);
 	offset = coef_var_offset(coef);
 	dim_map = intra_dim_map(ctx, graph, node, offset, 1);
 	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 0;
+	return isl_stat_ok;
 }
 
-/* Add constraints to graph->lp that force the dependence "map" (which
- * is part of the dependence relation of "edge")
- * to be respected and attempt to carry it, where the edge is one from
- * node j to node k.  "pos" is the sequence number of the given map.
- * That is, add constraints that enforce
+/* 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.
+ * "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".
+ *
+ * The constraints added to graph->lp need to enforce
  *
  *	(c_k_0 + c_k_n n + c_k_x y) - (c_j_0 + c_j_n n + c_j_x x) >= e_i
  *
- * for each (x,y) in R.
- * We obtain general constraints on coefficients (c_0, c_n, c_x, c_y)
- * of valid constraints for R and then plug in
+ * for each (x,y) in the dependence relation of the edge.
+ * That is,
  * (-e_i + c_k_0 - c_j_0, c_k_n - c_j_n, -c_j_x, c_k_x)
- * with each coefficient (except e_i, c_*_0 and c_*_n)
- * represented as a pair of non-negative coefficients.
- */
-static int add_inter_constraints(struct isl_sched_graph *graph,
-	struct isl_sched_edge *edge, __isl_take isl_map *map, int pos)
+ * 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.
+ */
+static isl_stat add_inter_constraints(struct isl_sched_graph *graph,
+	struct isl_sched_node *src, struct isl_sched_node *dst,
+	__isl_take isl_basic_set *coef, int pos)
 {
 	int offset;
-	isl_ctx *ctx = isl_map_get_ctx(map);
+	isl_ctx *ctx;
 	isl_dim_map *dim_map;
-	isl_basic_set *coef;
-	struct isl_sched_node *src = edge->src;
-	struct isl_sched_node *dst = edge->dst;
 
-	coef = inter_coefficients(graph, edge, map);
 	if (!coef)
-		return -1;
+		return isl_stat_error;
 
+	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);
 	graph->lp = add_constraints_dim_map(graph->lp, coef, dim_map);
 
-	return 0;
+	return isl_stat_ok;
 }
 
-/* Add constraints to graph->lp that force all (conditional) validity
- * dependences to be respected and attempt to carry them.
+/* 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.
+ */
+struct isl_carry {
+	isl_basic_set_list *intra;
+	isl_basic_set_list *inter;
+};
+
+/* Free all the data stored in "carry".
  */
-static isl_stat add_all_constraints(struct isl_sched_graph *graph)
+static void isl_carry_clear(struct isl_carry *carry)
 {
-	int i, j;
-	int pos;
+	isl_basic_set_list_free(carry->intra);
+	isl_basic_set_list_free(carry->inter);
+}
 
-	pos = 0;
-	for (i = 0; i < graph->n_edge; ++i) {
-		struct isl_sched_edge *edge = &graph->edge[i];
+/* Return a pointer to the node in "graph" that lives in "space".
+ * If the requested node has been compressed, then "space"
+ * corresponds to the compressed space.
+ *
+ * First try and see if "space" is the space of an uncompressed node.
+ * If so, return that node.
+ * Otherwise, "space" was constructed by construct_compressed_id and
+ * contains a user pointer pointing to the node in the tuple id.
+ */
+static struct isl_sched_node *graph_find_compressed_node(isl_ctx *ctx,
+	struct isl_sched_graph *graph, __isl_keep isl_space *space)
+{
+	isl_id *id;
+	struct isl_sched_node *node;
 
-		if (!is_any_validity(edge))
-			continue;
+	if (!space)
+		return NULL;
 
-		for (j = 0; j < edge->map->n; ++j) {
-			isl_basic_map *bmap;
-			isl_map *map;
-
-			bmap = isl_basic_map_copy(edge->map->p[j]);
-			map = isl_map_from_basic_map(bmap);
-
-			if (edge->src == edge->dst &&
-			    add_intra_constraints(graph, edge, map, pos) < 0)
-				return isl_stat_error;
-			if (edge->src != edge->dst &&
-			    add_inter_constraints(graph, edge, map, pos) < 0)
-				return isl_stat_error;
-			++pos;
-		}
-	}
+	node = graph_find_node(ctx, graph, space);
+	if (node)
+		return node;
 
-	return isl_stat_ok;
+	id = isl_space_get_tuple_id(space, isl_dim_set);
+	node = isl_id_get_user(id);
+	isl_id_free(id);
+
+	if (!node)
+		return NULL;
+
+	if (!(node >= &graph->node[0] && node < &graph->node[graph->n]))
+		isl_die(ctx, isl_error_internal,
+			"space points to invalid node", return NULL);
+
+	return node;
 }
 
-/* Count the number of equality and inequality constraints
- * that will be added to the carry_lp problem.
- * We count each edge exactly once.
+/* Internal data structure for add_all_constraints.
+ *
+ * "graph" is the schedule constraint graph for which an LP problem
+ * is being constructed.
+ * "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 pos;
+};
+
+/* Add the constraints "coef" derived from an edge from a node to itself
+ * to data->graph->lp in order to respect the dependences and
+ * to try and carry them.
+ *
+ * The space of "coef" is of the form
+ *
+ *	coefficients[[c_cst, c_n] -> S[c_x]]
+ *
+ * with S[c_x] the (compressed) space of the node.
+ * Extract the node from the space and call add_intra_constraints.
  */
-static isl_stat count_all_constraints(struct isl_sched_graph *graph,
-	int *n_eq, int *n_ineq)
+static isl_stat lp_add_intra(__isl_take isl_basic_set *coef, void *user)
 {
-	int i, j;
+	struct isl_add_all_constraints_data *data = user;
+	isl_space *space;
+	struct isl_sched_node *node;
 
-	*n_eq = *n_ineq = 0;
-	for (i = 0; i < graph->n_edge; ++i) {
-		struct isl_sched_edge *edge = &graph->edge[i];
+	space = isl_basic_set_get_space(coef);
+	space = isl_space_range(isl_space_unwrap(space));
+	node = graph_find_compressed_node(data->ctx, data->graph, space);
+	isl_space_free(space);
+	return add_intra_constraints(data->graph, node, coef, data->pos++);
+}
 
-		if (!is_any_validity(edge))
-			continue;
+/* 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.
+ *
+ * The space of "coef" is of the form
+ *
+ *	coefficients[[c_cst, c_n] -> [S_j[c_x] -> S_k[c_y]]]
+ *
+ * with S_j[c_x] and S_k[c_y] the (compressed) spaces of the nodes.
+ * Extract the nodes from the space and call add_inter_constraints.
+ */
+static isl_stat lp_add_inter(__isl_take isl_basic_set *coef, void *user)
+{
+	struct isl_add_all_constraints_data *data = user;
+	isl_space *space, *dom;
+	struct isl_sched_node *src, *dst;
 
-		for (j = 0; j < edge->map->n; ++j) {
-			isl_basic_map *bmap;
-			isl_map *map;
-
-			bmap = isl_basic_map_copy(edge->map->p[j]);
-			map = isl_map_from_basic_map(bmap);
-
-			if (count_map_constraints(graph, edge, map,
-						  n_eq, n_ineq, 1, 0) < 0)
-				    return isl_stat_error;
-		}
-	}
+	space = isl_basic_set_get_space(coef);
+	space = isl_space_unwrap(isl_space_range(isl_space_unwrap(space)));
+	dom = isl_space_domain(isl_space_copy(space));
+	src = graph_find_compressed_node(data->ctx, data->graph, dom);
+	isl_space_free(dom);
+	space = isl_space_range(space);
+	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++);
+}
+
+/* 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.
+ */
+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)
+{
+	struct isl_add_all_constraints_data data = { ctx, graph };
+
+	data.pos = 0;
+	if (isl_basic_set_list_foreach(intra, &lp_add_intra, &data) < 0)
+		return isl_stat_error;
+	if (isl_basic_set_list_foreach(inter, &lp_add_inter, &data) < 0)
+		return isl_stat_error;
 	return isl_stat_ok;
 }
 
-/* Return the total number of (validity) edges that carry_dependences will
- * attempt to carry.
+/* Internal data structure for count_all_constraints
+ * for keeping track of the number of equality and inequality constraints.
  */
-static int count_carry_edges(struct isl_sched_graph *graph)
+struct isl_sched_count {
+	int n_eq;
+	int n_ineq;
+};
+
+/* Add the number of equality and inequality constraints of "bset"
+ * to data->n_eq and data->n_ineq.
+ */
+static isl_stat bset_update_count(__isl_take isl_basic_set *bset, void *user)
 {
-	int i;
-	int n_edge;
+	struct isl_sched_count *data = user;
 
-	n_edge = 0;
-	for (i = 0; i < graph->n_edge; ++i) {
-		struct isl_sched_edge *edge = &graph->edge[i];
+	data->n_eq += isl_basic_set_n_equality(bset);
+	data->n_ineq += isl_basic_set_n_inequality(bset);
+	isl_basic_set_free(bset);
 
-		if (!is_any_validity(edge))
-			continue;
+	return isl_stat_ok;
+}
 
-		n_edge += isl_map_n_basic_map(edge->map);
-	}
+/* Count the number of equality and inequality constraints
+ * that will be added to the carry_lp problem.
+ * We count each edge exactly once.
+ * "intra" is the sequence of coefficient constraints for intra-node edges.
+ * "inter" is the sequence of coefficient constraints for inter-node edges.
+ */
+static isl_stat count_all_constraints(__isl_keep isl_basic_set_list *intra,
+	__isl_keep isl_basic_set_list *inter, int *n_eq, int *n_ineq)
+{
+	struct isl_sched_count data;
+
+	data.n_eq = data.n_ineq = 0;
+	if (isl_basic_set_list_foreach(inter, &bset_update_count, &data) < 0)
+		return isl_stat_error;
+	if (isl_basic_set_list_foreach(intra, &bset_update_count, &data) < 0)
+		return isl_stat_error;
 
-	return n_edge;
+	*n_eq = data.n_eq;
+	*n_ineq = data.n_ineq;
+
+	return isl_stat_ok;
 }
 
 /* Construct an LP problem for finding schedule coefficients
@@ -3688,12 +3783,9 @@ static int count_carry_edges(struct isl_
  * from below by e_i, with 0 <= e_i <= 1 and then maximize the sum
  * of all e_i's.  Dependences with e_i = 0 in the solution are simply
  * respected, while those with e_i > 0 (in practice e_i = 1) are carried.
- * Note that if the dependence relation is a union of basic maps,
- * then we have to consider each basic map individually as it may only
- * be possible to carry the dependences expressed by some of those
- * basic maps and not all of them.
- * Below, we consider each of those basic maps as a separate "edge".
- * "n_edge" is the number of these edges.
+ * "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.
  *
  * All variables of the LP are non-negative.  The actual coefficients
  * may be negative, so each coefficient is represented as the difference
@@ -3716,7 +3808,8 @@ static int count_carry_edges(struct isl_
  * 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)
+	int n_edge, __isl_keep isl_basic_set_list *intra,
+	__isl_keep isl_basic_set_list *inter)
 {
 	int i;
 	int k;
@@ -3731,7 +3824,7 @@ static isl_stat setup_carry_lp(isl_ctx *
 		total += 1 + node->nparam + 2 * node->nvar;
 	}
 
-	if (count_all_constraints(graph, &n_eq, &n_ineq) < 0)
+	if (count_all_constraints(intra, inter, &n_eq, &n_ineq) < 0)
 		return isl_stat_error;
 
 	dim = isl_space_set_alloc(ctx, 0, total);
@@ -3764,7 +3857,7 @@ static isl_stat setup_carry_lp(isl_ctx *
 		isl_int_set_si(graph->lp->ineq[k][0], 1);
 	}
 
-	if (add_all_constraints(graph) < 0)
+	if (add_all_constraints(ctx, graph, intra, inter) < 0)
 		return isl_stat_error;
 
 	return isl_stat_ok;
@@ -4092,10 +4185,12 @@ static int carries_dependences(__isl_kee
 /* Return the lexicographically smallest rational point in "lp",
  * assuming that all variables are non-negative and performing some
  * additional sanity checks.
+ * If "want_integral" is set, then compute the lexicographically smallest
+ * integer point instead.
  * In particular, "lp" should not be empty by construction.
  * Double check that this is the case.
- * Also, check that dependences are carried for at least one of
- * the "n_edge" edges.
+ * If dependences are not carried for any of the "n_edge" edges,
+ * then return an empty vector.
  *
  * If the schedule_treat_coalescing option is set and
  * if the computed schedule performs loop coalescing on a given node,
@@ -4107,11 +4202,22 @@ static int carries_dependences(__isl_kee
  * to cut out this solution.  Repeat this process until no more loop
  * coalescing occurs or until no more dependences can be carried.
  * In the latter case, revert to the previously computed solution.
+ *
+ * If the caller requests an integral solution and if coalescing should
+ * be treated, then perform the coalescing treatment first as
+ * an integral solution computed before coalescing treatment
+ * would carry the same number of edges and would therefore probably
+ * also be coalescing.
+ *
+ * To allow the coalescing treatment to be performed first,
+ * the initial solution is allowed to be rational and it is only
+ * cut out (if needed) in the next iteration, if no coalescing measures
+ * were taken.
  */
 static __isl_give isl_vec *non_neg_lexmin(struct isl_sched_graph *graph,
-	__isl_take isl_basic_set *lp, int n_edge)
+	__isl_take isl_basic_set *lp, int n_edge, int want_integral)
 {
-	int i, pos;
+	int i, pos, cut;
 	isl_ctx *ctx;
 	isl_tab_lexmin *tl;
 	isl_vec *sol, *prev = NULL;
@@ -4123,23 +4229,30 @@ static __isl_give isl_vec *non_neg_lexmi
 	treat_coalescing = isl_options_get_schedule_treat_coalescing(ctx);
 	tl = isl_tab_lexmin_from_basic_set(lp);
 
+	cut = 0;
 	do {
+		int integral;
+
+		if (cut)
+			tl = isl_tab_lexmin_cut_to_integer(tl);
 		sol = non_empty_solution(tl);
 		if (!sol)
 			goto error;
 
+		integral = isl_int_is_one(sol->el[0]);
 		if (!carries_dependences(sol, n_edge)) {
 			if (!prev)
-				isl_die(ctx, isl_error_unknown,
-					"unable to carry dependences",
-					goto error);
+				prev = isl_vec_alloc(ctx, 0);
 			isl_vec_free(sol);
 			sol = prev;
 			break;
 		}
 		prev = isl_vec_free(prev);
+		cut = want_integral && !integral;
+		if (cut)
+			prev = sol;
 		if (!treat_coalescing)
-			break;
+			continue;
 		for (i = 0; i < graph->n; ++i) {
 			struct isl_sched_node *node = &graph->node[i];
 
@@ -4152,8 +4265,9 @@ static __isl_give isl_vec *non_neg_lexmi
 		if (i < graph->n) {
 			prev = sol;
 			tl = zero_out_node_coef(tl, &graph->node[i], pos);
+			cut = 0;
 		}
-	} while (i < graph->n);
+	} while (prev);
 
 	isl_tab_lexmin_free(tl);
 
@@ -4165,14 +4279,228 @@ error:
 	return NULL;
 }
 
+/* If "edge" is an edge from a node to itself, then add the corresponding
+ * dependence relation to "umap".
+ * If "node" has been compressed, then the dependence relation
+ * is also compressed first.
+ */
+static __isl_give isl_union_map *add_intra(__isl_take isl_union_map *umap,
+	struct isl_sched_edge *edge)
+{
+	isl_map *map;
+	struct isl_sched_node *node = edge->src;
+
+	if (edge->src != edge->dst)
+		return umap;
+
+	map = isl_map_copy(edge->map);
+	if (node->compressed) {
+		map = isl_map_preimage_domain_multi_aff(map,
+				    isl_multi_aff_copy(node->decompress));
+		map = isl_map_preimage_range_multi_aff(map,
+				    isl_multi_aff_copy(node->decompress));
+	}
+	umap = isl_union_map_add_map(umap, map);
+	return umap;
+}
+
+/* If "edge" is an edge from a node to another node, then add the corresponding
+ * dependence relation to "umap".
+ * If the source or destination nodes of "edge" have been compressed,
+ * then the dependence relation is also compressed first.
+ */
+static __isl_give isl_union_map *add_inter(__isl_take isl_union_map *umap,
+	struct isl_sched_edge *edge)
+{
+	isl_map *map;
+
+	if (edge->src == edge->dst)
+		return umap;
+
+	map = isl_map_copy(edge->map);
+	if (edge->src->compressed)
+		map = isl_map_preimage_domain_multi_aff(map,
+				    isl_multi_aff_copy(edge->src->decompress));
+	if (edge->dst->compressed)
+		map = isl_map_preimage_range_multi_aff(map,
+				    isl_multi_aff_copy(edge->dst->decompress));
+	umap = isl_union_map_add_map(umap, map);
+	return umap;
+}
+
+/* For each (conditional) validity edge in "graph",
+ * add the corresponding dependence relation using "add"
+ * to a collection of dependence relations and return the result.
+ * If "coincidence" is set, then coincidence edges are considered as well.
+ */
+static __isl_give isl_union_map *collect_validity(struct isl_sched_graph *graph,
+	__isl_give isl_union_map *(*add)(__isl_take isl_union_map *umap,
+		struct isl_sched_edge *edge), int coincidence)
+{
+	int i;
+	isl_space *space;
+	isl_union_map *umap;
+
+	space = isl_space_copy(graph->node[0].space);
+	umap = isl_union_map_empty(space);
+
+	for (i = 0; i < graph->n_edge; ++i) {
+		struct isl_sched_edge *edge = &graph->edge[i];
+
+		if (!is_any_validity(edge) &&
+		    (!coincidence || !is_coincidence(edge)))
+			continue;
+
+		umap = add(umap, edge);
+	}
+
+	return umap;
+}
+
+/* For each dependence relation on a (conditional) validity edge
+ * from a node to itself,
+ * construct the set of coefficients of valid constraints for elements
+ * in that dependence relation and collect the results.
+ * 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
+ *
+ *	c_0 + c_n n + 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
+ * by intra_coefficients, except that it operates on multiple
+ * edges together.
+ *
+ * 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
+ * basic maps and not all of them.
+ * The collected validity constraints are therefore not coalesced and
+ * it is assumed that they are not coalesced automatically.
+ * Duplicate basic maps can be removed, however.
+ * 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)
+{
+	isl_union_map *intra;
+	isl_union_set *delta;
+	isl_basic_set_list *list;
+
+	intra = collect_validity(graph, &add_intra, coincidence);
+	delta = isl_union_map_deltas(intra);
+	delta = isl_union_set_remove_divs(delta);
+	list = isl_union_set_get_basic_set_list(delta);
+	isl_union_set_free(delta);
+
+	return isl_basic_set_list_coefficients(list);
+}
+
+/* For each dependence relation on a (conditional) validity edge
+ * from a node to some other node,
+ * construct the set of coefficients of valid constraints for elements
+ * in that dependence relation and collect the results.
+ * 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, c_y) are constructed such that
+ *
+ *	c_0 + c_n n + c_x x + c_y y >= 0 for each (x,y) in R
+ *
+ * This computation is essentially the same as that performed
+ * by inter_coefficients, except that it operates on multiple
+ * edges together.
+ *
+ * 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
+ * basic maps and not all of them.
+ * The collected validity constraints are therefore not coalesced and
+ * it is assumed that they are not coalesced automatically.
+ * Duplicate basic maps can be removed, however.
+ * 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_inter_validity(
+	struct isl_sched_graph *graph, int coincidence)
+{
+	isl_union_map *inter;
+	isl_union_set *wrap;
+	isl_basic_set_list *list;
+
+	inter = collect_validity(graph, &add_inter, coincidence);
+	inter = isl_union_map_remove_divs(inter);
+	wrap = isl_union_map_wrap(inter);
+	list = isl_union_set_get_basic_set_list(wrap);
+	isl_union_set_free(wrap);
+	return isl_basic_set_list_coefficients(list);
+}
+
+/* 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.
+ * If "fallback" is set, then the carrying is performed as a fallback
+ * for the Pluto-like scheduler.
+ * If "coincidence" is set, then try and carry coincidence edges as well.
+ *
+ * The variable "n_edge" stores the number of groups that should be carried.
+ * If none of the "n_edge" groups can be carried
+ * then return an empty vector.
+ * If, moreover, "n_edge" is zero, then the LP problem does not even
+ * need to be constructed.
+ *
+ * If a fallback solution is being computed, then compute an integral solution
+ * for the coefficients rather than using the numerators
+ * of a rational solution.
+ */
+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 };
+
+	carry.intra = collect_intra_validity(graph, coincidence);
+	carry.inter = collect_inter_validity(graph, coincidence);
+	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);
+	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;
+
+	isl_carry_clear(&carry);
+	lp = isl_basic_set_copy(graph->lp);
+	return non_neg_lexmin(graph, lp, n_edge, fallback);
+error:
+	isl_carry_clear(&carry);
+	return NULL;
+}
+
 /* Construct a schedule row for each node such that as many validity dependences
  * as possible are carried and then continue with the next band.
+ * If "fallback" is set, then the carrying is performed as a fallback
+ * for the Pluto-like scheduler.
+ * If "coincidence" is set, then try and carry coincidence edges as well.
  *
  * If there are no validity dependences, then no dependence can be carried and
  * the procedure is guaranteed to fail.  If there is more than one component,
  * then try computing a schedule on each component separately
  * to prevent or at least postpone this failure.
  *
+ * If a schedule row is computed, then check that dependences are carried
+ * for at least one of the edges.
+ *
  * If the computed schedule row turns out to be trivial on one or
  * more nodes where it should not be trivial, then we throw it away
  * and try again on each component separately.
@@ -4190,30 +4518,27 @@ error:
  * This insertion and the continued construction is performed by split_scaled
  * after optionally checking for non-trivial common divisors.
  */
-static __isl_give isl_schedule_node *carry_dependences(
-	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph)
+static __isl_give isl_schedule_node *carry(__isl_take isl_schedule_node *node,
+	struct isl_sched_graph *graph, int fallback, int coincidence)
 {
-	int n_edge;
 	int trivial;
 	isl_ctx *ctx;
 	isl_vec *sol;
-	isl_basic_set *lp;
 
 	if (!node)
 		return NULL;
 
-	n_edge = count_carry_edges(graph);
-	if (n_edge == 0 && graph->scc > 1)
-		return compute_component_schedule(node, graph, 1);
-
 	ctx = isl_schedule_node_get_ctx(node);
-	if (setup_carry_lp(ctx, graph, n_edge) < 0)
-		return isl_schedule_node_free(node);
-
-	lp = isl_basic_set_copy(graph->lp);
-	sol = non_neg_lexmin(graph, lp, n_edge);
+	sol = compute_carrying_sol(ctx, graph, fallback, coincidence);
 	if (!sol)
 		return isl_schedule_node_free(node);
+	if (sol->size == 0) {
+		isl_vec_free(sol);
+		if (graph->scc > 1)
+			return compute_component_schedule(node, graph, 1);
+		isl_die(ctx, isl_error_unknown, "unable to carry dependences",
+			return isl_schedule_node_free(node));
+	}
 
 	trivial = is_any_trivial(graph, sol);
 	if (trivial < 0) {
@@ -4231,6 +4556,50 @@ static __isl_give isl_schedule_node *car
 	return split_scaled(node, graph);
 }
 
+/* Construct a schedule row for each node such that as many validity dependences
+ * as possible are carried and then continue with the next band.
+ * Do so as a fallback for the Pluto-like scheduler.
+ * If "coincidence" is set, then try and carry coincidence edges as well.
+ */
+static __isl_give isl_schedule_node *carry_fallback(
+	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph,
+	int coincidence)
+{
+	return carry(node, graph, 1, coincidence);
+}
+
+/* Construct a schedule row for each node such that as many validity dependences
+ * as possible are carried and then continue with the next band.
+ * Do so for the case where the Feautrier scheduler was selected
+ * by the user.
+ */
+static __isl_give isl_schedule_node *carry_feautrier(
+	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph)
+{
+	return carry(node, graph, 0, 0);
+}
+
+/* Construct a schedule row for each node such that as many validity dependences
+ * as possible are carried and then continue with the next band.
+ * Do so as a fallback for the Pluto-like scheduler.
+ */
+static __isl_give isl_schedule_node *carry_dependences(
+	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph)
+{
+	return carry_fallback(node, graph, 0);
+}
+
+/* Construct a schedule row for each node such that as many validity or
+ * coincidence dependences as possible are carried and
+ * then continue with the next band.
+ * Do so as a fallback for the Pluto-like scheduler.
+ */
+static __isl_give isl_schedule_node *carry_coincidence(
+	__isl_take isl_schedule_node *node, struct isl_sched_graph *graph)
+{
+	return carry_fallback(node, graph, 1);
+}
+
 /* Topologically sort statements mapped to the same schedule iteration
  * and add insert a sequence node in front of "node"
  * corresponding to this order.
@@ -4331,7 +4700,7 @@ static int need_feautrier_step(isl_ctx *
 static __isl_give isl_schedule_node *compute_schedule_wcc_feautrier(
 	isl_schedule_node *node, struct isl_sched_graph *graph)
 {
-	return carry_dependences(node, graph);
+	return carry_feautrier(node, graph);
 }
 
 /* Turn off the "local" bit on all (condition) edges.
@@ -4540,8 +4909,11 @@ error:
  *	pair of SCCs between which to split)
  * - continue with the next band (assuming the current band has at least
  *	one row)
- * - try to carry as many dependences as possible and continue with the next
- *	band
+ * - if outer coincidence needs to be enforced, then try to carry as many
+ *	validity or coincidence dependences as possible and
+ *	continue with the next band
+ * - try to carry as many validity dependences as possible and
+ *	continue with the next band
  * In each case, we first insert a band node in the schedule tree
  * if any rows have been computed.
  *
@@ -4571,6 +4943,8 @@ static __isl_give isl_schedule_node *com
 			return compute_next_band(node, graph, 1);
 		if (!initialized && compute_maxvar(graph) < 0)
 			return isl_schedule_node_free(node);
+		if (isl_options_get_schedule_outer_coincidence(ctx))
+			return carry_coincidence(node, graph);
 		return carry_dependences(node, graph);
 	}
 

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_tab.h (original)
+++ polly/trunk/lib/External/isl/isl_tab.h Sun Jun  4 14:13:10 2017
@@ -281,6 +281,8 @@ __isl_give isl_tab_lexmin *isl_tab_lexmi
 int isl_tab_lexmin_dim(__isl_keep isl_tab_lexmin *tl);
 __isl_give isl_tab_lexmin *isl_tab_lexmin_add_eq(__isl_take isl_tab_lexmin *tl,
 	isl_int *eq);
+__isl_give isl_tab_lexmin *isl_tab_lexmin_cut_to_integer(
+	__isl_take isl_tab_lexmin *tl);
 __isl_give isl_vec *isl_tab_lexmin_get_solution(__isl_keep isl_tab_lexmin *tl);
 __isl_null isl_tab_lexmin *isl_tab_lexmin_free(__isl_take isl_tab_lexmin *tl);
 

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_tab_pip.c (original)
+++ polly/trunk/lib/External/isl/isl_tab_pip.c Sun Jun  4 14:13:10 2017
@@ -5426,6 +5426,20 @@ __isl_give isl_tab_lexmin *isl_tab_lexmi
 	return tl;
 }
 
+/* Add cuts to "tl" until the sample value reaches an integer value or
+ * until the result becomes empty.
+ */
+__isl_give isl_tab_lexmin *isl_tab_lexmin_cut_to_integer(
+	__isl_take isl_tab_lexmin *tl)
+{
+	if (!tl)
+		return NULL;
+	tl->tab = cut_to_integer_lexmin(tl->tab, CUT_ONE);
+	if (!tl->tab)
+		return isl_tab_lexmin_free(tl);
+	return tl;
+}
+
 /* Return the lexicographically smallest rational point in the basic set
  * from which "tl" was constructed.
  * If the original input was empty, then return a zero-length vector.

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=304686&r1=304685&r2=304686&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_union_map.c (original)
+++ polly/trunk/lib/External/isl/isl_union_map.c Sun Jun  4 14:13:10 2017
@@ -3463,6 +3463,24 @@ __isl_give isl_union_set *isl_union_set_
 	return isl_union_map_reset_user(uset);
 }
 
+/* Remove all existentially quantified variables and integer divisions
+ * from "umap" using Fourier-Motzkin elimination.
+ */
+__isl_give isl_union_map *isl_union_map_remove_divs(
+	__isl_take isl_union_map *umap)
+{
+	return total(umap, &isl_map_remove_divs);
+}
+
+/* Remove all existentially quantified variables and integer divisions
+ * from "uset" using Fourier-Motzkin elimination.
+ */
+__isl_give isl_union_set *isl_union_set_remove_divs(
+	__isl_take isl_union_set *uset)
+{
+	return isl_union_map_remove_divs(uset);
+}
+
 /* Internal data structure for isl_union_map_project_out.
  * "type", "first" and "n" are the arguments for the isl_map_project_out
  * call.
@@ -3789,3 +3807,68 @@ uint32_t isl_union_set_get_hash(__isl_ke
 {
 	return isl_union_map_get_hash(uset);
 }
+
+/* Add the number of basic sets in "set" to "n".
+ */
+static isl_stat add_n(__isl_take isl_set *set, void *user)
+{
+	int *n = user;
+
+	*n += isl_set_n_basic_set(set);
+	isl_set_free(set);
+
+	return isl_stat_ok;
+}
+
+/* Return the total number of basic sets in "uset".
+ */
+int isl_union_set_n_basic_set(__isl_keep isl_union_set *uset)
+{
+	int n = 0;
+
+	if (isl_union_set_foreach_set(uset, &add_n, &n) < 0)
+		return -1;
+
+	return n;
+}
+
+/* Add the basic sets in "set" to "list".
+ */
+static isl_stat add_list(__isl_take isl_set *set, void *user)
+{
+	isl_basic_set_list **list = user;
+	isl_basic_set_list *list_i;
+
+	list_i = isl_set_get_basic_set_list(set);
+	*list = isl_basic_set_list_concat(*list, list_i);
+	isl_set_free(set);
+
+	if (!*list)
+		return isl_stat_error;
+	return isl_stat_ok;
+}
+
+/* Return a list containing all the basic sets in "uset".
+ *
+ * First construct a list of the appropriate size and
+ * then add all the elements.
+ */
+__isl_give isl_basic_set_list *isl_union_set_get_basic_set_list(
+	__isl_keep isl_union_set *uset)
+{
+	int n;
+	isl_ctx *ctx;
+	isl_basic_set_list *list;
+
+	if (!uset)
+		return NULL;
+	ctx = isl_union_set_get_ctx(uset);
+	n = isl_union_set_n_basic_set(uset);
+	if (n < 0)
+		return NULL;
+	list = isl_basic_set_list_alloc(ctx, n);
+	if (isl_union_set_foreach_set(uset, &add_list, &list) < 0)
+		list = isl_basic_set_list_free(list);
+
+	return list;
+}




More information about the llvm-commits mailing list