xref: /llvm-project/polly/lib/External/isl/isl_pw_eval.c (revision a749e09e184b2b0b6dde71af01c82dd427b3e3e2)
1 /*
2  * Copyright 2010      INRIA Saclay
3  * Copyright 2013      Ecole Normale Superieure
4  *
5  * Use of this software is governed by the MIT license
6  *
7  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9  * 91893 Orsay, France
10  * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
11  */
12 
13 #include <isl/val.h>
14 #include <isl_space_private.h>
15 #include <isl_point_private.h>
16 
17 #include <isl_pw_macro.h>
18 
19 #undef SUFFIX
20 #define SUFFIX	point
21 #undef ARG1
22 #define ARG1	PW
23 #undef ARG2
24 #define ARG2	isl_point
25 
26 static
27 #include "isl_align_params_templ.c"
28 
29 /* Evaluate "pw" in the void point "pnt".
30  * In particular, return the value NaN.
31  */
FN(PW,eval_void)32 static __isl_give isl_val *FN(PW,eval_void)(__isl_take PW *pw,
33 	__isl_take isl_point *pnt)
34 {
35 	isl_ctx *ctx;
36 
37 	ctx = isl_point_get_ctx(pnt);
38 	FN(PW,free)(pw);
39 	isl_point_free(pnt);
40 	return isl_val_nan(ctx);
41 }
42 
43 /* Evaluate the piecewise function "pw" in "pnt".
44  * If the point is void, then return NaN.
45  * If the point lies outside the domain of "pw", then return 0 or NaN
46  * depending on whether 0 is the default value for this type of function.
47  *
48  * Align the parameters if needed, but "pnt" should specify a value
49  * for all parameters in "pw".
50  */
FN(PW,eval)51 __isl_give isl_val *FN(PW,eval)(__isl_take PW *pw, __isl_take isl_point *pnt)
52 {
53 	int i;
54 	isl_bool is_void;
55 	isl_bool found;
56 	isl_ctx *ctx;
57 	isl_bool ok;
58 	isl_space *pnt_space, *pw_space;
59 	isl_val *v;
60 
61 	FN(PW,align_params_point)(&pw, &pnt);
62 
63 	pnt_space = isl_point_peek_space(pnt);
64 	pw_space = FN(PW,peek_space)(pw);
65 	ok = isl_space_is_domain_internal(pnt_space, pw_space);
66 	if (ok < 0)
67 		goto error;
68 	ctx = isl_point_get_ctx(pnt);
69 	if (!ok)
70 		isl_die(ctx, isl_error_invalid,
71 			"incompatible spaces", goto error);
72 	is_void = isl_point_is_void(pnt);
73 	if (is_void < 0)
74 		goto error;
75 	if (is_void)
76 		return FN(PW,eval_void)(pw, pnt);
77 
78 	found = isl_bool_false;
79 	for (i = 0; i < pw->n; ++i) {
80 		found = isl_set_contains_point(pw->p[i].set, pnt);
81 		if (found < 0)
82 			goto error;
83 		if (found)
84 			break;
85 	}
86 	if (found) {
87 		v = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD),
88 					    isl_point_copy(pnt));
89 	} else if (DEFAULT_IS_ZERO) {
90 		v = isl_val_zero(ctx);
91 	} else {
92 		v = isl_val_nan(ctx);
93 	}
94 	FN(PW,free)(pw);
95 	isl_point_free(pnt);
96 	return v;
97 error:
98 	FN(PW,free)(pw);
99 	isl_point_free(pnt);
100 	return NULL;
101 }
102