[polly] r230528 - Update isl to 0980603 'isl_tab_pip.c: parallel_constraints: drop useless assignment'

Tobias Grosser tobias at grosser.es
Wed Feb 25 11:34:53 PST 2015


Author: grosser
Date: Wed Feb 25 13:34:52 2015
New Revision: 230528

URL: http://llvm.org/viewvc/llvm-project?rev=230528&view=rev
Log:
Update isl to 0980603 'isl_tab_pip.c: parallel_constraints: drop useless assignment'

This update contains:

  - Fixes of minor issues detected by clang's scan_build
  - More schedule tree infrastructure additions

This update slightly changes the output of our dependence analysis, but these
changes are purely syntactially.

Modified:
    polly/trunk/lib/External/isl/doc/user.pod
    polly/trunk/lib/External/isl/include/isl/flow.h
    polly/trunk/lib/External/isl/include/isl/schedule.h
    polly/trunk/lib/External/isl/include/isl/schedule_node.h
    polly/trunk/lib/External/isl/isl_aff.c
    polly/trunk/lib/External/isl/isl_arg.c
    polly/trunk/lib/External/isl/isl_ast.c
    polly/trunk/lib/External/isl/isl_ast_build_expr.c
    polly/trunk/lib/External/isl/isl_ast_codegen.c
    polly/trunk/lib/External/isl/isl_constraint.c
    polly/trunk/lib/External/isl/isl_convex_hull.c
    polly/trunk/lib/External/isl/isl_equalities.c
    polly/trunk/lib/External/isl/isl_flow.c
    polly/trunk/lib/External/isl/isl_id.c
    polly/trunk/lib/External/isl/isl_input.c
    polly/trunk/lib/External/isl/isl_local_space.c
    polly/trunk/lib/External/isl/isl_map_simplify.c
    polly/trunk/lib/External/isl/isl_mat.c
    polly/trunk/lib/External/isl/isl_output.c
    polly/trunk/lib/External/isl/isl_range.c
    polly/trunk/lib/External/isl/isl_sample.c
    polly/trunk/lib/External/isl/isl_schedule.c
    polly/trunk/lib/External/isl/isl_schedule_band.c
    polly/trunk/lib/External/isl/isl_schedule_band.h
    polly/trunk/lib/External/isl/isl_schedule_node.c
    polly/trunk/lib/External/isl/isl_schedule_node_private.h
    polly/trunk/lib/External/isl/isl_schedule_tree.c
    polly/trunk/lib/External/isl/isl_schedule_tree.h
    polly/trunk/lib/External/isl/isl_scheduler.c
    polly/trunk/lib/External/isl/isl_space.c
    polly/trunk/lib/External/isl/isl_tab_pip.c
    polly/trunk/lib/External/isl/isl_test.c
    polly/trunk/lib/External/isl/isl_transitive_closure.c
    polly/trunk/lib/External/isl/isl_vertices.c
    polly/trunk/test/Dependences/do_pluto_matmult.ll
    polly/trunk/test/Dependences/reduction_multiple_reductions_2.ll
    polly/trunk/test/Dependences/reduction_privatization_deps_2.ll
    polly/trunk/test/Dependences/reduction_privatization_deps_3.ll
    polly/trunk/test/Dependences/reduction_privatization_deps_4.ll
    polly/trunk/test/Dependences/reduction_privatization_deps_5.ll
    polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll
    polly/trunk/test/Dependences/reduction_simple_privatization_deps_2.ll
    polly/trunk/test/Dependences/sequential_loops.ll

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/doc/user.pod (original)
+++ polly/trunk/lib/External/isl/doc/user.pod Wed Feb 25 13:34:52 2015
@@ -222,6 +222,20 @@ to compute the sum on the union of defin
 The original behavior of C<isl_union_pw_multi_aff_add> was
 confused and is no longer available.
 
+=item * Band forests have been replaced by schedule trees.
+
+=item * The function C<isl_union_map_compute_flow> has been
+replaced by the function C<isl_union_access_info_compute_flow>.
+Note that the may dependence relation returned by
+C<isl_union_flow_get_may_dependence> is the union of
+the two dependence relations returned by
+C<isl_union_map_compute_flow>.  Similarly for the no source relations.
+The function C<isl_union_map_compute_flow> is still available
+for backward compatibility, but it will be removed in the future.
+
+=item * The function C<isl_basic_set_drop_constraint> has been
+deprecated.
+
 =back
 
 =head1 License
@@ -1873,9 +1887,6 @@ using the following functions.
 	__isl_give isl_set *isl_set_add_constraint(
 		__isl_take isl_set *set,
 		__isl_take isl_constraint *constraint);
-	__isl_give isl_basic_set *isl_basic_set_drop_constraint(
-		__isl_take isl_basic_set *bset,
-		__isl_take isl_constraint *constraint);
 
 For example, to create a set containing the even integers
 between 10 and 42, you would use the following code.
@@ -7283,6 +7294,14 @@ C<isl_schedule> objects may be copied an
 	__isl_null isl_schedule *isl_schedule_free(
 		__isl_take isl_schedule *sched);
 
+The following functions checks whether two C<isl_schedule> objects
+are obviously the same.
+
+	#include <isl/schedule.h>
+	int isl_schedule_plain_is_equal(
+		__isl_keep isl_schedule *schedule1,
+		__isl_keep isl_schedule *schedule2);
+
 The domain of the schedule, i.e., the domain described by the root node,
 can be obtained using the following function.
 
@@ -7290,6 +7309,64 @@ can be obtained using the following func
 	__isl_give isl_union_set *isl_schedule_get_domain(
 		__isl_keep isl_schedule *schedule);
 
+An extra top-level band node (right underneath the domain node) can
+be introduced into the schedule using the following function.
+
+	#include <isl/schedule.h>
+	__isl_give isl_schedule *
+	isl_schedule_insert_partial_schedule(
+		__isl_take isl_schedule *schedule,
+		__isl_take isl_multi_union_pw_aff *partial);
+
+A schedule that combines two schedules either in the given
+order or in an arbitrary order, i.e., with an C<isl_schedule_node_sequence>
+or an C<isl_schedule_node_set> node,
+can be created using the following functions.
+
+	#include <isl/schedule.h>
+	__isl_give isl_schedule *isl_schedule_sequence(
+		__isl_take isl_schedule *schedule1,
+		__isl_take isl_schedule *schedule2);
+	__isl_give isl_schedule *isl_schedule_set(
+		__isl_take isl_schedule *schedule1,
+		__isl_take isl_schedule *schedule2);
+
+The domains of the two input schedules need to be disjoint.
+
+The following function can be used to restrict the domain
+of a schedule to be a subset of the given union set.
+This operation may remove nodes in the tree that have become
+redundant.
+
+	#include <isl/schedule.h>
+	__isl_give isl_schedule *isl_schedule_intersect_domain(
+		__isl_take isl_schedule *schedule,
+		__isl_take isl_union_set *domain);
+
+The following function resets the user pointers on all parameter
+and tuple identifiers referenced by the nodes of the given schedule.
+
+	#include <isl/schedule.h>
+	__isl_give isl_schedule *isl_schedule_reset_user(
+		__isl_take isl_schedule *schedule);
+
+The following function aligns the parameters of all nodes
+in the given schedule to the given space.
+
+	#include <isl/schedule.h>
+	__isl_give isl_schedule *isl_schedule_align_params(
+		__isl_take isl_schedule *schedule,
+		__isl_take isl_space *space);
+
+The following function allows the user to plug in a given function
+in the iteration domains.
+
+	#include <isl/schedule.h>
+	__isl_give isl_schedule *
+	isl_schedule_pullback_union_pw_multi_aff(
+		__isl_take isl_schedule *schedule,
+		__isl_take isl_union_pw_multi_aff *upma);
+
 An C<isl_union_map> representation of the schedule can be obtained
 from an C<isl_schedule> using the following function.
 
@@ -7347,6 +7424,14 @@ Schedule nodes can be copied and freed u
 	__isl_null isl_schedule_node *isl_schedule_node_free(
 		__isl_take isl_schedule_node *node);
 
+The following functions can be used to check if two schedule
+nodes point to the same position in the same schedule.
+
+	#include <isl/schedule_node.h>
+	int isl_schedule_node_is_equal(
+		__isl_keep isl_schedule_node *node1,
+		__isl_keep isl_schedule_node *node2);
+
 The following properties can be obtained from a schedule node.
 
 	#include <isl/schedule_node.h>
@@ -7373,6 +7458,11 @@ exists.
 		__isl_keep isl_schedule_node *node);
 	__isl_give isl_schedule_node *isl_schedule_node_parent(
 		__isl_take isl_schedule_node *node);
+	__isl_give isl_schedule_node *isl_schedule_node_root(
+		__isl_take isl_schedule_node *node);
+	__isl_give isl_schedule_node *isl_schedule_node_ancestor(
+		__isl_take isl_schedule_node *node,
+		int generation);
 	int isl_schedule_node_n_children(
 		__isl_keep isl_schedule_node *node);
 	__isl_give isl_schedule_node *isl_schedule_node_child(
@@ -7392,18 +7482,33 @@ exists.
 	isl_schedule_node_next_sibling(
 		__isl_take isl_schedule_node *node);
 
+For C<isl_schedule_node_ancestor>, the ancestor of generation 0
+is the node itself, the ancestor of generation 1 is its parent and so on.
+
 It is also possible to query the number of ancestors of a node,
 the position of the current node
-within the children of its parent or to obtain a copy of a given
+within the children of its parent, the position of the subtree
+containing a node within the children of an ancestor
+or to obtain a copy of a given
 child without destroying the current node.
+Given two nodes that point to the same schedule, their closest
+shared ancestor can be obtained using
+C<isl_schedule_node_get_shared_ancestor>.
 
 	#include <isl/schedule_node.h>
 	int isl_schedule_node_get_tree_depth(
 		__isl_keep isl_schedule_node *node);
 	int isl_schedule_node_get_child_position(
 		__isl_keep isl_schedule_node *node);
+	int isl_schedule_node_get_ancestor_child_position(
+		__isl_keep isl_schedule_node *node,
+		__isl_keep isl_schedule_node *ancestor);
 	__isl_give isl_schedule_node *isl_schedule_node_get_child(
 		__isl_keep isl_schedule_node *node, int pos);
+	__isl_give isl_schedule_node *
+	isl_schedule_node_get_shared_ancestor(
+		__isl_keep isl_schedule_node *node1,
+		__isl_keep isl_schedule_node *node2);
 
 All nodes in a schedule tree or
 all descendants of a specific node (including the node) can be visited
@@ -7428,6 +7533,16 @@ of the given node should be visited.  In
 returns a positive value, then the children are visited, but if
 the callback returns zero, then the children are not visited.
 
+The ancestors of a node in a schedule tree can be visited from
+the root down to and including the parent of the node using
+the following function.
+
+	#include <isl/schedule_node.h>
+	int isl_schedule_node_foreach_ancestor_top_down(
+		__isl_keep isl_schedule_node *node,
+		int (*fn)(__isl_keep isl_schedule_node *node,
+			void *user), void *user);
+
 The following functions allows for a depth-first post-order
 traversal of the nodes in a schedule tree or
 of the descendants of a specific node (including the node
@@ -7454,6 +7569,43 @@ It is the responsibility of the user to
 lead to an infinite loop.  It is safest to always return a pointer
 to the same position (same ancestors and child positions) as the input node.
 
+The following function removes a node (along with its descendants)
+from a schedule tree and returns a pointer to the leaf at the
+same position in the updated tree.
+It is not allowed to remove the root of a schedule tree or
+a child of a set or sequence node.
+
+	#include <isl/schedule_node.h>
+	__isl_give isl_schedule_node *isl_schedule_node_cut(
+		__isl_take isl_schedule_node *node);
+
+The following function removes a single node
+from a schedule tree and returns a pointer to the child
+of the node, now located at the position of the original node
+or to a leaf node at that position if there was no child.
+It is not allowed to remove the root of a schedule tree,
+a set or sequence node or a child of a set or sequence node.
+
+	#include <isl/schedule_node.h>
+	__isl_give isl_schedule_node *isl_schedule_node_delete(
+		__isl_take isl_schedule_node *node);
+
+The following function resets the user pointers on all parameter
+and tuple identifiers referenced by the given schedule node.
+
+	#include <isl/schedule_node.h>
+	__isl_give isl_schedule_node *isl_schedule_node_reset_user(
+		__isl_take isl_schedule_node *node);
+
+The following function aligns the parameters of the given schedule
+node to the given space.
+
+	#include <isl/schedule_node.h>
+	__isl_give isl_schedule_node *
+	isl_schedule_node_align_params(
+		__isl_take isl_schedule_node *node,
+		__isl_take isl_space *space);
+
 Several node types have their own functions for querying
 (and in some cases setting) some node type specific properties.
 
@@ -7530,6 +7682,15 @@ The function C<isl_schedule_node_get_sub
 returns a representation of the partial schedule defined by the
 subtree rooted at the given node.
 
+The total number of outer band members of given node, i.e.,
+the shared output dimension of the maps in the result
+of C<isl_schedule_node_get_prefix_schedule_union_map> can be obtained
+using the following function.
+
+	#include <isl/schedule_node.h>
+	int isl_schedule_node_get_schedule_depth(
+		__isl_keep isl_schedule_node *node);
+
 The following function returns the union of universes in the spaces that
 contain elements that reach the given node.
 
@@ -7666,6 +7827,96 @@ then memory based dependence analysis is
 If, on the other hand, all sources are I<must> accesses,
 then value based dependence analysis is performed.
 
+=head3 High-level Interface
+
+A high-level interface to dependence analysis is provided
+by the following function.
+
+	#include <isl/flow.h>
+	__isl_give isl_union_flow *
+	isl_union_access_info_compute_flow(
+		__isl_take isl_union_access_info *access);
+
+The input C<isl_union_access_info> object describes the sink
+access relations, the source access relations and a schedule,
+while the output C<isl_union_flow> object describes
+the resulting dependence relations and the subsets of the
+sink relations for which no source was found.
+
+An C<isl_union_access_info> is created, modified and freed using
+the following functions.
+
+	#include <isl/flow.h>
+	__isl_give isl_union_access_info *
+	isl_union_access_info_from_sink(
+		__isl_take isl_union_map *sink);
+	__isl_give isl_union_access_info *
+	isl_union_access_info_set_must_source(
+		__isl_take isl_union_access_info *access,
+		__isl_take isl_union_map *must_source);
+	__isl_give isl_union_access_info *
+	isl_union_access_info_set_may_source(
+		__isl_take isl_union_access_info *access,
+		__isl_take isl_union_map *may_source);
+	__isl_give isl_union_access_info *
+	isl_union_access_info_set_schedule(
+		__isl_take isl_union_access_info *access,
+		__isl_take isl_schedule *schedule);
+	__isl_give isl_union_access_info *
+	isl_union_access_info_set_schedule_map(
+		__isl_take isl_union_access_info *access,
+		__isl_take isl_union_map *schedule_map);
+	__isl_null isl_union_access_info *
+	isl_union_access_info_free(
+		__isl_take isl_union_access_info *access);
+
+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,
+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.
+The current schedule is determined by the last call to either
+C<isl_union_access_info_set_schedule> or
+C<isl_union_access_info_set_schedule_map>.
+The domain of the schedule corresponds to the domains of
+the access relations.  In particular, the domains of the access
+relations are effectively intersected with the domain of the schedule
+and only the resulting accesses are considered by the dependence analysis.
+
+The output of C<isl_union_access_info_compute_flow> can be examined
+and freed using the following functions.
+
+	#include <isl/flow.h>
+	__isl_give isl_union_map *isl_union_flow_get_must_dependence(
+		__isl_keep isl_union_flow *flow);
+	__isl_give isl_union_map *isl_union_flow_get_may_dependence(
+		__isl_keep isl_union_flow *flow);
+	__isl_give isl_union_map *isl_union_flow_get_must_no_source(
+		__isl_keep isl_union_flow *flow);
+	__isl_give isl_union_map *isl_union_flow_get_may_no_source(
+		__isl_keep isl_union_flow *flow);
+	__isl_null isl_union_flow *isl_union_flow_free(
+		__isl_take isl_union_flow *flow);
+
+The relation returned by C<isl_union_flow_get_must_dependence>
+relates domain elements of must sources to domain elements of the sink.
+The relation returned by C<isl_union_flow_get_may_dependence>
+relates domain elements of must or may sources to domain elements of the sink
+and includes the previous relation as a subset.
+The relation returned by C<isl_union_flow_get_must_no_source> is the subset
+of the sink relation for which no dependences have been found.
+The relation returned by C<isl_union_flow_get_may_no_source> is the subset
+of the sink relation for which no definite dependences have been found.
+That is, it contains those sink access that do not contribute to any
+of the elements in the relation returned
+by C<isl_union_flow_get_must_dependence>.
+
+=head3 Low-level Interface
+
+A lower-level interface is provided by the following functions.
+
 	#include <isl/flow.h>
 
 	typedef int (*isl_access_level_before)(void *first, void *second);
@@ -7751,31 +8002,7 @@ source and if it is not followed by any
 After finishing with an C<isl_flow>, the user should call
 C<isl_flow_free> to free all associated memory.
 
-A higher-level interface to dependence analysis is provided
-by the following function.
-
-	#include <isl/flow.h>
-
-	int isl_union_map_compute_flow(__isl_take isl_union_map *sink,
-		__isl_take isl_union_map *must_source,
-		__isl_take isl_union_map *may_source,
-		__isl_take isl_union_map *schedule,
-		__isl_give isl_union_map **must_dep,
-		__isl_give isl_union_map **may_dep,
-		__isl_give isl_union_map **must_no_source,
-		__isl_give isl_union_map **may_no_source);
-
-The arrays are identified by the tuple names of the ranges
-of the accesses.  The iteration domains by the tuple names
-of the domains of the accesses and of the schedule.
-The relative order of the iteration domains is given by the
-schedule.  The relations returned through C<must_no_source>
-and C<may_no_source> are subsets of C<sink>.
-Any of C<must_dep>, C<may_dep>, C<must_no_source>
-or C<may_no_source> may be C<NULL>, but a C<NULL> value for
-any of the other arguments is treated as an error.
-
-=head3 Interaction with Dependence Analysis
+=head3 Interaction with the Low-level Interface
 
 During the dependence analysis, we frequently need to perform
 the following operation.  Given a relation between sink iterations
@@ -7976,114 +8203,6 @@ The generated schedule represents a sche
 For more information on schedule trees, see
 L</"Schedule Trees">.
 
-A representation of the schedule as a forest of bands can be obtained
-using the following function.
-
-	__isl_give isl_band_list *isl_schedule_get_band_forest(
-		__isl_keep isl_schedule *schedule);
-
-If the input schedule is represented by a schedule tree, then a call
-to C<isl_schedule_get_band_forest> replaces the internal schedule tree
-representation by a band forest representation.
-
-The individual bands can be visited in depth-first post-order
-using the following function.
-
-	#include <isl/schedule.h>
-	int isl_schedule_foreach_band(
-		__isl_keep isl_schedule *sched,
-		int (*fn)(__isl_keep isl_band *band, void *user),
-		void *user);
-
-The list can be manipulated as explained in L<"Lists">.
-The bands inside the list can be copied and freed using the following
-functions.
-
-	#include <isl/band.h>
-	__isl_give isl_band *isl_band_copy(
-		__isl_keep isl_band *band);
-	__isl_null isl_band *isl_band_free(
-		__isl_take isl_band *band);
-
-Each band contains zero or more scheduling dimensions.
-These are referred to as the members of the band.
-The section of the schedule that corresponds to the band is
-referred to as the partial schedule of the band.
-For those nodes that participate in a band, the outer scheduling
-dimensions form the prefix schedule, while the inner scheduling
-dimensions form the suffix schedule.
-That is, if we take a cut of the band forest, then the union of
-the concatenations of the prefix, partial and suffix schedules of
-each band in the cut is equal to the entire schedule (modulo
-some possible padding at the end with zero scheduling dimensions).
-The properties of a band can be inspected using the following functions.
-
-	#include <isl/band.h>
-	int isl_band_has_children(__isl_keep isl_band *band);
-	__isl_give isl_band_list *isl_band_get_children(
-		__isl_keep isl_band *band);
-
-	__isl_give isl_union_map *isl_band_get_prefix_schedule(
-		__isl_keep isl_band *band);
-	__isl_give isl_union_map *isl_band_get_partial_schedule(
-		__isl_keep isl_band *band);
-	__isl_give isl_union_map *isl_band_get_suffix_schedule(
-		__isl_keep isl_band *band);
-
-	int isl_band_n_member(__isl_keep isl_band *band);
-	int isl_band_member_is_coincident(
-		__isl_keep isl_band *band, int pos);
-
-	int isl_band_list_foreach_band(
-		__isl_keep isl_band_list *list,
-		int (*fn)(__isl_keep isl_band *band, void *user),
-		void *user);
-
-Note that a scheduling dimension is considered to be ``coincident''
-if it satisfies the coincidence constraints within its band.
-That is, if the dependence distances of the coincidence
-constraints are all zero in that direction (for fixed
-iterations of outer bands).
-Like C<isl_schedule_foreach_band>,
-the function C<isl_band_list_foreach_band> calls C<fn> on the bands
-in depth-first post-order.
-
-A band can be tiled using the following function.
-
-	#include <isl/band.h>
-	int isl_band_tile(__isl_keep isl_band *band,
-		__isl_take isl_vec *sizes);
-
-	int isl_options_set_tile_scale_tile_loops(isl_ctx *ctx,
-		int val);
-	int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx);
-	int isl_options_set_tile_shift_point_loops(isl_ctx *ctx,
-		int val);
-	int isl_options_get_tile_shift_point_loops(isl_ctx *ctx);
-
-The C<isl_band_tile> function tiles the band using the given tile sizes
-inside its schedule.
-A new child band is created to represent the point loops and it is
-inserted between the modified band and its children.
-The C<tile_scale_tile_loops> option specifies whether the tile
-loops iterators should be scaled by the tile sizes.
-If the C<tile_shift_point_loops> option is set, then the point loops
-are shifted to start at zero.
-
-A band can be split into two nested bands using the following function.
-
-	int isl_band_split(__isl_keep isl_band *band, int pos);
-
-The resulting outer band contains the first C<pos> dimensions of C<band>
-while the inner band contains the remaining dimensions.
-
-A representation of the band can be printed using
-
-	#include <isl/band.h>
-	__isl_give isl_printer *isl_printer_print_band(
-		__isl_take isl_printer *p,
-		__isl_keep isl_band *band);
-
 =head3 Options
 
 	#include <isl/schedule.h>

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/flow.h (original)
+++ polly/trunk/lib/External/isl/include/isl/flow.h Wed Feb 25 13:34:52 2015
@@ -5,6 +5,7 @@
 #include <isl/map_type.h>
 #include <isl/union_set_type.h>
 #include <isl/union_map_type.h>
+#include <isl/schedule.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -62,6 +63,41 @@ void isl_flow_free(__isl_take isl_flow *
 
 isl_ctx *isl_flow_get_ctx(__isl_keep isl_flow *deps);
 
+struct isl_union_access_info;
+typedef struct isl_union_access_info isl_union_access_info;
+struct isl_union_flow;
+typedef struct isl_union_flow isl_union_flow;
+
+__isl_give isl_union_access_info *isl_union_access_info_from_sink(
+	__isl_take isl_union_map *sink);
+__isl_give isl_union_access_info *isl_union_access_info_set_must_source(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *must_source);
+__isl_give isl_union_access_info *isl_union_access_info_set_may_source(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *may_source);
+__isl_give isl_union_access_info *isl_union_access_info_set_schedule(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_schedule *schedule);
+__isl_give isl_union_access_info *isl_union_access_info_set_schedule_map(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *schedule_map);
+__isl_null isl_union_access_info *isl_union_access_info_free(
+	__isl_take isl_union_access_info *access);
+
+__isl_give isl_union_flow *isl_union_access_info_compute_flow(
+	__isl_take isl_union_access_info *access);
+
+__isl_give isl_union_map *isl_union_flow_get_must_dependence(
+	__isl_keep isl_union_flow *flow);
+__isl_give isl_union_map *isl_union_flow_get_may_dependence(
+	__isl_keep isl_union_flow *flow);
+__isl_give isl_union_map *isl_union_flow_get_must_no_source(
+	__isl_keep isl_union_flow *flow);
+__isl_give isl_union_map *isl_union_flow_get_may_no_source(
+	__isl_keep isl_union_flow *flow);
+__isl_null isl_union_flow *isl_union_flow_free(__isl_take isl_union_flow *flow);
+
 int isl_union_map_compute_flow(__isl_take isl_union_map *sink,
 	__isl_take isl_union_map *must_source,
 	__isl_take isl_union_map *may_source,

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/schedule.h (original)
+++ polly/trunk/lib/External/isl/include/isl/schedule.h Wed Feb 25 13:34:52 2015
@@ -4,6 +4,7 @@
 #include <isl/union_set_type.h>
 #include <isl/union_map_type.h>
 #include <isl/schedule_type.h>
+#include <isl/aff_type.h>
 #include <isl/band.h>
 #include <isl/space.h>
 #include <isl/list.h>
@@ -82,6 +83,8 @@ __isl_null isl_schedule *isl_schedule_fr
 __isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched);
 
 isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *sched);
+int isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1,
+	__isl_keep isl_schedule *schedule2);
 
 __isl_give isl_schedule_node *isl_schedule_get_root(
 	__isl_keep isl_schedule *schedule);
@@ -95,6 +98,24 @@ __isl_give isl_schedule *isl_schedule_ma
 	__isl_give isl_schedule_node *(*fn)(
 		__isl_take isl_schedule_node *node, void *user), void *user);
 
+__isl_give isl_schedule *isl_schedule_insert_partial_schedule(
+	__isl_take isl_schedule *schedule,
+	__isl_take isl_multi_union_pw_aff *partial);
+__isl_give isl_schedule *isl_schedule_sequence(
+	__isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2);
+__isl_give isl_schedule *isl_schedule_set(
+	__isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2);
+__isl_give isl_schedule *isl_schedule_intersect_domain(
+	__isl_take isl_schedule *schedule, __isl_take isl_union_set *domain);
+
+__isl_give isl_schedule *isl_schedule_reset_user(
+	__isl_take isl_schedule *schedule);
+__isl_give isl_schedule *isl_schedule_align_params(
+	__isl_take isl_schedule *schedule, __isl_take isl_space *space);
+__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule *schedule,
+	__isl_take isl_union_pw_multi_aff *upma);
+
 __isl_give isl_band_list *isl_schedule_get_band_forest(
 	__isl_keep isl_schedule *schedule);
 

Modified: polly/trunk/lib/External/isl/include/isl/schedule_node.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/include/isl/schedule_node.h?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/include/isl/schedule_node.h (original)
+++ polly/trunk/lib/External/isl/include/isl/schedule_node.h Wed Feb 25 13:34:52 2015
@@ -18,6 +18,9 @@ __isl_give isl_schedule_node *isl_schedu
 __isl_null isl_schedule_node *isl_schedule_node_free(
 	__isl_take isl_schedule_node *node);
 
+int isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1,
+	__isl_keep isl_schedule_node *node2);
+
 isl_ctx *isl_schedule_node_get_ctx(__isl_keep isl_schedule_node *node);
 enum isl_schedule_node_type isl_schedule_node_get_type(
 	__isl_keep isl_schedule_node *node);
@@ -28,6 +31,9 @@ __isl_give isl_schedule *isl_schedule_no
 
 int isl_schedule_node_foreach_descendant(__isl_keep isl_schedule_node *node,
 	int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user);
+int isl_schedule_node_foreach_ancestor_top_down(
+	__isl_keep isl_schedule_node *node,
+	int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user);
 __isl_give isl_schedule_node *isl_schedule_node_map_descendant(
 	__isl_take isl_schedule_node *node,
 	__isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node,
@@ -40,11 +46,21 @@ int isl_schedule_node_has_previous_sibli
 int isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node);
 int isl_schedule_node_n_children(__isl_keep isl_schedule_node *node);
 int isl_schedule_node_get_child_position(__isl_keep isl_schedule_node *node);
+int isl_schedule_node_get_ancestor_child_position(
+	__isl_keep isl_schedule_node *node,
+	__isl_keep isl_schedule_node *ancestor);
 __isl_give isl_schedule_node *isl_schedule_node_get_child(
 	__isl_keep isl_schedule_node *node, int pos);
+__isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor(
+	__isl_keep isl_schedule_node *node1,
+	__isl_keep isl_schedule_node *node2);
 
+__isl_give isl_schedule_node *isl_schedule_node_root(
+	__isl_take isl_schedule_node *node);
 __isl_give isl_schedule_node *isl_schedule_node_parent(
 	__isl_take isl_schedule_node *node);
+__isl_give isl_schedule_node *isl_schedule_node_ancestor(
+	__isl_take isl_schedule_node *node, int generation);
 __isl_give isl_schedule_node *isl_schedule_node_child(
 	__isl_take isl_schedule_node *node, int pos);
 __isl_give isl_schedule_node *isl_schedule_node_first_child(
@@ -90,6 +106,7 @@ __isl_give isl_union_set *isl_schedule_n
 __isl_give isl_union_set *isl_schedule_node_filter_get_filter(
 	__isl_keep isl_schedule_node *node);
 
+int isl_schedule_node_get_schedule_depth(__isl_keep isl_schedule_node *node);
 __isl_give isl_union_set *isl_schedule_node_get_universe_domain(
 	__isl_keep isl_schedule_node *node);
 __isl_give isl_union_pw_multi_aff *
@@ -112,6 +129,16 @@ __isl_give isl_schedule_node *isl_schedu
 	__isl_take isl_schedule_node *node,
 	__isl_take isl_union_set_list *filters);
 
+__isl_give isl_schedule_node *isl_schedule_node_cut(
+	__isl_take isl_schedule_node *node);
+__isl_give isl_schedule_node *isl_schedule_node_delete(
+	__isl_take isl_schedule_node *node);
+
+__isl_give isl_schedule_node *isl_schedule_node_reset_user(
+	__isl_take isl_schedule_node *node);
+__isl_give isl_schedule_node *isl_schedule_node_align_params(
+	__isl_take isl_schedule_node *node, __isl_take isl_space *space);
+
 __isl_give isl_printer *isl_printer_print_schedule_node(
 	__isl_take isl_printer *p, __isl_keep isl_schedule_node *node);
 void isl_schedule_node_dump(__isl_keep isl_schedule_node *node);

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_aff.c (original)
+++ polly/trunk/lib/External/isl/isl_aff.c Wed Feb 25 13:34:52 2015
@@ -1459,12 +1459,10 @@ static __isl_give isl_aff *merge_divs(__
 static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
 {
 	int i, j, n;
-	unsigned off;
 
 	if (!aff)
 		return NULL;
 
-	off = isl_local_space_offset(aff->ls, isl_dim_div);
 	n = isl_aff_dim(aff, isl_dim_div);
 	for (i = 1; i < n; ++i) {
 		for (j = i - 1; j >= 0; --j) {
@@ -4908,7 +4906,7 @@ static __isl_give isl_pw_multi_aff *pw_m
 		map = set;
 	else
 		map = isl_set_unwrap(set);
-	pma = isl_pw_multi_aff_from_map(set);
+	pma = isl_pw_multi_aff_from_map(map);
 
 	if (!is_set) {
 		space = isl_pw_multi_aff_get_domain_space(pma);
@@ -6569,13 +6567,12 @@ error:
 static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
 {
-	int i, n_param, n_in, n_div;
+	int i, n_in, n_div;
 	isl_space *space;
 	isl_val *v;
 	isl_pw_aff *pa;
 	isl_aff *tmp;
 
-	n_param = isl_aff_dim(aff, isl_dim_param);
 	n_in = isl_aff_dim(aff, isl_dim_in);
 	n_div = isl_aff_dim(aff, isl_dim_div);
 

Modified: polly/trunk/lib/External/isl/isl_arg.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_arg.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_arg.c (original)
+++ polly/trunk/lib/External/isl/isl_arg.c Wed Feb 25 13:34:52 2015
@@ -386,7 +386,6 @@ static void print_default(struct isl_arg
 			printf("\n%30s", "");
 		else
 			printf("%*s", 30 - pos, "");
-		pos = 0;
 	} else {
 		if (pos + len >= 48)
 			printf("\n%30s", "");
@@ -456,7 +455,6 @@ static void print_default_flags(struct i
 			printf("\n%30s", "");
 		else
 			printf("%*s", 30 - pos, "");
-		pos = 0;
 	} else {
 		if (pos + len >= 48)
 			printf("\n%30s", "");

Modified: polly/trunk/lib/External/isl/isl_ast.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_ast.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_ast.c (original)
+++ polly/trunk/lib/External/isl/isl_ast.c Wed Feb 25 13:34:52 2015
@@ -351,7 +351,6 @@ int isl_ast_expr_is_equal(__isl_keep isl
 			int equal;
 			equal = isl_ast_expr_is_equal(expr1->u.op.args[i],
 							expr2->u.op.args[i]);
-				return 0;
 			if (equal < 0 || !equal)
 				return equal;
 		}

Modified: polly/trunk/lib/External/isl/isl_ast_build_expr.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_ast_build_expr.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_ast_build_expr.c (original)
+++ polly/trunk/lib/External/isl/isl_ast_build_expr.c Wed Feb 25 13:34:52 2015
@@ -332,14 +332,12 @@ static __isl_give isl_ast_expr *isl_ast_
 	__isl_keep isl_aff *aff, __isl_keep isl_val *d,
 	__isl_keep isl_ast_build *build)
 {
-	isl_ctx *ctx;
 	isl_ast_expr *expr;
 	isl_ast_expr *c;
 
 	if (!aff)
 		return NULL;
 
-	ctx = isl_aff_get_ctx(aff);
 	expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build);
 
 	c = isl_ast_expr_from_val(isl_val_copy(d));
@@ -443,7 +441,6 @@ static __isl_give isl_ast_expr *isl_ast_
 static __isl_give isl_ast_expr *isl_ast_expr_add_int(
 	__isl_take isl_ast_expr *expr, __isl_take isl_val *v)
 {
-	isl_ctx *ctx;
 	isl_ast_expr *expr_int;
 
 	if (!expr || !v)
@@ -454,7 +451,6 @@ static __isl_give isl_ast_expr *isl_ast_
 		return expr;
 	}
 
-	ctx = isl_ast_expr_get_ctx(expr);
 	if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) {
 		v = isl_val_neg(v);
 		expr_int = isl_ast_expr_from_val(v);

Modified: polly/trunk/lib/External/isl/isl_ast_codegen.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_ast_codegen.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_ast_codegen.c (original)
+++ polly/trunk/lib/External/isl/isl_ast_codegen.c Wed Feb 25 13:34:52 2015
@@ -882,7 +882,7 @@ static int pw_aff_constant_is_negative(_
 	r = isl_pw_aff_foreach_piece(pa, &aff_constant_is_negative, user);
 	isl_pw_aff_free(pa);
 
-	return *neg ? 0 : -1;
+	return (*neg && r >= 0) ? 0 : -1;
 }
 
 /* Does each element in "list" have a negative constant term?
@@ -2571,7 +2571,6 @@ static __isl_give isl_set *do_unroll(str
 {
 	int i, n;
 	int depth;
-	isl_ctx *ctx;
 	isl_aff *lower;
 	isl_multi_aff *expansion;
 	isl_basic_map *bmap;
@@ -2581,7 +2580,6 @@ static __isl_give isl_set *do_unroll(str
 	if (!domain)
 		return isl_set_free(class_domain);
 
-	ctx = isl_set_get_ctx(domain);
 	depth = isl_ast_build_get_depth(domains->build);
 	build = isl_ast_build_copy(domains->build);
 	domain = isl_ast_build_eliminate_inner(build, domain);
@@ -3360,14 +3358,12 @@ static __isl_give isl_ast_graft_list *ge
 	isl_ast_graft_list *list;
 	int first;
 	int depth;
-	isl_ctx *ctx;
 	isl_val *val;
 	isl_multi_val *mv;
 	isl_space *space;
 	isl_multi_aff *ma, *zero;
 	isl_union_map *executed;
 
-	ctx = isl_ast_build_get_ctx(build);
 	depth = isl_ast_build_get_depth(build);
 
 	first = first_offset(domain, order, n, build);

Modified: polly/trunk/lib/External/isl/isl_constraint.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_constraint.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_constraint.c (original)
+++ polly/trunk/lib/External/isl/isl_constraint.c Wed Feb 25 13:34:52 2015
@@ -669,11 +669,9 @@ __isl_give isl_constraint *isl_constrain
  * In particular, this means that the local spaces of "bset" and
  * "constraint" need to be the same.
  *
- * Since the given constraint may actually be a pointer into the bset,
- * we have to be careful not to reorder the constraints as the user
- * may be holding on to other constraints from the same bset.
- * This should be cleaned up when the internal representation of
- * isl_constraint is changed to use isl_aff.
+ * We manually set ISL_BASIC_SET_FINAL instead of calling
+ * isl_basic_set_finalize because this function is called by CLooG,
+ * which does not expect any variables to disappear.
  */
 __isl_give isl_basic_set *isl_basic_set_drop_constraint(
 	__isl_take isl_basic_set *bset, __isl_take isl_constraint *constraint)
@@ -684,6 +682,7 @@ __isl_give isl_basic_set *isl_basic_set_
 	unsigned total;
 	isl_local_space *ls1;
 	int equal;
+	int equality;
 
 	if (!bset || !constraint)
 		goto error;
@@ -698,7 +697,12 @@ __isl_give isl_basic_set *isl_basic_set_
 		return bset;
 	}
 
-	if (isl_constraint_is_equality(constraint)) {
+	bset = isl_basic_set_cow(bset);
+	if (!bset)
+		goto error;
+
+	equality = isl_constraint_is_equality(constraint);
+	if (equality) {
 		n = bset->n_eq;
 		row = bset->eq;
 	} else {
@@ -707,11 +711,18 @@ __isl_give isl_basic_set *isl_basic_set_
 	}
 
 	total = isl_constraint_dim(constraint, isl_dim_all);
-	for (i = 0; i < n; ++i)
-		if (isl_seq_eq(row[i], constraint->v->el, 1 + total))
-			isl_seq_clr(row[i], 1 + total);
+	for (i = 0; i < n; ++i) {
+		if (!isl_seq_eq(row[i], constraint->v->el, 1 + total))
+			continue;
+		if (equality && isl_basic_set_drop_equality(bset, i) < 0)
+			goto error;
+		if (!equality && isl_basic_set_drop_inequality(bset, i) < 0)
+			goto error;
+		break;
+	}
 			
 	isl_constraint_free(constraint);
+	ISL_F_SET(bset, ISL_BASIC_SET_FINAL);
 	return bset;
 error:
 	isl_constraint_free(constraint);

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_convex_hull.c (original)
+++ polly/trunk/lib/External/isl/isl_convex_hull.c Wed Feb 25 13:34:52 2015
@@ -1315,12 +1315,12 @@ static struct isl_basic_set *convex_hull
 
 	if (!bset1 || !bset2)
 		goto error;
-	ctx = bset1->ctx;
+	ctx = isl_basic_set_get_ctx(bset1);
 	dir = valid_direction(isl_basic_set_copy(bset1),
 				isl_basic_set_copy(bset2));
 	if (!dir)
 		goto error;
-	T = isl_mat_alloc(bset1->ctx, dir->size, dir->size);
+	T = isl_mat_alloc(ctx, dir->size, dir->size);
 	if (!T)
 		goto error;
 	isl_seq_cpy(T->row[0], dir->block.data, dir->size);
@@ -1926,14 +1926,12 @@ struct isl_basic_map *isl_map_convex_hul
 	struct isl_basic_set *affine_hull = NULL;
 	struct isl_basic_map *convex_hull = NULL;
 	struct isl_set *set = NULL;
-	struct isl_ctx *ctx;
 
 	map = isl_map_detect_equalities(map);
 	map = isl_map_align_divs(map);
 	if (!map)
 		goto error;
 
-	ctx = map->ctx;
 	if (map->n == 0) {
 		convex_hull = isl_basic_map_empty_like_map(map);
 		isl_map_free(map);

Modified: polly/trunk/lib/External/isl/isl_equalities.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_equalities.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_equalities.c (original)
+++ polly/trunk/lib/External/isl/isl_equalities.c Wed Feb 25 13:34:52 2015
@@ -638,10 +638,10 @@ int isl_basic_set_dim_residue_class(stru
 		return 0;
 	}
 
-	ctx = bset->ctx;
+	ctx = isl_basic_set_get_ctx(bset);
 	total = isl_basic_set_total_dim(bset);
 	nparam = isl_basic_set_n_param(bset);
-	H = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq, 1, total);
+	H = isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 1, total);
 	H = isl_mat_left_hermite(H, 0, &U, NULL);
 	if (!H)
 		return -1;
@@ -657,11 +657,11 @@ int isl_basic_set_dim_residue_class(stru
 		return 0;
 	}
 
-	C = isl_mat_alloc(bset->ctx, 1+bset->n_eq, 1);
+	C = isl_mat_alloc(ctx, 1 + bset->n_eq, 1);
 	if (!C)
 		goto error;
 	isl_int_set_si(C->row[0][0], 1);
-	isl_mat_sub_neg(C->ctx, C->row+1, bset->eq, bset->n_eq, 0, 0, 1);
+	isl_mat_sub_neg(ctx, C->row + 1, bset->eq, bset->n_eq, 0, 0, 1);
 	H1 = isl_mat_sub_alloc(H, 0, H->n_row, 0, H->n_row);
 	H1 = isl_mat_lin_to_aff(H1);
 	C = isl_mat_inverse_product(H1, C);

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_flow.c (original)
+++ polly/trunk/lib/External/isl/isl_flow.c Wed Feb 25 13:34:52 2015
@@ -3,6 +3,7 @@
  * Copyright 2008-2009 Katholieke Universiteit Leuven
  * Copyright 2010      INRIA Saclay
  * Copyright 2012      Universiteit Leiden
+ * Copyright 2014      Ecole Normale Superieure
  *
  * Use of this software is governed by the MIT license
  *
@@ -12,11 +13,13 @@
  * B-3001 Leuven, Belgium
  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
+ * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
  */
 
 #include <isl/set.h>
 #include <isl/map.h>
 #include <isl/flow.h>
+#include <isl/schedule_node.h>
 #include <isl_sort.h>
 
 enum isl_restriction_type {
@@ -1167,13 +1170,440 @@ error:
 	return NULL;
 }
 
-struct isl_compute_flow_data {
+/* This structure represents the input for a dependence analysis computation.
+ *
+ * "sink" represents the sink accesses.
+ * "must_source" represents the definite source accesses.
+ * "may_source" represents the possible source accesses.
+ *
+ * "schedule" or "schedule_map" represents the execution order.
+ * Exactly one of these fields should be NULL.  The other field
+ * determines the execution order.
+ *
+ * The domains of these four maps refer to the same iteration spaces(s).
+ * The ranges of the first three maps also refer to the same data space(s).
+ *
+ * After a call to isl_union_access_info_introduce_schedule,
+ * the "schedule_map" field no longer contains useful information.
+ */
+struct isl_union_access_info {
+	isl_union_map *sink;
 	isl_union_map *must_source;
 	isl_union_map *may_source;
+
+	isl_schedule *schedule;
+	isl_union_map *schedule_map;
+};
+
+/* Free "access" and return NULL.
+ */
+__isl_null isl_union_access_info *isl_union_access_info_free(
+	__isl_take isl_union_access_info *access)
+{
+	if (!access)
+		return NULL;
+
+	isl_union_map_free(access->sink);
+	isl_union_map_free(access->must_source);
+	isl_union_map_free(access->may_source);
+	isl_schedule_free(access->schedule);
+	isl_union_map_free(access->schedule_map);
+	free(access);
+
+	return NULL;
+}
+
+/* Return the isl_ctx to which "access" belongs.
+ */
+isl_ctx *isl_union_access_info_get_ctx(__isl_keep isl_union_access_info *access)
+{
+	return access ? isl_union_map_get_ctx(access->sink) : NULL;
+}
+
+/* Create a new isl_union_access_info with the given sink accesses and
+ * and no source accesses or schedule information.
+ *
+ * By default, we use the schedule field of the isl_union_access_info,
+ * but this may be overridden by a call
+ * to isl_union_access_info_set_schedule_map.
+ */
+__isl_give isl_union_access_info *isl_union_access_info_from_sink(
+	__isl_take isl_union_map *sink)
+{
+	isl_ctx *ctx;
+	isl_space *space;
+	isl_union_map *empty;
+	isl_union_access_info *access;
+
+	if (!sink)
+		return NULL;
+	ctx = isl_union_map_get_ctx(sink);
+	access = isl_alloc_type(ctx, isl_union_access_info);
+	if (!access)
+		goto error;
+
+	space = isl_union_map_get_space(sink);
+	empty = isl_union_map_empty(isl_space_copy(space));
+	access->sink = sink;
+	access->must_source = isl_union_map_copy(empty);
+	access->may_source = empty;
+	access->schedule = isl_schedule_empty(space);
+	access->schedule_map = NULL;
+
+	if (!access->sink || !access->must_source ||
+	    !access->may_source || !access->schedule)
+		return isl_union_access_info_free(access);
+
+	return access;
+error:
+	isl_union_map_free(sink);
+	return NULL;
+}
+
+/* Replace the definite source accesses of "access" by "must_source".
+ */
+__isl_give isl_union_access_info *isl_union_access_info_set_must_source(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *must_source)
+{
+	if (!access || !must_source)
+		goto error;
+
+	isl_union_map_free(access->must_source);
+	access->must_source = must_source;
+
+	return access;
+error:
+	isl_union_access_info_free(access);
+	isl_union_map_free(must_source);
+	return NULL;
+}
+
+/* Replace the possible source accesses of "access" by "may_source".
+ */
+__isl_give isl_union_access_info *isl_union_access_info_set_may_source(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *may_source)
+{
+	if (!access || !may_source)
+		goto error;
+
+	isl_union_map_free(access->may_source);
+	access->may_source = may_source;
+
+	return access;
+error:
+	isl_union_access_info_free(access);
+	isl_union_map_free(may_source);
+	return NULL;
+}
+
+/* Replace the schedule of "access" by "schedule".
+ * Also free the schedule_map in case it was set last.
+ */
+__isl_give isl_union_access_info *isl_union_access_info_set_schedule(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_schedule *schedule)
+{
+	if (!access || !schedule)
+		goto error;
+
+	access->schedule_map = isl_union_map_free(access->schedule_map);
+	isl_schedule_free(access->schedule);
+	access->schedule = schedule;
+
+	return access;
+error:
+	isl_union_access_info_free(access);
+	isl_schedule_free(schedule);
+	return NULL;
+}
+
+/* Replace the schedule map of "access" by "schedule_map".
+ * Also free the schedule in case it was set last.
+ */
+__isl_give isl_union_access_info *isl_union_access_info_set_schedule_map(
+	__isl_take isl_union_access_info *access,
+	__isl_take isl_union_map *schedule_map)
+{
+	if (!access || !schedule_map)
+		goto error;
+
+	isl_union_map_free(access->schedule_map);
+	access->schedule = isl_schedule_free(access->schedule);
+	access->schedule_map = schedule_map;
+
+	return access;
+error:
+	isl_union_access_info_free(access);
+	isl_union_map_free(schedule_map);
+	return NULL;
+}
+
+/* Update the fields of "access" such that they all have the same parameters,
+ * keeping in mind that the schedule_map field may be NULL and ignoring
+ * the schedule field.
+ */
+static __isl_give isl_union_access_info *isl_union_access_info_align_params(
+	__isl_take isl_union_access_info *access)
+{
+	isl_space *space;
+
+	if (!access)
+		return NULL;
+
+	space = isl_union_map_get_space(access->sink);
+	space = isl_space_align_params(space,
+				isl_union_map_get_space(access->must_source));
+	space = isl_space_align_params(space,
+				isl_union_map_get_space(access->may_source));
+	if (access->schedule_map)
+		space = isl_space_align_params(space,
+				isl_union_map_get_space(access->schedule_map));
+	access->sink = isl_union_map_align_params(access->sink,
+							isl_space_copy(space));
+	access->must_source = isl_union_map_align_params(access->must_source,
+							isl_space_copy(space));
+	access->may_source = isl_union_map_align_params(access->may_source,
+							isl_space_copy(space));
+	if (!access->schedule_map) {
+		isl_space_free(space);
+	} else {
+		access->schedule_map =
+		    isl_union_map_align_params(access->schedule_map, space);
+		if (!access->schedule_map)
+			return isl_union_access_info_free(access);
+	}
+
+	if (!access->sink || !access->must_source || !access->may_source)
+		return isl_union_access_info_free(access);
+
+	return access;
+}
+
+/* Prepend the schedule dimensions to the iteration domains.
+ *
+ * That is, if the schedule is of the form
+ *
+ *	D -> S
+ *
+ * while the access relations are of the form
+ *
+ *	D -> A
+ *
+ * then the updated access relations are of the form
+ *
+ *	[S -> D] -> A
+ *
+ * The schedule map is also replaced by the map
+ *
+ *	[S -> D] -> D
+ *
+ * that is used during the internal computation.
+ * Neither the original schedule map nor this updated schedule map
+ * are used after the call to this function.
+ */
+static __isl_give isl_union_access_info *
+isl_union_access_info_introduce_schedule(
+	__isl_take isl_union_access_info *access)
+{
+	isl_union_map *sm;
+
+	if (!access)
+		return NULL;
+
+	sm = isl_union_map_reverse(access->schedule_map);
+	sm = isl_union_map_range_map(sm);
+	access->sink = isl_union_map_apply_range(isl_union_map_copy(sm),
+						access->sink);
+	access->may_source = isl_union_map_apply_range(isl_union_map_copy(sm),
+						access->may_source);
+	access->must_source = isl_union_map_apply_range(isl_union_map_copy(sm),
+						access->must_source);
+	access->schedule_map = sm;
+
+	if (!access->sink || !access->must_source ||
+	    !access->may_source || !access->schedule_map)
+		return isl_union_access_info_free(access);
+
+	return access;
+}
+
+/* This structure epresents the result of a dependence analysis computation.
+ *
+ * "must_dep" represents the definite dependences.
+ * "may_dep" represents the non-definite dependences.
+ * "must_no_source" represents the subset of the sink accesses for which
+ * definitely no source was found.
+ * "may_no_source" represents the subset of the sink accesses for which
+ * possibly, but not definitely, no source was found.
+ */
+struct isl_union_flow {
 	isl_union_map *must_dep;
 	isl_union_map *may_dep;
 	isl_union_map *must_no_source;
 	isl_union_map *may_no_source;
+};
+
+/* Free "flow" and return NULL.
+ */
+__isl_null isl_union_flow *isl_union_flow_free(__isl_take isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	isl_union_map_free(flow->must_dep);
+	isl_union_map_free(flow->may_dep);
+	isl_union_map_free(flow->must_no_source);
+	isl_union_map_free(flow->may_no_source);
+	free(flow);
+	return NULL;
+}
+
+void isl_union_flow_dump(__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return;
+
+	fprintf(stderr, "must dependences: ");
+	isl_union_map_dump(flow->must_dep);
+	fprintf(stderr, "may dependences: ");
+	isl_union_map_dump(flow->may_dep);
+	fprintf(stderr, "must no source: ");
+	isl_union_map_dump(flow->must_no_source);
+	fprintf(stderr, "may no source: ");
+	isl_union_map_dump(flow->may_no_source);
+}
+
+/* Return the definite dependences in "flow".
+ */
+__isl_give isl_union_map *isl_union_flow_get_must_dependence(
+	__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	return isl_union_map_copy(flow->must_dep);
+}
+
+/* Return the possible dependences in "flow", including the definite
+ * dependences.
+ */
+__isl_give isl_union_map *isl_union_flow_get_may_dependence(
+	__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	return isl_union_map_union(isl_union_map_copy(flow->must_dep),
+				    isl_union_map_copy(flow->may_dep));
+}
+
+/* Return the non-definite dependences in "flow".
+ */
+static __isl_give isl_union_map *isl_union_flow_get_non_must_dependence(
+	__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	return isl_union_map_copy(flow->may_dep);
+}
+
+/* Return the subset of the sink accesses for which definitely
+ * no source was found.
+ */
+__isl_give isl_union_map *isl_union_flow_get_must_no_source(
+	__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	return isl_union_map_copy(flow->must_no_source);
+}
+
+/* Return the subset of the sink accesses for which possibly
+ * no source was found, including those for which definitely
+ * no source was found.
+ */
+__isl_give isl_union_map *isl_union_flow_get_may_no_source(
+	__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	return isl_union_map_union(isl_union_map_copy(flow->must_no_source),
+				    isl_union_map_copy(flow->may_no_source));
+}
+
+/* Return the subset of the sink accesses for which possibly, but not
+ * definitely, no source was found.
+ */
+static __isl_give isl_union_map *isl_union_flow_get_non_must_no_source(
+	__isl_keep isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+	return isl_union_map_copy(flow->may_no_source);
+}
+
+/* Create a new isl_union_flow object, initialized with empty
+ * dependence relations and sink subsets.
+ */
+static __isl_give isl_union_flow *isl_union_flow_alloc(
+	__isl_take isl_space *space)
+{
+	isl_ctx *ctx;
+	isl_union_map *empty;
+	isl_union_flow *flow;
+
+	if (!space)
+		return NULL;
+	ctx = isl_space_get_ctx(space);
+	flow = isl_alloc_type(ctx, isl_union_flow);
+	if (!flow)
+		goto error;
+
+	empty = isl_union_map_empty(space);
+	flow->must_dep = isl_union_map_copy(empty);
+	flow->may_dep = isl_union_map_copy(empty);
+	flow->must_no_source = isl_union_map_copy(empty);
+	flow->may_no_source = empty;
+
+	if (!flow->must_dep || !flow->may_dep ||
+	    !flow->must_no_source || !flow->may_no_source)
+		return isl_union_flow_free(flow);
+
+	return flow;
+error:
+	isl_space_free(space);
+	return NULL;
+}
+
+/* Drop the schedule dimensions from the iteration domains in "flow".
+ * In particular, the schedule dimensions have been prepended
+ * to the iteration domains prior to the dependence analysis by
+ * replacing the iteration domain D, by the wrapped map [S -> D].
+ * Replace these wrapped maps by the original D.
+ */
+static __isl_give isl_union_flow *isl_union_flow_drop_schedule(
+	__isl_take isl_union_flow *flow)
+{
+	if (!flow)
+		return NULL;
+
+	flow->must_dep = isl_union_map_factor_range(flow->must_dep);
+	flow->may_dep = isl_union_map_factor_range(flow->may_dep);
+	flow->must_no_source =
+		isl_union_map_domain_factor_range(flow->must_no_source);
+	flow->may_no_source =
+		isl_union_map_domain_factor_range(flow->may_no_source);
+
+	if (!flow->must_dep || !flow->may_dep ||
+	    !flow->must_no_source || !flow->may_no_source)
+		return isl_union_flow_free(flow);
+
+	return flow;
+}
+
+struct isl_compute_flow_data {
+	isl_union_map *must_source;
+	isl_union_map *may_source;
+	isl_union_flow *flow;
 
 	int count;
 	int must;
@@ -1297,8 +1727,10 @@ static int compute_flow(__isl_take isl_m
 	isl_ctx *ctx;
 	struct isl_compute_flow_data *data;
 	isl_flow *flow;
+	isl_union_flow *df;
 
 	data = (struct isl_compute_flow_data *)user;
+	df = data->flow;
 
 	ctx = isl_map_get_ctx(map);
 
@@ -1340,18 +1772,18 @@ static int compute_flow(__isl_take isl_m
 	if (!flow)
 		goto error;
 
-	data->must_no_source = isl_union_map_union(data->must_no_source,
+	df->must_no_source = isl_union_map_union(df->must_no_source,
 		    isl_union_map_from_map(isl_flow_get_no_source(flow, 1)));
-	data->may_no_source = isl_union_map_union(data->may_no_source,
+	df->may_no_source = isl_union_map_union(df->may_no_source,
 		    isl_union_map_from_map(isl_flow_get_no_source(flow, 0)));
 
 	for (i = 0; i < flow->n_source; ++i) {
 		isl_union_map *dep;
 		dep = isl_union_map_from_map(isl_map_copy(flow->dep[i].map));
 		if (flow->dep[i].must)
-			data->must_dep = isl_union_map_union(data->must_dep, dep);
+			df->must_dep = isl_union_map_union(df->must_dep, dep);
 		else
-			data->may_dep = isl_union_map_union(data->may_dep, dep);
+			df->may_dep = isl_union_map_union(df->may_dep, dep);
 	}
 
 	isl_flow_free(flow);
@@ -1380,6 +1812,521 @@ error:
 	return -1;
 }
 
+/* Remove the must accesses from the may accesses.
+ *
+ * A must access always trumps a may access, so there is no need
+ * for a must access to also be considered as a may access.  Doing so
+ * would only cost extra computations only to find out that
+ * the duplicated may access does not make any difference.
+ */
+static __isl_give isl_union_access_info *isl_union_access_info_normalize(
+	__isl_take isl_union_access_info *access)
+{
+	if (!access)
+		return NULL;
+	access->may_source = isl_union_map_subtract(access->may_source,
+				    isl_union_map_copy(access->must_source));
+	if (!access->may_source)
+		return isl_union_access_info_free(access);
+
+	return access;
+}
+
+/* Given a description of the "sink" accesses, the "source" accesses and
+ * a schedule, compute for each instance of a sink access
+ * and for each element accessed by that instance,
+ * the possible or definite source accesses that last accessed the
+ * element accessed by the sink access before this sink access
+ * in the sense that there is no intermediate definite source access.
+ *
+ * The must_no_source and may_no_source elements of the result
+ * are subsets of access->sink.  The elements must_dep and may_dep
+ * map domain elements of access->{may,must)_source to
+ * domain elements of access->sink.
+ *
+ * This function is used when only the schedule map representation
+ * is available.
+ *
+ * We first prepend the schedule dimensions to the domain
+ * of the accesses so that we can easily compare their relative order.
+ * Then we consider each sink access individually in compute_flow.
+ */
+static __isl_give isl_union_flow *compute_flow_union_map(
+	__isl_take isl_union_access_info *access)
+{
+	struct isl_compute_flow_data data;
+
+	access = isl_union_access_info_align_params(access);
+	access = isl_union_access_info_introduce_schedule(access);
+	if (!access)
+		return NULL;
+
+	data.must_source = access->must_source;
+	data.may_source = access->may_source;
+
+	data.flow = isl_union_flow_alloc(isl_union_map_get_space(access->sink));
+
+	if (isl_union_map_foreach_map(access->sink, &compute_flow, &data) < 0)
+		goto error;
+
+	data.flow = isl_union_flow_drop_schedule(data.flow);
+
+	isl_union_access_info_free(access);
+	return data.flow;
+error:
+	isl_union_access_info_free(access);
+	isl_union_flow_free(data.flow);
+	return NULL;
+}
+
+/* A schedule access relation.
+ *
+ * The access relation "access" is of the form [S -> D] -> A,
+ * where S corresponds to the prefix schedule at "node".
+ * "must" is only relevant for source accesses and indicates
+ * whether the access is a must source or a may source.
+ */
+struct isl_scheduled_access {
+	isl_map *access;
+	int must;
+	isl_schedule_node *node;
+};
+
+/* Data structure for keeping track of individual scheduled sink and source
+ * accesses when computing dependence analysis based on a schedule tree.
+ *
+ * "n_sink" is the number of used entries in "sink"
+ * "n_source" is the number of used entries in "source"
+ *
+ * "set_sink", "must" and "node" are only used inside collect_sink_source,
+ * to keep track of the current node and
+ * of what extract_sink_source needs to do.
+ */
+struct isl_compute_flow_schedule_data {
+	isl_union_access_info *access;
+
+	int n_sink;
+	int n_source;
+
+	struct isl_scheduled_access *sink;
+	struct isl_scheduled_access *source;
+
+	int set_sink;
+	int must;
+	isl_schedule_node *node;
+};
+
+/* Align the parameters of all sinks with all sources.
+ *
+ * If there are no sinks or no sources, then no alignment is needed.
+ */
+static void isl_compute_flow_schedule_data_align_params(
+	struct isl_compute_flow_schedule_data *data)
+{
+	int i;
+	isl_space *space;
+
+	if (data->n_sink == 0 || data->n_source == 0)
+		return;
+
+	space = isl_map_get_space(data->sink[0].access);
+
+	for (i = 1; i < data->n_sink; ++i)
+		space = isl_space_align_params(space,
+				isl_map_get_space(data->sink[i].access));
+	for (i = 0; i < data->n_source; ++i)
+		space = isl_space_align_params(space,
+				isl_map_get_space(data->source[i].access));
+
+	for (i = 0; i < data->n_sink; ++i)
+		data->sink[i].access =
+			isl_map_align_params(data->sink[i].access,
+							isl_space_copy(space));
+	for (i = 0; i < data->n_source; ++i)
+		data->source[i].access =
+			isl_map_align_params(data->source[i].access,
+							isl_space_copy(space));
+
+	isl_space_free(space);
+}
+
+/* Free all the memory referenced from "data".
+ * Do not free "data" itself as it may be allocated on the stack.
+ */
+static void isl_compute_flow_schedule_data_clear(
+	struct isl_compute_flow_schedule_data *data)
+{
+	int i;
+
+	for (i = 0; i < data->n_sink; ++i) {
+		isl_map_free(data->sink[i].access);
+		isl_schedule_node_free(data->sink[i].node);
+	}
+
+	for (i = 0; i < data->n_source; ++i) {
+		isl_map_free(data->source[i].access);
+		isl_schedule_node_free(data->source[i].node);
+	}
+
+	free(data->sink);
+}
+
+/* isl_schedule_foreach_schedule_node callback for counting
+ * (an upper bound on) the number of sinks and sources.
+ *
+ * Sinks and sources are only extracted at leaves of the tree,
+ * so we skip the node if it is not a leaf.
+ * Otherwise we increment data->n_sink and data->n_source with
+ * the number of spaces in the sink and source access domains
+ * that reach this node.
+ */
+static int count_sink_source(__isl_keep isl_schedule_node *node, void *user)
+{
+	struct isl_compute_flow_schedule_data *data = user;
+	isl_union_set *domain;
+	isl_union_map *umap;
+	int r = 0;
+
+	if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf)
+		return 1;
+
+	domain = isl_schedule_node_get_universe_domain(node);
+
+	umap = isl_union_map_copy(data->access->sink);
+	umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain));
+	data->n_sink += isl_union_map_n_map(umap);
+	isl_union_map_free(umap);
+	if (!umap)
+		r = -1;
+
+	umap = isl_union_map_copy(data->access->must_source);
+	umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain));
+	data->n_source += isl_union_map_n_map(umap);
+	isl_union_map_free(umap);
+	if (!umap)
+		r = -1;
+
+	umap = isl_union_map_copy(data->access->may_source);
+	umap = isl_union_map_intersect_domain(umap, isl_union_set_copy(domain));
+	data->n_source += isl_union_map_n_map(umap);
+	isl_union_map_free(umap);
+	if (!umap)
+		r = -1;
+
+	isl_union_set_free(domain);
+
+	return r;
+}
+
+/* Add a single scheduled sink or source (depending on data->set_sink)
+ * with scheduled access relation "map", must property data->must and
+ * schedule node data->node to the list of sinks or sources.
+ */
+static int extract_sink_source(__isl_take isl_map *map, void *user)
+{
+	struct isl_compute_flow_schedule_data *data = user;
+	struct isl_scheduled_access *access;
+
+	if (data->set_sink)
+		access = data->sink + data->n_sink++;
+	else
+		access = data->source + data->n_source++;
+
+	access->access = map;
+	access->must = data->must;
+	access->node = isl_schedule_node_copy(data->node);
+
+	return 0;
+}
+
+/* isl_schedule_foreach_schedule_node callback for collecting
+ * individual scheduled source and sink accesses.
+ *
+ * We only collect accesses at the leaves of the schedule tree.
+ * We prepend the schedule dimensions at the leaf to the iteration
+ * domains of the source and sink accesses and then extract
+ * the individual accesses (per space).
+ *
+ * In particular, if the prefix schedule at the node is of the form
+ *
+ *	D -> S
+ *
+ * while the access relations are of the form
+ *
+ *	D -> A
+ *
+ * then the updated access relations are of the form
+ *
+ *	[S -> D] -> A
+ *
+ * Note that S consists of a single space such that introducing S
+ * in the access relations does not increase the number of spaces.
+ */
+static int collect_sink_source(__isl_keep isl_schedule_node *node, void *user)
+{
+	struct isl_compute_flow_schedule_data *data = user;
+	isl_union_map *prefix;
+	isl_union_map *umap;
+	int r = 0;
+
+	if (isl_schedule_node_get_type(node) != isl_schedule_node_leaf)
+		return 1;
+
+	data->node = node;
+
+	prefix = isl_schedule_node_get_prefix_schedule_union_map(node);
+	prefix = isl_union_map_reverse(prefix);
+	prefix = isl_union_map_range_map(prefix);
+
+	data->set_sink = 1;
+	umap = isl_union_map_copy(data->access->sink);
+	umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap);
+	if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0)
+		r = -1;
+	isl_union_map_free(umap);
+
+	data->set_sink = 0;
+	data->must = 1;
+	umap = isl_union_map_copy(data->access->must_source);
+	umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap);
+	if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0)
+		r = -1;
+	isl_union_map_free(umap);
+
+	data->set_sink = 0;
+	data->must = 0;
+	umap = isl_union_map_copy(data->access->may_source);
+	umap = isl_union_map_apply_range(isl_union_map_copy(prefix), umap);
+	if (isl_union_map_foreach_map(umap, &extract_sink_source, data) < 0)
+		r = -1;
+	isl_union_map_free(umap);
+
+	isl_union_map_free(prefix);
+
+	return r;
+}
+
+/* isl_access_info_compute_flow callback for determining whether
+ * the shared nesting level and the ordering within that level
+ * for two scheduled accesses for use in compute_single_flow.
+ *
+ * The tokens passed to this function refer to the leaves
+ * in the schedule tree where the accesses take place.
+ *
+ * If n is the shared number of loops, then we need to return
+ * "2 * n + 1" if "first" precedes "second" inside the innermost
+ * shared loop and "2 * n" otherwise.
+ *
+ * The innermost shared ancestor may be the leaves themselves
+ * if the accesses take place in the same leaf.  Otherwise,
+ * it is either a set node or a sequence node.  Only in the case
+ * of a sequence node do we consider one access to precede the other.
+ */
+static int before_node(void *first, void *second)
+{
+	isl_schedule_node *node1 = first;
+	isl_schedule_node *node2 = second;
+	isl_schedule_node *shared;
+	int depth;
+	int before = 0;
+
+	shared = isl_schedule_node_get_shared_ancestor(node1, node2);
+	if (!shared)
+		return -1;
+
+	depth = isl_schedule_node_get_schedule_depth(shared);
+	if (isl_schedule_node_get_type(shared) == isl_schedule_node_sequence) {
+		int pos1, pos2;
+
+		pos1 = isl_schedule_node_get_ancestor_child_position(node1,
+								    shared);
+		pos2 = isl_schedule_node_get_ancestor_child_position(node2,
+								    shared);
+		before = pos1 < pos2;
+	}
+
+	isl_schedule_node_free(shared);
+
+	return 2 * depth + before;
+}
+
+/* Add the scheduled sources from "data" that access
+ * the same data space as "sink" to "access".
+ */
+static __isl_give isl_access_info *add_matching_sources(
+	__isl_take isl_access_info *access, struct isl_scheduled_access *sink,
+	struct isl_compute_flow_schedule_data *data)
+{
+	int i;
+	isl_space *space;
+
+	space = isl_space_range(isl_map_get_space(sink->access));
+	for (i = 0; i < data->n_source; ++i) {
+		struct isl_scheduled_access *source;
+		isl_space *source_space;
+		int eq;
+
+		source = &data->source[i];
+		source_space = isl_map_get_space(source->access);
+		source_space = isl_space_range(source_space);
+		eq = isl_space_is_equal(space, source_space);
+		isl_space_free(source_space);
+
+		if (!eq)
+			continue;
+		if (eq < 0)
+			goto error;
+
+		access = isl_access_info_add_source(access,
+		    isl_map_copy(source->access), source->must, source->node);
+	}
+
+	isl_space_free(space);
+	return access;
+error:
+	isl_space_free(space);
+	isl_access_info_free(access);
+	return NULL;
+}
+
+/* Given a scheduled sink access relation "sink", compute the corresponding
+ * dependences on the sources in "data" and add the computed dependences
+ * to "uf".
+ */
+static __isl_give isl_union_flow *compute_single_flow(
+	__isl_take isl_union_flow *uf, struct isl_scheduled_access *sink,
+	struct isl_compute_flow_schedule_data *data)
+{
+	int i;
+	isl_access_info *access;
+	isl_flow *flow;
+	isl_map *map;
+
+	if (!uf)
+		return NULL;
+
+	access = isl_access_info_alloc(isl_map_copy(sink->access), sink->node,
+					&before_node, data->n_source);
+	access = add_matching_sources(access, sink, data);
+
+	flow = isl_access_info_compute_flow(access);
+	if (!flow)
+		return isl_union_flow_free(uf);
+
+	map = isl_map_domain_factor_range(isl_flow_get_no_source(flow, 1));
+	uf->must_no_source = isl_union_map_union(uf->must_no_source,
+						isl_union_map_from_map(map));
+	map = isl_map_domain_factor_range(isl_flow_get_no_source(flow, 0));
+	uf->may_no_source = isl_union_map_union(uf->may_no_source,
+						isl_union_map_from_map(map));
+
+	for (i = 0; i < flow->n_source; ++i) {
+		isl_union_map *dep;
+
+		map = isl_map_factor_range(isl_map_copy(flow->dep[i].map));
+		dep = isl_union_map_from_map(map);
+		if (flow->dep[i].must)
+			uf->must_dep = isl_union_map_union(uf->must_dep, dep);
+		else
+			uf->may_dep = isl_union_map_union(uf->may_dep, dep);
+	}
+
+	isl_flow_free(flow);
+
+	return uf;
+}
+
+/* Given a description of the "sink" accesses, the "source" accesses and
+ * a schedule, compute for each instance of a sink access
+ * and for each element accessed by that instance,
+ * the possible or definite source accesses that last accessed the
+ * element accessed by the sink access before this sink access
+ * in the sense that there is no intermediate definite source access.
+ *
+ * The must_no_source and may_no_source elements of the result
+ * are subsets of access->sink.  The elements must_dep and may_dep
+ * map domain elements of access->{may,must)_source to
+ * domain elements of access->sink.
+ *
+ * This function is used when a schedule tree representation
+ * is available.
+ *
+ * We extract the individual scheduled source and sink access relations and
+ * then compute dependences for each scheduled sink individually.
+ */
+static __isl_give isl_union_flow *compute_flow_schedule(
+	__isl_take isl_union_access_info *access)
+{
+	struct isl_compute_flow_schedule_data data = { access };
+	int i, n;
+	isl_ctx *ctx;
+	isl_union_flow *flow;
+
+	ctx = isl_union_access_info_get_ctx(access);
+
+	data.n_sink = 0;
+	data.n_source = 0;
+	if (isl_schedule_foreach_schedule_node(access->schedule,
+						&count_sink_source, &data) < 0)
+		goto error;
+
+	n = data.n_sink + data.n_source;
+	data.sink = isl_calloc_array(ctx, struct isl_scheduled_access, n);
+	if (n && !data.sink)
+		goto error;
+	data.source = data.sink + data.n_sink;
+
+	data.n_sink = 0;
+	data.n_source = 0;
+	if (isl_schedule_foreach_schedule_node(access->schedule,
+					    &collect_sink_source, &data) < 0)
+		goto error;
+
+	flow = isl_union_flow_alloc(isl_union_map_get_space(access->sink));
+
+	isl_compute_flow_schedule_data_align_params(&data);
+
+	for (i = 0; i < data.n_sink; ++i)
+		flow = compute_single_flow(flow, &data.sink[i], &data);
+
+	isl_compute_flow_schedule_data_clear(&data);
+
+	isl_union_access_info_free(access);
+	return flow;
+error:
+	isl_union_access_info_free(access);
+	isl_compute_flow_schedule_data_clear(&data);
+	return NULL;
+}
+
+/* Given a description of the "sink" accesses, the "source" accesses and
+ * a schedule, compute for each instance of a sink access
+ * and for each element accessed by that instance,
+ * the possible or definite source accesses that last accessed the
+ * element accessed by the sink access before this sink access
+ * in the sense that there is no intermediate definite source access.
+ *
+ * The must_no_source and may_no_source elements of the result
+ * are subsets of access->sink.  The elements must_dep and may_dep
+ * map domain elements of access->{may,must)_source to
+ * domain elements of access->sink.
+ *
+ * We check whether the schedule is available as a schedule tree
+ * or a schedule map and call the correpsonding function to perform
+ * the analysis.
+ */
+__isl_give isl_union_flow *isl_union_access_info_compute_flow(
+	__isl_take isl_union_access_info *access)
+{
+	access = isl_union_access_info_normalize(access);
+	if (!access)
+		return NULL;
+	if (access->schedule)
+		return compute_flow_schedule(access);
+	else
+		return compute_flow_union_map(access);
+}
+
 /* Given a collection of "sink" and "source" accesses,
  * compute for each iteration of a sink access
  * and for each element accessed by that iteration,
@@ -1392,9 +2339,9 @@ error:
  * corresponding to those iterations that access an element
  * not previously accessed.
  *
- * We first prepend the schedule dimensions to the domain
- * of the accesses so that we can easily compare their relative order.
- * Then we consider each sink access individually in compute_flow.
+ * We collect the inputs in an isl_union_access_info object,
+ * call isl_union_access_info_compute_flow and extract
+ * the outputs from the result.
  */
 int isl_union_map_compute_flow(__isl_take isl_union_map *sink,
 	__isl_take isl_union_map *must_source,
@@ -1404,93 +2351,40 @@ int isl_union_map_compute_flow(__isl_tak
 	__isl_give isl_union_map **must_no_source,
 	__isl_give isl_union_map **may_no_source)
 {
-	isl_space *dim;
-	isl_union_map *range_map = NULL;
-	struct isl_compute_flow_data data;
-
-	sink = isl_union_map_align_params(sink,
-					    isl_union_map_get_space(must_source));
-	sink = isl_union_map_align_params(sink,
-					    isl_union_map_get_space(may_source));
-	sink = isl_union_map_align_params(sink,
-					    isl_union_map_get_space(schedule));
-	dim = isl_union_map_get_space(sink);
-	must_source = isl_union_map_align_params(must_source, isl_space_copy(dim));
-	may_source = isl_union_map_align_params(may_source, isl_space_copy(dim));
-	schedule = isl_union_map_align_params(schedule, isl_space_copy(dim));
-
-	schedule = isl_union_map_reverse(schedule);
-	range_map = isl_union_map_range_map(schedule);
-	schedule = isl_union_map_reverse(isl_union_map_copy(range_map));
-	sink = isl_union_map_apply_domain(sink, isl_union_map_copy(schedule));
-	must_source = isl_union_map_apply_domain(must_source,
-						isl_union_map_copy(schedule));
-	may_source = isl_union_map_apply_domain(may_source, schedule);
-
-	data.must_source = must_source;
-	data.may_source = may_source;
-	data.must_dep = must_dep ?
-		isl_union_map_empty(isl_space_copy(dim)) : NULL;
-	data.may_dep = may_dep ? isl_union_map_empty(isl_space_copy(dim)) : NULL;
-	data.must_no_source = must_no_source ?
-		isl_union_map_empty(isl_space_copy(dim)) : NULL;
-	data.may_no_source = may_no_source ?
-		isl_union_map_empty(isl_space_copy(dim)) : NULL;
-
-	isl_space_free(dim);
+	isl_union_access_info *access;
+	isl_union_flow *flow;
 
-	if (isl_union_map_foreach_map(sink, &compute_flow, &data) < 0)
-		goto error;
+	access = isl_union_access_info_from_sink(sink);
+	access = isl_union_access_info_set_must_source(access, must_source);
+	access = isl_union_access_info_set_may_source(access, may_source);
+	access = isl_union_access_info_set_schedule_map(access, schedule);
+	flow = isl_union_access_info_compute_flow(access);
 
-	isl_union_map_free(sink);
-	isl_union_map_free(must_source);
-	isl_union_map_free(may_source);
+	if (must_dep)
+		*must_dep = isl_union_flow_get_must_dependence(flow);
+	if (may_dep)
+		*may_dep = isl_union_flow_get_non_must_dependence(flow);
+	if (must_no_source)
+		*must_no_source = isl_union_flow_get_must_no_source(flow);
+	if (may_no_source)
+		*may_no_source = isl_union_flow_get_non_must_no_source(flow);
 
-	if (must_dep) {
-		data.must_dep = isl_union_map_apply_domain(data.must_dep,
-					isl_union_map_copy(range_map));
-		data.must_dep = isl_union_map_apply_range(data.must_dep,
-					isl_union_map_copy(range_map));
-		*must_dep = data.must_dep;
-	}
-	if (may_dep) {
-		data.may_dep = isl_union_map_apply_domain(data.may_dep,
-					isl_union_map_copy(range_map));
-		data.may_dep = isl_union_map_apply_range(data.may_dep,
-					isl_union_map_copy(range_map));
-		*may_dep = data.may_dep;
-	}
-	if (must_no_source) {
-		data.must_no_source = isl_union_map_apply_domain(
-			data.must_no_source, isl_union_map_copy(range_map));
-		*must_no_source = data.must_no_source;
-	}
-	if (may_no_source) {
-		data.may_no_source = isl_union_map_apply_domain(
-			data.may_no_source, isl_union_map_copy(range_map));
-		*may_no_source = data.may_no_source;
-	}
+	isl_union_flow_free(flow);
 
-	isl_union_map_free(range_map);
+	if ((must_dep && !*must_dep) || (may_dep && !*may_dep) ||
+	    (must_no_source && !*must_no_source) ||
+	    (may_no_source && !*may_no_source))
+		goto error;
 
 	return 0;
 error:
-	isl_union_map_free(range_map);
-	isl_union_map_free(sink);
-	isl_union_map_free(must_source);
-	isl_union_map_free(may_source);
-	isl_union_map_free(data.must_dep);
-	isl_union_map_free(data.may_dep);
-	isl_union_map_free(data.must_no_source);
-	isl_union_map_free(data.may_no_source);
-
 	if (must_dep)
-		*must_dep = NULL;
+		*must_dep = isl_union_map_free(*must_dep);
 	if (may_dep)
-		*may_dep = NULL;
+		*may_dep = isl_union_map_free(*may_dep);
 	if (must_no_source)
-		*must_no_source = NULL;
+		*must_no_source = isl_union_map_free(*must_no_source);
 	if (may_no_source)
-		*may_no_source = NULL;
+		*may_no_source = isl_union_map_free(*may_no_source);
 	return -1;
 }

Modified: polly/trunk/lib/External/isl/isl_id.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_id.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_id.c (original)
+++ polly/trunk/lib/External/isl/isl_id.c Wed Feb 25 13:34:52 2015
@@ -88,8 +88,10 @@ static int isl_id_has_name_and_user(cons
 
 	if (id->user != nu->user)
 		return 0;
-	if (!id->name && !nu->name)
+	if (id->name == nu->name)
 		return 1;
+	if (!id->name || !nu->name)
+		return 0;
 
 	return !strcmp(id->name, nu->name);
 }

Modified: polly/trunk/lib/External/isl/isl_input.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_input.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_input.c (original)
+++ polly/trunk/lib/External/isl/isl_input.c Wed Feb 25 13:34:52 2015
@@ -1771,15 +1771,10 @@ static __isl_give isl_basic_map *basic_m
 	int type;
 	int k;
 	isl_int *c;
-	unsigned nparam;
-	unsigned dim;
 
 	if (!bmap)
 		return NULL;
 
-	nparam = isl_basic_map_dim(bmap, isl_dim_param);
-	dim = isl_basic_map_dim(bmap, isl_dim_out);
-
 	tok = isl_stream_next_token(s);
 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
 		isl_stream_error(s, tok, "expecting coefficient");

Modified: polly/trunk/lib/External/isl/isl_local_space.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_local_space.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_local_space.c (original)
+++ polly/trunk/lib/External/isl/isl_local_space.c Wed Feb 25 13:34:52 2015
@@ -919,7 +919,7 @@ __isl_give isl_local_space *isl_local_sp
 	pos += isl_local_space_offset(ls, type);
 
 	isl_int_init(v);
-	for (i = first; i < ls->div->n_row; ++i) {
+	for (i = first; i < first + n; ++i) {
 		if (isl_int_is_zero(ls->div->row[i][1 + pos]))
 			continue;
 		isl_seq_substitute(ls->div->row[i], pos, subs,

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_map_simplify.c (original)
+++ polly/trunk/lib/External/isl/isl_map_simplify.c Wed Feb 25 13:34:52 2015
@@ -735,12 +735,14 @@ static struct isl_basic_map *remove_dupl
 	if (k <= 0)
 		return bmap;
 
-	elim_for = isl_calloc_array(ctx, int, bmap->n_div);
 	size = round_up(4 * bmap->n_div / 3 - 1);
+	if (size == 0)
+		return bmap;
+	elim_for = isl_calloc_array(ctx, int, bmap->n_div);
 	bits = ffs(size) - 1;
 	index = isl_calloc_array(ctx, int, size);
-	if (!index)
-		return bmap;
+	if (!elim_for || !index)
+		goto out;
 	eq = isl_blk_alloc(ctx, 1+total);
 	if (isl_blk_is_error(eq))
 		goto out;
@@ -1128,6 +1130,8 @@ __isl_give isl_basic_map *isl_basic_map_
 		return bmap;
 
 	size = round_up(4 * (bmap->n_ineq+1) / 3 - 1);
+	if (size == 0)
+		return bmap;
 	bits = ffs(size) - 1;
 	ctx = isl_basic_map_get_ctx(bmap);
 	index = isl_calloc_array(ctx, isl_int **, size);
@@ -1758,6 +1762,8 @@ static struct isl_basic_set *remove_shif
 		return NULL;
 
 	size = round_up(4 * (context->n_ineq+1) / 3 - 1);
+	if (size == 0)
+		return bset;
 	bits = ffs(size) - 1;
 	ctx = isl_basic_set_get_ctx(bset);
 	index = isl_calloc_array(ctx, isl_int **, size);
@@ -2298,7 +2304,7 @@ struct isl_basic_map *isl_basic_map_gist
 	n_eq = bset->n_eq;
 	n_ineq = bset->n_ineq;
 	eq = isl_basic_set_copy(bset);
-	eq = isl_basic_set_cow(bset);
+	eq = isl_basic_set_cow(eq);
 	if (isl_basic_set_free_inequality(eq, n_ineq) < 0)
 		eq = isl_basic_set_free(eq);
 	if (isl_basic_set_free_equality(bset, n_eq) < 0)

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_mat.c (original)
+++ polly/trunk/lib/External/isl/isl_mat.c Wed Feb 25 13:34:52 2015
@@ -1179,14 +1179,12 @@ error2:
 
 struct isl_set *isl_set_preimage(struct isl_set *set, struct isl_mat *mat)
 {
-	struct isl_ctx *ctx;
 	int i;
 
 	set = isl_set_cow(set);
 	if (!set)
 		return NULL;
 
-	ctx = set->ctx;
 	for (i = 0; i < set->n; ++i) {
 		set->p[i] = isl_basic_set_preimage(set->p[i],
 						    isl_mat_copy(mat));

Modified: polly/trunk/lib/External/isl/isl_output.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_output.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_output.c (original)
+++ polly/trunk/lib/External/isl/isl_output.c Wed Feb 25 13:34:52 2015
@@ -1096,7 +1096,7 @@ static int print_map_body(__isl_take isl
 static __isl_give isl_printer *isl_union_map_print_isl(
 	__isl_keep isl_union_map *umap, __isl_take isl_printer *p)
 {
-	struct isl_union_print_data data = { p, 1 };
+	struct isl_union_print_data data;
 	struct isl_print_space_data space_data = { 0 };
 	isl_space *dim;
 
@@ -1107,6 +1107,8 @@ static __isl_give isl_printer *isl_union
 	}
 	isl_space_free(dim);
 	p = isl_printer_print_str(p, s_open_set[0]);
+	data.p = p;
+	data.first = 1;
 	isl_union_map_foreach_map(umap, &print_map_body, &data);
 	p = data.p;
 	p = isl_printer_print_str(p, s_close_set[0]);
@@ -1766,7 +1768,7 @@ static int print_pwqp_body(__isl_take is
 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
 	__isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
 {
-	struct isl_union_print_data data = { p, 1 };
+	struct isl_union_print_data data;
 	struct isl_print_space_data space_data = { 0 };
 	isl_space *dim;
 
@@ -1777,6 +1779,8 @@ static __isl_give isl_printer *print_uni
 	}
 	isl_space_free(dim);
 	p = isl_printer_print_str(p, "{ ");
+	data.p = p;
+	data.first = 1;
 	isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
 							&data);
 	p = data.p;
@@ -1908,7 +1912,7 @@ static __isl_give isl_printer *print_uni
 	__isl_take isl_printer *p,
 	__isl_keep isl_union_pw_qpolynomial_fold *upwf)
 {
-	struct isl_union_print_data data = { p, 1 };
+	struct isl_union_print_data data;
 	struct isl_print_space_data space_data = { 0 };
 	isl_space *dim;
 
@@ -1919,6 +1923,8 @@ static __isl_give isl_printer *print_uni
 	}
 	isl_space_free(dim);
 	p = isl_printer_print_str(p, "{ ");
+	data.p = p;
+	data.first = 1;
 	isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
 							&print_pwf_body, &data);
 	p = data.p;
@@ -2005,13 +2011,11 @@ __isl_give isl_printer *isl_printer_prin
 	__isl_keep isl_local_space *ls)
 {
 	struct isl_print_space_data data = { 0 };
-	unsigned total;
 	unsigned n_div;
 
 	if (!ls)
 		goto error;
 
-	total = isl_local_space_dim(ls, isl_dim_all);
 	if (isl_local_space_dim(ls, isl_dim_param) > 0) {
 		p = print_tuple(ls->dim, p, isl_dim_param, &data);
 		p = isl_printer_print_str(p, " -> ");
@@ -2561,7 +2565,7 @@ static int print_pw_multi_aff_body_wrap(
 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
 	__isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
 {
-	struct isl_union_print_data data = { p, 1 };
+	struct isl_union_print_data data;
 	struct isl_print_space_data space_data = { 0 };
 	isl_space *space;
 
@@ -2572,6 +2576,8 @@ static __isl_give isl_printer *print_uni
 	}
 	isl_space_free(space);
 	p = isl_printer_print_str(p, s_open_set[0]);
+	data.p = p;
+	data.first = 1;
 	isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
 					&print_pw_multi_aff_body_wrap, &data);
 	p = data.p;

Modified: polly/trunk/lib/External/isl/isl_range.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_range.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_range.c (original)
+++ polly/trunk/lib/External/isl/isl_range.c Wed Feb 25 13:34:52 2015
@@ -29,7 +29,6 @@ static int has_sign(__isl_keep isl_basic
 	__isl_keep isl_qpolynomial *poly, int sign, int *signs)
 {
 	struct range_data data_m;
-	unsigned nvar;
 	unsigned nparam;
 	isl_space *dim;
 	isl_val *opt;
@@ -37,7 +36,6 @@ static int has_sign(__isl_keep isl_basic
 	enum isl_fold type;
 
 	nparam = isl_basic_set_dim(bset, isl_dim_param);
-	nvar = isl_basic_set_dim(bset, isl_dim_set);
 
 	bset = isl_basic_set_copy(bset);
 	poly = isl_qpolynomial_copy(poly);

Modified: polly/trunk/lib/External/isl/isl_sample.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_sample.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_sample.c (original)
+++ polly/trunk/lib/External/isl/isl_sample.c Wed Feb 25 13:34:52 2015
@@ -595,7 +595,6 @@ error:
 static struct isl_vec *sample_bounded(struct isl_basic_set *bset)
 {
 	unsigned dim;
-	struct isl_ctx *ctx;
 	struct isl_vec *sample;
 	struct isl_tab *tab = NULL;
 	isl_factorizer *f;
@@ -620,14 +619,12 @@ static struct isl_vec *sample_bounded(st
 	if (f->n_group != 0)
 		return factored_sample(bset, f);
 	isl_factorizer_free(f);
-		
-	ctx = bset->ctx;
 
 	tab = isl_tab_from_basic_set(bset, 1);
 	if (tab && tab->empty) {
 		isl_tab_free(tab);
 		ISL_F_SET(bset, ISL_BASIC_SET_EMPTY);
-		sample = isl_vec_alloc(bset->ctx, 0);
+		sample = isl_vec_alloc(isl_basic_set_get_ctx(bset), 0);
 		isl_basic_set_free(bset);
 		return sample;
 	}
@@ -924,11 +921,11 @@ __isl_give isl_vec *isl_basic_set_sample
 	if (!bset || !cone)
 		goto error;
 
-	ctx = bset->ctx;
+	ctx = isl_basic_set_get_ctx(bset);
 	total = isl_basic_set_total_dim(cone);
 	cone_dim = total - cone->n_eq;
 
-	M = isl_mat_sub_alloc6(bset->ctx, cone->eq, 0, cone->n_eq, 1, total);
+	M = isl_mat_sub_alloc6(ctx, cone->eq, 0, cone->n_eq, 1, total);
 	M = isl_mat_left_hermite(M, 0, &U, NULL);
 	if (!M)
 		goto error;

Modified: polly/trunk/lib/External/isl/isl_schedule.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule.c (original)
+++ polly/trunk/lib/External/isl/isl_schedule.c Wed Feb 25 13:34:52 2015
@@ -177,6 +177,19 @@ __isl_keep isl_schedule_tree *isl_schedu
 	return schedule ? &schedule->leaf : NULL;
 }
 
+/* Are "schedule1" and "schedule2" obviously equal to each other?
+ */
+int isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1,
+	__isl_keep isl_schedule *schedule2)
+{
+	if (!schedule1 || !schedule2)
+		return -1;
+	if (schedule1 == schedule2)
+		return 1;
+	return isl_schedule_tree_plain_is_equal(schedule1->root,
+						schedule2->root);
+}
+
 /* Return the (parameter) space of the schedule, i.e., the space
  * of the root domain.
  */
@@ -361,6 +374,101 @@ __isl_give isl_schedule *isl_schedule_ma
 	return schedule;
 }
 
+/* Wrapper around isl_schedule_node_reset_user for use as
+ * an isl_schedule_map_schedule_node callback.
+ */
+static __isl_give isl_schedule_node *reset_user(
+	__isl_take isl_schedule_node *node, void *user)
+{
+	return isl_schedule_node_reset_user(node);
+}
+
+/* Reset the user pointer on all identifiers of parameters and tuples
+ * in the schedule "schedule".
+ */
+__isl_give isl_schedule *isl_schedule_reset_user(
+	__isl_take isl_schedule *schedule)
+{
+	return isl_schedule_map_schedule_node(schedule, &reset_user, NULL);
+}
+
+/* Wrapper around isl_schedule_node_align_params for use as
+ * an isl_schedule_map_schedule_node callback.
+ */
+static __isl_give isl_schedule_node *align_params(
+	__isl_take isl_schedule_node *node, void *user)
+{
+	isl_space *space = user;
+
+	return isl_schedule_node_align_params(node, isl_space_copy(space));
+}
+
+/* Align the parameters of all nodes in schedule "schedule"
+ * to those of "space".
+ */
+__isl_give isl_schedule *isl_schedule_align_params(
+	__isl_take isl_schedule *schedule, __isl_take isl_space *space)
+{
+	schedule = isl_schedule_map_schedule_node(schedule,
+						    &align_params, space);
+	isl_space_free(space);
+	return schedule;
+}
+
+/* Wrapper around isl_schedule_node_pullback_union_pw_multi_aff for use as
+ * an isl_schedule_map_schedule_node callback.
+ */
+static __isl_give isl_schedule_node *pullback_upma(
+	__isl_take isl_schedule_node *node, void *user)
+{
+	isl_union_pw_multi_aff *upma = user;
+
+	return isl_schedule_node_pullback_union_pw_multi_aff(node,
+					isl_union_pw_multi_aff_copy(upma));
+}
+
+/* Compute the pullback of "schedule" by the function represented by "upma".
+ * In other words, plug in "upma" in the iteration domains of "schedule".
+ */
+__isl_give isl_schedule *isl_schedule_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule *schedule,
+	__isl_take isl_union_pw_multi_aff *upma)
+{
+	schedule = isl_schedule_map_schedule_node(schedule,
+						&pullback_upma, upma);
+	isl_union_pw_multi_aff_free(upma);
+	return schedule;
+}
+
+/* Intersect the domain of the schedule "schedule" with "domain".
+ */
+__isl_give isl_schedule *isl_schedule_intersect_domain(
+	__isl_take isl_schedule *schedule, __isl_take isl_union_set *domain)
+{
+	enum isl_schedule_node_type root_type;
+	isl_schedule_node *node;
+
+	if (!schedule || !domain)
+		goto error;
+
+	root_type = isl_schedule_tree_get_type(schedule->root);
+	if (root_type != isl_schedule_node_domain)
+		isl_die(isl_schedule_get_ctx(schedule), isl_error_internal,
+			"root node not a domain node", goto error);
+
+	node = isl_schedule_get_root(schedule);
+	isl_schedule_free(schedule);
+	node = isl_schedule_node_domain_intersect_domain(node, domain);
+	schedule = isl_schedule_node_get_schedule(node);
+	isl_schedule_node_free(node);
+
+	return schedule;
+error:
+	isl_schedule_free(schedule);
+	isl_union_set_free(domain);
+	return NULL;
+}
+
 /* Return an isl_union_map representation of the schedule.
  * If we still have access to the schedule tree, then we return
  * an isl_union_map corresponding to the subtree schedule of the child
@@ -738,6 +846,150 @@ static __isl_give isl_printer *print_ban
 	return p;
 }
 
+/* Insert a band node with partial schedule "partial" between the domain
+ * root node of "schedule" and its single child.
+ * Return a pointer to the updated schedule.
+ */
+__isl_give isl_schedule *isl_schedule_insert_partial_schedule(
+	__isl_take isl_schedule *schedule,
+	__isl_take isl_multi_union_pw_aff *partial)
+{
+	isl_schedule_node *node;
+
+	node = isl_schedule_get_root(schedule);
+	isl_schedule_free(schedule);
+	if (!node)
+		goto error;
+	if (isl_schedule_node_get_type(node) != isl_schedule_node_domain)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_internal,
+			"root node not a domain node", goto error);
+
+	node = isl_schedule_node_child(node, 0);
+	node = isl_schedule_node_insert_partial_schedule(node, partial);
+
+	schedule = isl_schedule_node_get_schedule(node);
+	isl_schedule_node_free(node);
+
+	return schedule;
+error:
+	isl_schedule_node_free(node);
+	isl_multi_union_pw_aff_free(partial);
+	return NULL;
+}
+
+/* Return a tree with as top-level node a filter corresponding to "filter" and
+ * as child, the (single) child of "tree".
+ * However, if this single child is of type "type", then the filter is inserted
+ * in the children of this single child instead.
+ */
+static __isl_give isl_schedule_tree *insert_filter_in_child_of_type(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter,
+	enum isl_schedule_node_type type)
+{
+	if (!isl_schedule_tree_has_children(tree)) {
+		isl_schedule_tree_free(tree);
+		return isl_schedule_tree_from_filter(filter);
+	} else {
+		tree = isl_schedule_tree_child(tree, 0);
+	}
+
+	if (isl_schedule_tree_get_type(tree) == type)
+		tree = isl_schedule_tree_children_insert_filter(tree, filter);
+	else
+		tree = isl_schedule_tree_insert_filter(tree, filter);
+
+	return tree;
+}
+
+/* Construct a schedule that combines the schedules "schedule1" and "schedule2"
+ * with a top-level node (underneath the domain node) of type "type",
+ * either isl_schedule_node_sequence or isl_schedule_node_set.
+ * The domains of the two schedules are assumed to be disjoint.
+ *
+ * The new schedule has as domain the union of the domains of the two
+ * schedules.  The child of the domain node is a node of type "type"
+ * with two filters corresponding to the domains of the input schedules.
+ * If one (or both) of the top-level nodes of the two schedules is itself
+ * of type "type", then the filter is pushed into the children of that
+ * node and the sequence of set is flattened.
+ */
+__isl_give isl_schedule *isl_schedule_pair(enum isl_schedule_node_type type,
+	__isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2)
+{
+	int disjoint;
+	isl_ctx *ctx;
+	enum isl_schedule_node_type root_type;
+	isl_schedule_tree *tree1, *tree2;
+	isl_union_set *filter1, *filter2, *domain;
+
+	if (!schedule1 || !schedule2)
+		goto error;
+
+	root_type = isl_schedule_tree_get_type(schedule1->root);
+	if (root_type != isl_schedule_node_domain)
+		isl_die(isl_schedule_get_ctx(schedule1), isl_error_internal,
+			"root node not a domain node", goto error);
+	root_type = isl_schedule_tree_get_type(schedule2->root);
+	if (root_type != isl_schedule_node_domain)
+		isl_die(isl_schedule_get_ctx(schedule1), isl_error_internal,
+			"root node not a domain node", goto error);
+
+	ctx = isl_schedule_get_ctx(schedule1);
+	tree1 = isl_schedule_tree_copy(schedule1->root);
+	filter1 = isl_schedule_tree_domain_get_domain(tree1);
+	tree2 = isl_schedule_tree_copy(schedule2->root);
+	filter2 = isl_schedule_tree_domain_get_domain(tree2);
+
+	isl_schedule_free(schedule1);
+	isl_schedule_free(schedule2);
+
+	disjoint = isl_union_set_is_disjoint(filter1, filter2);
+	if (disjoint < 0)
+		filter1 = isl_union_set_free(filter1);
+	if (!disjoint)
+		isl_die(ctx, isl_error_invalid,
+			"schedule domains not disjoint",
+			filter1 = isl_union_set_free(filter1));
+
+	domain = isl_union_set_union(isl_union_set_copy(filter1),
+				    isl_union_set_copy(filter2));
+	filter1 = isl_union_set_gist(filter1, isl_union_set_copy(domain));
+	filter2 = isl_union_set_gist(filter2, isl_union_set_copy(domain));
+
+	tree1 = insert_filter_in_child_of_type(tree1, filter1, type);
+	tree2 = insert_filter_in_child_of_type(tree2, filter2, type);
+
+	tree1 = isl_schedule_tree_from_pair(type, tree1, tree2);
+	tree1 = isl_schedule_tree_insert_domain(tree1, domain);
+
+	return isl_schedule_from_schedule_tree(ctx, tree1);
+error:
+	isl_schedule_free(schedule1);
+	isl_schedule_free(schedule2);
+	return NULL;
+}
+
+/* Construct a schedule that combines the schedules "schedule1" and "schedule2"
+ * through a sequence node.
+ * The domains of the input schedules are assumed to be disjoint.
+ */
+__isl_give isl_schedule *isl_schedule_sequence(
+	__isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2)
+{
+	return isl_schedule_pair(isl_schedule_node_sequence,
+				schedule1, schedule2);
+}
+
+/* Construct a schedule that combines the schedules "schedule1" and "schedule2"
+ * through a set node.
+ * The domains of the input schedules are assumed to be disjoint.
+ */
+__isl_give isl_schedule *isl_schedule_set(
+	__isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2)
+{
+	return isl_schedule_pair(isl_schedule_node_set, schedule1, schedule2);
+}
+
 /* Print "schedule" to "p".
  *
  * If "schedule" was created from a schedule tree, then we print

Modified: polly/trunk/lib/External/isl/isl_schedule_band.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_band.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_band.c (original)
+++ polly/trunk/lib/External/isl/isl_schedule_band.c Wed Feb 25 13:34:52 2015
@@ -1,10 +1,13 @@
 /*
  * Copyright 2013-2014 Ecole Normale Superieure
+ * Copyright 2014      INRIA Rocquencourt
  *
  * Use of this software is governed by the MIT license
  *
  * Written by Sven Verdoolaege,
  * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
+ * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
+ * B.P. 105 - 78153 Le Chesnay, France
  */
 
 #include <isl/schedule_node.h>
@@ -142,6 +145,29 @@ __isl_null isl_schedule_band *isl_schedu
 	return NULL;
 }
 
+/* Are "band1" and "band2" obviously equal?
+ */
+int isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1,
+	__isl_keep isl_schedule_band *band2)
+{
+	int i;
+
+	if (!band1 || !band2)
+		return -1;
+	if (band1 == band2)
+		return 1;
+
+	if (band1->n != band2->n)
+		return 0;
+	for (i = 0; i < band1->n; ++i)
+		if (band1->coincident[i] != band2->coincident[i])
+			return 0;
+	if (band1->permutable != band2->permutable)
+		return 0;
+
+	return isl_multi_union_pw_aff_plain_is_equal(band1->mupa, band2->mupa);
+}
+
 /* Return the number of scheduling dimensions in the band.
  */
 int isl_schedule_band_n_member(__isl_keep isl_schedule_band *band)
@@ -415,3 +441,89 @@ __isl_give isl_schedule_band *isl_schedu
 
 	return band;
 }
+
+/* Reset the user pointer on all identifiers of parameters and tuples
+ * in "band".
+ */
+__isl_give isl_schedule_band *isl_schedule_band_reset_user(
+	__isl_take isl_schedule_band *band)
+{
+	band = isl_schedule_band_cow(band);
+	if (!band)
+		return NULL;
+
+	band->mupa = isl_multi_union_pw_aff_reset_user(band->mupa);
+	if (!band->mupa)
+		return isl_schedule_band_free(band);
+
+	return band;
+}
+
+/* Align the parameters of "band" to those of "space".
+ */
+__isl_give isl_schedule_band *isl_schedule_band_align_params(
+	__isl_take isl_schedule_band *band, __isl_take isl_space *space)
+{
+	band = isl_schedule_band_cow(band);
+	if (!band || !space)
+		goto error;
+
+	band->mupa = isl_multi_union_pw_aff_align_params(band->mupa, space);
+	if (!band->mupa)
+		return isl_schedule_band_free(band);
+
+	return band;
+error:
+	isl_space_free(space);
+	isl_schedule_band_free(band);
+	return NULL;
+}
+
+/* Compute the pullback of "band" by the function represented by "upma".
+ * In other words, plug in "upma" in the iteration domains of "band".
+ */
+__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule_band *band,
+	__isl_take isl_union_pw_multi_aff *upma)
+{
+	band = isl_schedule_band_cow(band);
+	if (!band || !upma)
+		goto error;
+
+	band->mupa =
+		isl_multi_union_pw_aff_pullback_union_pw_multi_aff(band->mupa,
+									upma);
+	if (!band->mupa)
+		return isl_schedule_band_free(band);
+
+	return band;
+error:
+	isl_union_pw_multi_aff_free(upma);
+	isl_schedule_band_free(band);
+	return NULL;
+}
+
+/* Compute the gist of "band" with respect to "context".
+ * In particular, compute the gist of the associated partial schedule.
+ */
+__isl_give isl_schedule_band *isl_schedule_band_gist(
+	__isl_take isl_schedule_band *band, __isl_take isl_union_set *context)
+{
+	if (!band || !context)
+		goto error;
+	if (band->n == 0) {
+		isl_union_set_free(context);
+		return band;
+	}
+	band = isl_schedule_band_cow(band);
+	if (!band)
+		goto error;
+	band->mupa = isl_multi_union_pw_aff_gist(band->mupa, context);
+	if (!band->mupa)
+		return isl_schedule_band_free(band);
+	return band;
+error:
+	isl_union_set_free(context);
+	isl_schedule_band_free(band);
+	return NULL;
+}

Modified: polly/trunk/lib/External/isl/isl_schedule_band.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_band.h?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_band.h (original)
+++ polly/trunk/lib/External/isl/isl_schedule_band.h Wed Feb 25 13:34:52 2015
@@ -34,6 +34,9 @@ __isl_null isl_schedule_band *isl_schedu
 
 isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band);
 
+int isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1,
+	__isl_keep isl_schedule_band *band2);
+
 __isl_give isl_space *isl_schedule_band_get_space(
 	__isl_keep isl_schedule_band *band);
 __isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule(
@@ -59,5 +62,15 @@ __isl_give isl_schedule_band *isl_schedu
 	__isl_take isl_multi_val *sizes);
 __isl_give isl_schedule_band *isl_schedule_band_drop(
 	__isl_take isl_schedule_band *band, int pos, int n);
+__isl_give isl_schedule_band *isl_schedule_band_gist(
+	__isl_take isl_schedule_band *band, __isl_take isl_union_set *context);
+
+__isl_give isl_schedule_band *isl_schedule_band_reset_user(
+	__isl_take isl_schedule_band *band);
+__isl_give isl_schedule_band *isl_schedule_band_align_params(
+	__isl_take isl_schedule_band *band, __isl_take isl_space *space);
+__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule_band *band,
+	__isl_take isl_union_pw_multi_aff *upma);
 
 #endif

Modified: polly/trunk/lib/External/isl/isl_schedule_node.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_node.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_node.c (original)
+++ polly/trunk/lib/External/isl/isl_schedule_node.c Wed Feb 25 13:34:52 2015
@@ -1,10 +1,13 @@
 /*
- * Copyright 2013      Ecole Normale Superieure
+ * Copyright 2013-2014 Ecole Normale Superieure
+ * Copyright 2014      INRIA Rocquencourt
  *
  * Use of this software is governed by the MIT license
  *
  * Written by Sven Verdoolaege,
  * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
+ * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
+ * B.P. 105 - 78153 Le Chesnay, France
  */
 
 #include <isl/set.h>
@@ -218,6 +221,61 @@ __isl_null isl_schedule_node *isl_schedu
 	return NULL;
 }
 
+/* Do "node1" and "node2" point to the same position in the same
+ * schedule?
+ */
+int isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1,
+	__isl_keep isl_schedule_node *node2)
+{
+	int i, n1, n2;
+
+	if (!node1 || !node2)
+		return -1;
+	if (node1 == node2)
+		return 1;
+	if (node1->schedule != node2->schedule)
+		return 0;
+
+	n1 = isl_schedule_node_get_tree_depth(node1);
+	n2 = isl_schedule_node_get_tree_depth(node2);
+	if (n1 != n2)
+		return 0;
+	for (i = 0; i < n1; ++i)
+		if (node1->child_pos[i] != node2->child_pos[i])
+			return 0;
+
+	return 1;
+}
+
+/* Return the number of outer schedule dimensions of "node"
+ * in its schedule tree.
+ *
+ * Return -1 on error.
+ */
+int isl_schedule_node_get_schedule_depth(__isl_keep isl_schedule_node *node)
+{
+	int i, n;
+	int depth = 0;
+
+	if (!node)
+		return -1;
+
+	n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+	for (i = n - 1; i >= 0; --i) {
+		isl_schedule_tree *tree;
+
+		tree = isl_schedule_tree_list_get_schedule_tree(
+						    node->ancestors, i);
+		if (!tree)
+			return -1;
+		if (tree->type == isl_schedule_node_band)
+			depth += isl_schedule_tree_band_n_member(tree);
+		isl_schedule_tree_free(tree);
+	}
+
+	return depth;
+}
+
 /* Internal data structure for
  * isl_schedule_node_get_prefix_schedule_union_pw_multi_aff
  *
@@ -651,33 +709,72 @@ int isl_schedule_node_n_children(__isl_k
 	return n;
 }
 
-/* Move the "node" pointer to the parent of the node it currently points to.
+/* Move the "node" pointer to the ancestor of the given generation
+ * of the node it currently points to, where generation 0 is the node
+ * itself and generation 1 is its parent.
  */
-__isl_give isl_schedule_node *isl_schedule_node_parent(
-	__isl_take isl_schedule_node *node)
+__isl_give isl_schedule_node *isl_schedule_node_ancestor(
+	__isl_take isl_schedule_node *node, int generation)
 {
 	int n;
 	isl_schedule_tree *tree;
 
-	node = isl_schedule_node_cow(node);
 	if (!node)
 		return NULL;
-	if (!isl_schedule_node_has_parent(node))
+	if (generation == 0)
+		return node;
+	n = isl_schedule_node_get_tree_depth(node);
+	if (n < 0)
+		return isl_schedule_node_free(node);
+	if (generation < 0 || generation > n)
 		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
-			"node has no parent",
+			"generation out of bounds",
 			return isl_schedule_node_free(node));
-	n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-	tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n - 1);
+	node = isl_schedule_node_cow(node);
+	if (!node)
+		return NULL;
+
+	tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors,
+							n - generation);
 	isl_schedule_tree_free(node->tree);
 	node->tree = tree;
 	node->ancestors = isl_schedule_tree_list_drop(node->ancestors,
-								n - 1, 1);
+						    n - generation, generation);
 	if (!node->ancestors || !node->tree)
 		return isl_schedule_node_free(node);
 
 	return node;
 }
 
+/* Move the "node" pointer to the parent of the node it currently points to.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_parent(
+	__isl_take isl_schedule_node *node)
+{
+	if (!node)
+		return NULL;
+	if (!isl_schedule_node_has_parent(node))
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"node has no parent",
+			return isl_schedule_node_free(node));
+	return isl_schedule_node_ancestor(node, 1);
+}
+
+/* Move the "node" pointer to the root of its schedule tree.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_root(
+	__isl_take isl_schedule_node *node)
+{
+	int n;
+
+	if (!node)
+		return NULL;
+	n = isl_schedule_node_get_tree_depth(node);
+	if (n < 0)
+		return isl_schedule_node_free(node);
+	return isl_schedule_node_ancestor(node, n);
+}
+
 /* Move the "node" pointer to the child at position "pos" of the node
  * it currently points to.
  */
@@ -973,6 +1070,38 @@ __isl_give isl_schedule_node *isl_schedu
 	return traverse(node, &postorder_enter, &postorder_leave, &data);
 }
 
+/* Traverse the ancestors of "node" from the root down to and including
+ * the parent of "node", calling "fn" on each of them.
+ *
+ * If "fn" returns -1 on any of the nodes, then the traversal is aborted.
+ *
+ * Return 0 on success and -1 on failure.
+ */
+int isl_schedule_node_foreach_ancestor_top_down(
+	__isl_keep isl_schedule_node *node,
+	int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user)
+{
+	int i, n;
+
+	if (!node)
+		return -1;
+
+	n = isl_schedule_node_get_tree_depth(node);
+	for (i = 0; i < n; ++i) {
+		isl_schedule_node *ancestor;
+		int r;
+
+		ancestor = isl_schedule_node_copy(node);
+		ancestor = isl_schedule_node_ancestor(ancestor, n - i);
+		r = fn(ancestor, user);
+		isl_schedule_node_free(ancestor);
+		if (r < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
 /* Return the number of members in the given band node.
  */
 unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node)
@@ -1506,6 +1635,476 @@ __isl_give isl_schedule_node *isl_schedu
 					isl_schedule_node_set, filters);
 }
 
+/* Remove "node" from its schedule tree and return a pointer
+ * to the leaf at the same position in the updated schedule tree.
+ *
+ * It is not allowed to remove the root of a schedule tree or
+ * a child of a set or sequence node.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_cut(
+	__isl_take isl_schedule_node *node)
+{
+	isl_schedule_tree *leaf;
+	enum isl_schedule_node_type parent_type;
+
+	if (!node)
+		return NULL;
+	if (!isl_schedule_node_has_parent(node))
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"cannot cut root", return isl_schedule_node_free(node));
+
+	parent_type = isl_schedule_node_get_parent_type(node);
+	if (parent_type == isl_schedule_node_set ||
+	    parent_type == isl_schedule_node_sequence)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"cannot cut child of set or sequence",
+			return isl_schedule_node_free(node));
+
+	leaf = isl_schedule_node_get_leaf(node);
+	return isl_schedule_node_graft_tree(node, leaf);
+}
+
+/* Remove a single node from the schedule tree, attaching the child
+ * of "node" directly to its parent.
+ * Return a pointer to this former child or to the leaf the position
+ * of the original node if there was no child.
+ * It is not allowed to remove the root of a schedule tree,
+ * a set or sequence node or a child of a set or sequence node.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_delete(
+	__isl_take isl_schedule_node *node)
+{
+	int n;
+	isl_schedule_tree *tree;
+	enum isl_schedule_node_type type;
+
+	if (!node)
+		return NULL;
+
+	if (isl_schedule_node_get_tree_depth(node) == 0)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"cannot delete root node",
+			return isl_schedule_node_free(node));
+	n = isl_schedule_node_n_children(node);
+	if (n != 1)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"can only delete node with a single child",
+			return isl_schedule_node_free(node));
+	type = isl_schedule_node_get_parent_type(node);
+	if (type == isl_schedule_node_sequence || type == isl_schedule_node_set)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"cannot delete child of set or sequence",
+			return isl_schedule_node_free(node));
+
+	tree = isl_schedule_node_get_tree(node);
+	if (!tree || isl_schedule_tree_has_children(tree)) {
+		tree = isl_schedule_tree_child(tree, 0);
+	} else {
+		isl_schedule_tree_free(tree);
+		tree = isl_schedule_node_get_leaf(node);
+	}
+	node = isl_schedule_node_graft_tree(node, tree);
+
+	return node;
+}
+
+/* Compute the gist of the given band node with respect to "context".
+ */
+__isl_give isl_schedule_node *isl_schedule_node_band_gist(
+	__isl_take isl_schedule_node *node, __isl_take isl_union_set *context)
+{
+	isl_schedule_tree *tree;
+
+	tree = isl_schedule_node_get_tree(node);
+	tree = isl_schedule_tree_band_gist(tree, context);
+	return isl_schedule_node_graft_tree(node, tree);
+}
+
+/* Internal data structure for isl_schedule_node_gist.
+ * "filters" contains an element for each outer filter node
+ * with respect to the current position, each representing
+ * the intersection of the previous element and the filter on the filter node.
+ * The first element in the original context passed to isl_schedule_node_gist.
+ */
+struct isl_node_gist_data {
+	isl_union_set_list *filters;
+};
+
+/* Can we finish gisting at this node?
+ * That is, is the filter on the current filter node a subset of
+ * the original context passed to isl_schedule_node_gist?
+ */
+static int gist_done(__isl_keep isl_schedule_node *node,
+	struct isl_node_gist_data *data)
+{
+	isl_union_set *filter, *outer;
+	int subset;
+
+	filter = isl_schedule_node_filter_get_filter(node);
+	outer = isl_union_set_list_get_union_set(data->filters, 0);
+	subset = isl_union_set_is_subset(filter, outer);
+	isl_union_set_free(outer);
+	isl_union_set_free(filter);
+
+	return subset;
+}
+
+/* Callback for "traverse" to enter a node and to move
+ * to the deepest initial subtree that should be traversed
+ * by isl_schedule_node_gist.
+ *
+ * The "filters" list is extended by one element each time
+ * we come across a filter node by the result of intersecting
+ * the last element in the list with the filter on the filter node.
+ *
+ * If the filter on the current filter node is a subset of
+ * the original context passed to isl_schedule_node_gist,
+ * then there is no need to go into its subtree since it cannot
+ * be further simplified by the context.  The "filters" list is
+ * still extended for consistency, but the actual value of the
+ * added element is immaterial since it will not be used.
+ *
+ * Otherwise, the filter on the current filter node is replaced by
+ * the gist of the original filter with respect to the intersection
+ * of the original context with the intermediate filters.
+ *
+ * If the new element in the "filters" list is empty, then no elements
+ * can reach the descendants of the current filter node.  The subtree
+ * underneath the filter node is therefore removed.
+ */
+static __isl_give isl_schedule_node *gist_enter(
+	__isl_take isl_schedule_node *node, void *user)
+{
+	struct isl_node_gist_data *data = user;
+
+	do {
+		isl_union_set *filter, *inner;
+		int done, empty;
+		int n;
+
+		switch (isl_schedule_node_get_type(node)) {
+		case isl_schedule_node_error:
+			return isl_schedule_node_free(node);
+		case isl_schedule_node_band:
+		case isl_schedule_node_domain:
+		case isl_schedule_node_leaf:
+		case isl_schedule_node_sequence:
+		case isl_schedule_node_set:
+			continue;
+		case isl_schedule_node_filter:
+			break;
+		}
+		done = gist_done(node, data);
+		filter = isl_schedule_node_filter_get_filter(node);
+		if (done < 0 || done) {
+			data->filters = isl_union_set_list_add(data->filters,
+								filter);
+			if (done < 0)
+				return isl_schedule_node_free(node);
+			return node;
+		}
+		n = isl_union_set_list_n_union_set(data->filters);
+		inner = isl_union_set_list_get_union_set(data->filters, n - 1);
+		filter = isl_union_set_gist(filter, isl_union_set_copy(inner));
+		node = isl_schedule_node_filter_set_filter(node,
+						isl_union_set_copy(filter));
+		filter = isl_union_set_intersect(filter, inner);
+		empty = isl_union_set_is_empty(filter);
+		data->filters = isl_union_set_list_add(data->filters, filter);
+		if (empty < 0)
+			return isl_schedule_node_free(node);
+		if (!empty)
+			continue;
+		node = isl_schedule_node_child(node, 0);
+		node = isl_schedule_node_cut(node);
+		node = isl_schedule_node_parent(node);
+		return node;
+	} while (isl_schedule_node_has_children(node) &&
+		(node = isl_schedule_node_first_child(node)) != NULL);
+
+	return node;
+}
+
+/* Callback for "traverse" to leave a node for isl_schedule_node_gist.
+ *
+ * In particular, if the current node is a filter node, then we remove
+ * the element on the "filters" list that was added when we entered
+ * the node.  There is no need to compute any gist here, since we
+ * already did that when we entered the node.
+ *
+ * If the current node is a band node, then we compute the gist of
+ * the band node with respect to the intersection of the original context
+ * and the intermediate filters.
+ *
+ * If the current node is a sequence or set node, then some of
+ * the filter children may have become empty and so they are removed.
+ * If only one child is left, then the set or sequence node along with
+ * the single remaining child filter is removed.  The filter can be
+ * removed because the filters on a sequence or set node are supposed
+ * to partition the incoming domain instances.
+ * In principle, it should then be impossible for there to be zero
+ * remaining children, but should this happen, we replace the entire
+ * subtree with an empty filter.
+ */
+static __isl_give isl_schedule_node *gist_leave(
+	__isl_take isl_schedule_node *node, void *user)
+{
+	struct isl_node_gist_data *data = user;
+	isl_schedule_tree *tree;
+	int i, n;
+	isl_union_set *filter;
+
+	switch (isl_schedule_node_get_type(node)) {
+	case isl_schedule_node_error:
+		return isl_schedule_node_free(node);
+	case isl_schedule_node_filter:
+		n = isl_union_set_list_n_union_set(data->filters);
+		data->filters = isl_union_set_list_drop(data->filters,
+							n - 1, 1);
+		break;
+	case isl_schedule_node_band:
+		n = isl_union_set_list_n_union_set(data->filters);
+		filter = isl_union_set_list_get_union_set(data->filters, n - 1);
+		node = isl_schedule_node_band_gist(node, filter);
+		break;
+	case isl_schedule_node_set:
+	case isl_schedule_node_sequence:
+		tree = isl_schedule_node_get_tree(node);
+		n = isl_schedule_tree_n_children(tree);
+		for (i = n - 1; i >= 0; --i) {
+			isl_schedule_tree *child;
+			isl_union_set *filter;
+			int empty;
+
+			child = isl_schedule_tree_get_child(tree, i);
+			filter = isl_schedule_tree_filter_get_filter(child);
+			empty = isl_union_set_is_empty(filter);
+			isl_union_set_free(filter);
+			isl_schedule_tree_free(child);
+			if (empty < 0)
+				tree = isl_schedule_tree_free(tree);
+			else if (empty)
+				tree = isl_schedule_tree_drop_child(tree, i);
+		}
+		n = isl_schedule_tree_n_children(tree);
+		node = isl_schedule_node_graft_tree(node, tree);
+		if (n == 1) {
+			node = isl_schedule_node_delete(node);
+			node = isl_schedule_node_delete(node);
+		} else if (n == 0) {
+			isl_space *space;
+
+			filter =
+			    isl_union_set_list_get_union_set(data->filters, 0);
+			space = isl_union_set_get_space(filter);
+			isl_union_set_free(filter);
+			filter = isl_union_set_empty(space);
+			node = isl_schedule_node_cut(node);
+			node = isl_schedule_node_insert_filter(node, filter);
+		}
+		break;
+	case isl_schedule_node_domain:
+	case isl_schedule_node_leaf:
+		break;
+	}
+
+	return node;
+}
+
+/* Compute the gist of the subtree at "node" with respect to
+ * the reaching domain elements in "context".
+ * In particular, compute the gist of all band and filter nodes
+ * in the subtree with respect to "context".  Children of set or sequence
+ * nodes that end up with an empty filter are removed completely.
+ *
+ * We keep track of the intersection of "context" with all outer filters
+ * of the current node within the subtree in the final element of "filters".
+ * Initially, this list contains the single element "context" and it is
+ * extended or shortened each time we enter or leave a filter node.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_gist(
+	__isl_take isl_schedule_node *node, __isl_take isl_union_set *context)
+{
+	struct isl_node_gist_data data;
+
+	data.filters = isl_union_set_list_from_union_set(context);
+	node = traverse(node, &gist_enter, &gist_leave, &data);
+	isl_union_set_list_free(data.filters);
+	return node;
+}
+
+/* Intersect the domain of domain node "node" with "domain".
+ *
+ * If the domain of "node" is already a subset of "domain",
+ * then nothing needs to be changed.
+ *
+ * Otherwise, we replace the domain of the domain node by the intersection
+ * and simplify the subtree rooted at "node" with respect to this intersection.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_domain_intersect_domain(
+	__isl_take isl_schedule_node *node, __isl_take isl_union_set *domain)
+{
+	isl_schedule_tree *tree;
+	isl_union_set *uset;
+	int is_subset;
+
+	if (!node || !domain)
+		goto error;
+
+	uset = isl_schedule_tree_domain_get_domain(node->tree);
+	is_subset = isl_union_set_is_subset(uset, domain);
+	isl_union_set_free(uset);
+	if (is_subset < 0)
+		goto error;
+	if (is_subset) {
+		isl_union_set_free(domain);
+		return node;
+	}
+
+	tree = isl_schedule_tree_copy(node->tree);
+	uset = isl_schedule_tree_domain_get_domain(tree);
+	uset = isl_union_set_intersect(uset, domain);
+	tree = isl_schedule_tree_domain_set_domain(tree,
+						    isl_union_set_copy(uset));
+	node = isl_schedule_node_graft_tree(node, tree);
+
+	node = isl_schedule_node_child(node, 0);
+	node = isl_schedule_node_gist(node, uset);
+	node = isl_schedule_node_parent(node);
+
+	return node;
+error:
+	isl_schedule_node_free(node);
+	isl_union_set_free(domain);
+	return NULL;
+}
+
+/* Reset the user pointer on all identifiers of parameters and tuples
+ * in the schedule node "node".
+ */
+__isl_give isl_schedule_node *isl_schedule_node_reset_user(
+	__isl_take isl_schedule_node *node)
+{
+	isl_schedule_tree *tree;
+
+	tree = isl_schedule_node_get_tree(node);
+	tree = isl_schedule_tree_reset_user(tree);
+	node = isl_schedule_node_graft_tree(node, tree);
+
+	return node;
+}
+
+/* Align the parameters of the schedule node "node" to those of "space".
+ */
+__isl_give isl_schedule_node *isl_schedule_node_align_params(
+	__isl_take isl_schedule_node *node, __isl_take isl_space *space)
+{
+	isl_schedule_tree *tree;
+
+	tree = isl_schedule_node_get_tree(node);
+	tree = isl_schedule_tree_align_params(tree, space);
+	node = isl_schedule_node_graft_tree(node, tree);
+
+	return node;
+}
+
+/* Compute the pullback of schedule node "node"
+ * by the function represented by "upma".
+ * In other words, plug in "upma" in the iteration domains
+ * of schedule node "node".
+ *
+ * Note that this is only a helper function for
+ * isl_schedule_pullback_union_pw_multi_aff.  In order to maintain consistency,
+ * this function should not be called on a single node without also
+ * calling it on all the other nodes.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule_node *node,
+	__isl_take isl_union_pw_multi_aff *upma)
+{
+	isl_schedule_tree *tree;
+
+	tree = isl_schedule_node_get_tree(node);
+	tree = isl_schedule_tree_pullback_union_pw_multi_aff(tree, upma);
+	node = isl_schedule_node_graft_tree(node, tree);
+
+	return node;
+}
+
+/* Return the position of the subtree containing "node" among the children
+ * of "ancestor".  "node" is assumed to be a descendant of "ancestor".
+ * In particular, both nodes should point to the same schedule tree.
+ *
+ * Return -1 on error.
+ */
+int isl_schedule_node_get_ancestor_child_position(
+	__isl_keep isl_schedule_node *node,
+	__isl_keep isl_schedule_node *ancestor)
+{
+	int n1, n2;
+	isl_schedule_tree *tree;
+
+	if (!node || !ancestor)
+		return -1;
+
+	if (node->schedule != ancestor->schedule)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"not a descendant", return -1);
+
+	n1 = isl_schedule_node_get_tree_depth(ancestor);
+	n2 = isl_schedule_node_get_tree_depth(node);
+
+	if (n1 >= n2)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"not a descendant", return -1);
+	tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n1);
+	isl_schedule_tree_free(tree);
+	if (tree != ancestor->tree)
+		isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+			"not a descendant", return -1);
+
+	return node->child_pos[n1];
+}
+
+/* Given two nodes that point to the same schedule tree, return their
+ * closest shared ancestor.
+ *
+ * Since the two nodes point to the same schedule, they share at least
+ * one ancestor, the root of the schedule.  We move down from the root
+ * to the first ancestor where the respective children have a different
+ * child position.  This is the requested ancestor.
+ * If there is no ancestor where the children have a different position,
+ * then one node is an ancestor of the other and then this node is
+ * the requested ancestor.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor(
+	__isl_keep isl_schedule_node *node1,
+	__isl_keep isl_schedule_node *node2)
+{
+	int i, n1, n2;
+
+	if (!node1 || !node2)
+		return NULL;
+	if (node1->schedule != node2->schedule)
+		isl_die(isl_schedule_node_get_ctx(node1), isl_error_invalid,
+			"not part of same schedule", return NULL);
+	n1 = isl_schedule_node_get_tree_depth(node1);
+	n2 = isl_schedule_node_get_tree_depth(node2);
+	if (n2 < n1)
+		return isl_schedule_node_get_shared_ancestor(node2, node1);
+	if (n1 == 0)
+		return isl_schedule_node_copy(node1);
+	if (isl_schedule_node_is_equal(node1, node2))
+		return isl_schedule_node_copy(node1);
+
+	for (i = 0; i < n1; ++i)
+		if (node1->child_pos[i] != node2->child_pos[i])
+			break;
+
+	node1 = isl_schedule_node_copy(node1);
+	return isl_schedule_node_ancestor(node1, n1 - i);
+}
+
 /* Print "node" to "p".
  */
 __isl_give isl_printer *isl_printer_print_schedule_node(

Modified: polly/trunk/lib/External/isl/isl_schedule_node_private.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_node_private.h?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_node_private.h (original)
+++ polly/trunk/lib/External/isl/isl_schedule_node_private.h Wed Feb 25 13:34:52 2015
@@ -38,4 +38,11 @@ __isl_give isl_schedule_node *isl_schedu
 __isl_give isl_schedule_tree *isl_schedule_node_get_tree(
 	__isl_keep isl_schedule_node *node);
 
+__isl_give isl_schedule_node *isl_schedule_node_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule_node *node,
+	__isl_take isl_union_pw_multi_aff *upma);
+
+__isl_give isl_schedule_node *isl_schedule_node_domain_intersect_domain(
+	__isl_take isl_schedule_node *node, __isl_take isl_union_set *domain);
+
 #endif

Modified: polly/trunk/lib/External/isl/isl_schedule_tree.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_tree.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_tree.c (original)
+++ polly/trunk/lib/External/isl/isl_schedule_tree.c Wed Feb 25 13:34:52 2015
@@ -1,10 +1,13 @@
 /*
- * Copyright 2013      Ecole Normale Superieure
+ * Copyright 2013-2014 Ecole Normale Superieure
+ * Copyright 2014      INRIA Rocquencourt
  *
  * Use of this software is governed by the MIT license
  *
  * Written by Sven Verdoolaege,
  * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
+ * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
+ * B.P. 105 - 78153 Le Chesnay, France
  */
 
 #include <isl/map.h>
@@ -286,6 +289,46 @@ error:
 	return NULL;
 }
 
+/* Construct a tree with a root node of type "type" and as children
+ * "tree1" and "tree2".
+ * If the root of one (or both) of the input trees is itself of type "type",
+ * then the tree is replaced by its children.
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_from_pair(
+	enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1,
+	__isl_take isl_schedule_tree *tree2)
+{
+	isl_ctx *ctx;
+	isl_schedule_tree_list *list;
+
+	if (!tree1 || !tree2)
+		goto error;
+
+	ctx = isl_schedule_tree_get_ctx(tree1);
+	if (isl_schedule_tree_get_type(tree1) == type) {
+		list = isl_schedule_tree_list_copy(tree1->children);
+		isl_schedule_tree_free(tree1);
+	} else {
+		list = isl_schedule_tree_list_alloc(ctx, 2);
+		list = isl_schedule_tree_list_add(list, tree1);
+	}
+	if (isl_schedule_tree_get_type(tree2) == type) {
+		isl_schedule_tree_list *children;
+
+		children = isl_schedule_tree_list_copy(tree2->children);
+		list = isl_schedule_tree_list_concat(list, children);
+		isl_schedule_tree_free(tree2);
+	} else {
+		list = isl_schedule_tree_list_add(list, tree2);
+	}
+
+	return isl_schedule_tree_from_children(type, list);
+error:
+	isl_schedule_tree_free(tree1);
+	isl_schedule_tree_free(tree2);
+	return NULL;
+}
+
 /* Return the isl_ctx to which "tree" belongs.
  */
 isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree)
@@ -302,6 +345,64 @@ enum isl_schedule_node_type isl_schedule
 	return tree ? tree->type : isl_schedule_node_error;
 }
 
+/* Are "tree1" and "tree2" obviously equal to each other?
+ */
+int isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1,
+	__isl_keep isl_schedule_tree *tree2)
+{
+	int equal;
+	int i, n;
+
+	if (!tree1 || !tree2)
+		return -1;
+	if (tree1 == tree2)
+		return 1;
+	if (tree1->type != tree2->type)
+		return 0;
+
+	switch (tree1->type) {
+	case isl_schedule_node_band:
+		equal = isl_schedule_band_plain_is_equal(tree1->band,
+							tree2->band);
+		break;
+	case isl_schedule_node_domain:
+		equal = isl_union_set_is_equal(tree1->domain, tree2->domain);
+		break;
+	case isl_schedule_node_filter:
+		equal = isl_union_set_is_equal(tree1->filter, tree2->filter);
+		break;
+	case isl_schedule_node_leaf:
+	case isl_schedule_node_sequence:
+	case isl_schedule_node_set:
+		equal = 1;
+		break;
+	case isl_schedule_node_error:
+		equal = -1;
+		break;
+	}
+
+	if (equal < 0 || !equal)
+		return equal;
+
+	n = isl_schedule_tree_n_children(tree1);
+	if (n != isl_schedule_tree_n_children(tree2))
+		return 0;
+	for (i = 0; i < n; ++i) {
+		isl_schedule_tree *child1, *child2;
+
+		child1 = isl_schedule_tree_get_child(tree1, i);
+		child2 = isl_schedule_tree_get_child(tree2, i);
+		equal = isl_schedule_tree_plain_is_equal(child1, child2);
+		isl_schedule_tree_free(child1);
+		isl_schedule_tree_free(child2);
+
+		if (equal < 0 || !equal)
+			return equal;
+	}
+
+	return 1;
+}
+
 /* Does "tree" have any children, other than an implicit leaf.
  */
 int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree)
@@ -360,6 +461,37 @@ __isl_give isl_schedule_tree *isl_schedu
 	return tree;
 }
 
+/* Remove the child at position "pos" from the children of "tree".
+ * If there was only one child to begin with, then remove all children.
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_drop_child(
+	__isl_take isl_schedule_tree *tree, int pos)
+{
+	int n;
+
+	tree = isl_schedule_tree_cow(tree);
+	if (!tree)
+		return NULL;
+
+	if (!isl_schedule_tree_has_children(tree))
+		isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+			"tree does not have any explicit children",
+			return isl_schedule_tree_free(tree));
+	n = isl_schedule_tree_list_n_schedule_tree(tree->children);
+	if (pos < 0 || pos >= n)
+		isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+			"position out of bounds",
+			return isl_schedule_tree_free(tree));
+	if (n == 1)
+		return isl_schedule_tree_reset_children(tree);
+
+	tree->children = isl_schedule_tree_list_drop(tree->children, pos, 1);
+	if (!tree->children)
+		return isl_schedule_tree_free(tree);
+
+	return tree;
+}
+
 /* Replace the child at position "pos" of "tree" by "child".
  *
  * If the new child is a leaf, then it is not explicitly
@@ -470,6 +602,35 @@ __isl_give isl_schedule_tree *isl_schedu
 	return isl_schedule_tree_replace_child(res, 0, tree);
 }
 
+/* Insert a filter node with filter set "filter"
+ * in each of the children of "tree".
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter)
+{
+	int i, n;
+
+	if (!tree || !filter)
+		goto error;
+
+	n = isl_schedule_tree_n_children(tree);
+	for (i = 0; i < n; ++i) {
+		isl_schedule_tree *child;
+
+		child = isl_schedule_tree_get_child(tree, i);
+		child = isl_schedule_tree_insert_filter(child,
+						    isl_union_set_copy(filter));
+		tree = isl_schedule_tree_replace_child(tree, i, child);
+	}
+
+	isl_union_set_free(filter);
+	return tree;
+error:
+	isl_union_set_free(filter);
+	isl_schedule_tree_free(tree);
+	return NULL;
+}
+
 /* Return the number of members in the band tree root.
  */
 unsigned isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree)
@@ -1234,6 +1395,197 @@ error:
 	return NULL;
 }
 
+/* Reset the user pointer on all identifiers of parameters and tuples
+ * in the root of "tree".
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_reset_user(
+	__isl_take isl_schedule_tree *tree)
+{
+	if (isl_schedule_tree_is_leaf(tree))
+		return tree;
+
+	tree = isl_schedule_tree_cow(tree);
+	if (!tree)
+		return NULL;
+
+	switch (tree->type) {
+	case isl_schedule_node_error:
+		return isl_schedule_tree_free(tree);
+	case isl_schedule_node_band:
+		tree->band = isl_schedule_band_reset_user(tree->band);
+		if (!tree->band)
+			return isl_schedule_tree_free(tree);
+		break;
+	case isl_schedule_node_domain:
+		tree->domain = isl_union_set_reset_user(tree->domain);
+		if (!tree->domain)
+			return isl_schedule_tree_free(tree);
+		break;
+	case isl_schedule_node_filter:
+		tree->filter = isl_union_set_reset_user(tree->filter);
+		if (!tree->filter)
+			return isl_schedule_tree_free(tree);
+		break;
+	case isl_schedule_node_leaf:
+	case isl_schedule_node_sequence:
+	case isl_schedule_node_set:
+		break;
+	}
+
+	return tree;
+}
+
+/* Align the parameters of the root of "tree" to those of "space".
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_align_params(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_space *space)
+{
+	if (!space)
+		goto error;
+
+	if (isl_schedule_tree_is_leaf(tree)) {
+		isl_space_free(space);
+		return tree;
+	}
+
+	tree = isl_schedule_tree_cow(tree);
+	if (!tree)
+		goto error;
+
+	switch (tree->type) {
+	case isl_schedule_node_error:
+		goto error;
+	case isl_schedule_node_band:
+		tree->band = isl_schedule_band_align_params(tree->band, space);
+		if (!tree->band)
+			return isl_schedule_tree_free(tree);
+		break;
+	case isl_schedule_node_domain:
+		tree->domain = isl_union_set_align_params(tree->domain, space);
+		if (!tree->domain)
+			return isl_schedule_tree_free(tree);
+		break;
+	case isl_schedule_node_filter:
+		tree->filter = isl_union_set_align_params(tree->filter, space);
+		if (!tree->filter)
+			return isl_schedule_tree_free(tree);
+		break;
+	case isl_schedule_node_leaf:
+	case isl_schedule_node_sequence:
+	case isl_schedule_node_set:
+		isl_space_free(space);
+		break;
+	}
+
+	return tree;
+error:
+	isl_space_free(space);
+	isl_schedule_tree_free(tree);
+	return NULL;
+}
+
+/* Does "tree" involve the iteration domain?
+ * That is, does it need to be modified
+ * by isl_schedule_tree_pullback_union_pw_multi_aff?
+ */
+static int involves_iteration_domain(__isl_keep isl_schedule_tree *tree)
+{
+	if (!tree)
+		return -1;
+
+	switch (tree->type) {
+	case isl_schedule_node_error:
+		return -1;
+	case isl_schedule_node_band:
+	case isl_schedule_node_domain:
+	case isl_schedule_node_filter:
+		return 1;
+	case isl_schedule_node_leaf:
+	case isl_schedule_node_sequence:
+	case isl_schedule_node_set:
+		return 0;
+	}
+}
+
+/* Compute the pullback of the root node of "tree" by the function
+ * represented by "upma".
+ * In other words, plug in "upma" in the iteration domains of
+ * the root node of "tree".
+ *
+ * We first check if the root node involves any iteration domains.
+ * If so, we handle the specific cases.
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule_tree *tree,
+	__isl_take isl_union_pw_multi_aff *upma)
+{
+	int involves;
+
+	if (!tree || !upma)
+		goto error;
+
+	involves = involves_iteration_domain(tree);
+	if (involves < 0)
+		goto error;
+	if (!involves) {
+		isl_union_pw_multi_aff_free(upma);
+		return tree;
+	}
+
+	tree = isl_schedule_tree_cow(tree);
+	if (!tree)
+		goto error;
+
+	if (tree->type == isl_schedule_node_band) {
+		tree->band = isl_schedule_band_pullback_union_pw_multi_aff(
+							    tree->band, upma);
+		if (!tree->band)
+			return isl_schedule_tree_free(tree);
+	} else if (tree->type == isl_schedule_node_domain) {
+		tree->domain =
+			isl_union_set_preimage_union_pw_multi_aff(tree->domain,
+									upma);
+		if (!tree->domain)
+			return isl_schedule_tree_free(tree);
+	} else if (tree->type == isl_schedule_node_filter) {
+		tree->filter =
+			isl_union_set_preimage_union_pw_multi_aff(tree->filter,
+									upma);
+		if (!tree->filter)
+			return isl_schedule_tree_free(tree);
+	}
+
+	return tree;
+error:
+	isl_union_pw_multi_aff_free(upma);
+	isl_schedule_tree_free(tree);
+	return NULL;
+}
+
+/* Compute the gist of the band tree root with respect to "context".
+ */
+__isl_give isl_schedule_tree *isl_schedule_tree_band_gist(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context)
+{
+	if (!tree)
+		return NULL;
+	if (tree->type != isl_schedule_node_band)
+		isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
+			"not a band node", goto error);
+	tree = isl_schedule_tree_cow(tree);
+	if (!tree)
+		goto error;
+
+	tree->band = isl_schedule_band_gist(tree->band, context);
+	if (!tree->band)
+		return isl_schedule_tree_free(tree);
+	return tree;
+error:
+	isl_union_set_free(context);
+	isl_schedule_tree_free(tree);
+	return NULL;
+}
+
 /* Are any members in "band" marked coincident?
  */
 static int any_coincident(__isl_keep isl_schedule_band *band)

Modified: polly/trunk/lib/External/isl/isl_schedule_tree.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_schedule_tree.h?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_schedule_tree.h (original)
+++ polly/trunk/lib/External/isl/isl_schedule_tree.h Wed Feb 25 13:34:52 2015
@@ -49,6 +49,9 @@ enum isl_schedule_node_type isl_schedule
 __isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx);
 int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree);
 
+int isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1,
+	__isl_keep isl_schedule_tree *tree2);
+
 __isl_give isl_schedule_tree *isl_schedule_tree_copy(
 	__isl_keep isl_schedule_tree *tree);
 __isl_null isl_schedule_tree *isl_schedule_tree_free(
@@ -63,6 +66,9 @@ __isl_give isl_schedule_tree *isl_schedu
 __isl_give isl_schedule_tree *isl_schedule_tree_from_children(
 	enum isl_schedule_node_type type,
 	__isl_take isl_schedule_tree_list *list);
+__isl_give isl_schedule_tree *isl_schedule_tree_from_pair(
+	enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1,
+	__isl_take isl_schedule_tree *tree2);
 
 __isl_give isl_space *isl_schedule_tree_band_get_space(
 	__isl_keep isl_schedule_tree *tree);
@@ -103,6 +109,8 @@ __isl_give isl_schedule_tree *isl_schedu
 	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain);
 __isl_give isl_schedule_tree *isl_schedule_tree_insert_filter(
 	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter);
+__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter);
 
 __isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves(
 	__isl_take isl_schedule_tree *tree1,
@@ -116,15 +124,27 @@ __isl_give isl_schedule_tree *isl_schedu
 	__isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes);
 __isl_give isl_schedule_tree *isl_schedule_tree_band_split(
 	__isl_take isl_schedule_tree *tree, int pos);
+__isl_give isl_schedule_tree *isl_schedule_tree_band_gist(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context);
 
 __isl_give isl_schedule_tree *isl_schedule_tree_child(
 	__isl_take isl_schedule_tree *tree, int pos);
 __isl_give isl_schedule_tree *isl_schedule_tree_reset_children(
 	__isl_take isl_schedule_tree *tree);
+__isl_give isl_schedule_tree *isl_schedule_tree_drop_child(
+	__isl_take isl_schedule_tree *tree, int pos);
 __isl_give isl_schedule_tree *isl_schedule_tree_replace_child(
 	__isl_take isl_schedule_tree *tree, int pos,
 	__isl_take isl_schedule_tree *new_child);
 
+__isl_give isl_schedule_tree *isl_schedule_tree_reset_user(
+	__isl_take isl_schedule_tree *tree);
+__isl_give isl_schedule_tree *isl_schedule_tree_align_params(
+	__isl_take isl_schedule_tree *tree, __isl_take isl_space *space);
+__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff(
+	__isl_take isl_schedule_tree *tree,
+	__isl_take isl_union_pw_multi_aff *upma);
+
 __isl_give isl_printer *isl_printer_print_schedule_tree(
 	__isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree);
 __isl_give isl_printer *isl_printer_print_schedule_tree_mark(

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_scheduler.c (original)
+++ polly/trunk/lib/External/isl/isl_scheduler.c Wed Feb 25 13:34:52 2015
@@ -2363,10 +2363,9 @@ static __isl_give isl_multi_aff *node_ex
 	isl_local_space *ls;
 	isl_aff *aff;
 	isl_multi_aff *ma;
-	int nrow, ncol;
+	int nrow;
 
 	nrow = isl_mat_rows(node->sched);
-	ncol = isl_mat_cols(node->sched) - 1;
 	if (node->compressed)
 		space = isl_multi_aff_get_domain_space(node->decompress);
 	else

Modified: polly/trunk/lib/External/isl/isl_space.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_space.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_space.c (original)
+++ polly/trunk/lib/External/isl/isl_space.c Wed Feb 25 13:34:52 2015
@@ -1305,7 +1305,7 @@ __isl_give isl_space *isl_space_domain_f
 
 	nested = space->nested[0];
 	domain = isl_space_copy(space);
-	domain = isl_space_drop_dims(space, isl_dim_in,
+	domain = isl_space_drop_dims(domain, isl_dim_in,
 					nested->n_in, nested->n_out);
 	if (!domain)
 		return isl_space_free(space);
@@ -1344,7 +1344,7 @@ __isl_give isl_space *isl_space_domain_f
 
 	nested = space->nested[0];
 	range = isl_space_copy(space);
-	range = isl_space_drop_dims(space, isl_dim_in, 0, nested->n_in);
+	range = isl_space_drop_dims(range, isl_dim_in, 0, nested->n_in);
 	if (!range)
 		return isl_space_free(space);
 	if (nested->tuple_id[1]) {
@@ -1382,7 +1382,7 @@ __isl_give isl_space *isl_space_range_fa
 
 	nested = space->nested[1];
 	domain = isl_space_copy(space);
-	domain = isl_space_drop_dims(space, isl_dim_out,
+	domain = isl_space_drop_dims(domain, isl_dim_out,
 					nested->n_in, nested->n_out);
 	if (!domain)
 		return isl_space_free(space);
@@ -1421,7 +1421,7 @@ __isl_give isl_space *isl_space_range_fa
 
 	nested = space->nested[1];
 	range = isl_space_copy(space);
-	range = isl_space_drop_dims(space, isl_dim_out, 0, nested->n_in);
+	range = isl_space_drop_dims(range, isl_dim_out, 0, nested->n_in);
 	if (!range)
 		return isl_space_free(space);
 	if (nested->tuple_id[1]) {

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_tab_pip.c (original)
+++ polly/trunk/lib/External/isl/isl_tab_pip.c Wed Feb 25 13:34:52 2015
@@ -3137,11 +3137,8 @@ static int context_gbr_detect_equalities
 	struct isl_tab *tab)
 {
 	struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
-	struct isl_ctx *ctx;
 	unsigned n_ineq;
 
-	ctx = cgbr->tab->mat->ctx;
-
 	if (!cgbr->cone) {
 		struct isl_basic_set *bset = isl_tab_peek_bset(cgbr->tab);
 		cgbr->cone = isl_tab_from_recession_cone(bset, 0);
@@ -3833,7 +3830,6 @@ static void find_solutions(struct isl_so
 			sol_inc_level(sol);
 			find_in_pos(sol, tab, ineq->el);
 			tab->row_sign[split] = isl_tab_row_neg;
-			row = split;
 			isl_seq_neg(ineq->el, ineq->el, ineq->size);
 			isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
 			if (!sol->error)
@@ -4191,7 +4187,7 @@ static int parallel_constraints(__isl_ke
 	int *first, int *second)
 {
 	int i;
-	isl_ctx *ctx = isl_basic_map_get_ctx(bmap);
+	isl_ctx *ctx;
 	struct isl_hash_table *table = NULL;
 	struct isl_hash_table_entry *entry;
 	struct isl_constraint_equal_info info;
@@ -4295,13 +4291,11 @@ static __isl_give isl_set *set_minimum(_
 {
 	int i, k;
 	isl_basic_set *bset = NULL;
-	isl_ctx *ctx;
 	isl_set *set = NULL;
 
 	if (!dim || !var)
 		goto error;
 
-	ctx = isl_space_get_ctx(dim);
 	set = isl_set_alloc_space(isl_space_copy(dim),
 				var->n_row, ISL_SET_DISJOINT);
 
@@ -5447,7 +5441,6 @@ static __isl_give isl_pw_aff *set_minimu
 	int i;
 	isl_aff *aff = NULL;
 	isl_basic_set *bset = NULL;
-	isl_ctx *ctx;
 	isl_pw_aff *paff = NULL;
 	isl_space *pw_space;
 	isl_local_space *ls = NULL;
@@ -5455,7 +5448,6 @@ static __isl_give isl_pw_aff *set_minimu
 	if (!space || !var)
 		goto error;
 
-	ctx = isl_space_get_ctx(space);
 	ls = isl_local_space_from_space(isl_space_copy(space));
 	pw_space = isl_space_copy(space);
 	pw_space = isl_space_from_domain(pw_space);

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=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_test.c (original)
+++ polly/trunk/lib/External/isl/isl_test.c Wed Feb 25 13:34:52 2015
@@ -4546,6 +4546,9 @@ struct {
 	{ "{ B[i] -> C[([i/2])] }", "{ B[5] }", "{ C[2] }" },
 	{ "[n] -> { B[i,j] -> C[([i/2]) + 2j] }",
 	  "[n] -> { B[n,[n/3]] }", "[n] -> { C[([n/2]) + 2*[n/3]] }", },
+	{ "{ [i, j] -> [floor((i)/4) + floor((2*i+j)/5)] }",
+	  "{ [i, j] -> [floor((i)/3), j] }",
+	  "{ [i, j] -> [(floor((i)/12) + floor((j + 2*floor((i)/3))/5))] }" },
 };
 
 static int test_pullback(isl_ctx *ctx)
@@ -4573,25 +4576,33 @@ static int test_pullback(isl_ctx *ctx)
 	return 0;
 }
 
-/* Check that negation is printed correctly.
+/* Check that negation is printed correctly and that equal expressions
+ * are correctly identified.
  */
 static int test_ast(isl_ctx *ctx)
 {
 	isl_ast_expr *expr, *expr1, *expr2, *expr3;
 	char *str;
-	int ok;
+	int ok, equal;
 
 	expr1 = isl_ast_expr_from_id(isl_id_alloc(ctx, "A", NULL));
 	expr2 = isl_ast_expr_from_id(isl_id_alloc(ctx, "B", NULL));
 	expr = isl_ast_expr_add(expr1, expr2);
+	expr2 = isl_ast_expr_copy(expr);
 	expr = isl_ast_expr_neg(expr);
+	expr2 = isl_ast_expr_neg(expr2);
+	equal = isl_ast_expr_is_equal(expr, expr2);
 	str = isl_ast_expr_to_str(expr);
 	ok = str ? !strcmp(str, "-(A + B)") : -1;
 	free(str);
 	isl_ast_expr_free(expr);
+	isl_ast_expr_free(expr2);
 
-	if (ok < 0)
+	if (ok < 0 || equal < 0)
 		return -1;
+	if (!equal)
+		isl_die(ctx, isl_error_unknown,
+			"equal expressions not considered equal", return -1);
 	if (!ok)
 		isl_die(ctx, isl_error_unknown,
 			"isl_ast_expr printed incorrectly", return -1);

Modified: polly/trunk/lib/External/isl/isl_transitive_closure.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_transitive_closure.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_transitive_closure.c (original)
+++ polly/trunk/lib/External/isl/isl_transitive_closure.c Wed Feb 25 13:34:52 2015
@@ -1948,14 +1948,12 @@ static __isl_give isl_map *construct_pow
 {
 	struct isl_map *app = NULL;
 	isl_space *dim = NULL;
-	unsigned d;
 
 	if (!map)
 		return NULL;
 
 	dim = isl_map_get_space(map);
 
-	d = isl_space_dim(dim, isl_dim_in);
 	dim = isl_space_add_dims(dim, isl_dim_in, 1);
 	dim = isl_space_add_dims(dim, isl_dim_out, 1);
 

Modified: polly/trunk/lib/External/isl/isl_vertices.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/External/isl/isl_vertices.c?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/lib/External/isl/isl_vertices.c (original)
+++ polly/trunk/lib/External/isl/isl_vertices.c Wed Feb 25 13:34:52 2015
@@ -114,14 +114,12 @@ static int add_vertex(struct isl_vertex_
 	__isl_keep isl_basic_set *bset, struct isl_tab *tab)
 {
 	unsigned nvar;
-	unsigned nparam;
 	struct isl_vertex_list *v = NULL;
 
 	if (isl_tab_detect_implicit_equalities(tab) < 0)
 		return -1;
 
 	nvar = isl_basic_set_dim(bset, isl_dim_set);
-	nparam = isl_basic_set_dim(bset, isl_dim_param);
 
 	v = isl_calloc_type(tab->mat->ctx, struct isl_vertex_list);
 	if (!v)
@@ -155,13 +153,10 @@ error:
 static __isl_give isl_vertices *vertices_empty(__isl_keep isl_basic_set *bset)
 {
 	isl_vertices *vertices;
-	unsigned nparam;
 
 	if (!bset)
 		return NULL;
 
-	nparam = isl_basic_set_dim(bset, isl_dim_param);
-
 	vertices = isl_calloc_type(bset->ctx, isl_vertices);
 	if (!vertices)
 		return NULL;
@@ -183,13 +178,10 @@ static __isl_give isl_vertices *vertices
 static __isl_give isl_vertices *vertices_0D(__isl_keep isl_basic_set *bset)
 {
 	isl_vertices *vertices;
-	unsigned nparam;
 
 	if (!bset)
 		return NULL;
 
-	nparam = isl_basic_set_dim(bset, isl_dim_param);
-
 	vertices = isl_calloc_type(bset->ctx, isl_vertices);
 	if (!vertices)
 		return NULL;

Modified: polly/trunk/test/Dependences/do_pluto_matmult.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/do_pluto_matmult.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/do_pluto_matmult.ll (original)
+++ polly/trunk/test/Dependences/do_pluto_matmult.ll Wed Feb 25 13:34:52 2015
@@ -66,11 +66,12 @@ do.end45:
 }
 
 ; VALUE: RAW dependences:
-; VALUE:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 34 }
+; VALUE: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 34 }
 ; VALUE: WAR dependences:
-; VALUE:  {  }
+; VALUE: {  }
 ; VALUE: WAW dependences:
-; VALUE:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 34 }
+; VALUE: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 <= 34 and i2 >= 0 }
+
 
 ; MEMORY: RAW dependences:
 ; MEMORY:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }

Modified: polly/trunk/test/Dependences/reduction_multiple_reductions_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_multiple_reductions_2.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_multiple_reductions_2.ll (original)
+++ polly/trunk/test/Dependences/reduction_multiple_reductions_2.ll Wed Feb 25 13:34:52 2015
@@ -2,7 +2,7 @@
 ;
 ; CHECK: RAW dependences:
 ; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[i0] : i0 <= 1023 and i0 >= 0 and i1 <= 1023 and i1 >= 0
-; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 1022
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 <= 1022 and i0 >= 0
 ; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
 ; These are the important RAW dependences, as they need to originate/end in only one iteration:
 ; CHECK-DAG: Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
@@ -11,7 +11,7 @@
 ; CHECK:   {  }
 ; CHECK: WAW dependences:
 ; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[i0] : i0 <= 1023 and i0 >= 0 and i1 <= 1023 and i1 >= 0
-; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 1022
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 <= 1022 and i0 >= 0
 ; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
 ; These are the important WAW dependences, as they need to originate/end in only one iteration:
 ; CHECK-DAG: Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0

Modified: polly/trunk/test/Dependences/reduction_privatization_deps_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_privatization_deps_2.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_privatization_deps_2.ll (original)
+++ polly/trunk/test/Dependences/reduction_privatization_deps_2.ll Wed Feb 25 13:34:52 2015
@@ -5,12 +5,12 @@
 ;
 ;  CHECK: RAW dependences:
 ;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[1 + i0, o1] : i0 <= 97 and i0 >= 0 and o1 <= 99 and o1 >= 0
-;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
 ;  CHECK: WAR dependences:
 ;  CHECK:   {  }
 ;  CHECK: WAW dependences:
 ;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[1 + i0, o1] : i0 <= 97 and i0 >= 0 and o1 <= 99 and o1 >= 0
-;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
 ;  CHECK: Reduction dependences:
 ;  CHECK:   { Stmt_S2[i0, i1] -> Stmt_S2[i0, 1 + i1] : i0 <= 98 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
 ;

Modified: polly/trunk/test/Dependences/reduction_privatization_deps_3.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_privatization_deps_3.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_privatization_deps_3.ll (original)
+++ polly/trunk/test/Dependences/reduction_privatization_deps_3.ll Wed Feb 25 13:34:52 2015
@@ -3,13 +3,13 @@
 ;  CHECK: RAW dependences:
 ;  CHECK-DAG:  Stmt_S2[i0, i1] -> Stmt_S3[o0] : o0 <= 1 and i1 <= 1 - i0 and o0 <= 1 + i0 - i1 and o0 >= 1 - i1
 ;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
-;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 >= 0 and i0 <= 96
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 <= 96 and i0 >= 0
 ;  CHECK: WAR dependences:
 ;  CHECK:   {  }
 ;  CHECK: WAW dependences:
 ;  CHECK-DAG:  Stmt_S2[i0, i1] -> Stmt_S3[o0] : o0 <= 1 and i1 <= 1 - i0 and o0 <= 1 + i0 - i1 and o0 >= 1 - i1
 ;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
-;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 >= 0 and i0 <= 96
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 <= 96 and i0 >= 0
 ;  CHECK: Reduction dependences:
 ;  CHECK-DAG:  Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : i0 <= 97 and i0 >= 0 and i1 <= 98 - i0 and i1 >= 0 and i1 >= 2 - i0
 ;  CHECK-DAG:  Stmt_S2[0, 0] -> Stmt_S2[1, 0]

Modified: polly/trunk/test/Dependences/reduction_privatization_deps_4.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_privatization_deps_4.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_privatization_deps_4.ll (original)
+++ polly/trunk/test/Dependences/reduction_privatization_deps_4.ll Wed Feb 25 13:34:52 2015
@@ -2,15 +2,15 @@
 ;
 ; CHECK:     RAW dependences:
 ; CHECK-DAG:   Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= 98
-; CHECK-DAG:   Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 >= 0 and i0 <= 98
-; CHECK-DAG:   Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 <= 98 and i0 >= 0
+; CHECK-DAG:   Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
 ; CHECK-DAG:   Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
 ; CHECK:     WAR dependences:
 ; CHECK-DAG:    {  }
 ; CHECK:     WAW dependences:
 ; CHECK-DAG:   Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= 98
-; CHECK-DAG:   Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 >= 0 and i0 <= 98
-; CHECK-DAG:   Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 <= 98 and i0 >= 0
+; CHECK-DAG:   Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
 ; CHECK-DAG:   Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
 ; CHECK:     Reduction dependences:
 ; CHECK-DAG:    { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : (i0 >= 0 and i1 >= 2 + i0 and i1 <= 99) or (i0 <= 97 and i1 >= 0 and i1 <= -1 + i0) }

Modified: polly/trunk/test/Dependences/reduction_privatization_deps_5.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_privatization_deps_5.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_privatization_deps_5.ll (original)
+++ polly/trunk/test/Dependences/reduction_privatization_deps_5.ll Wed Feb 25 13:34:52 2015
@@ -1,13 +1,13 @@
 ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
 ;
 ; CHECK:     RAW dependences:
-; CHECK-DAG:   Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 >= 0 and i0 <= 97
-; CHECK-DAG:   Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 <= 97 and i0 >= 0
+; CHECK-DAG:   Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 <= 98 and i0 >= 0
 ; CHECK:     WAR dependences:
 ; CHECK-DAG:   {  }
 ; CHECK:     WAW dependences:
-; CHECK-DAG:   Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 >= 0 and i0 <= 97
-; CHECK-DAG:   Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 <= 97 and i0 >= 0
+; CHECK-DAG:   Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 <= 98 and i0 >= 0
 ; CHECK:     Reduction dependences:
 ; CHECK-DAG:   { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : i0 <= 97 and i0 >= 0 and i1 <= 99 and i1 >= 1 }
 ;

Modified: polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll (original)
+++ polly/trunk/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll Wed Feb 25 13:34:52 2015
@@ -10,11 +10,11 @@
 ; CHECK: }
 ; CHECK: Wrapped Dependences:
 ; CHECK: RAW dependences:
-; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
 ; CHECK: WAR dependences:
 ; CHECK:   {  }
 ; CHECK: WAW dependences:
-; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
 ; CHECK: Reduction dependences:
 ; CHECK:   n/a
 ; CHECK: Final Wrapped Dependences:

Modified: polly/trunk/test/Dependences/reduction_simple_privatization_deps_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/reduction_simple_privatization_deps_2.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/reduction_simple_privatization_deps_2.ll (original)
+++ polly/trunk/test/Dependences/reduction_simple_privatization_deps_2.ll Wed Feb 25 13:34:52 2015
@@ -3,13 +3,13 @@
 ; CHECK:      RAW dependences:
 ; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S2[i0] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0
 ; CHECK-DAG:    Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 99 and i0 >= 0 and o1 <= 99 and o1 >= 0
-; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 <= 98 and i0 >= 0
 ; CHECK:      WAR dependences:
 ; CHECK-DAG:     {  }
 ; CHECK:      WAW dependences:
 ; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S2[i0] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0
 ; CHECK-DAG:    Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 99 and i0 >= 0 and o1 <= 99 and o1 >= 0
-; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 <= 98 and i0 >= 0
 ; CHECK:      Reduction dependences:
 ; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0
 ;

Modified: polly/trunk/test/Dependences/sequential_loops.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Dependences/sequential_loops.ll?rev=230528&r1=230527&r2=230528&view=diff
==============================================================================
--- polly/trunk/test/Dependences/sequential_loops.ll (original)
+++ polly/trunk/test/Dependences/sequential_loops.ll Wed Feb 25 13:34:52 2015
@@ -273,7 +273,7 @@ exit.2:
 ; VALUE:   RAW dependences:
 ; VALUE:     [p] -> {
 ; VALUE:       Stmt_S1[i0] -> Stmt_S2[-p + i0] :
-; VALUE:           i0 >= p and i0 <= 9 + p and p <= 190 and i0 <= 99 and i0 >= 0
+; VALUE:           p <= 190 and i0 >= p and i0 <= 9 + p and i0 >= 0 and i0 <= 99
 ; VALUE:     }
 ; VALUE:   WAR dependences:
 ; VALUE:     [p] -> {





More information about the llvm-commits mailing list