2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 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
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
39 /* A pet_context represents the context in which a pet_expr
40 * in converted to an affine expression.
42 * "domain" prescribes the domain space of the affine expressions.
44 * "assignments" maps variable names to their currently known values.
45 * The domains of the values are equal to "domain".
46 * If a variable has been assigned an unknown value (possibly because
47 * it may be assigned a different expression in each iteration) or a value
48 * that is not an affine expression, then the corresponding isl_pw_aff
51 * If "allow_nested" is set, then the affine expression created
52 * in this context may involve new parameters that encode a pet_expr.
58 isl_id_to_pw_aff
*assignments
;
62 /* Create a pet_context with the given domain, assignments,
63 * and value for allow_nested.
65 static __isl_give pet_context
*context_alloc(__isl_take isl_space
*domain
,
66 __isl_take isl_id_to_pw_aff
*assignments
, int allow_nested
)
70 if (!domain
|| !assignments
)
73 pc
= isl_calloc_type(isl_space_get_ctx(domain
), struct pet_context
);
79 pc
->assignments
= assignments
;
80 pc
->allow_nested
= allow_nested
;
84 isl_space_free(domain
);
85 isl_id_to_pw_aff_free(assignments
);
89 /* Create a pet_context with the given domain.
91 * Initially, there are no assigned values and parameters that
92 * encode a pet_expr are not allowed.
94 __isl_give pet_context
*pet_context_alloc(__isl_take isl_space
*domain
)
96 isl_id_to_pw_aff
*assignments
;
101 assignments
= isl_id_to_pw_aff_alloc(isl_space_get_ctx(domain
), 0);;
102 return context_alloc(domain
, assignments
, 0);
105 /* Return an independent duplicate of "pc".
107 static __isl_give pet_context
*pet_context_dup(__isl_keep pet_context
*pc
)
114 dup
= context_alloc(isl_space_copy(pc
->domain
),
115 isl_id_to_pw_aff_copy(pc
->assignments
),
121 /* Return a pet_context that is equal to "pc" and that has only one reference.
123 static __isl_give pet_context
*pet_context_cow(__isl_take pet_context
*pc
)
131 return pet_context_dup(pc
);
134 /* Return an extra reference to "pc".
136 __isl_give pet_context
*pet_context_copy(__isl_keep pet_context
*pc
)
145 /* Free a reference to "pc" and return NULL.
147 __isl_null pet_context
*pet_context_free(__isl_take pet_context
*pc
)
154 isl_space_free(pc
->domain
);
155 isl_id_to_pw_aff_free(pc
->assignments
);
160 /* Return the isl_ctx in which "pc" was created.
162 isl_ctx
*pet_context_get_ctx(__isl_keep pet_context
*pc
)
164 return pc
? isl_space_get_ctx(pc
->domain
) : NULL
;
167 /* Return the domain space of "pc".
169 __isl_give isl_space
*pet_context_get_space(__isl_keep pet_context
*pc
)
173 return isl_space_copy(pc
->domain
);
176 /* Return the dimension of the domain space of "pc".
178 unsigned pet_context_dim(__isl_keep pet_context
*pc
)
182 return isl_space_dim(pc
->domain
, isl_dim_set
);
185 /* Return the assignments of "pc".
187 __isl_give isl_id_to_pw_aff
*pet_context_get_assignments(
188 __isl_keep pet_context
*pc
)
192 return isl_id_to_pw_aff_copy(pc
->assignments
);
195 /* Is "id" assigned any value in "pc"?
197 int pet_context_is_assigned(__isl_keep pet_context
*pc
, __isl_keep isl_id
*id
)
201 return isl_id_to_pw_aff_has(pc
->assignments
, id
);
204 /* Return the value assigned to "id" in "pc".
206 __isl_give isl_pw_aff
*pet_context_get_value(__isl_keep pet_context
*pc
,
207 __isl_take isl_id
*id
)
212 return isl_id_to_pw_aff_get(pc
->assignments
, id
);
218 /* Assign the value "value" to "id" in "pc", replacing the previously
219 * assigned value, if any.
221 __isl_give pet_context
*pet_context_set_value(__isl_take pet_context
*pc
,
222 __isl_take isl_id
*id
, isl_pw_aff
*value
)
224 pc
= pet_context_cow(pc
);
227 pc
->assignments
= isl_id_to_pw_aff_set(pc
->assignments
, id
, value
);
228 if (!pc
->assignments
)
229 return pet_context_free(pc
);
233 isl_pw_aff_free(value
);
237 /* Remove any assignment to "id" in "pc".
239 __isl_give pet_context
*pet_context_clear_value(__isl_keep pet_context
*pc
,
240 __isl_take isl_id
*id
)
242 pc
= pet_context_cow(pc
);
245 pc
->assignments
= isl_id_to_pw_aff_drop(pc
->assignments
, id
);
246 if (!pc
->assignments
)
247 return pet_context_free(pc
);
254 /* Return a piecewise affine expression defined on the specified domain
255 * that represents NaN.
257 static __isl_give isl_pw_aff
*nan_on_domain(__isl_take isl_space
*space
)
259 return isl_pw_aff_nan_on_domain(isl_local_space_from_space(space
));
262 /* Assign the value NaN to "id" in "pc", marked it as having an unknown
265 __isl_give pet_context
*pet_context_mark_unknown(__isl_take pet_context
*pc
,
266 __isl_take isl_id
*id
)
270 pa
= nan_on_domain(pet_context_get_space(pc
));
271 pc
= pet_context_set_value(pc
, id
, pa
);
276 /* Are affine expressions created in this context allowed to involve
277 * parameters that encode a pet_expr?
279 int pet_context_allow_nesting(__isl_keep pet_context
*pc
)
283 return pc
->allow_nested
;
286 /* Allow affine expressions created in this context to involve
287 * parameters that encode a pet_expr based on the value of "allow_nested".
289 __isl_give pet_context
*pet_context_set_allow_nested(__isl_take pet_context
*pc
,
294 if (pc
->allow_nested
== allow_nested
)
296 pc
= pet_context_cow(pc
);
299 pc
->allow_nested
= allow_nested
;
303 void pet_context_dump(__isl_keep pet_context
*pc
)
307 fprintf(stderr
, "domain: ");
308 isl_space_dump(pc
->domain
);
309 fprintf(stderr
, "assignments: ");
310 isl_id_to_pw_aff_dump(pc
->assignments
);
311 fprintf(stderr
, "nesting allowed: %d\n", pc
->allow_nested
);