README: update latest release of clang
[pet.git] / array.c
blob3aeacf452245f0b340fb95488c8f085f665c63b3
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2012-2014 Ecole Normale Superieure. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
32 * Leiden University.
35 #include <string.h>
37 #include "array.h"
39 /* Given a partial index expression "base" and an extra index "index",
40 * append the extra index to "base" and return the result.
41 * Additionally, add the constraints that the extra index is non-negative.
42 * If "index" represent a member access, i.e., if its range is a wrapped
43 * relation, then we recursively extend the range of this nested relation.
45 * The inputs "base" and "index", as well as the result, all have
46 * an anonymous zero-dimensional domain.
48 __isl_give isl_multi_pw_aff *pet_array_subscript(
49 __isl_take isl_multi_pw_aff *base, __isl_take isl_pw_aff *index)
51 isl_id *id;
52 isl_set *domain;
53 isl_multi_pw_aff *access;
54 int member_access;
56 member_access = isl_multi_pw_aff_range_is_wrapping(base);
57 if (member_access < 0)
58 goto error;
59 if (member_access) {
60 isl_multi_pw_aff *domain, *range;
61 isl_id *id;
63 id = isl_multi_pw_aff_get_tuple_id(base, isl_dim_out);
64 domain = isl_multi_pw_aff_copy(base);
65 domain = isl_multi_pw_aff_range_factor_domain(domain);
66 range = isl_multi_pw_aff_range_factor_range(base);
67 range = pet_array_subscript(range, index);
68 access = isl_multi_pw_aff_range_product(domain, range);
69 access = isl_multi_pw_aff_set_tuple_id(access, isl_dim_out, id);
70 return access;
73 id = isl_multi_pw_aff_get_tuple_id(base, isl_dim_set);
74 domain = isl_pw_aff_nonneg_set(isl_pw_aff_copy(index));
75 index = isl_pw_aff_intersect_domain(index, domain);
76 access = isl_multi_pw_aff_from_pw_aff(index);
77 access = isl_multi_pw_aff_flat_range_product(base, access);
78 access = isl_multi_pw_aff_set_tuple_id(access, isl_dim_set, id);
80 return access;
81 error:
82 isl_multi_pw_aff_free(base);
83 isl_pw_aff_free(index);
84 return NULL;
87 /* Construct a name for a member access by concatenating the name
88 * of the array of structures and the member, separated by an underscore.
90 * The caller is responsible for freeing the result.
92 char *pet_array_member_access_name(isl_ctx *ctx, const char *base,
93 const char *field)
95 int len;
96 char *name;
98 len = strlen(base) + 1 + strlen(field);
99 name = isl_alloc_array(ctx, char, len + 1);
100 if (!name)
101 return NULL;
102 snprintf(name, len + 1, "%s_%s", base, field);
104 return name;
107 /* Given an index expression "base" for an element of an array of structures
108 * and an expression "field" for the field member being accessed, construct
109 * an index expression for an access to that member of the given structure.
110 * In particular, take the range product of "base" and "field" and
111 * attach a name to the result.
113 __isl_give isl_multi_pw_aff *pet_array_member(
114 __isl_take isl_multi_pw_aff *base, __isl_take isl_multi_pw_aff *field)
116 isl_ctx *ctx;
117 isl_multi_pw_aff *access;
118 const char *base_name, *field_name;
119 char *name;
121 ctx = isl_multi_pw_aff_get_ctx(base);
123 base_name = isl_multi_pw_aff_get_tuple_name(base, isl_dim_out);
124 field_name = isl_multi_pw_aff_get_tuple_name(field, isl_dim_out);
125 name = pet_array_member_access_name(ctx, base_name, field_name);
127 access = isl_multi_pw_aff_range_product(base, field);
129 access = isl_multi_pw_aff_set_tuple_name(access, isl_dim_out, name);
130 free(name);
132 return access;