[polly] r290538 - Update to isl-0.18-17-g2844ebf

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 26 04:11:40 PST 2016


Author: grosser
Date: Mon Dec 26 06:11:40 2016
New Revision: 290538

URL: http://llvm.org/viewvc/llvm-project?rev=290538&view=rev
Log:
Update to isl-0.18-17-g2844ebf

This update improves isl's ability to coalesce different convex sets/maps,
especially when the contain existentially quantified variables.

Modified:
    polly/trunk/lib/External/isl/GIT_HEAD_ID
    polly/trunk/lib/External/isl/doc/manual.pdf
    polly/trunk/lib/External/isl/isl_coalesce.c
    polly/trunk/lib/External/isl/isl_test.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=290538&r1=290537&r2=290538&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/GIT_HEAD_ID (original)
+++ polly/trunk/lib/External/isl/GIT_HEAD_ID Mon Dec 26 06:11:40 2016
@@ -1 +1 @@
-isl-0.18-9-gd4734f3
+isl-0.18-17-g2844ebf

Modified: polly/trunk/lib/External/isl/doc/manual.pdf
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/doc/manual.pdf?rev=290538&r1=290537&r2=290538&view=diff
==============================================================================
Binary files polly/trunk/lib/External/isl/doc/manual.pdf (original) and polly/trunk/lib/External/isl/doc/manual.pdf Mon Dec 26 06:11:40 2016 differ

Modified: polly/trunk/lib/External/isl/isl_coalesce.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_coalesce.c?rev=290538&r1=290537&r2=290538&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_coalesce.c (original)
+++ polly/trunk/lib/External/isl/isl_coalesce.c Mon Dec 26 06:11:40 2016
@@ -131,6 +131,19 @@ static int any(int *con, unsigned len, i
 	return 0;
 }
 
+/* Return the first position of "status" in the list "con" of length "len".
+ * Return -1 if there is no such entry.
+ */
+static int find(int *con, unsigned len, int status)
+{
+	int i;
+
+	for (i = 0; i < len ; ++i)
+		if (con[i] == status)
+			return i;
+	return -1;
+}
+
 static int count(int *con, unsigned len, int status)
 {
 	int i;
@@ -639,10 +652,8 @@ static enum isl_change is_adj_ineq_exten
 	if (isl_tab_extend_cons(info[i].tab, 1 + info[j].bmap->n_ineq) < 0)
 		return isl_change_error;
 
-	for (k = 0; k < info[i].bmap->n_ineq; ++k)
-		if (info[i].ineq[k] == STATUS_ADJ_INEQ)
-			break;
-	if (k >= info[i].bmap->n_ineq)
+	k = find(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ);
+	if (k < 0)
 		isl_die(isl_basic_map_get_ctx(info[i].bmap), isl_error_internal,
 			"info[i].ineq should have exactly one STATUS_ADJ_INEQ",
 			return isl_change_error);
@@ -856,11 +867,14 @@ static __isl_give isl_vec *try_tightenin
 /* Tighten the (non-redundant) constraints on the facet represented
  * by info->tab.
  * In particular, on input, info->tab represents the result
- * of replacing constraint k of info->bmap, i.e., f_k >= 0,
- * by the adjacent equality, i.e., f_k + 1 = 0.
+ * of relaxing the "n" inequality constraints of info->bmap in "relaxed"
+ * by one, i.e., replacing f_i >= 0 by f_i + 1 >= 0, and then
+ * replacing the one at index "l" by the corresponding equality,
+ * i.e., f_k + 1 = 0, with k = relaxed[l].
  *
  * Compute a variable compression from the equality constraint f_k + 1 = 0
- * and use it to tighten the other constraints of info->bmap,
+ * and use it to tighten the other constraints of info->bmap
+ * (that is, all constraints that have not been relaxed),
  * updating info->tab (and leaving info->bmap untouched).
  * The compression handles essentially two cases, one where a variable
  * is assigned a fixed value and can therefore be eliminated, and one
@@ -888,15 +902,17 @@ static __isl_give isl_vec *try_tightenin
  * the fusion detection should not exploit them.
  */
 static isl_stat tighten_on_relaxed_facet(struct isl_coalesce_info *info,
-	int k)
+	int n, int *relaxed, int l)
 {
 	unsigned total;
 	isl_ctx *ctx;
 	isl_vec *v = NULL;
 	isl_mat *T;
 	int i;
+	int k;
 	int *affected;
 
+	k = relaxed[l];
 	ctx = isl_basic_map_get_ctx(info->bmap);
 	total = isl_basic_map_total_dim(info->bmap);
 	isl_int_add_ui(info->bmap->ineq[k][0], info->bmap->ineq[k][0], 1);
@@ -918,7 +934,7 @@ static isl_stat tighten_on_relaxed_facet
 		affected[i] = not_unique_unit_row(T, 1 + i);
 
 	for (i = 0; i < info->bmap->n_ineq; ++i) {
-		if (i == k)
+		if (any(relaxed, n, i))
 			continue;
 		if (info->ineq[i] == STATUS_REDUNDANT)
 			continue;
@@ -944,81 +960,113 @@ error:
 	return isl_stat_error;
 }
 
-/* Basic map "i" has an inequality "k" that is adjacent to some equality
- * of basic map "j".  All the other inequalities are valid for "j".
+/* Replace the basic maps "i" and "j" by an extension of "i"
+ * along the "n" inequality constraints in "relax" by one.
+ * The tableau info[i].tab has already been extended.
+ * Extend info[i].bmap accordingly by relaxing all constraints in "relax"
+ * by one.
+ * Each integer division that does not have exactly the same
+ * definition in "i" and "j" is marked unknown and the basic map
+ * is scheduled to be simplified in an attempt to recover
+ * the integer division definition.
+ * Place the extension in the position that is the smallest of i and j.
+ */
+static enum isl_change extend(int i, int j, int n, int *relax,
+	struct isl_coalesce_info *info)
+{
+	int l;
+	unsigned total;
+
+	info[i].bmap = isl_basic_map_cow(info[i].bmap);
+	if (!info[i].bmap)
+		return isl_change_error;
+	total = isl_basic_map_total_dim(info[i].bmap);
+	for (l = 0; l < info[i].bmap->n_div; ++l)
+		if (!isl_seq_eq(info[i].bmap->div[l],
+				info[j].bmap->div[l], 1 + 1 + total)) {
+			isl_int_set_si(info[i].bmap->div[l][0], 0);
+			info[i].simplify = 1;
+		}
+	for (l = 0; l < n; ++l)
+		isl_int_add_ui(info[i].bmap->ineq[relax[l]][0],
+				info[i].bmap->ineq[relax[l]][0], 1);
+	ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_FINAL);
+	drop(&info[j]);
+	if (j < i)
+		exchange(&info[i], &info[j]);
+	return isl_change_fuse;
+}
+
+/* Basic map "i" has "n" inequality constraints (collected in "relax")
+ * that are such that they include basic map "j" if they are relaxed
+ * by one.  All the other inequalities are valid for "j".
  * Check if basic map "j" forms an extension of basic map "i".
  *
- * In particular, we relax constraint "k", compute the corresponding
- * facet and check whether it is included in the other basic map.
- * Before testing for inclusion, the constraints on the facet
+ * In particular, relax the constraints in "relax", compute the corresponding
+ * facets one by one and check whether each of these is included
+ * in the other basic map.
+ * Before testing for inclusion, the constraints on each facet
  * are tightened to increase the chance of an inclusion being detected.
- * If the facet is included, we know that relaxing the constraint extends
+ * (Adding the valid constraints of "j" to the tableau of "i", as is done
+ * in is_adj_ineq_extension, may further increase those chances, but this
+ * is not currently done.)
+ * If each facet is included, we know that relaxing the constraints extends
  * the basic map with exactly the other basic map (we already know that this
- * other basic map is included in the extension, because there
- * were no "cut" inequalities in "i") and we can replace the
+ * other basic map is included in the extension, because all other
+ * inequality constraints are valid of "j") and we can replace the
  * two basic maps by this extension.
- * Each integer division that does not have exactly the same
- * definition in "i" and "j" is marked unknown and the basic map
- * is scheduled to be simplified in an attempt to recover
- * the integer division definition.
- * Place this extension in the position that is the smallest of i and j.
  *        ____			  _____
  *       /    || 		 /     |
  *      /     ||  		/      |
  *      \     ||   	=>	\      |
  *       \    ||		 \     |
  *        \___||		  \____|
+ *
+ *
+ *	 \			|\
+ *	|\\			| \
+ *	| \\			|  \
+ *	|  |		=>	|  /
+ *	| /			| /
+ *	|/			|/
  */
-static enum isl_change is_adj_eq_extension(int i, int j, int k,
+static enum isl_change is_relaxed_extension(int i, int j, int n, int *relax,
 	struct isl_coalesce_info *info)
 {
-	int change = isl_change_none;
+	int l;
 	int super;
 	struct isl_tab_undo *snap, *snap2;
 	unsigned n_eq = info[i].bmap->n_eq;
 
-	if (isl_tab_is_equality(info[i].tab, n_eq + k))
-		return isl_change_none;
+	for (l = 0; l < n; ++l)
+		if (isl_tab_is_equality(info[i].tab, n_eq + relax[l]))
+			return isl_change_none;
 
 	snap = isl_tab_snap(info[i].tab);
-	if (isl_tab_relax(info[i].tab, n_eq + k) < 0)
-		return isl_change_error;
+	for (l = 0; l < n; ++l)
+		if (isl_tab_relax(info[i].tab, n_eq + relax[l]) < 0)
+			return isl_change_error;
 	snap2 = isl_tab_snap(info[i].tab);
-	if (isl_tab_select_facet(info[i].tab, n_eq + k) < 0)
-		return isl_change_error;
-	if (tighten_on_relaxed_facet(&info[i], k) < 0)
-		return isl_change_error;
-	super = contains(&info[j], info[i].tab);
-	if (super < 0)
-		return isl_change_error;
-	if (super) {
-		int l;
-		unsigned total;
-
+	for (l = 0; l < n; ++l) {
 		if (isl_tab_rollback(info[i].tab, snap2) < 0)
 			return isl_change_error;
-		info[i].bmap = isl_basic_map_cow(info[i].bmap);
-		if (!info[i].bmap)
+		if (isl_tab_select_facet(info[i].tab, n_eq + relax[l]) < 0)
+			return isl_change_error;
+		if (tighten_on_relaxed_facet(&info[i], n, relax, l) < 0)
+			return isl_change_error;
+		super = contains(&info[j], info[i].tab);
+		if (super < 0)
 			return isl_change_error;
-		total = isl_basic_map_total_dim(info[i].bmap);
-		for (l = 0; l < info[i].bmap->n_div; ++l)
-			if (!isl_seq_eq(info[i].bmap->div[l],
-					info[j].bmap->div[l], 1 + 1 + total)) {
-				isl_int_set_si(info[i].bmap->div[l][0], 0);
-				info[i].simplify = 1;
-			}
-		isl_int_add_ui(info[i].bmap->ineq[k][0],
-				info[i].bmap->ineq[k][0], 1);
-		ISL_F_SET(info[i].bmap, ISL_BASIC_MAP_FINAL);
-		drop(&info[j]);
-		if (j < i)
-			exchange(&info[i], &info[j]);
-		change = isl_change_fuse;
-	} else
+		if (super)
+			continue;
 		if (isl_tab_rollback(info[i].tab, snap) < 0)
 			return isl_change_error;
+		return isl_change_none;
+	}
 
-	return change;
+	if (isl_tab_rollback(info[i].tab, snap2) < 0)
+		return isl_change_error;
+	return extend(i, j, n, relax, info);
 }
 
 /* Data structure that keeps track of the wrapping constraints
@@ -1690,6 +1738,88 @@ static enum isl_change check_wrap(int i,
 	return change;
 }
 
+/* Check if all inequality constraints of "i" that cut "j" cease
+ * to be cut constraints if they are relaxed by one.
+ * If so, collect the cut constraints in "list".
+ * The caller is responsible for allocating "list".
+ */
+static isl_bool all_cut_by_one(int i, int j, struct isl_coalesce_info *info,
+	int *list)
+{
+	int l, n;
+
+	n = 0;
+	for (l = 0; l < info[i].bmap->n_ineq; ++l) {
+		enum isl_ineq_type type;
+
+		if (info[i].ineq[l] != STATUS_CUT)
+			continue;
+		type = type_of_relaxed(info[j].tab, info[i].bmap->ineq[l]);
+		if (type == isl_ineq_error)
+			return isl_bool_error;
+		if (type != isl_ineq_redundant)
+			return isl_bool_false;
+		list[n++] = l;
+	}
+
+	return isl_bool_true;
+}
+
+/* Given two basic maps such that "j" has at least one equality constraint
+ * that is adjacent to an inequality constraint of "i" and such that "i" has
+ * exactly one inequality constraint that is adjacent to an equality
+ * constraint of "j", check whether "i" can be extended to include "j" or
+ * whether "j" can be wrapped into "i".
+ * All remaining constraints of "i" and "j" are assumed to be valid
+ * or cut constraints of the other basic map.
+ * However, none of the equality constraints of "i" are cut constraints.
+ *
+ * If "i" has any "cut" inequality constraints, then check if relaxing
+ * each of them by one is sufficient for them to become valid.
+ * If so, check if the inequality constraint adjacent to an equality
+ * constraint of "j" along with all these cut constraints
+ * can be relaxed by one to contain exactly "j".
+ * Otherwise, or if this fails, check if "j" can be wrapped into "i".
+ */
+static enum isl_change check_single_adj_eq(int i, int j,
+	struct isl_coalesce_info *info)
+{
+	enum isl_change change = isl_change_none;
+	int k;
+	int n_cut;
+	int *relax;
+	isl_ctx *ctx;
+	isl_bool try_relax;
+
+	n_cut = count(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT);
+
+	k = find(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_EQ);
+
+	if (n_cut > 0) {
+		ctx = isl_basic_map_get_ctx(info[i].bmap);
+		relax = isl_calloc_array(ctx, int, 1 + n_cut);
+		if (!relax)
+			return isl_change_error;
+		relax[0] = k;
+		try_relax = all_cut_by_one(i, j, info, relax + 1);
+		if (try_relax < 0)
+			change = isl_change_error;
+	} else {
+		try_relax = isl_bool_true;
+		relax = &k;
+	}
+	if (try_relax && change == isl_change_none)
+		change = is_relaxed_extension(i, j, 1 + n_cut, relax, info);
+	if (n_cut > 0)
+		free(relax);
+	if (change != isl_change_none)
+		return change;
+
+	change = can_wrap_in_facet(i, j, k, info, n_cut > 0);
+
+	return change;
+}
+
 /* At least one of the basic maps has an equality that is adjacent
  * to inequality.  Make sure that only one of the basic maps has
  * such an equality and that the other basic map has exactly one
@@ -1697,21 +1827,12 @@ static enum isl_change check_wrap(int i,
  * If the other basic map does not have such an inequality, then
  * check if all its constraints are either valid or cut constraints
  * and, if so, try wrapping in the first map into the second.
- *
- * We call the basic map that has the inequality "i" and the basic
- * map that has the equality "j".
- * If "i" has any "cut" (in)equality, then relaxing the inequality
- * by one would not result in a basic map that contains the other
- * basic map.  However, it may still be possible to wrap in the other
- * basic map.
+ * Otherwise, try to extend one basic map with the other or
+ * wrap one basic map in the other.
  */
 static enum isl_change check_adj_eq(int i, int j,
 	struct isl_coalesce_info *info)
 {
-	enum isl_change change = isl_change_none;
-	int k;
-	int any_cut;
-
 	if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ) &&
 	    any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_INEQ))
 		/* ADJ EQ TOO MANY */
@@ -1729,26 +1850,13 @@ static enum isl_change check_adj_eq(int
 	}
 	if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT))
 		return isl_change_none;
-	any_cut = any(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT);
 	if (any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_EQ) ||
 	    any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ) ||
 	    any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ))
 		/* ADJ EQ TOO MANY */
 		return isl_change_none;
 
-	for (k = 0; k < info[i].bmap->n_ineq; ++k)
-		if (info[i].ineq[k] == STATUS_ADJ_EQ)
-			break;
-
-	if (!any_cut) {
-		change = is_adj_eq_extension(i, j, k, info);
-		if (change != isl_change_none)
-			return change;
-	}
-
-	change = can_wrap_in_facet(i, j, k, info, any_cut);
-
-	return change;
+	return check_single_adj_eq(i, j, info);
 }
 
 /* The two basic maps lie on adjacent hyperplanes.  In particular,
@@ -1786,9 +1894,7 @@ static enum isl_change check_eq_adj_eq(i
 	if (count(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ) != 1)
 		detect_equalities = 1;
 
-	for (k = 0; k < 2 * info[i].bmap->n_eq ; ++k)
-		if (info[i].eq[k] == STATUS_ADJ_EQ)
-			break;
+	k = find(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ);
 
 	set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
 	set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);

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=290538&r1=290537&r2=290538&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_test.c (original)
+++ polly/trunk/lib/External/isl/isl_test.c Mon Dec 26 06:11:40 2016
@@ -1870,6 +1870,14 @@ struct {
 	       "[x, y] : 0 <= x <= 10 and 1 <= y <= 10 }" },
 	{ 1, "{ [a] : a <= 8 and "
 			"(a mod 10 = 7 or a mod 10 = 8 or a mod 10 = 9) }" },
+	{ 1, "{ [x, y] : 2y = -x and x <= 0 or "
+			"x <= -1 and 2y <= -x - 1 and 2y >= x - 1 }" },
+	{ 0, "{ [x, y] : 2y = -x and x <= 0 or "
+			"x <= -2 and 2y <= -x - 1 and 2y >= x - 1 }" },
+	{ 1, "{ [a] : (a <= 0 and 3*floor((a)/3) = a) or "
+			"(a < 0 and 3*floor((a)/3) < a) }" },
+	{ 1, "{ [a] : (a <= 0 and 3*floor((a)/3) = a) or "
+			"(a < -1 and 3*floor((a)/3) < a) }" },
 };
 
 /* A specialized coalescing test case that would result




More information about the llvm-commits mailing list