/* * Copyright 2013-2014 Ecole Normale Superieure * Copyright 2014 INRIA Rocquencourt * Copyright 2016 INRIA Paris * * 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 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12, * CS 42112, 75589 Paris Cedex 12, France */ #include <isl/id.h> #include <isl/val.h> #include <isl/space.h> #include <isl/map.h> #include <isl_schedule_band.h> #include <isl_schedule_private.h> #undef EL #define EL … #include <isl_list_templ.h> #undef EL_BASE #define EL_BASE … #include <isl_list_templ.c> /* Is "tree" the leaf of a schedule tree? */ int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree) { … } /* Create a new schedule tree of type "type". * The caller is responsible for filling in the type specific fields and * the children. * * By default, the single node tree does not have any anchored nodes. * The caller is responsible for updating the anchored field if needed. */ static __isl_give isl_schedule_tree *isl_schedule_tree_alloc(isl_ctx *ctx, enum isl_schedule_node_type type) { … } /* Return a fresh copy of "tree". */ __isl_give isl_schedule_tree *isl_schedule_tree_dup( __isl_keep isl_schedule_tree *tree) { … } /* Return an isl_schedule_tree that is equal to "tree" and that has only * a single reference. */ __isl_give isl_schedule_tree *isl_schedule_tree_cow( __isl_take isl_schedule_tree *tree) { … } /* Return a new reference to "tree". */ __isl_give isl_schedule_tree *isl_schedule_tree_copy( __isl_keep isl_schedule_tree *tree) { … } /* Free "tree" and return NULL. */ __isl_null isl_schedule_tree *isl_schedule_tree_free( __isl_take isl_schedule_tree *tree) { … } /* Create and return a new leaf schedule tree. */ __isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx) { … } /* Create a new band schedule tree referring to "band" * with no children. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_band( __isl_take isl_schedule_band *band) { … } /* Create a new context schedule tree with the given context and no children. * Since the context references the outer schedule dimension, * the tree is anchored. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_context( __isl_take isl_set *context) { … } /* Create a new domain schedule tree with the given domain and no children. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_domain( __isl_take isl_union_set *domain) { … } /* Create a new expansion schedule tree with the given contraction and * expansion and no children. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_expansion( __isl_take isl_union_pw_multi_aff *contraction, __isl_take isl_union_map *expansion) { … } /* Create a new extension schedule tree with the given extension and * no children. * Since the domain of the extension refers to the outer schedule dimension, * the tree is anchored. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_extension( __isl_take isl_union_map *extension) { … } /* Create a new filter schedule tree with the given filter and no children. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_filter( __isl_take isl_union_set *filter) { … } /* Create a new guard schedule tree with the given guard and no children. * Since the guard references the outer schedule dimension, * the tree is anchored. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_guard( __isl_take isl_set *guard) { … } /* Create a new mark schedule tree with the given mark identifier and * no children. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_mark( __isl_take isl_id *mark) { … } /* Does "tree" have any node that depends on its position * in the complete schedule tree? */ isl_bool isl_schedule_tree_is_subtree_anchored( __isl_keep isl_schedule_tree *tree) { … } /* Does the root node of "tree" depend on its position in the complete * schedule tree? * Band nodes may be anchored depending on the associated AST build options. * Context, extension and guard nodes are always anchored. */ int isl_schedule_tree_is_anchored(__isl_keep isl_schedule_tree *tree) { … } /* Update the anchored field of "tree" based on whether the root node * itself in anchored and the anchored fields of the children. * * This function should be called whenever the children of a tree node * are changed or the anchoredness of the tree root itself changes. */ __isl_give isl_schedule_tree *isl_schedule_tree_update_anchored( __isl_take isl_schedule_tree *tree) { … } /* Create a new tree of the given type (isl_schedule_node_sequence or * isl_schedule_node_set) with the given children. */ __isl_give isl_schedule_tree *isl_schedule_tree_from_children( enum isl_schedule_node_type type, __isl_take isl_schedule_tree_list *list) { … } /* 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) { … } /* Construct a tree with a sequence root node and as children * "tree1" and "tree2". * If the root of one (or both) of the input trees is itself a sequence, * then the tree is replaced by its children. */ __isl_give isl_schedule_tree *isl_schedule_tree_sequence_pair( __isl_take isl_schedule_tree *tree1, __isl_take isl_schedule_tree *tree2) { … } /* Construct a tree with a set root node and as children * "tree1" and "tree2". * If the root of one (or both) of the input trees is itself a set, * then the tree is replaced by its children. */ __isl_give isl_schedule_tree *isl_schedule_tree_set_pair( __isl_take isl_schedule_tree *tree1, __isl_take isl_schedule_tree *tree2) { … } /* Return the isl_ctx to which "tree" belongs. */ isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree) { … } /* Return the type of the root of the tree or isl_schedule_node_error * on error. */ enum isl_schedule_node_type isl_schedule_tree_get_type( __isl_keep isl_schedule_tree *tree) { … } /* Are "tree1" and "tree2" obviously equal to each other? */ isl_bool isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1, __isl_keep isl_schedule_tree *tree2) { … } /* Does "tree" have any children, other than an implicit leaf. */ int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree) { … } /* Return the number of children of "tree", excluding implicit leaves. * The "children" field is NULL if there are * no children (except for the implicit leaves). */ isl_size isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree) { … } /* Return a copy of the (explicit) child at position "pos" of "tree". */ __isl_give isl_schedule_tree *isl_schedule_tree_get_child( __isl_keep isl_schedule_tree *tree, int pos) { … } /* Return a copy of the (explicit) child at position "pos" of "tree" and * free "tree". */ __isl_give isl_schedule_tree *isl_schedule_tree_child( __isl_take isl_schedule_tree *tree, int pos) { … } /* Remove all (explicit) children from "tree". */ __isl_give isl_schedule_tree *isl_schedule_tree_reset_children( __isl_take isl_schedule_tree *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) { … } /* Replace the child at position "pos" of "tree" by "child". * * If the new child is a leaf, then it is not explicitly * recorded in the list of children. Instead, the list of children * (which is assumed to have only one element) is removed. * Note that the children of set and sequence nodes are always * filters, so they cannot be replaced by empty trees. */ __isl_give isl_schedule_tree *isl_schedule_tree_replace_child( __isl_take isl_schedule_tree *tree, int pos, __isl_take isl_schedule_tree *child) { … } /* Replace the (explicit) children of "tree" by "children"? */ __isl_give isl_schedule_tree *isl_schedule_tree_set_children( __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_tree_list *children) { … } /* Create a new band schedule tree referring to "band" * with "tree" as single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_band( __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band) { … } /* Create a new context schedule tree with the given context and * with "tree" as single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_context( __isl_take isl_schedule_tree *tree, __isl_take isl_set *context) { … } /* Create a new domain schedule tree with the given domain and * with "tree" as single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_domain( __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) { … } /* Create a new expansion schedule tree with the given contraction and * expansion and with "tree" as single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_expansion( __isl_take isl_schedule_tree *tree, __isl_take isl_union_pw_multi_aff *contraction, __isl_take isl_union_map *expansion) { … } /* Create a new extension schedule tree with the given extension and * with "tree" as single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_extension( __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension) { … } /* Create a new filter schedule tree with the given filter and single child. * * If the root of "tree" is itself a filter node, then the two * filter nodes are merged into one node. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_filter( __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) { … } /* 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) { … } /* Create a new guard schedule tree with the given guard and * with "tree" as single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_guard( __isl_take isl_schedule_tree *tree, __isl_take isl_set *guard) { … } /* Create a new mark schedule tree with the given mark identifier and * single child. */ __isl_give isl_schedule_tree *isl_schedule_tree_insert_mark( __isl_take isl_schedule_tree *tree, __isl_take isl_id *mark) { … } /* Return the number of members in the band tree root. */ isl_size isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree) { … } /* Is the band member at position "pos" of the band tree root * marked coincident? */ isl_bool isl_schedule_tree_band_member_get_coincident( __isl_keep isl_schedule_tree *tree, int pos) { … } /* Mark the given band member as being coincident or not * according to "coincident". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident( __isl_take isl_schedule_tree *tree, int pos, int coincident) { … } /* Is the band tree root marked permutable? */ isl_bool isl_schedule_tree_band_get_permutable( __isl_keep isl_schedule_tree *tree) { … } /* Mark the band tree root permutable or not according to "permutable"? */ __isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable( __isl_take isl_schedule_tree *tree, int permutable) { … } /* Return the schedule space of the band tree root. */ __isl_give isl_space *isl_schedule_tree_band_get_space( __isl_keep isl_schedule_tree *tree) { … } /* Intersect the domain of the band schedule of the band tree root * with "domain". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_intersect_domain( __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) { … } /* Return the schedule of the band tree root in isolation. */ __isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule( __isl_keep isl_schedule_tree *tree) { … } /* Replace the schedule of the band tree root by "schedule". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_set_partial_schedule( __isl_take isl_schedule_tree *tree, __isl_take isl_multi_union_pw_aff *schedule) { … } /* Return the loop AST generation type for the band member * of the band tree root at position "pos". */ enum isl_ast_loop_type isl_schedule_tree_band_member_get_ast_loop_type( __isl_keep isl_schedule_tree *tree, int pos) { … } /* Set the loop AST generation type for the band member of the band tree root * at position "pos" to "type". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_ast_loop_type( __isl_take isl_schedule_tree *tree, int pos, enum isl_ast_loop_type type) { … } /* Return the loop AST generation type for the band member * of the band tree root at position "pos" for the isolated part. */ enum isl_ast_loop_type isl_schedule_tree_band_member_get_isolate_ast_loop_type( __isl_keep isl_schedule_tree *tree, int pos) { … } /* Set the loop AST generation type for the band member of the band tree root * at position "pos" for the isolated part to "type". */ __isl_give isl_schedule_tree * isl_schedule_tree_band_member_set_isolate_ast_loop_type( __isl_take isl_schedule_tree *tree, int pos, enum isl_ast_loop_type type) { … } /* Return the AST build options associated to the band tree root. */ __isl_give isl_union_set *isl_schedule_tree_band_get_ast_build_options( __isl_keep isl_schedule_tree *tree) { … } /* Replace the AST build options associated to band tree root by "options". * Updated the anchored field if the anchoredness of the root node itself * changes. */ __isl_give isl_schedule_tree *isl_schedule_tree_band_set_ast_build_options( __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *options) { … } /* Return the "isolate" option associated to the band tree root of "tree", * which is assumed to appear at schedule depth "depth". */ __isl_give isl_set *isl_schedule_tree_band_get_ast_isolate_option( __isl_keep isl_schedule_tree *tree, int depth) { … } /* Return the context of the context tree root. */ __isl_give isl_set *isl_schedule_tree_context_get_context( __isl_keep isl_schedule_tree *tree) { … } /* Return the domain of the domain tree root. */ __isl_give isl_union_set *isl_schedule_tree_domain_get_domain( __isl_keep isl_schedule_tree *tree) { … } /* Replace the domain of domain tree root "tree" by "domain". */ __isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain( __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain) { … } /* Return the contraction of the expansion tree root. */ __isl_give isl_union_pw_multi_aff *isl_schedule_tree_expansion_get_contraction( __isl_keep isl_schedule_tree *tree) { … } /* Return the expansion of the expansion tree root. */ __isl_give isl_union_map *isl_schedule_tree_expansion_get_expansion( __isl_keep isl_schedule_tree *tree) { … } /* Replace the contraction and the expansion of the expansion tree root "tree" * by "contraction" and "expansion". */ __isl_give isl_schedule_tree * isl_schedule_tree_expansion_set_contraction_and_expansion( __isl_take isl_schedule_tree *tree, __isl_take isl_union_pw_multi_aff *contraction, __isl_take isl_union_map *expansion) { … } /* Return the extension of the extension tree root. */ __isl_give isl_union_map *isl_schedule_tree_extension_get_extension( __isl_take isl_schedule_tree *tree) { … } /* Replace the extension of extension tree root "tree" by "extension". */ __isl_give isl_schedule_tree *isl_schedule_tree_extension_set_extension( __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension) { … } /* Return the filter of the filter tree root. */ __isl_give isl_union_set *isl_schedule_tree_filter_get_filter( __isl_keep isl_schedule_tree *tree) { … } /* Replace the filter of the filter tree root by "filter". */ __isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter( __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter) { … } /* Return the guard of the guard tree root. */ __isl_give isl_set *isl_schedule_tree_guard_get_guard( __isl_take isl_schedule_tree *tree) { … } /* Return the mark identifier of the mark tree root "tree". */ __isl_give isl_id *isl_schedule_tree_mark_get_id( __isl_keep isl_schedule_tree *tree) { … } /* Set dim to the range dimension of "map" and abort the search. */ static isl_stat set_range_dim(__isl_take isl_map *map, void *user) { … } /* Return the dimension of the range of "umap". * "umap" is assumed not to be empty and * all maps inside "umap" are assumed to have the same range. * * We extract the range dimension from the first map in "umap". */ static isl_size range_dim(__isl_keep isl_union_map *umap) { … } /* Append an "extra" number of zeros to the range of "umap" and * return the result. */ static __isl_give isl_union_map *append_range(__isl_take isl_union_map *umap, int extra) { … } /* Should we skip the root of "tree" while looking for the first * descendant with schedule information? * That is, is it impossible to derive any information about * the iteration domain from this node? * * We do not want to skip leaf or error nodes because there is * no point in looking any deeper from these nodes. * We can only extract partial iteration domain information * from an extension node, but extension nodes are not supported * by the caller and it will error out on them. */ static isl_bool domain_less(__isl_keep isl_schedule_tree *tree) { … } /* Move down to the first descendant of "tree" that contains any schedule * information or return "leaf" if there is no such descendant. */ __isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant( __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf) { … } static __isl_give isl_union_map *subtree_schedule_extend( __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer); /* Extend the schedule map "outer" with the subtree schedule * of the (single) child of "tree", if any. * * If "tree" does not have any descendants (apart from those that * do not carry any schedule information), then we simply return "outer". * Otherwise, we extend the schedule map "outer" with the subtree schedule * of the single child. */ static __isl_give isl_union_map *subtree_schedule_extend_child( __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) { … } /* Extract the parameter space from one of the children of "tree", * which are assumed to be filters. */ static __isl_give isl_space *extract_space_from_filter_child( __isl_keep isl_schedule_tree *tree) { … } /* Extend the schedule map "outer" with the subtree schedule * of a set or sequence node. * * The schedule for the set or sequence node itself is composed of * pieces of the form * * filter -> [] * * or * * filter -> [index] * * The first form is used if there is only a single child or * if the current node is a set node and the schedule_separate_components * option is not set. * * Each of the pieces above is extended with the subtree schedule of * the child of the corresponding filter, if any, padded with zeros * to ensure that all pieces have the same range dimension. */ static __isl_give isl_union_map *subtree_schedule_extend_from_children( __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) { … } /* Extend the schedule map "outer" with the subtree schedule of "tree". * * If the root of the tree is a set or a sequence, then we extend * the schedule map in subtree_schedule_extend_from_children. * Otherwise, we extend the schedule map with the partial schedule * corresponding to the root of the tree and then continue with * the single child of this root. * In the special case of an expansion, the schedule map is "extended" * by applying the expansion to the domain of the schedule map. */ static __isl_give isl_union_map *subtree_schedule_extend( __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer) { … } static __isl_give isl_union_set *initial_domain( __isl_keep isl_schedule_tree *tree); /* Extract a universe domain from the children of the tree root "tree", * which is a set or sequence, meaning that its children are filters. * In particular, return the union of the universes of the filters. */ static __isl_give isl_union_set *initial_domain_from_children( __isl_keep isl_schedule_tree *tree) { … } /* Extract a universe domain from the tree root "tree". * The caller is responsible for making sure that this node * would not be skipped by isl_schedule_tree_first_schedule_descendant * and that it is not a leaf node. */ static __isl_give isl_union_set *initial_domain( __isl_keep isl_schedule_tree *tree) { … } /* Return the subtree schedule of a node that contains some schedule * information, i.e., a node that would not be skipped by * isl_schedule_tree_first_schedule_descendant and that is not a leaf. * * If the tree contains any expansions, then the returned subtree * schedule is formulated in terms of the expanded domains. * The tree is not allowed to contain any extension nodes. * * We start with an initial zero-dimensional subtree schedule based * on the domain information in the root node and then extend it * based on the schedule information in the root node and its descendants. */ __isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map( __isl_keep isl_schedule_tree *tree) { … } /* Multiply the partial schedule of the band root node of "tree" * with the factors in "mv". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_scale( __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) { … } /* Divide the partial schedule of the band root node of "tree" * by the factors in "mv". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down( __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) { … } /* Reduce the partial schedule of the band root node of "tree" * modulo the factors in "mv". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_mod( __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv) { … } /* Shift the partial schedule of the band root node of "tree" by "shift". */ __isl_give isl_schedule_tree *isl_schedule_tree_band_shift( __isl_take isl_schedule_tree *tree, __isl_take isl_multi_union_pw_aff *shift) { … } /* Given two trees with sequence roots, replace the child at position * "pos" of "tree" with the children of "child". */ __isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice( __isl_take isl_schedule_tree *tree, int pos, __isl_take isl_schedule_tree *child) { … } /* Tile the band root node of "tree" with tile sizes "sizes". * * We duplicate the band node, change the schedule of one of them * to the tile schedule and the other to the point schedule and then * attach the point band as a child to the tile band. */ __isl_give isl_schedule_tree *isl_schedule_tree_band_tile( __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes) { … } /* Given an isolate AST generation option "isolate" for a band of size pos + n, * return the corresponding option for a band covering the first "pos" * members. * * The input isolate option is of the form * * isolate[[flattened outer bands] -> [pos; n]] * * The output isolate option is of the form * * isolate[[flattened outer bands] -> [pos]] */ static __isl_give isl_set *isolate_initial(__isl_keep isl_set *isolate, int pos, int n) { … } /* Given an isolate AST generation option "isolate" for a band of size pos + n, * return the corresponding option for a band covering the final "n" * members within a band covering the first "pos" members. * * The input isolate option is of the form * * isolate[[flattened outer bands] -> [pos; n]] * * The output isolate option is of the form * * isolate[[flattened outer bands; pos] -> [n]] * * * The range is first split into * * isolate[[flattened outer bands] -> [[pos] -> [n]]] * * and then the first pos members are moved to the domain * * isolate[[[flattened outer bands] -> [pos]] -> [n]] * * after which the domain is flattened to obtain the desired output. */ static __isl_give isl_set *isolate_final(__isl_keep isl_set *isolate, int pos, int n) { … } /* Split the band root node of "tree" into two nested band nodes, * one with the first "pos" dimensions and * one with the remaining dimensions. * The tree is itself positioned at schedule depth "depth". * * The loop AST generation type options and the isolate option * are split over the two band nodes. */ __isl_give isl_schedule_tree *isl_schedule_tree_band_split( __isl_take isl_schedule_tree *tree, int pos, int depth) { … } /* Attach "tree2" at each of the leaves of "tree1". * * If "tree1" does not have any explicit children, then make "tree2" * its single child. Otherwise, attach "tree2" to the leaves of * each of the children of "tree1". */ __isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves( __isl_take isl_schedule_tree *tree1, __isl_take isl_schedule_tree *tree2) { … } /* 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) { … } /* 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) { … } /* 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) { … } /* 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 currently do not handle expansion nodes. * * 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) { … } /* 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) { … } /* Are any members in "band" marked coincident? */ static isl_bool any_coincident(__isl_keep isl_schedule_band *band) { … } /* Print the band node "band" to "p". * * The permutable and coincident properties are only printed if they * are different from the defaults. * The coincident property is always printed in YAML flow style. */ static __isl_give isl_printer *print_tree_band(__isl_take isl_printer *p, __isl_keep isl_schedule_band *band) { … } #undef BASE #define BASE … #define isl_str … #include "print_yaml_field_templ.c" #undef BASE #define BASE … #include "print_yaml_field_templ.c" #undef BASE #define BASE … #include "print_yaml_field_templ.c" #undef BASE #define BASE … #include "print_yaml_field_templ.c" #undef BASE #define BASE … #include "print_yaml_field_templ.c" /* Print "tree" to "p". * * If "n_ancestor" is non-negative, then "child_pos" contains the child * positions of a descendant of the current node that should be marked * (by the comment "YOU ARE HERE"). In particular, if "n_ancestor" * is zero, then the current node should be marked. * The marking is only printed in YAML block format. * * Implicit leaf nodes are not printed, except if they correspond * to the node that should be marked. */ __isl_give isl_printer *isl_printer_print_schedule_tree_mark( __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree, int n_ancestor, int *child_pos) { … } /* Print "tree" to "p". */ __isl_give isl_printer *isl_printer_print_schedule_tree( __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree) { … } void isl_schedule_tree_dump(__isl_keep isl_schedule_tree *tree) { … }