/* * Copyright 2010 INRIA Saclay * Copyright 2013 Ecole Normale Superieure * Copyright 2015 INRIA Paris-Rocquencourt * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France * and INRIA Paris-Rocquencourt, Domaine de Voluceau, Rocquenqourt, B.P. 105, * 78153 Le Chesnay Cedex France */ #include <isl/hash.h> #include <isl_union_macro.h> /* A group of expressions defined over the same domain space "domain_space". * The entries of "part_table" are the individual expressions, * keyed on the entire space of the expression (ignoring parameters). * * Each UNION has its own groups, so there can only ever be a single * reference to each group. */ S(UNION,group) { … }; /* A union of expressions defined over different disjoint domains. * "space" describes the parameters. * The entries of "table" are keyed on the domain space of the entry * (ignoring parameters) and * contain groups of expressions that are defined over the same domain space. */ struct UNION { … }; /* Internal data structure for isl_union_*_foreach_group. * "fn" is the function that needs to be called on each group. */ S(UNION,foreach_group_data) { … }; /* Call data->fn on the group stored at *entry. */ static isl_stat FN(UNION,call_on_group)(void **entry, void *user) { … } /* Call "fn" on each group of expressions in "u". */ static isl_stat FN(UNION,foreach_group)(__isl_keep UNION *u, isl_stat (*fn)(__isl_keep S(UNION,group) *group, void *user), void *user) { … } /* A isl_union_*_foreach_group callback for counting the total number * of expressions in a UNION. Add the number of expressions in "group" * to *n. */ static isl_stat FN(UNION,count_part)(__isl_keep S(UNION,group) *group, void *user) { … } /* Return the number of base expressions in "u". */ isl_size FN(FN(UNION,n),BASE)(__isl_keep UNION *u) { … } /* Free an entry in a group of expressions. * Each entry in such a group is a single expression. */ static isl_stat FN(UNION,free_group_entry)(void **entry, void *user) { … } /* Free all memory allocated for "group" and return NULL. */ static __isl_null S(UNION,group) *FN(UNION,group_free)( __isl_take S(UNION,group) *group) { … } /* Allocate a group of expressions defined over the same domain space * with domain space "domain_space" and initial size "size". */ static __isl_give S(UNION,group) *FN(UNION,group_alloc)( __isl_take isl_space *domain_space, int size) { … } /* Is the space of "entry" equal to "space", ignoring parameters? */ static isl_bool FN(UNION,has_space_tuples)(const void *entry, const void *val) { … } /* Return a group equal to "group", but with a single reference. * Since all groups have only a single reference, simply return "group". */ static __isl_give S(UNION,group) *FN(UNION,group_cow)( __isl_take S(UNION,group) *group) { … } S(UNION,foreach_data) { … }; static isl_stat FN(UNION,call_on_copy)(void **entry, void *user) { … } /* Call data->fn on a copy of each expression in "group". */ static isl_stat FN(UNION,group_call_on_copy)(__isl_keep S(UNION,group) *group, void *user) { … } isl_stat FN(FN(UNION,foreach),BASE)(__isl_keep UNION *u, isl_stat (*fn)(__isl_take PART *part, void *user), void *user) { … } /* Is the domain space of the group of expressions at "entry" * equal to that of "space", ignoring parameters? */ static isl_bool FN(UNION,group_has_same_domain_space_tuples)(const void *entry, const void *val) { … } /* Return the entry, if any, in "u" that lives in "space". * If "reserve" is set, then an entry is created if it does not exist yet. * Return NULL on error and isl_hash_table_entry_none if no entry was found. * Note that when "reserve" is set, the function will never return * isl_hash_table_entry_none. * * First look for the group of expressions with the same domain space, * creating one if needed. * Then look for the expression living in the specified space in that group. */ static struct isl_hash_table_entry *FN(UNION,find_part_entry)( __isl_keep UNION *u, __isl_keep isl_space *space, int reserve) { … } /* Remove "part_entry" from the hash table of "u". * * First look the group_entry in "u" holding the group that * contains "part_entry". Remove "part_entry" from that group. * If the group becomes empty, then also remove the group_entry from "u". */ static __isl_give UNION *FN(UNION,remove_part_entry)(__isl_take UNION *u, struct isl_hash_table_entry *part_entry) { … } /* Are the domains of "part1" and "part2" disjoint? */ static isl_bool FN(UNION,disjoint_domain)(__isl_keep PART *part1, __isl_keep PART *part2) { … } /* Check that the expression at *entry has a domain that is disjoint * from that of "part", unless they also have the same target space. */ static isl_stat FN(UNION,check_disjoint_domain_entry)(void **entry, void *user) { … } /* Check that the domain of "part" is disjoint from the domain of the entries * in "u" that are defined on the same domain space, but have a different * target space. * If there is no group of expressions in "u" with the same domain space, * then everything is fine. Otherwise, check the individual expressions * in that group. */ static isl_stat FN(UNION,check_disjoint_domain_other)(__isl_keep UNION *u, __isl_keep PART *part) { … } /* Check that the domain of "part1" is disjoint from the domain of "part2". * This check is performed before "part2" is added to a UNION to ensure * that the UNION expression remains a function. */ static isl_stat FN(UNION,check_disjoint_domain)(__isl_keep PART *part1, __isl_keep PART *part2) { … } /* Internal data structure for isl_union_*_foreach_inplace. * "fn" is the function that needs to be called on each entry. */ S(UNION,foreach_inplace_data) { … }; /* isl_union_*_foreach_group callback for calling data->fn on * each part entry in the group. */ static isl_stat FN(UNION,group_call_inplace)(__isl_keep S(UNION,group) *group, void *user) { … } /* Call "fn" on each part entry of "u". */ static isl_stat FN(UNION,foreach_inplace)(__isl_keep UNION *u, isl_stat (*fn)(void **part, void *user), void *user) { … } static isl_stat FN(UNION,free_u_entry)(void **entry, void *user) { … } /* Does "u" have an obviously empty definition domain? */ isl_bool FN(UNION,plain_is_empty)(__isl_take UNION *u) { … } /* Set "single" to true if this group of expressions * contains an expression living in exactly one space. */ static isl_stat FN(UNION,group_single_space)(__isl_keep S(UNION,group) *group, void *user) { … } /* Can this union expression be converted to a single base expression? * That is, does it contain a base expression in exactly one space? * In particular, is only one domain space involved and * is only a single expression associated to that domain? */ isl_bool FN(FN(UNION,isa),BASE)(__isl_take UNION *u) { … } /* Callback for isl_union_*_foreach_inplace call * on a union expression with a single base expression. * Store that base expression in "user". * This callback should only be called once * for any given isl_union_*_foreach_inplace call. */ static isl_stat FN(UNION,extract_part)(void **entry, void *user) { … } /* Convert the union expression to its single base expression. */ __isl_give PART *FN(FN(UNION,as),BASE)(__isl_take UNION *u) { … } #include <isl_union_templ.c>