/* * Copyright 2013-2014 Ecole Normale Superieure * Copyright 2014 INRIA Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, * B.P. 105 - 78153 Le Chesnay, France */ #include <string.h> #include <isl/val.h> #include <isl/space.h> #include <isl/map.h> #include <isl/schedule_node.h> #include <isl_schedule_band.h> #include <isl_schedule_private.h> isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band) { … } /* Return a new uninitialized isl_schedule_band. */ static __isl_give isl_schedule_band *isl_schedule_band_alloc(isl_ctx *ctx) { … } /* Return a new isl_schedule_band with partial schedule "mupa". * First replace "mupa" by its greatest integer part to ensure * that the schedule is always integral. * The band is not marked permutable, the dimensions are not * marked coincident and the AST build options are empty. * Since there are no build options, the node is not anchored. */ __isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff( __isl_take isl_multi_union_pw_aff *mupa) { … } /* Create a duplicate of the given isl_schedule_band. */ __isl_give isl_schedule_band *isl_schedule_band_dup( __isl_keep isl_schedule_band *band) { … } /* Return an isl_schedule_band that is equal to "band" and that has only * a single reference. */ __isl_give isl_schedule_band *isl_schedule_band_cow( __isl_take isl_schedule_band *band) { … } /* Return a new reference to "band". */ __isl_give isl_schedule_band *isl_schedule_band_copy( __isl_keep isl_schedule_band *band) { … } /* Free a reference to "band" and return NULL. */ __isl_null isl_schedule_band *isl_schedule_band_free( __isl_take isl_schedule_band *band) { … } /* Are "band1" and "band2" obviously equal? */ isl_bool isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1, __isl_keep isl_schedule_band *band2) { … } /* Return the number of scheduling dimensions in the band. */ isl_size isl_schedule_band_n_member(__isl_keep isl_schedule_band *band) { … } /* Is the given scheduling dimension coincident within the band and * with respect to the coincidence constraints? */ isl_bool isl_schedule_band_member_get_coincident( __isl_keep isl_schedule_band *band, int pos) { … } /* Mark the given scheduling dimension as being coincident or not * according to "coincident". */ __isl_give isl_schedule_band *isl_schedule_band_member_set_coincident( __isl_take isl_schedule_band *band, int pos, int coincident) { … } /* Is the schedule band mark permutable? */ isl_bool isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band) { … } /* Mark the schedule band permutable or not according to "permutable"? */ __isl_give isl_schedule_band *isl_schedule_band_set_permutable( __isl_take isl_schedule_band *band, int permutable) { … } /* Is the band node "node" anchored? That is, does it reference * the outer band nodes? */ int isl_schedule_band_is_anchored(__isl_keep isl_schedule_band *band) { … } /* Return the schedule space of the band. */ __isl_give isl_space *isl_schedule_band_get_space( __isl_keep isl_schedule_band *band) { … } /* Intersect the domain of the band schedule of "band" with "domain". */ __isl_give isl_schedule_band *isl_schedule_band_intersect_domain( __isl_take isl_schedule_band *band, __isl_take isl_union_set *domain) { … } /* Return the schedule of the band in isolation. */ __isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule( __isl_keep isl_schedule_band *band) { … } /* Replace the schedule of "band" by "schedule". */ __isl_give isl_schedule_band *isl_schedule_band_set_partial_schedule( __isl_take isl_schedule_band *band, __isl_take isl_multi_union_pw_aff *schedule) { … } /* Return the loop AST generation type for the band member of "band" * at position "pos". */ enum isl_ast_loop_type isl_schedule_band_member_get_ast_loop_type( __isl_keep isl_schedule_band *band, int pos) { … } /* Set the loop AST generation type for the band member of "band" * at position "pos" to "type". */ __isl_give isl_schedule_band *isl_schedule_band_member_set_ast_loop_type( __isl_take isl_schedule_band *band, int pos, enum isl_ast_loop_type type) { … } /* Return the loop AST generation type for the band member of "band" * at position "pos" for the part that has been isolated by the isolate option. */ enum isl_ast_loop_type isl_schedule_band_member_get_isolate_ast_loop_type( __isl_keep isl_schedule_band *band, int pos) { … } /* Set the loop AST generation type for the band member of "band" * at position "pos" to "type" for the part that has been isolated * by the isolate option. */ __isl_give isl_schedule_band * isl_schedule_band_member_set_isolate_ast_loop_type( __isl_take isl_schedule_band *band, int pos, enum isl_ast_loop_type type) { … } static const char *option_str[] = …; /* Given a parameter space "space", extend it to a set space * * { type[x] } * * or * * { [isolate[] -> type[x]] } * * depending on whether "isolate" is set. * These can be used to encode loop AST generation options of the given type. */ static __isl_give isl_space *loop_type_space(__isl_take isl_space *space, enum isl_ast_loop_type type, int isolate) { … } /* Add encodings of the "n" loop AST generation options "type" to "options". * If "isolate" is set, then these options refer to the isolated part. * * In particular, for each sequence of consecutive identical types "t", * different from the default, add an option * * { t[x] : first <= x <= last } * * or * * { [isolate[] -> t[x]] : first <= x <= last } */ static __isl_give isl_union_set *add_loop_types( __isl_take isl_union_set *options, int n, enum isl_ast_loop_type *type, int isolate) { … } /* Return the AST build options associated to "band". */ __isl_give isl_union_set *isl_schedule_band_get_ast_build_options( __isl_keep isl_schedule_band *band) { … } /* Internal data structure for not(). */ struct isl_not_data { … }; /* Does "set" not satisfy data->is()? */ static isl_bool not(__isl_keep isl_set *set, void *user) { … } /* Does "uset" contain any set that satisfies "is"? * In other words, is it not the case that all of them do not satisfy "is"? */ static isl_bool has_any(__isl_keep isl_union_set *uset, isl_bool (*is)(__isl_keep isl_set *set)) { … } /* Does "set" live in a space of the form * * isolate[[...] -> [...]] * * ? */ static isl_bool is_isolate(__isl_keep isl_set *set) { … } /* Does "options" include an option of the ofrm * * isolate[[...] -> [...]] * * ? */ static isl_bool has_isolate_option(__isl_keep isl_union_set *options) { … } /* Does "set" encode a loop AST generation option? */ static isl_bool is_loop_type_option(__isl_keep isl_set *set) { … } /* Does "set" encode a loop AST generation option for the isolated part? * That is, is of the form * * { [isolate[] -> t[x]] } * * with t equal to "atomic", "unroll" or "separate"? */ static isl_bool is_isolate_loop_type_option(__isl_keep isl_set *set) { … } /* Does "options" encode any loop AST generation options * for the isolated part? */ static isl_bool has_isolate_loop_type_options(__isl_keep isl_union_set *options) { … } /* Does "options" encode any loop AST generation options? */ static isl_bool has_loop_type_options(__isl_keep isl_union_set *options) { … } /* Extract the loop AST generation type for the band member * at position "pos" from "options". * If "isolate" is set, then extract the loop types for the isolated part. */ static enum isl_ast_loop_type extract_loop_type( __isl_keep isl_union_set *options, int pos, int isolate) { … } /* Extract the loop AST generation types for the members of "band" * from "options" and store them in band->loop_type. * Return -1 on error. */ static int extract_loop_types(__isl_keep isl_schedule_band *band, __isl_keep isl_union_set *options) { … } /* Extract the loop AST generation types for the members of "band" * from "options" for the isolated part and * store them in band->isolate_loop_type. * Return -1 on error. */ static int extract_isolate_loop_types(__isl_keep isl_schedule_band *band, __isl_keep isl_union_set *options) { … } /* Construct universe sets of the spaces that encode loop AST generation * types (for the isolated part if "isolate" is set). That is, construct * * { atomic[x]; separate[x]; unroll[x] } * * or * * { [isolate[] -> atomic[x]]; [isolate[] -> separate[x]]; * [isolate[] -> unroll[x]] } */ static __isl_give isl_union_set *loop_types(__isl_take isl_space *space, int isolate) { … } /* Remove all elements from spaces that encode loop AST generation types * from "options". */ static __isl_give isl_union_set *clear_loop_types( __isl_take isl_union_set *options) { … } /* Remove all elements from spaces that encode loop AST generation types * for the isolated part from "options". */ static __isl_give isl_union_set *clear_isolate_loop_types( __isl_take isl_union_set *options) { … } /* Replace the AST build options associated to "band" by "options". * If there are any loop AST generation type options, then they * are extracted and stored in band->loop_type. Otherwise, * band->loop_type is removed to indicate that the default applies * to all members. Similarly for the loop AST generation type options * for the isolated part, which are stored in band->isolate_loop_type. * The remaining options are stored in band->ast_build_options. * * Set anchored if the options include an isolate option since the * domain of the wrapped map references the outer band node schedules. */ __isl_give isl_schedule_band *isl_schedule_band_set_ast_build_options( __isl_take isl_schedule_band *band, __isl_take isl_union_set *options) { … } /* Return the "isolate" option associated to "band", assuming * it at appears at schedule depth "depth". * * The isolate option is of the form * * isolate[[flattened outer bands] -> band] */ __isl_give isl_set *isl_schedule_band_get_ast_isolate_option( __isl_keep isl_schedule_band *band, int depth) { … } /* Replace the option "drop" in the AST build options by "add". * That is, remove "drop" and add "add". */ __isl_give isl_schedule_band *isl_schedule_band_replace_ast_build_option( __isl_take isl_schedule_band *band, __isl_take isl_set *drop, __isl_take isl_set *add) { … } /* Multiply the partial schedule of "band" with the factors in "mv". * Replace the result by its greatest integer part to ensure * that the schedule is always integral. */ __isl_give isl_schedule_band *isl_schedule_band_scale( __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) { … } /* Divide the partial schedule of "band" by the factors in "mv". * Replace the result by its greatest integer part to ensure * that the schedule is always integral. */ __isl_give isl_schedule_band *isl_schedule_band_scale_down( __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) { … } /* Reduce the partial schedule of "band" modulo the factors in "mv". */ __isl_give isl_schedule_band *isl_schedule_band_mod( __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv) { … } /* Shift the partial schedule of "band" by "shift" after checking * that the domain of the partial schedule would not be affected * by this shift. */ __isl_give isl_schedule_band *isl_schedule_band_shift( __isl_take isl_schedule_band *band, __isl_take isl_multi_union_pw_aff *shift) { … } /* Given the schedule of a band, construct the corresponding * schedule for the tile loops based on the given tile sizes * and return the result. * * If the scale tile loops options is set, then the tile loops * are scaled by the tile sizes. * * That is replace each schedule dimension "i" by either * "floor(i/s)" or "s * floor(i/s)". */ static isl_multi_union_pw_aff *isl_multi_union_pw_aff_tile( __isl_take isl_multi_union_pw_aff *sched, __isl_take isl_multi_val *sizes) { … } /* Replace "band" by a band corresponding to the tile loops of a tiling * with the given tile sizes. */ __isl_give isl_schedule_band *isl_schedule_band_tile( __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes) { … } /* Replace "band" by a band corresponding to the point loops of a tiling * with the given tile sizes. * "tile" is the corresponding tile loop band. * * If the shift point loops option is set, then the point loops * are shifted to start at zero. That is, each schedule dimension "i" * is replaced by "i - s * floor(i/s)". * The expression "floor(i/s)" (or "s * floor(i/s)") is extracted from * the tile band. * * Otherwise, the band is left untouched. */ __isl_give isl_schedule_band *isl_schedule_band_point( __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile, __isl_take isl_multi_val *sizes) { … } /* Drop the "n" dimensions starting at "pos" from "band". * * We apply the transformation even if "n" is zero to ensure consistent * behavior with respect to changes in the schedule space. * * The caller is responsible for updating the isolate option. */ __isl_give isl_schedule_band *isl_schedule_band_drop( __isl_take isl_schedule_band *band, int pos, int n) { … } /* Reset the user pointer on all identifiers of parameters and tuples * in "band". */ __isl_give isl_schedule_band *isl_schedule_band_reset_user( __isl_take isl_schedule_band *band) { … } /* Align the parameters of "band" to those of "space". */ __isl_give isl_schedule_band *isl_schedule_band_align_params( __isl_take isl_schedule_band *band, __isl_take isl_space *space) { … } /* Compute the pullback of "band" by the function represented by "upma". * In other words, plug in "upma" in the iteration domains of "band". */ __isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff( __isl_take isl_schedule_band *band, __isl_take isl_union_pw_multi_aff *upma) { … } /* Compute the gist of "band" with respect to "context". * In particular, compute the gist of the associated partial schedule. */ __isl_give isl_schedule_band *isl_schedule_band_gist( __isl_take isl_schedule_band *band, __isl_take isl_union_set *context) { … }