doc: update supported versions of clang
[isl.git] / isl_schedule_node.c
index ba48462..9d140e5 100644 (file)
@@ -29,11 +29,12 @@ __isl_give isl_schedule_node *isl_schedule_node_alloc(
 {
        isl_ctx *ctx;
        isl_schedule_node *node;
-       int i, n;
+       int i;
+       isl_size n;
 
-       if (!schedule || !tree || !ancestors)
-               goto error;
        n = isl_schedule_tree_list_n_schedule_tree(ancestors);
+       if (!schedule || !tree || n < 0)
+               goto error;
        if (n > 0 && !child_pos)
                goto error;
        ctx = isl_schedule_get_ctx(schedule);
@@ -134,6 +135,7 @@ enum isl_schedule_node_type isl_schedule_node_get_type(
 enum isl_schedule_node_type isl_schedule_node_get_parent_type(
        __isl_keep isl_schedule_node *node)
 {
+       isl_size n;
        int pos;
        int has_parent;
        isl_schedule_tree *parent;
@@ -147,8 +149,11 @@ enum isl_schedule_node_type isl_schedule_node_get_parent_type(
        if (!has_parent)
                isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
                        "node has no parent", return isl_schedule_node_error);
+       n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_schedule_node_error;
 
-       pos = isl_schedule_tree_list_n_schedule_tree(node->ancestors) - 1;
+       pos = n - 1;
        parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors, pos);
        type = isl_schedule_tree_get_type(parent);
        isl_schedule_tree_free(parent);
@@ -179,7 +184,7 @@ __isl_give isl_schedule *isl_schedule_node_get_schedule(
 
 /* Return a fresh copy of "node".
  */
-__isl_take isl_schedule_node *isl_schedule_node_dup(
+__isl_give isl_schedule_node *isl_schedule_node_dup(
        __isl_keep isl_schedule_node *node)
 {
        if (!node)
@@ -243,7 +248,8 @@ __isl_null isl_schedule_node *isl_schedule_node_free(
 isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1,
        __isl_keep isl_schedule_node *node2)
 {
-       int i, n1, n2;
+       int i;
+       isl_size n1, n2;
 
        if (!node1 || !node2)
                return isl_bool_error;
@@ -254,6 +260,8 @@ isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1,
 
        n1 = isl_schedule_node_get_tree_depth(node1);
        n2 = isl_schedule_node_get_tree_depth(node2);
+       if (n1 < 0 || n2 < 0)
+               return isl_bool_error;
        if (n1 != n2)
                return isl_bool_false;
        for (i = 0; i < n1; ++i)
@@ -266,27 +274,36 @@ isl_bool isl_schedule_node_is_equal(__isl_keep isl_schedule_node *node1,
 /* Return the number of outer schedule dimensions of "node"
  * in its schedule tree.
  *
- * Return -1 on error.
+ * Return isl_size_error on error.
  */
-int isl_schedule_node_get_schedule_depth(__isl_keep isl_schedule_node *node)
+isl_size isl_schedule_node_get_schedule_depth(
+       __isl_keep isl_schedule_node *node)
 {
-       int i, n;
+       int i;
+       isl_size n;
        int depth = 0;
 
        if (!node)
-               return -1;
+               return isl_size_error;
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_size_error;
        for (i = n - 1; i >= 0; --i) {
                isl_schedule_tree *tree;
+               isl_size n;
 
                tree = isl_schedule_tree_list_get_schedule_tree(
                                                    node->ancestors, i);
                if (!tree)
-                       return -1;
+                       return isl_size_error;
+               n = 0;
                if (tree->type == isl_schedule_node_band)
-                       depth += isl_schedule_tree_band_n_member(tree);
+                       n = isl_schedule_tree_band_n_member(tree);
+               depth += n;
                isl_schedule_tree_free(tree);
+               if (n < 0)
+                       return isl_size_error;
        }
 
        return depth;
@@ -314,7 +331,7 @@ struct isl_schedule_node_get_filter_prefix_data {
        isl_multi_union_pw_aff *prefix;
 };
 
-static int collect_filter_prefix(__isl_keep isl_schedule_tree_list *list,
+static isl_stat collect_filter_prefix(__isl_keep isl_schedule_tree_list *list,
        int n, struct isl_schedule_node_get_filter_prefix_data *data);
 
 /* Update the filter and prefix information in "data" based on the first "n"
@@ -325,7 +342,8 @@ static int collect_filter_prefix(__isl_keep isl_schedule_tree_list *list,
  * Then we map the results to the expanded space and combined them
  * with the results already in "data".
  */
-static int collect_filter_prefix_expansion(__isl_take isl_schedule_tree *tree,
+static isl_stat collect_filter_prefix_expansion(
+       __isl_take isl_schedule_tree *tree,
        __isl_keep isl_schedule_tree_list *list, int n,
        struct isl_schedule_node_get_filter_prefix_data *data)
 {
@@ -378,7 +396,7 @@ static int collect_filter_prefix_expansion(__isl_take isl_schedule_tree *tree,
        isl_union_map_free(exp);
        isl_schedule_tree_free(tree);
 
-       return 0;
+       return isl_stat_ok;
 }
 
 /* Update the filter information in "data" based on the first "n"
@@ -389,7 +407,8 @@ static int collect_filter_prefix_expansion(__isl_take isl_schedule_tree *tree,
  * add it to the universe range of the extension (intersected
  * with the already collected filter, if any).
  */
-static int collect_universe_domain_extension(__isl_take isl_schedule_tree *tree,
+static isl_stat collect_universe_domain_extension(
+       __isl_take isl_schedule_tree *tree,
        __isl_keep isl_schedule_tree_list *list, int n,
        struct isl_schedule_node_get_filter_prefix_data *data)
 {
@@ -419,7 +438,7 @@ static int collect_universe_domain_extension(__isl_take isl_schedule_tree *tree,
 
        isl_schedule_tree_free(tree);
 
-       return 0;
+       return isl_stat_ok;
 }
 
 /* Update "data" based on the tree node "tree" in case "data" has
@@ -437,30 +456,31 @@ static int collect_universe_domain_extension(__isl_take isl_schedule_tree *tree,
  * to the universe of the schedule domain and replace the zero-dimensional
  * data->prefix by the band schedule (if data->collect_prefix is set).
  */
-static int collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree,
+static isl_stat collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree,
        struct isl_schedule_node_get_filter_prefix_data *data)
 {
        enum isl_schedule_node_type type;
        isl_multi_union_pw_aff *mupa;
        isl_union_set *filter;
+       isl_size n;
 
        type = isl_schedule_tree_get_type(tree);
        switch (type) {
        case isl_schedule_node_error:
-               return -1;
+               return isl_stat_error;
        case isl_schedule_node_expansion:
                isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,
-                       "should be handled by caller", return -1);
+                       "should be handled by caller", return isl_stat_error);
        case isl_schedule_node_extension:
                isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
-                       "cannot handle extension nodes", return -1);
+                       "cannot handle extension nodes", return isl_stat_error);
        case isl_schedule_node_context:
        case isl_schedule_node_leaf:
        case isl_schedule_node_guard:
        case isl_schedule_node_mark:
        case isl_schedule_node_sequence:
        case isl_schedule_node_set:
-               return 0;
+               return isl_stat_ok;
        case isl_schedule_node_domain:
                filter = isl_schedule_tree_domain_get_domain(tree);
                if (data->universe_domain)
@@ -468,8 +488,11 @@ static int collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree,
                data->filter = filter;
                break;
        case isl_schedule_node_band:
-               if (isl_schedule_tree_band_n_member(tree) == 0)
-                       return 0;
+               n = isl_schedule_tree_band_n_member(tree);
+               if (n < 0)
+                       return isl_stat_error;
+               if (n == 0)
+                       return isl_stat_ok;
                mupa = isl_schedule_tree_band_get_partial_schedule(tree);
                if (data->collect_prefix) {
                        isl_multi_union_pw_aff_free(data->prefix);
@@ -490,11 +513,11 @@ static int collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree,
        }
 
        if ((data->collect_prefix && !data->prefix) || !data->filter)
-               return -1;
+               return isl_stat_error;
 
        data->initialized = 1;
 
-       return 0;
+       return isl_stat_ok;
 }
 
 /* Update "data" based on the tree node "tree" in case "data" has
@@ -511,22 +534,23 @@ static int collect_filter_prefix_init(__isl_keep isl_schedule_tree *tree,
  * If "tree" is an extension, then we make sure that we are not collecting
  * information on any extended domain elements.
  */
-static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
+static isl_stat collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
        struct isl_schedule_node_get_filter_prefix_data *data)
 {
        enum isl_schedule_node_type type;
        isl_multi_union_pw_aff *mupa;
        isl_union_set *filter;
        isl_union_map *extension;
-       int empty;
+       isl_bool empty;
+       isl_size n;
 
        type = isl_schedule_tree_get_type(tree);
        switch (type) {
        case isl_schedule_node_error:
-               return -1;
+               return isl_stat_error;
        case isl_schedule_node_expansion:
                isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,
-                       "should be handled by caller", return -1);
+                       "should be handled by caller", return isl_stat_error);
        case isl_schedule_node_extension:
                extension = isl_schedule_tree_extension_get_extension(tree);
                extension = isl_union_map_intersect_range(extension,
@@ -534,11 +558,11 @@ static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
                empty = isl_union_map_is_empty(extension);
                isl_union_map_free(extension);
                if (empty < 0)
-                       return -1;
+                       return isl_stat_error;
                if (empty)
                        break;
                isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,
-                       "cannot handle extension nodes", return -1);
+                       "cannot handle extension nodes", return isl_stat_error);
        case isl_schedule_node_context:
        case isl_schedule_node_leaf:
        case isl_schedule_node_guard:
@@ -553,7 +577,10 @@ static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
                data->filter = isl_union_set_intersect(data->filter, filter);
                break;
        case isl_schedule_node_band:
-               if (isl_schedule_tree_band_n_member(tree) == 0)
+               n = isl_schedule_tree_band_n_member(tree);
+               if (n < 0)
+                       return isl_stat_error;
+               if (n == 0)
                        break;
                if (!data->collect_prefix)
                        break;
@@ -561,7 +588,7 @@ static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
                data->prefix = isl_multi_union_pw_aff_flat_range_product(mupa,
                                                                data->prefix);
                if (!data->prefix)
-                       return -1;
+                       return isl_stat_error;
                break;
        case isl_schedule_node_filter:
                filter = isl_schedule_tree_filter_get_filter(tree);
@@ -569,11 +596,11 @@ static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
                        filter = isl_union_set_universe(filter);
                data->filter = isl_union_set_intersect(data->filter, filter);
                if (!data->filter)
-                       return -1;
+                       return isl_stat_error;
                break;
        }
 
-       return 0;
+       return isl_stat_ok;
 }
 
 /* Collect filter and/or prefix information from the first "n"
@@ -602,22 +629,22 @@ static int collect_filter_prefix_update(__isl_keep isl_schedule_tree *tree,
  * On successful return, data->initialized will be set since the outermost
  * ancestor is a domain node, which always results in an initialization.
  */
-static int collect_filter_prefix(__isl_keep isl_schedule_tree_list *list,
+static isl_stat collect_filter_prefix(__isl_keep isl_schedule_tree_list *list,
        int n, struct isl_schedule_node_get_filter_prefix_data *data)
 {
        int i;
 
        if (!list)
-               return -1;
+               return isl_stat_error;
 
        for (i = n - 1; i >= 0; --i) {
                isl_schedule_tree *tree;
                enum isl_schedule_node_type type;
-               int r;
+               isl_stat r;
 
                tree = isl_schedule_tree_list_get_schedule_tree(list, i);
                if (!tree)
-                       return -1;
+                       return isl_stat_error;
                type = isl_schedule_tree_get_type(tree);
                if (type == isl_schedule_node_expansion)
                        return collect_filter_prefix_expansion(tree, list, i,
@@ -632,10 +659,10 @@ static int collect_filter_prefix(__isl_keep isl_schedule_tree_list *list,
                        r = collect_filter_prefix_update(tree, data);
                isl_schedule_tree_free(tree);
                if (r < 0)
-                       return -1;
+                       return isl_stat_error;
        }
 
-       return 0;
+       return isl_stat_ok;
 }
 
 /* Return the concatenation of the partial schedules of all outer band
@@ -656,7 +683,7 @@ __isl_give isl_multi_union_pw_aff *
 isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(
        __isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
        isl_space *space;
        struct isl_schedule_node_get_filter_prefix_data data;
 
@@ -676,7 +703,7 @@ isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(
        data.prefix = isl_multi_union_pw_aff_zero(space);
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       if (collect_filter_prefix(node->ancestors, n, &data) < 0)
+       if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0)
                data.prefix = isl_multi_union_pw_aff_free(data.prefix);
 
        data.prefix = isl_multi_union_pw_aff_intersect_domain(data.prefix,
@@ -708,7 +735,7 @@ __isl_give isl_union_pw_multi_aff *
 isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(
        __isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n, dim;
        isl_space *space;
        isl_union_pw_multi_aff *prefix;
        struct isl_schedule_node_get_filter_prefix_data data;
@@ -729,11 +756,13 @@ isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(
        data.prefix = isl_multi_union_pw_aff_zero(space);
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       if (collect_filter_prefix(node->ancestors, n, &data) < 0)
+       if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0)
                data.prefix = isl_multi_union_pw_aff_free(data.prefix);
 
-       if (data.prefix &&
-           isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set) == 0) {
+       dim = isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set);
+       if (dim < 0)
+               data.prefix = isl_multi_union_pw_aff_free(data.prefix);
+       if (data.prefix && dim == 0) {
                isl_multi_union_pw_aff_free(data.prefix);
                prefix = isl_union_pw_multi_aff_from_domain(data.filter);
        } else {
@@ -773,7 +802,7 @@ __isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map(
 __isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation(
        __isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n, dim;
        isl_space *space;
        isl_union_map *prefix;
        struct isl_schedule_node_get_filter_prefix_data data;
@@ -794,11 +823,13 @@ __isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation(
        data.prefix = isl_multi_union_pw_aff_zero(space);
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       if (collect_filter_prefix(node->ancestors, n, &data) < 0)
+       if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0)
                data.prefix = isl_multi_union_pw_aff_free(data.prefix);
 
-       if (data.prefix &&
-           isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set) == 0) {
+       dim = isl_multi_union_pw_aff_dim(data.prefix, isl_dim_set);
+       if (dim < 0)
+               data.prefix = isl_multi_union_pw_aff_free(data.prefix);
+       if (data.prefix && dim == 0) {
                isl_multi_union_pw_aff_free(data.prefix);
                prefix = isl_union_map_from_domain(data.filter);
        } else {
@@ -824,7 +855,7 @@ __isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_relation(
 __isl_give isl_union_set *isl_schedule_node_get_domain(
        __isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
        struct isl_schedule_node_get_filter_prefix_data data;
 
        if (!node)
@@ -845,7 +876,7 @@ __isl_give isl_union_set *isl_schedule_node_get_domain(
        data.prefix = NULL;
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       if (collect_filter_prefix(node->ancestors, n, &data) < 0)
+       if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0)
                data.filter = isl_union_set_free(data.filter);
 
        return data.filter;
@@ -863,7 +894,7 @@ __isl_give isl_union_set *isl_schedule_node_get_domain(
 __isl_give isl_union_set *isl_schedule_node_get_universe_domain(
        __isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
        struct isl_schedule_node_get_filter_prefix_data data;
 
        if (!node)
@@ -884,7 +915,7 @@ __isl_give isl_union_set *isl_schedule_node_get_universe_domain(
        data.prefix = NULL;
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       if (collect_filter_prefix(node->ancestors, n, &data) < 0)
+       if (n < 0 || collect_filter_prefix(node->ancestors, n, &data) < 0)
                data.filter = isl_union_set_free(data.filter);
 
        return data.filter;
@@ -926,10 +957,10 @@ __isl_give isl_union_map *isl_schedule_node_get_subtree_schedule_union_map(
 
 /* Return the number of ancestors of "node" in its schedule tree.
  */
-int isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node)
+isl_size isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node)
 {
        if (!node)
-               return -1;
+               return isl_size_error;
        return isl_schedule_tree_list_n_schedule_tree(node->ancestors);
 }
 
@@ -939,32 +970,33 @@ int isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node)
  */
 isl_bool isl_schedule_node_has_parent(__isl_keep isl_schedule_node *node)
 {
-       if (!node)
-               return isl_bool_error;
-       if (!node->ancestors)
-               return isl_bool_error;
+       isl_size depth;
 
-       return isl_schedule_tree_list_n_schedule_tree(node->ancestors) != 0;
+       depth = isl_schedule_node_get_tree_depth(node);
+       if (depth < 0)
+               return isl_bool_error;
+       return isl_bool_ok(depth != 0);
 }
 
 /* Return the position of "node" among the children of its parent.
  */
-int isl_schedule_node_get_child_position(__isl_keep isl_schedule_node *node)
+isl_size isl_schedule_node_get_child_position(
+       __isl_keep isl_schedule_node *node)
 {
-       int n;
-       int has_parent;
+       isl_size n;
+       isl_bool has_parent;
 
        if (!node)
-               return -1;
+               return isl_size_error;
        has_parent = isl_schedule_node_has_parent(node);
        if (has_parent < 0)
-               return -1;
+               return isl_size_error;
        if (!has_parent)
                isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
-                       "node has no parent", return -1);
+                       "node has no parent", return isl_size_error);
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       return node->child_pos[n - 1];
+       return n < 0 ? isl_size_error : node->child_pos[n - 1];
 }
 
 /* Does the parent (if any) of "node" have any children with a smaller child
@@ -973,7 +1005,7 @@ int isl_schedule_node_get_child_position(__isl_keep isl_schedule_node *node)
 isl_bool isl_schedule_node_has_previous_sibling(
        __isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
        isl_bool has_parent;
 
        if (!node)
@@ -983,8 +1015,10 @@ isl_bool isl_schedule_node_has_previous_sibling(
                return has_parent;
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_bool_error;
 
-       return node->child_pos[n - 1] > 0;
+       return isl_bool_ok(node->child_pos[n - 1] > 0);
 }
 
 /* Does the parent (if any) of "node" have any children with a greater child
@@ -992,7 +1026,7 @@ isl_bool isl_schedule_node_has_previous_sibling(
  */
 isl_bool isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node)
 {
-       int n, n_child;
+       isl_size n, n_child;
        isl_bool has_parent;
        isl_schedule_tree *tree;
 
@@ -1003,13 +1037,15 @@ isl_bool isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node)
                return has_parent;
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
-       tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n - 1);
-       if (!tree)
+       if (n < 0)
                return isl_bool_error;
-       n_child = isl_schedule_tree_list_n_schedule_tree(tree->children);
+       tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors, n - 1);
+       n_child = isl_schedule_tree_n_children(tree);
        isl_schedule_tree_free(tree);
+       if (n_child < 0)
+               return isl_bool_error;
 
-       return node->child_pos[n - 1] + 1 < n_child;
+       return isl_bool_ok(node->child_pos[n - 1] + 1 < n_child);
 }
 
 /* Does "node" have any children?
@@ -1022,7 +1058,7 @@ isl_bool isl_schedule_node_has_children(__isl_keep isl_schedule_node *node)
 {
        if (!node)
                return isl_bool_error;
-       return !isl_schedule_tree_is_leaf(node->tree);
+       return isl_bool_ok(!isl_schedule_tree_is_leaf(node->tree));
 }
 
 /* Return the number of children of "node"?
@@ -1035,17 +1071,19 @@ isl_bool isl_schedule_node_has_children(__isl_keep isl_schedule_node *node)
  * to the number of children of "node".  If it has zero children,
  * then "node" still has a leaf node as child.
  */
-int isl_schedule_node_n_children(__isl_keep isl_schedule_node *node)
+isl_size isl_schedule_node_n_children(__isl_keep isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
 
        if (!node)
-               return -1;
+               return isl_size_error;
 
        if (isl_schedule_tree_is_leaf(node->tree))
                return 0;
 
        n = isl_schedule_tree_n_children(node->tree);
+       if (n < 0)
+               return isl_size_error;
        if (n == 0)
                return 1;
 
@@ -1059,7 +1097,7 @@ int isl_schedule_node_n_children(__isl_keep isl_schedule_node *node)
 __isl_give isl_schedule_node *isl_schedule_node_ancestor(
        __isl_take isl_schedule_node *node, int generation)
 {
-       int n;
+       isl_size n;
        isl_schedule_tree *tree;
 
        if (!node)
@@ -1103,12 +1141,20 @@ __isl_give isl_schedule_node *isl_schedule_node_parent(
        return isl_schedule_node_ancestor(node, 1);
 }
 
+/* Move the "node" pointer to the parent of its parent.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_grandparent(
+       __isl_take isl_schedule_node *node)
+{
+       return isl_schedule_node_ancestor(node, 2);
+}
+
 /* 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;
+       isl_size n;
 
        if (!node)
                return NULL;
@@ -1124,7 +1170,7 @@ __isl_give isl_schedule_node *isl_schedule_node_root(
 __isl_give isl_schedule_node *isl_schedule_node_child(
        __isl_take isl_schedule_node *node, int pos)
 {
-       int n;
+       isl_size n;
        isl_ctx *ctx;
        isl_schedule_tree *tree;
        int *child_pos;
@@ -1139,6 +1185,8 @@ __isl_give isl_schedule_node *isl_schedule_node_child(
 
        ctx = isl_schedule_node_get_ctx(node);
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        child_pos = isl_realloc_array(ctx, node->child_pos, int, n + 1);
        if (!child_pos)
                return isl_schedule_node_free(node);
@@ -1161,6 +1209,17 @@ __isl_give isl_schedule_node *isl_schedule_node_child(
        return node;
 }
 
+/* Move the "node" pointer to the child at position "pos2" of the child
+ * at position "pos1".
+ */
+__isl_give isl_schedule_node *isl_schedule_node_grandchild(
+       __isl_take isl_schedule_node *node, int pos1, int pos2)
+{
+       node = isl_schedule_node_child(node, pos1);
+       node = isl_schedule_node_child(node, pos2);
+       return node;
+}
+
 /* Move the "node" pointer to the first child of the node
  * it currently points to.
  */
@@ -1176,7 +1235,7 @@ __isl_give isl_schedule_node *isl_schedule_node_first_child(
 __isl_give isl_schedule_node *isl_schedule_node_previous_sibling(
        __isl_take isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
        isl_schedule_tree *parent, *tree;
 
        node = isl_schedule_node_cow(node);
@@ -1188,6 +1247,8 @@ __isl_give isl_schedule_node *isl_schedule_node_previous_sibling(
                        return isl_schedule_node_free(node));
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors,
                                                                        n - 1);
        if (!parent)
@@ -1210,7 +1271,7 @@ __isl_give isl_schedule_node *isl_schedule_node_previous_sibling(
 __isl_give isl_schedule_node *isl_schedule_node_next_sibling(
        __isl_take isl_schedule_node *node)
 {
-       int n;
+       isl_size n;
        isl_schedule_tree *parent, *tree;
 
        node = isl_schedule_node_cow(node);
@@ -1222,6 +1283,8 @@ __isl_give isl_schedule_node *isl_schedule_node_next_sibling(
                        return isl_schedule_node_free(node));
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        parent = isl_schedule_tree_list_get_schedule_tree(node->ancestors,
                                                                        n - 1);
        if (!parent)
@@ -1260,23 +1323,27 @@ static __isl_give isl_schedule_node *traverse(
                __isl_take isl_schedule_node *node, void *user),
        void *user)
 {
-       int depth;
-
-       if (!node)
-               return NULL;
+       isl_size depth;
+       isl_size node_depth;
 
        depth = isl_schedule_node_get_tree_depth(node);
+       if (depth < 0)
+               return isl_schedule_node_free(node);
+
        do {
                node = enter(node, user);
                node = leave(node, user);
-               while (node && isl_schedule_node_get_tree_depth(node) > depth &&
+               while ((node_depth = isl_schedule_node_get_tree_depth(node)) >
+                               depth &&
                                !isl_schedule_node_has_next_sibling(node)) {
                        node = isl_schedule_node_parent(node);
                        node = leave(node, user);
                }
-               if (node && isl_schedule_node_get_tree_depth(node) > depth)
+               if (node_depth < 0)
+                       return isl_schedule_node_free(node);
+               if (node_depth > depth)
                        node = isl_schedule_node_next_sibling(node);
-       } while (node && isl_schedule_node_get_tree_depth(node) > depth);
+       } while (node_depth > depth);
 
        return node;
 }
@@ -1478,12 +1545,13 @@ isl_stat isl_schedule_node_foreach_ancestor_top_down(
        isl_stat (*fn)(__isl_keep isl_schedule_node *node, void *user),
        void *user)
 {
-       int i, n;
+       int i;
+       isl_size n;
 
-       if (!node)
+       n = isl_schedule_node_get_tree_depth(node);
+       if (n < 0)
                return isl_stat_error;
 
-       n = isl_schedule_node_get_tree_depth(node);
        for (i = 0; i < n; ++i) {
                isl_schedule_node *ancestor;
                isl_stat r;
@@ -1512,9 +1580,11 @@ isl_bool isl_schedule_node_is_subtree_anchored(
 
 /* Return the number of members in the given band node.
  */
-unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node)
+isl_size isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node)
 {
-       return node ? isl_schedule_tree_band_n_member(node->tree) : 0;
+       if (!node)
+               return isl_size_error;
+       return isl_schedule_tree_band_n_member(node->tree);
 }
 
 /* Is the band member at position "pos" of the band node "node"
@@ -1614,6 +1684,7 @@ __isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule(
 __isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map(
        __isl_keep isl_schedule_node *node)
 {
+       isl_size n;
        isl_multi_union_pw_aff *mupa;
 
        if (!node)
@@ -1622,7 +1693,10 @@ __isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map(
        if (isl_schedule_node_get_type(node) != isl_schedule_node_band)
                isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
                        "not a band node", return NULL);
-       if (isl_schedule_node_band_n_member(node) == 0) {
+       n = isl_schedule_node_band_n_member(node);
+       if (n < 0)
+               return NULL;
+       if (n == 0) {
                isl_union_set *domain;
 
                domain = isl_schedule_node_get_universe_domain(node);
@@ -1729,12 +1803,12 @@ error:
 __isl_give isl_set *isl_schedule_node_band_get_ast_isolate_option(
        __isl_keep isl_schedule_node *node)
 {
-       int depth;
+       isl_size depth;
 
-       if (!node)
+       depth = isl_schedule_node_get_schedule_depth(node);
+       if (depth < 0)
                return NULL;
 
-       depth = isl_schedule_node_get_schedule_depth(node);
        return isl_schedule_tree_band_get_ast_isolate_option(node->tree, depth);
 }
 
@@ -1980,7 +2054,8 @@ __isl_give isl_schedule_node *isl_schedule_node_band_sink(
        enum isl_schedule_node_type type;
        isl_schedule_tree *tree, *child;
        isl_union_pw_multi_aff *contraction;
-       int anchored;
+       isl_bool anchored;
+       isl_size n;
 
        if (!node)
                return NULL;
@@ -1996,7 +2071,10 @@ __isl_give isl_schedule_node *isl_schedule_node_band_sink(
                isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
                        "cannot sink band node in anchored subtree",
                        return isl_schedule_node_free(node));
-       if (isl_schedule_tree_n_children(node->tree) == 0)
+       n = isl_schedule_tree_n_children(node->tree);
+       if (n < 0)
+               return isl_schedule_node_free(node);
+       if (n == 0)
                return node;
 
        contraction = isl_schedule_node_get_subtree_contraction(node);
@@ -2019,10 +2097,12 @@ __isl_give isl_schedule_node *isl_schedule_node_band_sink(
 __isl_give isl_schedule_node *isl_schedule_node_band_split(
        __isl_take isl_schedule_node *node, int pos)
 {
-       int depth;
+       isl_size depth;
        isl_schedule_tree *tree;
 
        depth = isl_schedule_node_get_schedule_depth(node);
+       if (depth < 0)
+               return isl_schedule_node_free(node);
        tree = isl_schedule_node_get_tree(node);
        tree = isl_schedule_tree_band_split(tree, pos, depth);
        return isl_schedule_node_graft_tree(node, tree);
@@ -2212,6 +2292,20 @@ __isl_give isl_id *isl_schedule_node_mark_get_id(
        return isl_schedule_tree_mark_get_id(node->tree);
 }
 
+/* Check that "node" is a sequence node.
+ */
+static isl_stat check_is_sequence(__isl_keep isl_schedule_node *node)
+{
+       if (!node)
+               return isl_stat_error;
+
+       if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence)
+               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
+                       "not a sequence node", return isl_stat_error);
+
+       return isl_stat_ok;
+}
+
 /* Replace the child at position "pos" of the sequence node "node"
  * by the children of sequence root node of "tree".
  */
@@ -2221,11 +2315,8 @@ __isl_give isl_schedule_node *isl_schedule_node_sequence_splice(
 {
        isl_schedule_tree *node_tree;
 
-       if (!node || !tree)
+       if (check_is_sequence(node) < 0 || !tree)
                goto error;
-       if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence)
-               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
-                       "not a sequence node", goto error);
        if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence)
                isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
                        "not a sequence node", goto error);
@@ -2250,27 +2341,23 @@ error:
 __isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child(
        __isl_take isl_schedule_node *node, int pos)
 {
-       int i, n;
+       int i;
+       isl_size n;
        isl_union_set *filter;
        isl_schedule_node *child;
        isl_schedule_tree *tree;
 
-       if (!node)
-               return NULL;
-       if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence)
-               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
-                       "not a sequence node",
-                       return isl_schedule_node_free(node));
-       node = isl_schedule_node_child(node, pos);
-       node = isl_schedule_node_child(node, 0);
-       if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence)
-               isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
-                       "not a sequence node",
-                       return isl_schedule_node_free(node));
+       if (check_is_sequence(node) < 0)
+               return isl_schedule_node_free(node);
+       node = isl_schedule_node_grandchild(node, pos, 0);
+       if (check_is_sequence(node) < 0)
+               return isl_schedule_node_free(node);
+       n = isl_schedule_node_n_children(node);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        child = isl_schedule_node_copy(node);
        node = isl_schedule_node_parent(node);
        filter = isl_schedule_node_filter_get_filter(node);
-       n = isl_schedule_node_n_children(child);
        for (i = 0; i < n; ++i) {
                child = isl_schedule_node_child(child, i);
                child = isl_schedule_node_filter_intersect_filter(child,
@@ -2286,6 +2373,46 @@ __isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child(
        return node;
 }
 
+/* Given a sequence node "node", for each child that is also
+ * (the parent of) a sequence node, attach the children of that node directly
+ * as children of "node" at the position of the child,
+ * replacing this original child.
+ *
+ * Since splicing in a child may change the positions of later children,
+ * iterate through the children from last to first.
+ */
+__isl_give isl_schedule_node *isl_schedule_node_sequence_splice_children(
+       __isl_take isl_schedule_node *node)
+{
+       int i;
+       isl_size n;
+
+       if (check_is_sequence(node) < 0)
+               return isl_schedule_node_free(node);
+       n = isl_schedule_node_n_children(node);
+       if (n < 0)
+               return isl_schedule_node_free(node);
+
+       for (i = n - 1; i >= 0; --i) {
+               enum isl_schedule_node_type type;
+               int is_seq;
+
+               node = isl_schedule_node_grandchild(node, i, 0);
+               type = isl_schedule_node_get_type(node);
+               if (type < 0)
+                       return isl_schedule_node_free(node);
+               is_seq = type == isl_schedule_node_sequence;
+               node = isl_schedule_node_grandparent(node);
+
+               if (!is_seq)
+                       continue;
+
+               node = isl_schedule_node_sequence_splice_child(node, i);
+       }
+
+       return node;
+}
+
 /* Update the ancestors of "node" to point to the tree that "node"
  * now points to.
  * That is, replace the child in the original parent that corresponds
@@ -2306,7 +2433,8 @@ static __isl_give isl_schedule_node *update_ancestors(
        __isl_give isl_schedule_tree *(*fn)(__isl_take isl_schedule_tree *tree,
                __isl_keep isl_schedule_node *pos, void *user), void *user)
 {
-       int i, n;
+       int i;
+       isl_size n;
        int is_leaf;
        isl_schedule_tree *tree;
        isl_schedule_node *pos = NULL;
@@ -2319,6 +2447,8 @@ static __isl_give isl_schedule_node *update_ancestors(
                return isl_schedule_node_free(pos);
 
        n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_schedule_node_free(pos);
        tree = isl_schedule_tree_copy(node->tree);
 
        for (i = n - 1; i >= 0; --i) {
@@ -2572,7 +2702,8 @@ static __isl_give isl_schedule_node *isl_schedule_node_insert_children(
        enum isl_schedule_node_type type,
        __isl_take isl_union_set_list *filters)
 {
-       int i, n;
+       int i;
+       isl_size n;
        isl_ctx *ctx;
        isl_schedule_tree *tree;
        isl_schedule_tree_list *list;
@@ -2580,11 +2711,11 @@ static __isl_give isl_schedule_node *isl_schedule_node_insert_children(
        if (check_insert(node) < 0)
                node = isl_schedule_node_free(node);
 
-       if (!node || !filters)
+       n = isl_union_set_list_n_union_set(filters);
+       if (!node || n < 0)
                goto error;
 
        ctx = isl_schedule_node_get_ctx(node);
-       n = isl_union_set_list_n_union_set(filters);
        list = isl_schedule_tree_list_alloc(ctx, n);
        for (i = 0; i < n; ++i) {
                isl_schedule_node *node_i;
@@ -2677,18 +2808,19 @@ __isl_give isl_schedule_node *isl_schedule_node_cut(
 __isl_give isl_schedule_node *isl_schedule_node_delete(
        __isl_take isl_schedule_node *node)
 {
-       int n;
+       isl_size n, depth;
        isl_schedule_tree *tree;
        enum isl_schedule_node_type type;
 
-       if (!node)
-               return NULL;
+       depth = isl_schedule_node_get_tree_depth(node);
+       n = isl_schedule_node_n_children(node);
+       if (depth < 0 || n < 0)
+               return isl_schedule_node_free(node);
 
-       if (isl_schedule_node_get_tree_depth(node) == 0)
+       if (depth == 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",
@@ -2760,10 +2892,10 @@ struct isl_schedule_group_data {
 
 /* Is domain covered by data->domain within data->domain_universe?
  */
-static int locally_covered_by_domain(__isl_keep isl_union_set *domain,
+static isl_bool locally_covered_by_domain(__isl_keep isl_union_set *domain,
        struct isl_schedule_group_data *data)
 {
-       int is_subset;
+       isl_bool is_subset;
        isl_union_set *test;
 
        test = isl_union_set_copy(domain);
@@ -2794,8 +2926,9 @@ static __isl_give isl_schedule_tree *group_band(
        isl_union_set *domain;
        isl_multi_aff *ma;
        isl_multi_union_pw_aff *mupa, *partial;
-       int is_covered;
-       int depth, n, has_id;
+       isl_bool is_covered;
+       isl_size depth, n;
+       isl_bool has_id;
 
        domain = isl_schedule_node_get_domain(pos);
        is_covered = locally_covered_by_domain(domain, data);
@@ -2810,6 +2943,8 @@ static __isl_give isl_schedule_tree *group_band(
                return isl_schedule_tree_free(tree);
        depth = isl_schedule_node_get_schedule_depth(pos);
        n = isl_schedule_tree_band_n_member(tree);
+       if (depth < 0 || n < 0)
+               return isl_schedule_tree_free(tree);
        ma = isl_multi_aff_copy(data->sched);
        ma = isl_multi_aff_drop_dims(ma, isl_dim_out, 0, depth);
        ma = isl_multi_aff_drop_dims(ma, isl_dim_out, n, data->dim - depth - n);
@@ -2836,10 +2971,12 @@ static __isl_give isl_schedule_tree *group_band(
 static __isl_give isl_union_set *union_set_drop_extra_params(
        __isl_take isl_union_set *uset, __isl_keep isl_space *space, int n)
 {
-       int n2;
+       isl_size n2;
 
        uset = isl_union_set_align_params(uset, isl_space_copy(space));
        n2 = isl_union_set_dim(uset, isl_dim_param);
+       if (n2 < 0)
+               return isl_union_set_free(uset);
        uset = isl_union_set_project_out(uset, isl_dim_param, n, n2 - n);
 
        return uset;
@@ -2860,10 +2997,14 @@ static __isl_give isl_schedule_tree *group_context(
 {
        isl_space *space;
        isl_union_set *domain;
-       int n1, n2;
-       int involves;
+       isl_size n1, n2;
+       isl_bool involves;
+       isl_size depth;
 
-       if (isl_schedule_node_get_tree_depth(pos) == 1)
+       depth = isl_schedule_node_get_tree_depth(pos);
+       if (depth < 0)
+               return isl_schedule_tree_free(tree);
+       if (depth == 1)
                return tree;
 
        domain = isl_schedule_node_get_universe_domain(pos);
@@ -2874,7 +3015,7 @@ static __isl_give isl_schedule_tree *group_context(
        data->expansion = isl_union_map_align_params(data->expansion, space);
        n2 = isl_union_map_dim(data->expansion, isl_dim_param);
 
-       if (!data->expansion)
+       if (n1 < 0 || n2 < 0)
                return isl_schedule_tree_free(tree);
        if (n1 == n2)
                return tree;
@@ -2895,6 +3036,9 @@ static __isl_give isl_schedule_tree *group_context(
        data->contraction = isl_union_pw_multi_aff_align_params(
                                data->contraction, isl_space_copy(space));
        n2 = isl_union_pw_multi_aff_dim(data->contraction, isl_dim_param);
+       if (n2 < 0)
+               data->contraction =
+                               isl_union_pw_multi_aff_free(data->contraction);
        data->contraction = isl_union_pw_multi_aff_drop_dims(data->contraction,
                                isl_dim_param, n1, n2 - n1);
 
@@ -2908,6 +3052,8 @@ static __isl_give isl_schedule_tree *group_context(
        data->sched = isl_multi_aff_align_params(data->sched,
                                isl_space_copy(space));
        n2 = isl_multi_aff_dim(data->sched, isl_dim_param);
+       if (n2 < 0)
+               data->sched = isl_multi_aff_free(data->sched);
        data->sched = isl_multi_aff_drop_dims(data->sched,
                                isl_dim_param, n1, n2 - n1);
 
@@ -2930,7 +3076,7 @@ static __isl_give isl_schedule_tree *group_domain(
        struct isl_schedule_group_data *data)
 {
        isl_union_set *domain;
-       int is_subset;
+       isl_bool is_subset;
 
        domain = isl_schedule_tree_domain_get_domain(tree);
        is_subset = isl_union_set_is_subset(data->domain, domain);
@@ -3033,7 +3179,7 @@ static __isl_give isl_schedule_tree *group_ancestor(
 {
        struct isl_schedule_group_data *data = user;
        isl_union_set *domain;
-       int is_covered;
+       isl_bool is_covered;
 
        if (!tree || !pos)
                return isl_schedule_tree_free(tree);
@@ -3114,9 +3260,11 @@ __isl_give isl_schedule_node *isl_schedule_node_group(
        isl_union_set *domain;
        isl_union_pw_multi_aff *contraction;
        isl_union_map *expansion;
-       int disjoint;
+       isl_bool disjoint;
+       isl_size depth;
 
-       if (!node || !group_id)
+       depth = isl_schedule_node_get_schedule_depth(node);
+       if (depth < 0 || !group_id)
                goto error;
        if (check_insert(node) < 0)
                goto error;
@@ -3126,7 +3274,7 @@ __isl_give isl_schedule_node *isl_schedule_node_group(
        data.domain_universe = isl_union_set_copy(domain);
        data.domain_universe = isl_union_set_universe(data.domain_universe);
 
-       data.dim = isl_schedule_node_get_schedule_depth(node);
+       data.dim = depth;
        if (data.dim == 0) {
                isl_ctx *ctx;
                isl_set *set;
@@ -3236,7 +3384,7 @@ struct isl_node_gist_data {
 static __isl_give isl_schedule_node *gist_enter_expansion(
        __isl_take isl_schedule_node *node, struct isl_node_gist_data *data)
 {
-       int n;
+       isl_size n;
        isl_union_set *inner;
        isl_union_map *expansion;
        isl_union_pw_multi_aff *contraction;
@@ -3244,6 +3392,8 @@ static __isl_give isl_schedule_node *gist_enter_expansion(
        data->n_expansion++;
 
        n = isl_union_set_list_n_union_set(data->filters);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        inner = isl_union_set_list_get_union_set(data->filters, n - 1);
        expansion = isl_schedule_node_expansion_get_expansion(node);
        inner = isl_union_set_apply(inner, expansion);
@@ -3275,7 +3425,7 @@ static __isl_give isl_schedule_node *gist_enter_expansion(
 static __isl_give isl_schedule_node *gist_leave_expansion(
        __isl_take isl_schedule_node *node, struct isl_node_gist_data *data)
 {
-       int n;
+       isl_size n;
        isl_bool identity;
        isl_union_map *expansion;
 
@@ -3289,6 +3439,8 @@ static __isl_give isl_schedule_node *gist_leave_expansion(
                node = isl_schedule_node_delete(node);
 
        n = isl_union_set_list_n_union_set(data->filters);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        data->filters = isl_union_set_list_drop(data->filters, n - 1, 1);
 
        data->n_expansion--;
@@ -3305,11 +3457,13 @@ static __isl_give isl_schedule_node *gist_leave_expansion(
 static __isl_give isl_schedule_node *gist_enter_extension(
        __isl_take isl_schedule_node *node, struct isl_node_gist_data *data)
 {
-       int n;
+       isl_size n;
        isl_union_set *inner, *extra;
        isl_union_map *extension;
 
        n = isl_union_set_list_n_union_set(data->filters);
+       if (n < 0)
+               return isl_schedule_node_free(node);
        inner = isl_union_set_list_get_union_set(data->filters, n - 1);
        extension = isl_schedule_node_extension_get_extension(node);
        extra = isl_union_map_range(extension);
@@ -3327,14 +3481,14 @@ static __isl_give isl_schedule_node *gist_enter_extension(
  * this test since the current domain elements are incomparable
  * to the domain elements in the original context.
  */
-static int gist_done(__isl_keep isl_schedule_node *node,
+static isl_bool gist_done(__isl_keep isl_schedule_node *node,
        struct isl_node_gist_data *data)
 {
        isl_union_set *filter, *outer;
-       int subset;
+       isl_bool subset;
 
        if (data->n_expansion != 0)
-               return 0;
+               return isl_bool_false;
 
        filter = isl_schedule_node_filter_get_filter(node);
        outer = isl_union_set_list_get_union_set(data->filters, 0);
@@ -3381,8 +3535,8 @@ static __isl_give isl_schedule_node *gist_enter(
 
        do {
                isl_union_set *filter, *inner;
-               int done, empty;
-               int n;
+               isl_bool done, empty;
+               isl_size n;
 
                switch (isl_schedule_node_get_type(node)) {
                case isl_schedule_node_error:
@@ -3407,14 +3561,14 @@ static __isl_give isl_schedule_node *gist_enter(
                }
                done = gist_done(node, data);
                filter = isl_schedule_node_filter_get_filter(node);
-               if (done < 0 || done) {
+               n = isl_union_set_list_n_union_set(data->filters);
+               if (n < 0 || done < 0 || done) {
                        data->filters = isl_union_set_list_add(data->filters,
                                                                filter);
-                       if (done < 0)
+                       if (n < 0 || 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,
@@ -3467,7 +3621,8 @@ static __isl_give isl_schedule_node *gist_leave(
 {
        struct isl_node_gist_data *data = user;
        isl_schedule_tree *tree;
-       int i, n;
+       int i;
+       isl_size n;
        isl_union_set *filter;
 
        switch (isl_schedule_node_get_type(node)) {
@@ -3479,11 +3634,15 @@ static __isl_give isl_schedule_node *gist_leave(
        case isl_schedule_node_extension:
        case isl_schedule_node_filter:
                n = isl_union_set_list_n_union_set(data->filters);
+               if (n < 0)
+                       return isl_schedule_node_free(node);
                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);
+               if (n < 0)
+                       return isl_schedule_node_free(node);
                filter = isl_union_set_list_get_union_set(data->filters, n - 1);
                node = isl_schedule_node_band_gist(node, filter);
                break;
@@ -3491,10 +3650,12 @@ static __isl_give isl_schedule_node *gist_leave(
        case isl_schedule_node_sequence:
                tree = isl_schedule_node_get_tree(node);
                n = isl_schedule_tree_n_children(tree);
+               if (n < 0)
+                       tree = isl_schedule_tree_free(tree);
                for (i = n - 1; i >= 0; --i) {
                        isl_schedule_tree *child;
                        isl_union_set *filter;
-                       int empty;
+                       isl_bool empty;
 
                        child = isl_schedule_tree_get_child(tree, i);
                        filter = isl_schedule_tree_filter_get_filter(child);
@@ -3507,6 +3668,8 @@ static __isl_give isl_schedule_node *gist_leave(
                                tree = isl_schedule_tree_drop_child(tree, i);
                }
                n = isl_schedule_tree_n_children(tree);
+               if (n < 0)
+                       tree = isl_schedule_tree_free(tree);
                node = isl_schedule_node_graft_tree(node, tree);
                if (n == 1) {
                        node = isl_schedule_node_delete(node);
@@ -3662,7 +3825,7 @@ static __isl_give isl_schedule_node *subtree_expansion_enter(
                enum isl_schedule_node_type type;
                isl_union_set *filter;
                isl_union_map *inner, *expansion;
-               int n;
+               isl_size n;
 
                switch (isl_schedule_node_get_type(node)) {
                case isl_schedule_node_error:
@@ -3674,6 +3837,9 @@ static __isl_give isl_schedule_node *subtree_expansion_enter(
                                break;
                        filter = isl_schedule_node_filter_get_filter(node);
                        n = isl_union_map_list_n_union_map(data->expansions);
+                       if (n < 0)
+                               data->expansions =
+                                   isl_union_map_list_free(data->expansions);
                        inner =
                            isl_union_map_list_get_union_map(data->expansions,
                                                                n - 1);
@@ -3683,6 +3849,9 @@ static __isl_give isl_schedule_node *subtree_expansion_enter(
                        break;
                case isl_schedule_node_expansion:
                        n = isl_union_map_list_n_union_map(data->expansions);
+                       if (n < 0)
+                               data->expansions =
+                                   isl_union_map_list_free(data->expansions);
                        expansion =
                                isl_schedule_node_expansion_get_expansion(node);
                        inner =
@@ -3724,7 +3893,7 @@ static __isl_give isl_schedule_node *subtree_expansion_leave(
        __isl_take isl_schedule_node *node, void *user)
 {
        struct isl_subtree_expansion_data *data = user;
-       int n;
+       isl_size n;
        isl_union_map *inner;
        enum isl_schedule_node_type type;
 
@@ -3737,11 +3906,17 @@ static __isl_give isl_schedule_node *subtree_expansion_leave(
                    type != isl_schedule_node_sequence)
                        break;
                n = isl_union_map_list_n_union_map(data->expansions);
+               if (n < 0)
+                       data->expansions =
+                                   isl_union_map_list_free(data->expansions);
                data->expansions = isl_union_map_list_drop(data->expansions,
                                                        n - 1, 1);
                break;
        case isl_schedule_node_leaf:
                n = isl_union_map_list_n_union_map(data->expansions);
+               if (n < 0)
+                       data->expansions =
+                                   isl_union_map_list_free(data->expansions);
                inner = isl_union_map_list_get_union_map(data->expansions,
                                                        n - 1);
                data->res = isl_union_map_union(data->res, inner);
@@ -3835,7 +4010,7 @@ static __isl_give isl_schedule_node *subtree_contraction_enter(
                enum isl_schedule_node_type type;
                isl_union_set *filter;
                isl_union_pw_multi_aff *inner, *contraction;
-               int n;
+               isl_size n;
 
                switch (isl_schedule_node_get_type(node)) {
                case isl_schedule_node_error:
@@ -3848,6 +4023,10 @@ static __isl_give isl_schedule_node *subtree_contraction_enter(
                        filter = isl_schedule_node_filter_get_filter(node);
                        n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff(
                                                data->contractions);
+                       if (n < 0)
+                               data->contractions =
+                                   isl_union_pw_multi_aff_list_free(
+                                                           data->contractions);
                        inner =
                            isl_union_pw_multi_aff_list_get_union_pw_multi_aff(
                                                data->contractions, n - 1);
@@ -3860,6 +4039,10 @@ static __isl_give isl_schedule_node *subtree_contraction_enter(
                case isl_schedule_node_expansion:
                        n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff(
                                                data->contractions);
+                       if (n < 0)
+                               data->contractions =
+                                   isl_union_pw_multi_aff_list_free(
+                                                           data->contractions);
                        contraction =
                            isl_schedule_node_expansion_get_contraction(node);
                        inner =
@@ -3903,7 +4086,7 @@ static __isl_give isl_schedule_node *subtree_contraction_leave(
        __isl_take isl_schedule_node *node, void *user)
 {
        struct isl_subtree_contraction_data *data = user;
-       int n;
+       isl_size n;
        isl_union_pw_multi_aff *inner;
        enum isl_schedule_node_type type;
 
@@ -3917,6 +4100,9 @@ static __isl_give isl_schedule_node *subtree_contraction_leave(
                        break;
                n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff(
                                                data->contractions);
+               if (n < 0)
+                       data->contractions = isl_union_pw_multi_aff_list_free(
+                                                           data->contractions);
                data->contractions =
                        isl_union_pw_multi_aff_list_drop(data->contractions,
                                                        n - 1, 1);
@@ -3924,6 +4110,9 @@ static __isl_give isl_schedule_node *subtree_contraction_leave(
        case isl_schedule_node_leaf:
                n = isl_union_pw_multi_aff_list_n_union_pw_multi_aff(
                                                data->contractions);
+               if (n < 0)
+                       data->contractions = isl_union_pw_multi_aff_list_free(
+                                                           data->contractions);
                inner = isl_union_pw_multi_aff_list_get_union_pw_multi_aff(
                                                data->contractions, n - 1);
                data->res = isl_union_pw_multi_aff_union_add(data->res, inner);
@@ -3987,17 +4176,20 @@ __isl_give isl_union_pw_multi_aff *isl_schedule_node_get_subtree_contraction(
 /* Do the nearest "n" ancestors of "node" have the types given in "types"
  * (starting at the parent of "node")?
  */
-static int has_ancestors(__isl_keep isl_schedule_node *node,
+static isl_bool has_ancestors(__isl_keep isl_schedule_node *node,
        int n, enum isl_schedule_node_type *types)
 {
-       int i, n_ancestor;
+       int i;
+       isl_size n_ancestor;
 
        if (!node)
-               return -1;
+               return isl_bool_error;
 
        n_ancestor = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n_ancestor < 0)
+               return isl_bool_error;
        if (n_ancestor < n)
-               return 0;
+               return isl_bool_false;
 
        for (i = 0; i < n; ++i) {
                isl_schedule_tree *tree;
@@ -4006,14 +4198,14 @@ static int has_ancestors(__isl_keep isl_schedule_node *node,
                tree = isl_schedule_tree_list_get_schedule_tree(node->ancestors,
                                                            n_ancestor - 1 - i);
                if (!tree)
-                       return -1;
+                       return isl_bool_error;
                correct_type = isl_schedule_tree_get_type(tree) == types[i];
                isl_schedule_tree_free(tree);
                if (!correct_type)
-                       return 0;
+                       return isl_bool_false;
        }
 
-       return 1;
+       return isl_bool_true;
 }
 
 /* Given a node "node" that appears in an extension (i.e., it is the child
@@ -4022,17 +4214,15 @@ static int has_ancestors(__isl_keep isl_schedule_node *node,
  * of both the original extension and the domain elements that reach
  * that original extension?
  */
-static int is_disjoint_extension(__isl_keep isl_schedule_node *node,
+static isl_bool is_disjoint_extension(__isl_keep isl_schedule_node *node,
        __isl_keep isl_union_map *extension)
 {
        isl_union_map *old;
        isl_union_set *domain;
-       int empty;
+       isl_bool empty;
 
        node = isl_schedule_node_copy(node);
-       node = isl_schedule_node_parent(node);
-       node = isl_schedule_node_parent(node);
-       node = isl_schedule_node_parent(node);
+       node = isl_schedule_node_ancestor(node, 3);
        old = isl_schedule_node_extension_get_extension(node);
        domain = isl_schedule_node_get_universe_domain(node);
        isl_schedule_node_free(node);
@@ -4058,20 +4248,20 @@ static int is_disjoint_extension(__isl_keep isl_schedule_node *node,
 static __isl_give isl_schedule_node *extend_extension(
        __isl_take isl_schedule_node *node, __isl_take isl_union_map *extension)
 {
-       int pos;
-       int disjoint;
+       isl_size pos;
+       isl_bool disjoint;
        isl_union_map *node_extension;
 
        node = isl_schedule_node_parent(node);
        pos = isl_schedule_node_get_child_position(node);
-       node = isl_schedule_node_parent(node);
-       node = isl_schedule_node_parent(node);
+       if (pos < 0)
+               node = isl_schedule_node_free(node);
+       node = isl_schedule_node_grandparent(node);
        node_extension = isl_schedule_node_extension_get_extension(node);
        disjoint = isl_union_map_is_disjoint(extension, node_extension);
        extension = isl_union_map_union(extension, node_extension);
        node = isl_schedule_node_extension_set_extension(node, extension);
-       node = isl_schedule_node_child(node, 0);
-       node = isl_schedule_node_child(node, pos);
+       node = isl_schedule_node_grandchild(node, 0, pos);
 
        if (disjoint < 0)
                return isl_schedule_node_free(node);
@@ -4142,13 +4332,13 @@ static __isl_give isl_schedule_node *insert_extension(
                  isl_schedule_node_extension };
        isl_union_set *domain;
        isl_union_set *filter;
-       int in_ext;
+       isl_bool in_ext;
 
        in_ext = has_ancestors(node, 3, ancestors);
        if (in_ext < 0)
                goto error;
        if (in_ext) {
-               int disjoint;
+               isl_bool disjoint;
 
                disjoint = is_disjoint_extension(node, extension);
                if (disjoint < 0)
@@ -4183,19 +4373,20 @@ static __isl_give isl_schedule_node *graft_or_splice(
        __isl_take isl_schedule_node *node, __isl_take isl_schedule_tree *tree,
        int tree_pos)
 {
-       int pos;
+       isl_size pos;
 
        if (isl_schedule_node_get_parent_type(node) ==
            isl_schedule_node_sequence) {
                pos = isl_schedule_node_get_child_position(node);
+               if (pos < 0)
+                       node = isl_schedule_node_free(node);
                node = isl_schedule_node_parent(node);
                node = isl_schedule_node_sequence_splice(node, pos, tree);
        } else {
                pos = 0;
                node = isl_schedule_node_graft_tree(node, tree);
        }
-       node = isl_schedule_node_child(node, pos + tree_pos);
-       node = isl_schedule_node_child(node, 0);
+       node = isl_schedule_node_grandchild(node, pos + tree_pos, 0);
 
        return node;
 }
@@ -4266,21 +4457,21 @@ static __isl_give isl_schedule_node *extension_from_domain(
        isl_union_set *universe;
        isl_union_set *domain;
        isl_union_map *ext;
-       int depth;
-       int anchored;
+       isl_size depth;
+       isl_bool anchored;
        isl_space *space;
        isl_schedule_node *res;
        isl_schedule_tree *tree;
 
+       depth = isl_schedule_node_get_schedule_depth(pos);
        anchored = isl_schedule_node_is_subtree_anchored(node);
-       if (anchored < 0)
+       if (depth < 0 || anchored < 0)
                return isl_schedule_node_free(node);
        if (anchored)
                isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported,
                        "cannot graft anchored tree with domain root",
                        return isl_schedule_node_free(node));
 
-       depth = isl_schedule_node_get_schedule_depth(pos);
        domain = isl_schedule_node_domain_get_domain(node);
        space = isl_union_set_get_space(domain);
        space = isl_space_set_from_params(space);
@@ -4414,8 +4605,8 @@ static __isl_give isl_schedule_node *isl_schedule_node_order_before_or_after(
        isl_union_set *node_domain, *node_filter = NULL, *parent_filter;
        isl_schedule_node *node2;
        isl_schedule_tree *tree1, *tree2;
-       int empty1, empty2;
-       int in_seq;
+       isl_bool empty1, empty2;
+       isl_bool in_seq;
 
        if (!node || !filter)
                goto error;
@@ -4649,33 +4840,32 @@ __isl_give isl_schedule_node *isl_schedule_node_expand(
  * 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.
+ * Return isl_size_error on error.
  */
-int isl_schedule_node_get_ancestor_child_position(
+isl_size isl_schedule_node_get_ancestor_child_position(
        __isl_keep isl_schedule_node *node,
        __isl_keep isl_schedule_node *ancestor)
 {
-       int n1, n2;
+       isl_size n1, n2;
        isl_schedule_tree *tree;
 
-       if (!node || !ancestor)
-               return -1;
+       n1 = isl_schedule_node_get_tree_depth(ancestor);
+       n2 = isl_schedule_node_get_tree_depth(node);
+       if (n1 < 0 || n2 < 0)
+               return isl_size_error;
 
        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);
+                       "not a descendant", return isl_size_error);
 
        if (n1 >= n2)
                isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
-                       "not a descendant", return -1);
+                       "not a descendant", return isl_size_error);
        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);
+                       "not a descendant", return isl_size_error);
 
        return node->child_pos[n1];
 }
@@ -4695,15 +4885,16 @@ __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;
+       int i;
+       isl_size n1, n2;
 
-       if (!node1 || !node2)
+       n1 = isl_schedule_node_get_tree_depth(node1);
+       n2 = isl_schedule_node_get_tree_depth(node2);
+       if (n1 < 0 || n2 < 0)
                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)
@@ -4724,10 +4915,14 @@ __isl_give isl_schedule_node *isl_schedule_node_get_shared_ancestor(
 __isl_give isl_printer *isl_printer_print_schedule_node(
        __isl_take isl_printer *p, __isl_keep isl_schedule_node *node)
 {
+       isl_size n;
+
        if (!node)
                return isl_printer_free(p);
-       return isl_printer_print_schedule_tree_mark(p, node->schedule->root,
-                       isl_schedule_tree_list_n_schedule_tree(node->ancestors),
+       n = isl_schedule_tree_list_n_schedule_tree(node->ancestors);
+       if (n < 0)
+               return isl_printer_free(p);
+       return isl_printer_print_schedule_tree_mark(p, node->schedule->root, n,
                        node->child_pos);
 }