LCOV - code coverage report
Current view: top level - metalib_isl - isl_union_multi.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 0 167 0.0 %
Date: 2018-11-01 11:27:00 Functions: 0 22 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2010      INRIA Saclay
       3             :  * Copyright 2013      Ecole Normale Superieure
       4             :  * Copyright 2015      INRIA Paris-Rocquencourt
       5             :  *
       6             :  * Use of this software is governed by the MIT license
       7             :  *
       8             :  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
       9             :  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
      10             :  * 91893 Orsay, France
      11             :  * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
      12             :  * and INRIA Paris-Rocquencourt, Domaine de Voluceau, Rocquenqourt, B.P. 105,
      13             :  * 78153 Le Chesnay Cedex France
      14             :  */
      15             : 
      16             : #include <isl_hash_private.h>
      17             : #include <isl_union_macro.h>
      18             : 
      19             : /* A group of expressions defined over the same domain space "domain_space".
      20             :  * The entries of "part_table" are the individual expressions,
      21             :  * keyed on the entire space of the expression.
      22             :  *
      23             :  * Each UNION has its own groups, so there can only ever be a single
      24             :  * reference to each group.
      25             :  */
      26             : S(UNION,group) {
      27             :         isl_space *domain_space;
      28             :         struct isl_hash_table   part_table;
      29             : };
      30             : 
      31             : /* A union of expressions defined over different disjoint domains.
      32             :  * "space" describes the parameters.
      33             :  * The entries of "table" are keyed on the domain space of the entry and
      34             :  * contain groups of expressions that are defined over the same domain space.
      35             :  */
      36             : struct UNION {
      37             :         int ref;
      38             :         isl_space *space;
      39             : 
      40             :         struct isl_hash_table   table;
      41             : };
      42             : 
      43             : /* Internal data structure for isl_union_*_foreach_group.
      44             :  * "fn" is the function that needs to be called on each group.
      45             :  */
      46             : S(UNION,foreach_group_data)
      47             : {
      48             :         isl_stat (*fn)(__isl_keep S(UNION,group) *group, void *user);
      49             :         void *user;
      50             : };
      51             : 
      52             : /* Call data->fn on the group stored at *entry.
      53             :  */
      54           0 : static isl_stat FN(UNION,call_on_group)(void **entry, void *user)
      55             : {
      56           0 :         S(UNION,group) *group = *entry;
      57             :         S(UNION,foreach_group_data) *data;
      58             : 
      59           0 :         data = (S(UNION,foreach_group_data) *) user;
      60           0 :         return data->fn(group, data->user);
      61             : }
      62             : 
      63             : /* Call "fn" on each group of expressions in "u".
      64             :  */
      65           0 : static isl_stat FN(UNION,foreach_group)(__isl_keep UNION *u,
      66             :         isl_stat (*fn)(__isl_keep S(UNION,group) *group, void *user),
      67             :         void *user)
      68             : {
      69           0 :         S(UNION,foreach_group_data) data = { fn, user };
      70             : 
      71           0 :         if (!u)
      72           0 :                 return isl_stat_error;
      73             : 
      74           0 :         return isl_hash_table_foreach(u->space->ctx, &u->table,
      75             :                                       &FN(UNION,call_on_group), &data);
      76             : }
      77             : 
      78             : /* A isl_union_*_foreach_group callback for counting the total number
      79             :  * of expressions in a UNION.  Add the number of expressions in "group"
      80             :  * to *n.
      81             :  */
      82           0 : static isl_stat FN(UNION,count_part)(__isl_keep S(UNION,group) *group,
      83             :         void *user)
      84             : {
      85           0 :         int *n = user;
      86             : 
      87           0 :         if (!group)
      88           0 :                 return isl_stat_error;
      89             : 
      90           0 :         *n += group->part_table.n;
      91           0 :         return isl_stat_ok;
      92             : }
      93             : 
      94             : /* Return the number of base expressions in "u".
      95             :  */
      96           0 : int FN(FN(UNION,n),BASE)(__isl_keep UNION *u)
      97             : {
      98             :         int n;
      99             : 
     100           0 :         n = 0;
     101           0 :         if (FN(UNION,foreach_group)(u, &FN(UNION,count_part), &n) < 0)
     102           0 :                 n = -1;
     103           0 :         return n;
     104             : }
     105             : 
     106             : /* Free an entry in a group of expressions.
     107             :  * Each entry in such a group is a single expression.
     108             :  */
     109           0 : static isl_stat FN(UNION,free_group_entry)(void **entry, void *user)
     110             : {
     111           0 :         PART *part = *entry;
     112             : 
     113           0 :         FN(PART,free)(part);
     114           0 :         return isl_stat_ok;
     115             : }
     116             : 
     117             : /* Free all memory allocated for "group" and return NULL.
     118             :  */
     119           0 : static __isl_null S(UNION,group) *FN(UNION,group_free)(
     120             :         __isl_take S(UNION,group) *group)
     121             : {
     122             :         isl_ctx *ctx;
     123             : 
     124           0 :         if (!group)
     125           0 :                 return NULL;
     126             : 
     127           0 :         ctx = isl_space_get_ctx(group->domain_space);
     128           0 :         isl_hash_table_foreach(ctx, &group->part_table,
     129             :                                 &FN(UNION,free_group_entry), NULL);
     130           0 :         isl_hash_table_clear(&group->part_table);
     131           0 :         isl_space_free(group->domain_space);
     132           0 :         free(group);
     133           0 :         return NULL;
     134             : }
     135             : 
     136             : /* Allocate a group of expressions defined over the same domain space
     137             :  * with domain space "domain_space" and initial size "size".
     138             :  */
     139           0 : static __isl_give S(UNION,group) *FN(UNION,group_alloc)(
     140             :         __isl_take isl_space *domain_space, int size)
     141             : {
     142             :         isl_ctx *ctx;
     143             :         S(UNION,group) *group;
     144             : 
     145           0 :         if (!domain_space)
     146           0 :                 return NULL;
     147           0 :         ctx = isl_space_get_ctx(domain_space);
     148           0 :         group = isl_calloc_type(ctx, S(UNION,group));
     149           0 :         if (!group)
     150           0 :                 goto error;
     151           0 :         group->domain_space = domain_space;
     152           0 :         if (isl_hash_table_init(ctx, &group->part_table, size) < 0)
     153           0 :                 return FN(UNION,group_free)(group);
     154             : 
     155           0 :         return group;
     156             : error:
     157           0 :         isl_space_free(domain_space);
     158           0 :         return NULL;
     159             : }
     160             : 
     161             : /* Is the space of "entry" equal to "space"?
     162             :  */
     163           0 : static int FN(UNION,has_space)(const void *entry, const void *val)
     164             : {
     165           0 :         PART *part = (PART *) entry;
     166           0 :         isl_space *space = (isl_space *) val;
     167             : 
     168           0 :         return isl_space_is_equal(part->dim, space);
     169             : }
     170             : 
     171             : /* Return a group equal to "group", but with a single reference.
     172             :  * Since all groups have only a single reference, simply return "group".
     173             :  */
     174           0 : static __isl_give S(UNION,group) *FN(UNION,group_cow)(
     175             :         __isl_take S(UNION,group) *group)
     176             : {
     177           0 :         return group;
     178             : }
     179             : 
     180             : S(UNION,foreach_data)
     181             : {
     182             :         isl_stat (*fn)(__isl_take PART *part, void *user);
     183             :         void *user;
     184             : };
     185             : 
     186           0 : static isl_stat FN(UNION,call_on_copy)(void **entry, void *user)
     187             : {
     188           0 :         PART *part = *entry;
     189           0 :         S(UNION,foreach_data) *data = (S(UNION,foreach_data) *) user;
     190             : 
     191           0 :         part = FN(PART,copy)(part);
     192           0 :         if (!part)
     193           0 :                 return isl_stat_error;
     194           0 :         return data->fn(part, data->user);
     195             : }
     196             : 
     197             : /* Call data->fn on a copy of each expression in "group".
     198             :  */
     199           0 : static isl_stat FN(UNION,group_call_on_copy)(__isl_keep S(UNION,group) *group,
     200             :         void *user)
     201             : {
     202             :         isl_ctx *ctx;
     203             : 
     204           0 :         if (!group)
     205           0 :                 return isl_stat_error;
     206             : 
     207           0 :         ctx = isl_space_get_ctx(group->domain_space);
     208           0 :         return isl_hash_table_foreach(ctx, &group->part_table,
     209             :                                       &FN(UNION,call_on_copy), user);
     210             : }
     211             : 
     212           0 : isl_stat FN(FN(UNION,foreach),BASE)(__isl_keep UNION *u,
     213             :         isl_stat (*fn)(__isl_take PART *part, void *user), void *user)
     214             : {
     215           0 :         S(UNION,foreach_data) data = { fn, user };
     216             : 
     217           0 :         if (!u)
     218           0 :                 return isl_stat_error;
     219             : 
     220           0 :         return FN(UNION,foreach_group)(u, &FN(UNION,group_call_on_copy), &data);
     221             : }
     222             : 
     223             : /* Is the domain space of the group of expressions at "entry"
     224             :  * equal to "space"?
     225             :  */
     226           0 : static int FN(UNION,group_has_domain_space)(const void *entry, const void *val)
     227             : {
     228           0 :         S(UNION,group) *group = (S(UNION,group) *) entry;
     229           0 :         isl_space *space = (isl_space *) val;
     230             : 
     231           0 :         return isl_space_is_domain_internal(group->domain_space, space);
     232             : }
     233             : 
     234             : /* Return the entry, if any, in "u" that lives in "space".
     235             :  * If "reserve" is set, then an entry is created if it does not exist yet.
     236             :  * Return NULL on error and isl_hash_table_entry_none if no entry was found.
     237             :  * Note that when "reserve" is set, the function will never return
     238             :  * isl_hash_table_entry_none.
     239             :  *
     240             :  * First look for the group of expressions with the same domain space,
     241             :  * creating one if needed.
     242             :  * Then look for the expression living in the specified space in that group.
     243             :  */
     244           0 : static struct isl_hash_table_entry *FN(UNION,find_part_entry)(
     245             :         __isl_keep UNION *u, __isl_keep isl_space *space, int reserve)
     246             : {
     247             :         isl_ctx *ctx;
     248             :         uint32_t hash;
     249             :         struct isl_hash_table_entry *group_entry, *part_entry;
     250             :         S(UNION,group) *group;
     251             : 
     252           0 :         if (!u || !space)
     253           0 :                 return NULL;
     254             : 
     255           0 :         ctx = FN(UNION,get_ctx)(u);
     256           0 :         hash = isl_space_get_domain_hash(space);
     257           0 :         group_entry = isl_hash_table_find(ctx, &u->table, hash,
     258             :                             &FN(UNION,group_has_domain_space), space, reserve);
     259           0 :         if (!group_entry)
     260           0 :                 return reserve ? NULL : isl_hash_table_entry_none;
     261           0 :         if (reserve && !group_entry->data) {
     262           0 :                 isl_space *domain = isl_space_domain(isl_space_copy(space));
     263           0 :                 group = FN(UNION,group_alloc)(domain, 1);
     264           0 :                 group_entry->data = group;
     265             :         } else {
     266           0 :                 group = group_entry->data;
     267           0 :                 if (reserve)
     268           0 :                         group = FN(UNION,group_cow)(group);
     269             :         }
     270           0 :         if (!group)
     271           0 :                 return NULL;
     272           0 :         hash = isl_space_get_hash(space);
     273           0 :         part_entry = isl_hash_table_find(ctx, &group->part_table, hash,
     274             :                                 &FN(UNION,has_space), space, reserve);
     275           0 :         if (!reserve && !part_entry)
     276           0 :                 return isl_hash_table_entry_none;
     277           0 :         return part_entry;
     278             : }
     279             : 
     280             : /* Remove "part_entry" from the hash table of "u".
     281             :  *
     282             :  * First look the group_entry in "u" holding the group that
     283             :  * contains "part_entry".  Remove "part_entry" from that group.
     284             :  * If the group becomes empty, then also remove the group_entry from "u".
     285             :  */
     286           0 : static __isl_give UNION *FN(UNION,remove_part_entry)(__isl_take UNION *u,
     287             :         struct isl_hash_table_entry *part_entry)
     288             : {
     289             :         isl_ctx *ctx;
     290             :         uint32_t hash;
     291             :         PART *part;
     292             :         struct isl_hash_table_entry *group_entry;
     293             :         S(UNION,group) *group;
     294             : 
     295           0 :         if (!u || !part_entry)
     296           0 :                 return FN(UNION,free)(u);
     297             : 
     298           0 :         part = part_entry->data;
     299           0 :         ctx = FN(UNION,get_ctx)(u);
     300           0 :         hash = isl_space_get_domain_hash(part->dim);
     301           0 :         group_entry = isl_hash_table_find(ctx, &u->table, hash,
     302           0 :                             &FN(UNION,group_has_domain_space), part->dim, 0);
     303           0 :         if (!group_entry)
     304           0 :                 isl_die(ctx, isl_error_internal, "missing group",
     305             :                         return FN(UNION,free)(u));
     306           0 :         group = group_entry->data;
     307           0 :         isl_hash_table_remove(ctx, &group->part_table, part_entry);
     308           0 :         FN(PART,free)(part);
     309             : 
     310           0 :         if (group->part_table.n != 0)
     311           0 :                 return u;
     312             : 
     313           0 :         isl_hash_table_remove(ctx, &u->table, group_entry);
     314           0 :         FN(UNION,group_free)(group);
     315             : 
     316           0 :         return u;
     317             : }
     318             : 
     319             : /* Are the domains of "part1" and "part2" disjoint?
     320             :  */
     321           0 : static isl_bool FN(UNION,disjoint_domain)(__isl_keep PART *part1,
     322             :         __isl_keep PART *part2)
     323             : {
     324             :         isl_set *dom1, *dom2;
     325             :         isl_bool disjoint;
     326             : 
     327           0 :         if (!part1 || !part2)
     328           0 :                 return isl_bool_error;
     329           0 :         dom1 = FN(PART,domain)(FN(PART,copy)(part1));
     330           0 :         dom2 = FN(PART,domain)(FN(PART,copy)(part2));
     331           0 :         disjoint = isl_set_is_disjoint(dom1, dom2);
     332           0 :         isl_set_free(dom1);
     333           0 :         isl_set_free(dom2);
     334             : 
     335           0 :         return disjoint;
     336             : }
     337             : 
     338             : /* Check that the expression at *entry has a domain that is disjoint
     339             :  * from that of "part", unless they also have the same target space.
     340             :  */
     341           0 : static isl_stat FN(UNION,check_disjoint_domain_entry)(void **entry, void *user)
     342             : {
     343           0 :         PART *part = user;
     344           0 :         PART *other = *entry;
     345             :         isl_bool equal;
     346             :         isl_bool disjoint;
     347             : 
     348           0 :         equal = isl_space_is_equal(part->dim, other->dim);
     349           0 :         if (equal < 0)
     350           0 :                 return isl_stat_error;
     351           0 :         if (equal)
     352           0 :                 return isl_stat_ok;
     353             : 
     354           0 :         disjoint = FN(UNION,disjoint_domain)(part, other);
     355           0 :         if (disjoint < 0)
     356           0 :                 return isl_stat_error;
     357           0 :         if (!disjoint)
     358           0 :                 isl_die(FN(PART,get_ctx)(part), isl_error_invalid,
     359             :                         "overlapping domain with other part",
     360             :                         return isl_stat_error);
     361           0 :         return isl_stat_ok;
     362             : }
     363             : 
     364             : /* Check that the domain of "part" is disjoint from the domain of the entries
     365             :  * in "u" that are defined on the same domain space, but have a different
     366             :  * target space.
     367             :  * If there is no group of expressions in "u" with the same domain space,
     368             :  * then everything is fine.  Otherwise, check the individual expressions
     369             :  * in that group.
     370             :  */
     371           0 : static isl_stat FN(UNION,check_disjoint_domain_other)(__isl_keep UNION *u,
     372             :         __isl_keep PART *part)
     373             : {
     374             :         isl_ctx *ctx;
     375             :         uint32_t hash;
     376             :         struct isl_hash_table_entry *group_entry;
     377             :         S(UNION,group) *group;
     378             : 
     379           0 :         if (!u || !part)
     380           0 :                 return isl_stat_error;
     381           0 :         ctx = FN(UNION,get_ctx)(u);
     382           0 :         hash = isl_space_get_domain_hash(part->dim);
     383           0 :         group_entry = isl_hash_table_find(ctx, &u->table, hash,
     384           0 :                             &FN(UNION,group_has_domain_space), part->dim, 0);
     385           0 :         if (!group_entry)
     386           0 :                 return isl_stat_ok;
     387           0 :         group = group_entry->data;
     388           0 :         return isl_hash_table_foreach(ctx, &group->part_table,
     389             :                               &FN(UNION,check_disjoint_domain_entry), part);
     390             : }
     391             : 
     392             : /* Check that the domain of "part1" is disjoint from the domain of "part2".
     393             :  * This check is performed before "part2" is added to a UNION to ensure
     394             :  * that the UNION expression remains a function.
     395             :  */
     396           0 : static isl_stat FN(UNION,check_disjoint_domain)(__isl_keep PART *part1,
     397             :         __isl_keep PART *part2)
     398             : {
     399             :         isl_bool disjoint;
     400             : 
     401           0 :         disjoint = FN(UNION,disjoint_domain)(part1, part2);
     402           0 :         if (disjoint < 0)
     403           0 :                 return isl_stat_error;
     404           0 :         if (!disjoint)
     405           0 :                 isl_die(FN(PART,get_ctx)(part1), isl_error_invalid,
     406             :                         "domain of additional part should be disjoint",
     407             :                         return isl_stat_error);
     408           0 :         return isl_stat_ok;
     409             : }
     410             : 
     411             : /* Internal data structure for isl_union_*_foreach_inplace.
     412             :  * "fn" is the function that needs to be called on each entry.
     413             :  */
     414             : S(UNION,foreach_inplace_data)
     415             : {
     416             :         isl_stat (*fn)(void **entry, void *user);
     417             :         void *user;
     418             : };
     419             : 
     420             : /* isl_union_*_foreach_group callback for calling data->fn on
     421             :  * each part entry in the group.
     422             :  */
     423           0 : static isl_stat FN(UNION,group_call_inplace)(__isl_keep S(UNION,group) *group,
     424             :         void *user)
     425             : {
     426             :         isl_ctx *ctx;
     427             :         S(UNION,foreach_inplace_data) *data;
     428             : 
     429           0 :         if (!group)
     430           0 :                 return isl_stat_error;
     431             : 
     432           0 :         data = (S(UNION,foreach_inplace_data) *) user;
     433           0 :         ctx = isl_space_get_ctx(group->domain_space);
     434           0 :         return isl_hash_table_foreach(ctx, &group->part_table,
     435             :                                       data->fn, data->user);
     436             : }
     437             : 
     438             : /* Call "fn" on each part entry of "u".
     439             :  */
     440           0 : static isl_stat FN(UNION,foreach_inplace)(__isl_keep UNION *u,
     441             :         isl_stat (*fn)(void **part, void *user), void *user)
     442             : {
     443           0 :         S(UNION,foreach_inplace_data) data = { fn, user };
     444             : 
     445           0 :         return FN(UNION,foreach_group)(u, &FN(UNION,group_call_inplace), &data);
     446             : }
     447             : 
     448           0 : static isl_stat FN(UNION,free_u_entry)(void **entry, void *user)
     449             : {
     450           0 :         S(UNION,group) *group = *entry;
     451           0 :         FN(UNION,group_free)(group);
     452           0 :         return isl_stat_ok;
     453             : }
     454             : 
     455             : #include <isl_union_templ.c>

Generated by: LCOV version 1.12