Optionally store domains of scattering dimensions in clast for
[cloog.git] / source / clast.c
blobc12bac0be01ee432a1db46e559711b4391355077
1 #include <stdlib.h>
2 #include <string.h>
3 #include <assert.h>
4 #include "../include/cloog/cloog.h"
6 #define ALLOC(type) (type*)malloc(sizeof(type))
7 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
9 /**
10 * CloogInfos structure:
11 * this structure contains all the informations necessary for pretty printing,
12 * they come from the original CloogProgram structure (language, names), from
13 * genereral options (options) or are built only for pretty printing (stride).
14 * This structure is mainly there to reduce the number of function parameters,
15 * since most pprint.c functions need most of its field.
17 struct clooginfos {
18 CloogState *state; /**< State. */
19 CloogStride **stride;
20 int nb_scattdims ; /**< Scattering dimension number. */
21 int * scaldims ; /**< Boolean array saying whether a given
22 * scattering dimension is scalar or not.
24 CloogNames * names ; /**< Names of iterators and parameters. */
25 CloogOptions * options ; /**< Options on CLooG's behaviour. */
26 CloogEqualities *equal; /**< Matrix of equalities. */
27 } ;
29 typedef struct clooginfos CloogInfos ;
31 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2);
32 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2);
33 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2);
34 static int clast_reduction_cmp(struct clast_reduction *r1,
35 struct clast_reduction *r2);
37 static struct clast_expr *clast_expr_copy(struct clast_expr *e);
39 static int clast_equal_add(CloogEqualities *equal,
40 CloogConstraintSet *constraints,
41 int level, CloogConstraint *constraint,
42 CloogInfos *infos);
44 static struct clast_stmt *clast_equal(int level, CloogInfos *infos);
45 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
46 int level, int max, int guard,
47 int lower_bound,
48 CloogInfos *infos);
49 static void insert_guard(CloogConstraintSet *constraints, int level,
50 struct clast_stmt ***next, CloogInfos *infos);
51 static int insert_modulo_guard(CloogConstraint *upper,
52 CloogConstraint *lower, int level,
53 struct clast_stmt ***next, CloogInfos *infos);
54 static int insert_equation(CloogDomain *domain, CloogConstraint *upper,
55 CloogConstraint *lower, int level,
56 struct clast_stmt ***next, CloogInfos *infos);
57 static int insert_for(CloogDomain *domain, CloogConstraintSet *constraints,
58 int level, int otl, struct clast_stmt ***next,
59 CloogInfos *infos);
60 static void insert_block(CloogDomain *domain, CloogBlock *block, int level,
61 struct clast_stmt ***next, CloogInfos *infos);
62 static void insert_loop(CloogLoop * loop, int level,
63 struct clast_stmt ***next, CloogInfos *infos);
66 struct clast_name *new_clast_name(const char *name)
68 struct clast_name *n = malloc(sizeof(struct clast_name));
69 n->expr.type = clast_expr_name;
70 n->name = name;
71 return n;
74 struct clast_term *new_clast_term(cloog_int_t c, struct clast_expr *v)
76 struct clast_term *t = malloc(sizeof(struct clast_term));
77 t->expr.type = clast_expr_term;
78 cloog_int_init(t->val);
79 cloog_int_set(t->val, c);
80 t->var = v;
81 return t;
84 struct clast_binary *new_clast_binary(enum clast_bin_type t,
85 struct clast_expr *lhs, cloog_int_t rhs)
87 struct clast_binary *b = malloc(sizeof(struct clast_binary));
88 b->expr.type = clast_expr_bin;
89 b->type = t;
90 b->LHS = lhs;
91 cloog_int_init(b->RHS);
92 cloog_int_set(b->RHS, rhs);
93 return b;
96 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
98 int i;
99 struct clast_reduction *r;
100 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
101 r->expr.type = clast_expr_red;
102 r->type = t;
103 r->n = n;
104 for (i = 0; i < n; ++i)
105 r->elts[i] = NULL;
106 return r;
109 static void free_clast_root(struct clast_stmt *s);
111 const struct clast_stmt_op stmt_root = { free_clast_root };
113 static void free_clast_root(struct clast_stmt *s)
115 struct clast_root *r = (struct clast_root *)s;
116 assert(CLAST_STMT_IS_A(s, stmt_root));
117 cloog_names_free(r->names);
118 free(r);
121 struct clast_root *new_clast_root(CloogNames *names)
123 struct clast_root *r = malloc(sizeof(struct clast_root));
124 r->stmt.op = &stmt_root;
125 r->stmt.next = NULL;
126 r->names = cloog_names_copy(names);
127 return r;
130 static void free_clast_assignment(struct clast_stmt *s);
132 const struct clast_stmt_op stmt_ass = { free_clast_assignment };
134 static void free_clast_assignment(struct clast_stmt *s)
136 struct clast_assignment *a = (struct clast_assignment *)s;
137 assert(CLAST_STMT_IS_A(s, stmt_ass));
138 free_clast_expr(a->RHS);
139 free(a);
142 struct clast_assignment *new_clast_assignment(const char *lhs,
143 struct clast_expr *rhs)
145 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
146 a->stmt.op = &stmt_ass;
147 a->stmt.next = NULL;
148 a->LHS = lhs;
149 a->RHS = rhs;
150 return a;
153 static void free_clast_user_stmt(struct clast_stmt *s);
155 const struct clast_stmt_op stmt_user = { free_clast_user_stmt };
157 static void free_clast_user_stmt(struct clast_stmt *s)
159 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
160 assert(CLAST_STMT_IS_A(s, stmt_user));
161 cloog_domain_free(u->domain);
162 cloog_statement_free(u->statement);
163 cloog_clast_free(u->substitutions);
164 free(u);
167 struct clast_user_stmt *new_clast_user_stmt(CloogDomain *domain,
168 CloogStatement *stmt, struct clast_stmt *subs)
170 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
171 u->stmt.op = &stmt_user;
172 u->stmt.next = NULL;
173 u->domain = cloog_domain_copy(domain);
174 u->statement = cloog_statement_copy(stmt);
175 u->substitutions = subs;
176 return u;
179 static void free_clast_block(struct clast_stmt *b);
181 const struct clast_stmt_op stmt_block = { free_clast_block };
183 static void free_clast_block(struct clast_stmt *s)
185 struct clast_block *b = (struct clast_block *)s;
186 assert(CLAST_STMT_IS_A(s, stmt_block));
187 cloog_clast_free(b->body);
188 free(b);
191 struct clast_block *new_clast_block()
193 struct clast_block *b = malloc(sizeof(struct clast_block));
194 b->stmt.op = &stmt_block;
195 b->stmt.next = NULL;
196 b->body = NULL;
197 return b;
200 static void free_clast_for(struct clast_stmt *s);
202 const struct clast_stmt_op stmt_for = { free_clast_for };
204 static void free_clast_for(struct clast_stmt *s)
206 struct clast_for *f = (struct clast_for *)s;
207 assert(CLAST_STMT_IS_A(s, stmt_for));
208 cloog_domain_free(f->domain);
209 free_clast_expr(f->LB);
210 free_clast_expr(f->UB);
211 cloog_int_clear(f->stride);
212 cloog_clast_free(f->body);
213 free(f);
216 struct clast_for *new_clast_for(CloogDomain *domain, const char *it,
217 struct clast_expr *LB, struct clast_expr *UB,
218 CloogStride *stride)
220 struct clast_for *f = malloc(sizeof(struct clast_for));
221 f->stmt.op = &stmt_for;
222 f->stmt.next = NULL;
223 f->domain = cloog_domain_copy(domain);
224 f->iterator = it;
225 f->LB = LB;
226 f->UB = UB;
227 f->body = NULL;
228 cloog_int_init(f->stride);
229 if (stride)
230 cloog_int_set(f->stride, stride->stride);
231 else
232 cloog_int_set_si(f->stride, 1);
233 return f;
236 static void free_clast_guard(struct clast_stmt *s);
238 const struct clast_stmt_op stmt_guard = { free_clast_guard };
240 static void free_clast_guard(struct clast_stmt *s)
242 int i;
243 struct clast_guard *g = (struct clast_guard *)s;
244 assert(CLAST_STMT_IS_A(s, stmt_guard));
245 cloog_clast_free(g->then);
246 for (i = 0; i < g->n; ++i) {
247 free_clast_expr(g->eq[i].LHS);
248 free_clast_expr(g->eq[i].RHS);
250 free(g);
253 struct clast_guard *new_clast_guard(int n)
255 int i;
256 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
257 (n-1) * sizeof(struct clast_equation));
258 g->stmt.op = &stmt_guard;
259 g->stmt.next = NULL;
260 g->then = NULL;
261 g->n = n;
262 for (i = 0; i < n; ++i) {
263 g->eq[i].LHS = NULL;
264 g->eq[i].RHS = NULL;
266 return g;
269 void free_clast_name(struct clast_name *n)
271 free(n);
274 void free_clast_term(struct clast_term *t)
276 cloog_int_clear(t->val);
277 free_clast_expr(t->var);
278 free(t);
281 void free_clast_binary(struct clast_binary *b)
283 cloog_int_clear(b->RHS);
284 free_clast_expr(b->LHS);
285 free(b);
288 void free_clast_reduction(struct clast_reduction *r)
290 int i;
291 for (i = 0; i < r->n; ++i)
292 free_clast_expr(r->elts[i]);
293 free(r);
296 void free_clast_expr(struct clast_expr *e)
298 if (!e)
299 return;
300 switch (e->type) {
301 case clast_expr_name:
302 free_clast_name((struct clast_name*) e);
303 break;
304 case clast_expr_term:
305 free_clast_term((struct clast_term*) e);
306 break;
307 case clast_expr_red:
308 free_clast_reduction((struct clast_reduction*) e);
309 break;
310 case clast_expr_bin:
311 free_clast_binary((struct clast_binary*) e);
312 break;
313 default:
314 assert(0);
318 void free_clast_stmt(struct clast_stmt *s)
320 assert(s->op);
321 assert(s->op->free);
322 s->op->free(s);
325 void cloog_clast_free(struct clast_stmt *s)
327 struct clast_stmt *next;
328 while (s) {
329 next = s->next;
330 free_clast_stmt(s);
331 s = next;
335 static int clast_name_cmp(struct clast_name *n1, struct clast_name *n2)
337 return n1->name == n2->name ? 0 : strcmp(n1->name, n2->name);
340 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
342 int c;
343 if (!t1->var && t2->var)
344 return -1;
345 if (t1->var && !t2->var)
346 return 1;
347 c = clast_expr_cmp(t1->var, t2->var);
348 if (c)
349 return c;
350 return cloog_int_cmp(t1->val, t2->val);
353 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
355 int c;
357 if (b1->type != b2->type)
358 return b1->type - b2->type;
359 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
360 return c;
361 return clast_expr_cmp(b1->LHS, b2->LHS);
364 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
366 int i;
367 int c;
369 if (r1->n == 1 && r2->n == 1)
370 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
371 if (r1->type != r2->type)
372 return r1->type - r2->type;
373 if (r1->n != r2->n)
374 return r1->n - r2->n;
375 for (i = 0; i < r1->n; ++i)
376 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
377 return c;
378 return 0;
381 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
383 if (!e1 && !e2)
384 return 0;
385 if (!e1)
386 return -1;
387 if (!e2)
388 return 1;
389 if (e1->type != e2->type)
390 return e1->type - e2->type;
391 switch (e1->type) {
392 case clast_expr_name:
393 return clast_name_cmp((struct clast_name*) e1,
394 (struct clast_name*) e2);
395 case clast_expr_term:
396 return clast_term_cmp((struct clast_term*) e1,
397 (struct clast_term*) e2);
398 case clast_expr_bin:
399 return clast_binary_cmp((struct clast_binary*) e1,
400 (struct clast_binary*) e2);
401 case clast_expr_red:
402 return clast_reduction_cmp((struct clast_reduction*) e1,
403 (struct clast_reduction*) e2);
404 default:
405 assert(0);
409 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
411 return clast_expr_cmp(e1, e2) == 0;
415 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
417 int clast_expr_is_bigger_constant(struct clast_expr *e1, struct clast_expr *e2)
419 struct clast_term *t1, *t2;
420 struct clast_reduction *r;
422 if (!e1 || !e2)
423 return 0;
424 if (e1->type == clast_expr_red) {
425 r = (struct clast_reduction *)e1;
426 return r->n == 1 && clast_expr_is_bigger_constant(r->elts[0], e2);
428 if (e2->type == clast_expr_red) {
429 r = (struct clast_reduction *)e2;
430 return r->n == 1 && clast_expr_is_bigger_constant(e1, r->elts[0]);
432 if (e1->type != clast_expr_term || e2->type != clast_expr_term)
433 return 0;
434 t1 = (struct clast_term *)e1;
435 t2 = (struct clast_term *)e2;
436 if (t1->var || t2->var)
437 return 0;
438 return cloog_int_gt(t1->val, t2->val);
441 static int qsort_expr_cmp(const void *p1, const void *p2)
443 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
446 static void clast_reduction_sort(struct clast_reduction *r)
448 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
451 static int qsort_eq_cmp(const void *p1, const void *p2)
453 struct clast_equation *eq1 = (struct clast_equation *)p1;
454 struct clast_equation *eq2 = (struct clast_equation *)p2;
455 int cmp;
457 cmp = clast_expr_cmp(eq1->LHS, eq2->LHS);
458 if (cmp)
459 return cmp;
461 cmp = clast_expr_cmp(eq1->RHS, eq2->RHS);
462 if (cmp)
463 return cmp;
465 return eq1->sign - eq2->sign;
469 * Sort equations in a clast_guard.
471 static void clast_guard_sort(struct clast_guard *g)
473 qsort(&g->eq[0], g->n, sizeof(struct clast_equation), qsort_eq_cmp);
478 * Construct a (deep) copy of an expression clast.
480 static struct clast_expr *clast_expr_copy(struct clast_expr *e)
482 if (!e)
483 return NULL;
484 switch (e->type) {
485 case clast_expr_name: {
486 struct clast_name* n = (struct clast_name*) e;
487 return &new_clast_name(n->name)->expr;
489 case clast_expr_term: {
490 struct clast_term* t = (struct clast_term*) e;
491 return &new_clast_term(t->val, clast_expr_copy(t->var))->expr;
493 case clast_expr_red: {
494 int i;
495 struct clast_reduction *r = (struct clast_reduction*) e;
496 struct clast_reduction *r2 = new_clast_reduction(r->type, r->n);
497 for (i = 0; i < r->n; ++i)
498 r2->elts[i] = clast_expr_copy(r->elts[i]);
499 return &r2->expr;
501 case clast_expr_bin: {
502 struct clast_binary *b = (struct clast_binary*) e;
503 return &new_clast_binary(b->type, clast_expr_copy(b->LHS), b->RHS)->expr;
505 default:
506 assert(0);
511 /******************************************************************************
512 * Equalities spreading functions *
513 ******************************************************************************/
517 * clast_equal_allow function:
518 * This function checks whether the options allow us to spread the equality or
519 * not. It returns 1 if so, 0 otherwise.
520 * - equal is the matrix of equalities,
521 * - level is the column number in equal of the element which is 'equal to',
522 * - line is the line number in equal of the constraint we want to study,
523 * - the infos structure gives the user all options on code printing and more.
525 * - October 27th 2005: first version (extracted from old pprint_equal_add).
527 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
528 CloogInfos *infos)
530 if (level < infos->options->fsp)
531 return 0 ;
533 if ((cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
534 !infos->options->esp)
535 return 0 ;
537 return 1 ;
542 * clast_equal_add function:
543 * This function updates the row (level-1) of the equality matrix (equal) with
544 * the row that corresponds to the row (line) of the matrix (matrix). It returns
545 * 1 if the row can be updated, 0 otherwise.
546 * - equal is the matrix of equalities,
547 * - matrix is the matrix of constraints,
548 * - level is the column number in matrix of the element which is 'equal to',
549 * - line is the line number in matrix of the constraint we want to study,
550 * - the infos structure gives the user all options on code printing and more.
552 static int clast_equal_add(CloogEqualities *equal,
553 CloogConstraintSet *constraints,
554 int level, CloogConstraint *constraint,
555 CloogInfos *infos)
557 cloog_equal_add(equal, constraints, level, constraint,
558 infos->names->nb_parameters);
560 return clast_equal_allow(equal, level, level-1, infos);
566 * clast_equal function:
567 * This function prints the substitution data of a statement into a clast_stmt.
568 * Using this function instead of pprint_equal is useful for generating
569 * a compilable pseudo-code by using preprocessor macro for each statement.
570 * By opposition to pprint_equal, the result is less human-readable. For
571 * instance this function will print (i,i+3,k,3) where pprint_equal would
572 * return (j=i+3,l=3).
573 * - level is the number of loops enclosing the statement,
574 * - the infos structure gives the user all options on code printing and more.
576 * - March 12th 2004: first version.
577 * - November 21th 2005: (debug) now works well with GMP version.
579 static struct clast_stmt *clast_equal(int level, CloogInfos *infos)
581 int i ;
582 struct clast_expr *e;
583 struct clast_stmt *a = NULL;
584 struct clast_stmt **next = &a;
585 CloogEqualities *equal = infos->equal;
586 CloogConstraint *equal_constraint;
588 for (i=infos->names->nb_scattering;i<level-1;i++)
589 { if (cloog_equal_type(equal, i+1)) {
590 equal_constraint = cloog_equal_constraint(equal, i);
591 e = clast_bound_from_constraint(equal_constraint, i+1, infos->names);
592 cloog_constraint_release(equal_constraint);
593 } else {
594 e = &new_clast_term(infos->state->one, &new_clast_name(
595 cloog_names_name_at_level(infos->names, i+1))->expr)->expr;
597 *next = &new_clast_assignment(NULL, e)->stmt;
598 next = &(*next)->next;
601 return a;
606 * clast_bound_from_constraint function:
607 * This function returns a clast_expr containing the printing of the
608 * 'right part' of a constraint according to an element.
609 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
610 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
611 * function should return 'ceild(3*i+M,2)'.
612 * - matrix is the polyhedron containing all the constraints,
613 * - line_num is the line number in domain of the constraint we want to print,
614 * - level is the column number in domain of the element we want to use,
615 * - names structure gives the user some options about code printing,
616 * the number of parameters in domain (nb_par), and the arrays of iterator
617 * names and parameters (iters and params).
619 * - November 2nd 2001: first version.
620 * - June 27th 2003: 64 bits version ready.
622 struct clast_expr *clast_bound_from_constraint(CloogConstraint *constraint,
623 int level, CloogNames *names)
625 int i, sign, nb_elts=0, len;
626 cloog_int_t *line, numerator, denominator, temp, division;
627 struct clast_expr *e = NULL;
628 struct cloog_vec *line_vector;
630 len = cloog_constraint_total_dimension(constraint) + 2;
631 line_vector = cloog_vec_alloc(len);
632 line = line_vector->p;
633 cloog_constraint_copy_coefficients(constraint, line+1);
634 cloog_int_init(temp);
635 cloog_int_init(numerator);
636 cloog_int_init(denominator);
638 if (!cloog_int_is_zero(line[level])) {
639 struct clast_reduction *r;
640 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
641 sign = -cloog_int_sgn(line[level]);
643 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
644 if (i != level && !cloog_int_is_zero(line[i]))
645 nb_elts++;
646 r = new_clast_reduction(clast_red_sum, nb_elts);
647 nb_elts = 0;
649 /* First, we have to print the iterators and the parameters. */
650 for (i = 1; i <= len - 2; i++) {
651 struct clast_expr *v;
653 if (i == level || cloog_int_is_zero(line[i]))
654 continue;
656 v = cloog_constraint_variable_expr(constraint, i, names);
658 if (sign == -1)
659 cloog_int_neg(temp,line[i]);
660 else
661 cloog_int_set(temp,line[i]);
663 r->elts[nb_elts++] = &new_clast_term(temp, v)->expr;
666 if (sign == -1) {
667 cloog_int_neg(numerator, line[len - 1]);
668 cloog_int_set(denominator, line[level]);
670 else {
671 cloog_int_set(numerator, line[len - 1]);
672 cloog_int_neg(denominator, line[level]);
675 /* Finally, the constant, and the final printing. */
676 if (nb_elts) {
677 if (!cloog_int_is_zero(numerator))
678 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
680 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
681 { if (!cloog_constraint_is_equality(constraint))
682 { if (cloog_int_is_pos(line[level]))
683 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
684 else
685 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
686 } else
687 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
689 else
690 e = &r->expr;
691 } else {
692 free_clast_reduction(r);
693 if (cloog_int_is_zero(numerator))
694 e = &new_clast_term(numerator, NULL)->expr;
695 else
696 { if (!cloog_int_is_one(denominator))
697 { if (!cloog_constraint_is_equality(constraint)) { /* useful? */
698 if (cloog_int_is_divisible_by(numerator, denominator)) {
699 cloog_int_divexact(temp, numerator, denominator);
700 e = &new_clast_term(temp, NULL)->expr;
702 else {
703 cloog_int_init(division);
704 cloog_int_tdiv_q(division, numerator, denominator);
705 if (cloog_int_is_neg(numerator)) {
706 if (cloog_int_is_pos(line[level])) {
707 /* nb<0 need max */
708 e = &new_clast_term(division, NULL)->expr;
709 } else {
710 /* nb<0 need min */
711 cloog_int_sub_ui(temp, division, 1);
712 e = &new_clast_term(temp, NULL)->expr;
715 else
716 { if (cloog_int_is_pos(line[level]))
717 { /* nb>0 need max */
718 cloog_int_add_ui(temp, division, 1);
719 e = &new_clast_term(temp, NULL)->expr;
721 else
722 /* nb>0 need min */
723 e = &new_clast_term(division, NULL)->expr;
725 cloog_int_clear(division);
728 else
729 e = &new_clast_binary(clast_bin_div,
730 &new_clast_term(numerator, NULL)->expr,
731 denominator)->expr;
733 else
734 e = &new_clast_term(numerator, NULL)->expr;
739 cloog_vec_free(line_vector);
741 cloog_int_clear(temp);
742 cloog_int_clear(numerator);
743 cloog_int_clear(denominator);
745 return e;
749 /* Temporary structure for communication between clast_minmax and
750 * its cloog_constraint_set_foreach_constraint callback functions.
752 struct clast_minmax_data {
753 int level;
754 int max;
755 int guard;
756 int lower_bound;
757 CloogInfos *infos;
758 int n;
759 struct clast_reduction *r;
763 /* Should constraint "c" be considered by clast_minmax?
765 static int valid_bound(CloogConstraint *c, struct clast_minmax_data *d)
767 if (d->max && !cloog_constraint_is_lower_bound(c, d->level - 1))
768 return 0;
769 if (!d->max && !cloog_constraint_is_upper_bound(c, d->level - 1))
770 return 0;
771 if (cloog_constraint_is_equality(c))
772 return 0;
773 if (d->guard && cloog_constraint_involves(c, d->guard - 1))
774 return 0;
776 return 1;
780 /* Increment n for each bound that should be considered by clast_minmax.
782 static int count_bounds(CloogConstraint *c, void *user)
784 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
786 if (!valid_bound(c, d))
787 return 0;
789 d->n++;
791 return 0;
795 /* Update the given lower bound based on stride information.
796 * In some backends, the lower bounds are updated from within
797 * cloog_loop_stride, but other backends leave the updating to
798 * this function. In the later case, the original lower bound
799 * is known to be a constant.
800 * If the bound turns out not to be a constant, we know we
801 * are in the former case and nothing needs to be done.
802 * If the bound has already been updated and it just happens
803 * to be a constant, then this function performs an identity
804 * operation on the constant.
806 static void update_lower_bound(struct clast_expr *expr, int level,
807 CloogStride *stride)
809 struct clast_term *t;
810 if (stride->constraint)
811 return;
812 if (expr->type != clast_expr_term)
813 return;
814 t = (struct clast_term *)expr;
815 if (t->var)
816 return;
817 cloog_int_sub(t->val, t->val, stride->offset);
818 cloog_int_cdiv_q(t->val, t->val, stride->stride);
819 cloog_int_mul(t->val, t->val, stride->stride);
820 cloog_int_add(t->val, t->val, stride->offset);
824 /* Add all relevant bounds to r->elts and update lower bounds
825 * based on stride information.
827 static int collect_bounds(CloogConstraint *c, void *user)
829 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
831 if (!valid_bound(c, d))
832 return 0;
834 d->r->elts[d->n] = clast_bound_from_constraint(c, d->level,
835 d->infos->names);
836 if (d->lower_bound && d->infos->stride[d->level - 1]) {
837 update_lower_bound(d->r->elts[d->n], d->level,
838 d->infos->stride[d->level - 1]);
841 d->n++;
843 return 0;
848 * clast_minmax function:
849 * This function returns a clast_expr containing the printing of a minimum or a
850 * maximum of the 'right parts' of all constraints according to an element.
851 * For instance consider the constraints:
852 * -3*i +2*j -M >= 0
853 * 2*i +j >= 0
854 * -i -j +2*M >= 0
855 * if we are looking for the minimum for the element j, the function should
856 * return 'max(ceild(3*i+M,2),-2*i)'.
857 * - constraints is the constraints,
858 * - level is the column number in domain of the element we want to use,
859 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
860 * - guard is set to 0 if there is no guard, and set to the level of the element
861 * with a guard otherwise (then the function gives the max or the min only
862 * for the constraint where the guarded coefficient is 0),
863 * - lower is set to 1 if the maximum is to be used a lower bound on a loop
864 * - the infos structure gives the user some options about code printing,
865 * the number of parameters in domain (nb_par), and the arrays of iterator
866 * names and parameters (iters and params).
868 * - November 2nd 2001: first version.
870 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
871 int level, int max, int guard,
872 int lower_bound,
873 CloogInfos *infos)
875 struct clast_minmax_data data = { level, max, guard, lower_bound, infos };
877 data.n = 0;
879 cloog_constraint_set_foreach_constraint(constraints, count_bounds, &data);
881 if (!data.n)
882 return NULL;
883 data.r = new_clast_reduction(max ? clast_red_max : clast_red_min, data.n);
885 data.n = 0;
886 cloog_constraint_set_foreach_constraint(constraints, collect_bounds, &data);
888 clast_reduction_sort(data.r);
889 return &data.r->expr;
894 * Insert modulo guards defined by existentially quantified dimensions,
895 * not involving the given level.
897 * This function is called from within insert_guard.
898 * Any constraint used in constructing a modulo guard is removed
899 * from the constraint set to avoid insert_guard
900 * adding a duplicate (pair of) constraint(s).
902 static void insert_extra_modulo_guards(CloogConstraintSet *constraints,
903 int level, struct clast_stmt ***next, CloogInfos *infos)
905 int i;
906 int nb_iter;
907 int total_dim;
908 CloogConstraint *upper, *lower;
910 total_dim = cloog_constraint_set_total_dimension(constraints);
911 nb_iter = cloog_constraint_set_n_iterators(constraints,
912 infos->names->nb_parameters);
914 for (i = total_dim - infos->names->nb_parameters; i >= nb_iter + 1; i--) {
915 if (cloog_constraint_is_valid(upper =
916 cloog_constraint_set_defining_equality(constraints, i))) {
917 if (!level || (nb_iter < level) ||
918 !cloog_constraint_involves(upper, level-1)) {
919 insert_modulo_guard(upper,
920 cloog_constraint_invalid(), i, next, infos);
921 cloog_constraint_clear(upper);
923 cloog_constraint_release(upper);
924 } else if (cloog_constraint_is_valid(upper =
925 cloog_constraint_set_defining_inequalities(constraints,
926 i, &lower, infos->names->nb_parameters))) {
927 if (!level || (nb_iter < level) ||
928 !cloog_constraint_involves(upper, level-1)) {
929 insert_modulo_guard(upper, lower, i, next, infos);
930 cloog_constraint_clear(upper);
931 cloog_constraint_clear(lower);
933 cloog_constraint_release(upper);
934 cloog_constraint_release(lower);
940 static int clear_lower_bound_at_level(CloogConstraint *c, void *user)
942 int level = *(int *)user;
944 if (cloog_constraint_is_lower_bound(c, level - 1))
945 cloog_constraint_clear(c);
947 return 0;
951 static int clear_upper_bound_at_level(CloogConstraint *c, void *user)
953 int level = *(int *)user;
955 if (cloog_constraint_is_upper_bound(c, level - 1))
956 cloog_constraint_clear(c);
958 return 0;
962 /* Temporary structure for communication between insert_guard and
963 * its cloog_constraint_set_foreach_constraint callback function.
965 struct clast_guard_data {
966 int level;
967 CloogInfos *infos;
968 int n;
969 int i;
970 int nb_iter;
971 CloogConstraintSet *copy;
972 struct clast_guard *g;
976 static int guard_count_bounds(CloogConstraint *c, void *user)
978 struct clast_guard_data *d = (struct clast_guard_data *) user;
980 d->n++;
982 return 0;
986 /* Insert a guard, if necesessary, for constraint j.
988 static int insert_guard_constraint(CloogConstraint *j, void *user)
990 struct clast_guard_data *d = (struct clast_guard_data *) user;
991 int minmax = -1;
992 struct clast_expr *v;
993 struct clast_term *t;
995 if (!cloog_constraint_involves(j, d->i - 1))
996 return 0;
998 if (d->level && d->nb_iter >= d->level &&
999 cloog_constraint_involves(j, d->level - 1))
1000 return 0;
1002 v = cloog_constraint_variable_expr(j, d->i, d->infos->names);
1003 d->g->eq[d->n].LHS = &(t = new_clast_term(d->infos->state->one, v))->expr;
1004 if (!d->level || cloog_constraint_is_equality(j)) {
1005 /* put the "denominator" in the LHS */
1006 cloog_constraint_coefficient_get(j, d->i - 1, &t->val);
1007 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->one);
1008 if (cloog_int_is_neg(t->val)) {
1009 cloog_int_neg(t->val, t->val);
1010 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->negone);
1012 if (d->level || cloog_constraint_is_equality(j))
1013 d->g->eq[d->n].sign = 0;
1014 else if (cloog_constraint_is_lower_bound(j, d->i - 1))
1015 d->g->eq[d->n].sign = 1;
1016 else
1017 d->g->eq[d->n].sign = -1;
1018 d->g->eq[d->n].RHS = clast_bound_from_constraint(j, d->i, d->infos->names);
1019 } else {
1020 int guarded;
1022 if (cloog_constraint_is_lower_bound(j, d->i - 1)) {
1023 minmax = 1;
1024 d->g->eq[d->n].sign = 1;
1025 } else {
1026 minmax = 0;
1027 d->g->eq[d->n].sign = -1;
1030 guarded = (d->nb_iter >= d->level) ? d->level : 0 ;
1031 d->g->eq[d->n].RHS = clast_minmax(d->copy, d->i, minmax, guarded, 0,
1032 d->infos);
1034 d->n++;
1036 /* 'elimination' of the current constraint, this avoid to use one
1037 * constraint more than once. The current line is always eliminated,
1038 * and the next lines if they are in a min or a max.
1040 cloog_constraint_clear(j);
1042 if (minmax == -1)
1043 return 0;
1044 if (minmax == 1)
1045 cloog_constraint_set_foreach_constraint(d->copy,
1046 clear_lower_bound_at_level, &d->i);
1047 else if (minmax == 0)
1048 cloog_constraint_set_foreach_constraint(d->copy,
1049 clear_upper_bound_at_level, &d->i);
1051 return 0;
1056 * insert_guard function:
1057 * This function inserts a guard in the clast.
1058 * A guard on an element (level) is :
1059 * -> the conjunction of all the existing constraints where the coefficient of
1060 * this element is 0 if the element is an iterator,
1061 * -> the conjunction of all the existing constraints if the element isn't an
1062 * iterator.
1063 * For instance, considering these constraints and the element j:
1064 * -3*i +2*j -M >= 0
1065 * 2*i +M >= 0
1066 * this function should return 'if (2*i+M>=0) {'.
1067 * - matrix is the polyhedron containing all the constraints,
1068 * - level is the column number of the element in matrix we want to use,
1069 * - the infos structure gives the user some options about code printing,
1070 * the number of parameters in matrix (nb_par), and the arrays of iterator
1071 * names and parameters (iters and params).
1073 * - November 3rd 2001: first version.
1074 * - November 14th 2001: a lot of 'purifications'.
1075 * - July 31th 2002: (debug) some guard parts are no more redundants.
1076 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
1077 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
1078 * (the need came from loop_simplify that may result in
1079 * domain unions, now it should be fixed directly in
1080 * cloog_loop_simplify).
1082 static void insert_guard(CloogConstraintSet *constraints, int level,
1083 struct clast_stmt ***next, CloogInfos *infos)
1085 int total_dim;
1086 struct clast_guard_data data = { level, infos, 0 };
1088 if (!constraints)
1089 return;
1091 data.copy = cloog_constraint_set_copy(constraints);
1093 insert_extra_modulo_guards(data.copy, level, next, infos);
1095 cloog_constraint_set_foreach_constraint(constraints,
1096 guard_count_bounds, &data);
1098 data.g = new_clast_guard(data.n);
1099 data.n = 0;
1101 /* Well, it looks complicated because I wanted to have a particular, more
1102 * readable, ordering, obviously this function may be far much simpler !
1104 data.nb_iter = cloog_constraint_set_n_iterators(constraints,
1105 infos->names->nb_parameters);
1107 /* We search for guard parts. */
1108 total_dim = cloog_constraint_set_total_dimension(constraints);
1109 for (data.i = 1; data.i <= total_dim; data.i++)
1110 cloog_constraint_set_foreach_constraint(data.copy,
1111 insert_guard_constraint, &data);
1113 cloog_constraint_set_free(data.copy);
1115 data.g->n = data.n;
1116 if (data.n) {
1117 clast_guard_sort(data.g);
1118 **next = &data.g->stmt;
1119 *next = &data.g->then;
1120 } else
1121 free_clast_stmt(&data.g->stmt);
1125 * Check if the constant "cst" satisfies the modulo guard that
1126 * would be introduced by insert_computed_modulo_guard.
1127 * The constant is assumed to have been reduced prior to calling
1128 * this function.
1130 static int constant_modulo_guard_is_satisfied(CloogConstraint *lower,
1131 cloog_int_t bound, cloog_int_t cst)
1133 if (cloog_constraint_is_valid(lower))
1134 return cloog_int_le(cst, bound);
1135 else
1136 return cloog_int_is_zero(cst);
1140 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
1141 * depending on whether lower represents a valid constraint.
1143 static void insert_computed_modulo_guard(struct clast_reduction *r,
1144 CloogConstraint *lower, cloog_int_t mod, cloog_int_t bound,
1145 struct clast_stmt ***next)
1147 struct clast_expr *e;
1148 struct clast_guard *g;
1150 e = &new_clast_binary(clast_bin_mod, &r->expr, mod)->expr;
1151 g = new_clast_guard(1);
1152 if (!cloog_constraint_is_valid(lower)) {
1153 g->eq[0].LHS = e;
1154 cloog_int_set_si(bound, 0);
1155 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1156 g->eq[0].sign = 0;
1157 } else {
1158 g->eq[0].LHS = e;
1159 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1160 g->eq[0].sign = -1;
1163 **next = &g->stmt;
1164 *next = &g->then;
1168 /* Try and eliminate coefficients from a modulo constraint based on
1169 * stride information of an earlier level.
1170 * The modulo of the constraint being constructed is "m".
1171 * The stride information at level "level" is given by "stride"
1172 * and indicated that the iterator i at level "level" is equal to
1173 * some expression modulo stride->stride.
1174 * If stride->stride is a multiple of "m' then i is also equal to
1175 * the expression modulo m and so we can eliminate the coefficient of i.
1177 * If stride->constraint is NULL, then i has a constant value modulo m, stored
1178 * stride->offset. We simply multiply this constant with the coefficient
1179 * of i and add the result to the constant term, reducing it modulo m.
1181 * If stride->constraint is not NULL, then it is a constraint of the form
1183 * e + k i = s a
1185 * with s equal to stride->stride, e an expression in terms of the
1186 * parameters and earlier iterators and a some arbitrary expression
1187 * in terms of existentially quantified variables.
1188 * stride->factor is a value f such that f * k = -1 mod s.
1189 * Adding stride->constraint f * c times to the current modulo constraint,
1190 * with c the coefficient of i eliminates i in favor of parameters and
1191 * earlier variables.
1193 static void eliminate_using_stride_constraint(cloog_int_t *line, int len,
1194 int nb_iter, CloogStride *stride, int level, cloog_int_t m)
1196 if (!stride)
1197 return;
1198 if (!cloog_int_is_divisible_by(stride->stride, m))
1199 return;
1201 if (stride->constraint) {
1202 int i;
1203 cloog_int_t t, v;
1205 cloog_int_init(t);
1206 cloog_int_init(v);
1207 cloog_int_mul(t, line[level], stride->factor);
1208 for (i = 1; i < level; ++i) {
1209 cloog_constraint_coefficient_get(stride->constraint,
1210 i - 1, &v);
1211 cloog_int_addmul(line[i], t, v);
1212 cloog_int_fdiv_r(line[i], line[i], m);
1214 for (i = nb_iter + 1; i <= len - 2; ++i) {
1215 cloog_constraint_coefficient_get(stride->constraint,
1216 i - nb_iter - 1 + level, &v);
1217 cloog_int_addmul(line[i], t, v);
1218 cloog_int_fdiv_r(line[i], line[i], m);
1220 cloog_constraint_constant_get(stride->constraint, &v);
1221 cloog_int_addmul(line[len - 1], t, v);
1222 cloog_int_fdiv_r(line[len - 1], line[len - 1], m);
1223 cloog_int_clear(v);
1224 cloog_int_clear(t);
1225 } else {
1226 cloog_int_addmul(line[len - 1], line[level], stride->offset);
1227 cloog_int_fdiv_r(line[len - 1], line[len - 1], m);
1230 cloog_int_set_si(line[level], 0);
1234 /* Temporary structure for communication between insert_modulo_guard and
1235 * its cloog_constraint_set_foreach_constraint callback function.
1237 struct clast_modulo_guard_data {
1238 CloogConstraint *lower;
1239 int level;
1240 struct clast_stmt ***next;
1241 CloogInfos *infos;
1242 int empty;
1243 cloog_int_t val, bound;
1247 /* Insert a modulo guard for constraint c.
1248 * The constraint may be either an equality or an inequality.
1249 * Since this function returns -1, it is only called on a single constraint.
1250 * In case of an inequality, the constraint is usually an upper bound
1251 * on d->level. However, if this variable is an existentially
1252 * quantified variable, the upper bound constraint may get removed
1253 * as trivially holding and then this function is called with
1254 * a lower bound instead. In this case, we need to adjust the constraint
1255 * based on the sum of the constant terms of the lower and upper bound
1256 * stored in d->bound.
1258 static int insert_modulo_guard_constraint(CloogConstraint *c, void *user)
1260 struct clast_modulo_guard_data *d = (struct clast_modulo_guard_data *) user;
1261 int level = d->level;
1262 CloogInfos *infos = d->infos;
1263 int i, nb_elts = 0, len, len2, nb_iter, nb_par;
1264 int constant;
1265 struct cloog_vec *line_vector;
1266 cloog_int_t *line;
1268 len = cloog_constraint_total_dimension(c) + 2;
1269 len2 = cloog_equal_total_dimension(infos->equal) + 2;
1270 nb_par = infos->names->nb_parameters;
1271 nb_iter = len - 2 - nb_par;
1273 line_vector = cloog_vec_alloc(len);
1274 line = line_vector->p;
1275 cloog_constraint_copy_coefficients(c, line + 1);
1277 if (cloog_int_is_pos(line[level])) {
1278 cloog_seq_neg(line + 1, line + 1, len - 1);
1279 if (!cloog_constraint_is_equality(c))
1280 cloog_int_add(line[len - 1], line[len - 1], d->bound);
1282 cloog_int_neg(line[level], line[level]);
1283 assert(cloog_int_is_pos(line[level]));
1285 nb_elts = 0;
1286 for (i = 1; i <= len-1; ++i) {
1287 if (i == level)
1288 continue;
1289 cloog_int_fdiv_r(line[i], line[i], line[level]);
1290 if (cloog_int_is_zero(line[i]))
1291 continue;
1292 if (i == len-1)
1293 continue;
1295 nb_elts++;
1298 if (nb_elts || !cloog_int_is_zero(line[len-1])) {
1299 struct clast_reduction *r;
1300 const char *name;
1302 r = new_clast_reduction(clast_red_sum, nb_elts + 1);
1303 nb_elts = 0;
1305 /* First, the modulo guard : the iterators... */
1306 for (i = level - 1; i >= 1; --i)
1307 eliminate_using_stride_constraint(line, len, nb_iter,
1308 infos->stride[i - 1], i, line[level]);
1309 for (i=1;i<=nb_iter;i++) {
1310 if (i == level || cloog_int_is_zero(line[i]))
1311 continue;
1313 name = cloog_names_name_at_level(infos->names, i);
1315 r->elts[nb_elts++] = &new_clast_term(line[i],
1316 &new_clast_name(name)->expr)->expr;
1319 /* ...the parameters... */
1320 for (i=nb_iter+1;i<=len-2;i++) {
1321 if (cloog_int_is_zero(line[i]))
1322 continue;
1324 name = infos->names->parameters[i-nb_iter-1] ;
1325 r->elts[nb_elts++] = &new_clast_term(line[i],
1326 &new_clast_name(name)->expr)->expr;
1329 constant = nb_elts == 0;
1330 /* ...the constant. */
1331 if (!cloog_int_is_zero(line[len-1]))
1332 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1334 /* our initial computation may have been an overestimate */
1335 r->n = nb_elts;
1337 if (constant) {
1338 d->empty = !constant_modulo_guard_is_satisfied(d->lower, d->bound,
1339 line[len - 1]);
1340 free_clast_reduction(r);
1341 } else
1342 insert_computed_modulo_guard(r, d->lower, line[level], d->bound,
1343 d->next);
1346 cloog_vec_free(line_vector);
1348 return -1;
1353 * insert_modulo_guard:
1354 * This function inserts a modulo guard corresponding to an equality
1355 * or a pair of inequalities.
1356 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
1358 * See insert_equation.
1359 * - matrix is the polyhedron containing all the constraints,
1360 * - upper and lower are the line numbers of the constraint in matrix
1361 * we want to print; in particular, if we want to print an equality,
1362 * then lower == -1 and upper is the row of the equality; if we want
1363 * to print an inequality, then upper is the row of the upper bound
1364 * and lower in the row of the lower bound
1365 * - level is the column number of the element in matrix we want to use,
1366 * - the infos structure gives the user some options about code printing,
1367 * the number of parameters in matrix (nb_par), and the arrays of iterator
1368 * names and parameters (iters and params).
1370 static int insert_modulo_guard(CloogConstraint *upper,
1371 CloogConstraint *lower, int level,
1372 struct clast_stmt ***next, CloogInfos *infos)
1374 int nb_par;
1375 CloogConstraintSet *set;
1376 struct clast_modulo_guard_data data = { lower, level, next, infos, 0 };
1378 cloog_int_init(data.val);
1379 cloog_constraint_coefficient_get(upper, level-1, &data.val);
1380 if (cloog_int_is_one(data.val) || cloog_int_is_neg_one(data.val)) {
1381 cloog_int_clear(data.val);
1382 return 1;
1385 nb_par = infos->names->nb_parameters;
1387 cloog_int_init(data.bound);
1388 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1389 if (cloog_constraint_is_valid(lower)) {
1390 cloog_constraint_constant_get(upper, &data.val);
1391 cloog_constraint_constant_get(lower, &data.bound);
1392 cloog_int_add(data.bound, data.val, data.bound);
1393 cloog_constraint_coefficient_get(lower, level-1, &data.val);
1394 cloog_int_sub_ui(data.val, data.val, 1);
1395 if (cloog_int_eq(data.val, data.bound)) {
1396 cloog_int_clear(data.val);
1397 cloog_int_clear(data.bound);
1398 return 1;
1402 set = cloog_constraint_set_for_reduction(upper, lower);
1403 set = cloog_constraint_set_reduce(set, level, infos->equal, nb_par, &data.bound);
1404 cloog_constraint_set_foreach_constraint(set,
1405 insert_modulo_guard_constraint, &data);
1407 cloog_constraint_set_free(set);
1408 cloog_int_clear(data.val);
1409 cloog_int_clear(data.bound);
1411 return !data.empty;
1416 * We found an equality or a pair of inequalities identifying
1417 * a loop with a single iteration, but the user wants us to generate
1418 * a loop anyway, so we do it here.
1420 static int insert_equation_as_loop(CloogDomain *domain, CloogConstraint *upper,
1421 CloogConstraint *lower, int level, struct clast_stmt ***next,
1422 CloogInfos *infos)
1424 const char *iterator = cloog_names_name_at_level(infos->names, level);
1425 struct clast_expr *e1, *e2;
1426 struct clast_for *f;
1428 e2 = clast_bound_from_constraint(upper, level, infos->names);
1429 if (!cloog_constraint_is_valid(lower))
1430 e1 = clast_expr_copy(e2);
1431 else
1432 e1 = clast_bound_from_constraint(lower, level, infos->names);
1434 f = new_clast_for(domain, iterator, e1, e2, infos->stride[level-1]);
1435 **next = &f->stmt;
1436 *next = &f->body;
1438 cloog_constraint_release(lower);
1439 cloog_constraint_release(upper);
1440 return 1;
1445 * insert_equation function:
1446 * This function inserts an equality
1447 * constraint according to an element in the clast.
1448 * Returns 1 if the calling function should recurse into inner loops.
1450 * An equality can be preceded by a 'modulo guard'.
1451 * For instance, consider the constraint i -2*j = 0 and the
1452 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1453 * - matrix is the polyhedron containing all the constraints,
1454 * - num is the line number of the constraint in matrix we want to print,
1455 * - level is the column number of the element in matrix we want to use,
1456 * - the infos structure gives the user some options about code printing,
1457 * the number of parameters in matrix (nb_par), and the arrays of iterator
1458 * names and parameters (iters and params).
1460 * - November 13th 2001: first version.
1461 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1462 * modulo is 0, compare vivien or vivien2 with a previous
1463 * version for an idea).
1464 * - June 29th 2003: non-unit strides support.
1465 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1466 * it was previously included in a stride calculation.
1468 static int insert_equation(CloogDomain *domain, CloogConstraint *upper,
1469 CloogConstraint *lower, int level, struct clast_stmt
1470 ***next, CloogInfos *infos)
1472 struct clast_expr *e;
1473 struct clast_assignment *ass;
1475 if (!infos->options->otl)
1476 return insert_equation_as_loop(domain, upper, lower, level, next, infos);
1478 if (!insert_modulo_guard(upper, lower, level, next, infos)) {
1479 cloog_constraint_release(lower);
1480 cloog_constraint_release(upper);
1482 return 0;
1485 if (cloog_constraint_is_valid(lower) ||
1486 !clast_equal_add(infos->equal, NULL, level, upper, infos))
1487 { /* Finally, the equality. */
1489 /* If we have to make a block by dimension, we start the block. Function
1490 * pprint knows if there is an equality, if this is the case, it checks
1491 * for the same following condition to close the brace.
1493 if (infos->options->block) {
1494 struct clast_block *b = new_clast_block();
1495 **next = &b->stmt;
1496 *next = &b->body;
1499 e = clast_bound_from_constraint(upper, level, infos->names);
1500 ass = new_clast_assignment(cloog_names_name_at_level(infos->names, level), e);
1502 **next = &ass->stmt;
1503 *next = &(**next)->next;
1506 cloog_constraint_release(lower);
1507 cloog_constraint_release(upper);
1509 return 1;
1514 * Insert a loop that is executed exactly once as an assignment.
1515 * In particular, the loop
1517 * for (i = e; i <= e; ++i) {
1518 * S;
1521 * is generated as
1523 * i = e;
1524 * S;
1527 static void insert_otl_for(CloogConstraintSet *constraints, int level,
1528 struct clast_expr *e, struct clast_stmt ***next, CloogInfos *infos)
1530 const char *iterator;
1532 iterator = cloog_names_name_at_level(infos->names, level);
1534 if (!clast_equal_add(infos->equal, constraints, level,
1535 cloog_constraint_invalid(), infos)) {
1536 struct clast_assignment *ass;
1537 if (infos->options->block) {
1538 struct clast_block *b = new_clast_block();
1539 **next = &b->stmt;
1540 *next = &b->body;
1542 ass = new_clast_assignment(iterator, e);
1543 **next = &ass->stmt;
1544 *next = &(**next)->next;
1545 } else {
1546 free_clast_expr(e);
1552 * Insert a loop that is executed at most once as an assignment followed
1553 * by a guard. In particular, the loop
1555 * for (i = e1; i <= e2; ++i) {
1556 * S;
1559 * is generated as
1561 * i = e1;
1562 * if (i <= e2) {
1563 * S;
1567 static void insert_guarded_otl_for(CloogConstraintSet *constraints, int level,
1568 struct clast_expr *e1, struct clast_expr *e2,
1569 struct clast_stmt ***next, CloogInfos *infos)
1571 const char *iterator;
1572 struct clast_assignment *ass;
1573 struct clast_guard *guard;
1575 iterator = cloog_names_name_at_level(infos->names, level);
1577 if (infos->options->block) {
1578 struct clast_block *b = new_clast_block();
1579 **next = &b->stmt;
1580 *next = &b->body;
1582 ass = new_clast_assignment(iterator, e1);
1583 **next = &ass->stmt;
1584 *next = &(**next)->next;
1586 guard = new_clast_guard(1);
1587 guard->eq[0].sign = -1;
1588 guard->eq[0].LHS = &new_clast_term(infos->state->one,
1589 &new_clast_name(iterator)->expr)->expr;
1590 guard->eq[0].RHS = e2;
1592 **next = &guard->stmt;
1593 *next = &guard->then;
1598 * insert_for function:
1599 * This function inserts a for loop in the clast.
1600 * Returns 1 if the calling function should recurse into inner loops.
1602 * A loop header according to an element is the conjunction of a minimum and a
1603 * maximum on a given element (they give the loop bounds).
1604 * For instance, considering these constraints and the element j:
1605 * i + j -9*M >= 0
1606 * -j +5*M >= 0
1607 * j -4*M >= 0
1608 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1609 * - constraints contains all constraints,
1610 * - level is the column number of the element in matrix we want to use,
1611 * - otl is set if the loop is executed at most once,
1612 * - the infos structure gives the user some options about code printing,
1613 * the number of parameters in matrix (nb_par), and the arrays of iterator
1614 * names and parameters (iters and params).
1616 static int insert_for(CloogDomain *domain, CloogConstraintSet *constraints,
1617 int level, int otl, struct clast_stmt ***next,
1618 CloogInfos *infos)
1620 const char *iterator;
1621 struct clast_expr *e1;
1622 struct clast_expr *e2;
1624 e1 = clast_minmax(constraints, level, 1, 0, 1, infos);
1625 e2 = clast_minmax(constraints, level, 0, 0, 0, infos);
1627 if (clast_expr_is_bigger_constant(e1, e2)) {
1628 free_clast_expr(e1);
1629 free_clast_expr(e2);
1630 return 0;
1633 /* If min and max are not equal there is a 'for' else, there is a '='.
1634 * In the special case e1 = e2 = NULL, this is an infinite loop
1635 * so this is not a '='.
1637 if (e1 && e2 && infos->options->otl && clast_expr_equal(e1, e2)) {
1638 free_clast_expr(e2);
1639 insert_otl_for(constraints, level, e1, next, infos);
1640 } else if (otl) {
1641 insert_guarded_otl_for(constraints, level, e1, e2, next, infos);
1642 } else {
1643 struct clast_for *f;
1644 iterator = cloog_names_name_at_level(infos->names, level);
1646 f = new_clast_for(domain, iterator, e1, e2, infos->stride[level-1]);
1647 **next = &f->stmt;
1648 *next = &f->body;
1651 return 1;
1656 * insert_block function:
1657 * This function inserts a statement block.
1658 * - block is the statement block,
1659 * - level is the number of loops enclosing the statement,
1660 * - the infos structure gives the user some options about code printing,
1661 * the number of parameters in domain (nb_par), and the arrays of iterator
1662 * names and parameters (iters and params).
1664 * - September 21th 2003: first version (pick from pprint function).
1666 static void insert_block(CloogDomain *domain, CloogBlock *block, int level,
1667 struct clast_stmt ***next, CloogInfos *infos)
1669 CloogStatement * statement ;
1670 struct clast_stmt *subs;
1672 if (!block)
1673 return;
1675 for (statement = block->statement; statement; statement = statement->next) {
1676 CloogStatement *s_next = statement->next;
1678 subs = clast_equal(level,infos);
1680 statement->next = NULL;
1681 **next = &new_clast_user_stmt(domain, statement, subs)->stmt;
1682 statement->next = s_next;
1683 *next = &(**next)->next;
1689 * insert_loop function:
1690 * This function converts the content of a CloogLoop structure (loop) into a
1691 * clast_stmt (inserted at **next).
1692 * The iterator (level) of
1693 * the current loop is given by 'level': this is the column number of the
1694 * domain corresponding to the current loop iterator. The data of a loop are
1695 * written in this order:
1696 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1697 * depend on the iterator (when the entry in the column 'level' is 0).
1698 * 2. The iteration domain of the iterator, given by the constraints in the
1699 * domain depending on the iterator, i.e.:
1700 * * an equality if the iterator has only one value (possibly preceded by
1701 * a guard verifying if this value is integral), *OR*
1702 * * a loop from the minimum possible value of the iterator to the maximum
1703 * possible value.
1704 * 3. The included statement block.
1705 * 4. The inner loops (recursive call).
1706 * 5. The following loops (recursive call).
1707 * - level is the recursion level or the iteration level that we are printing,
1708 * - the infos structure gives the user some options about code printing,
1709 * the number of parameters in domain (nb_par), and the arrays of iterator
1710 * names and parameters (iters and params).
1712 * - November 2nd 2001: first version.
1713 * - March 6th 2003: infinite domain support.
1714 * - April 19th 2003: (debug) NULL loop support.
1715 * - June 29th 2003: non-unit strides support.
1716 * - April 28th 2005: (debug) level is level+equality when print statement!
1717 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1718 * added to avoid iteration duplication (see DaeGon Kim
1719 * bug in cloog_program_generate). Try vasilache.cloog
1720 * with and without the call to cloog_polylib_matrix_normalize,
1721 * using -f 8 -l 9 options for an idea.
1722 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1723 * - October 16th 2005: (debug) scalar value is saved for next loops.
1725 static void insert_loop(CloogLoop * loop, int level,
1726 struct clast_stmt ***next, CloogInfos *infos)
1728 int equality = 0;
1729 CloogConstraintSet *constraints, *temp;
1730 struct clast_stmt **top = *next;
1731 CloogConstraint *i, *j;
1732 int empty_loop = 0;
1734 /* It can happen that loop be NULL when an input polyhedron is empty. */
1735 if (loop == NULL)
1736 return;
1738 /* The constraints do not always have a shape that allows us to generate code from it,
1739 * thus we normalize it, we also simplify it with the equalities.
1741 temp = cloog_domain_constraints(loop->domain);
1742 cloog_constraint_set_normalize(temp,level);
1743 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1744 infos->names->nb_parameters);
1745 cloog_constraint_set_free(temp);
1746 if (level)
1747 infos->stride[level - 1] = loop->stride;
1749 /* First of all we have to print the guard. */
1750 insert_guard(constraints,level, next, infos);
1752 if (level && cloog_constraint_set_contains_level(constraints, level,
1753 infos->names->nb_parameters)) {
1754 /* We scan all the constraints to know in which case we are :
1755 * [[if] equation] or [for].
1757 if (cloog_constraint_is_valid(i =
1758 cloog_constraint_set_defining_equality(constraints, level))) {
1759 empty_loop = !insert_equation(loop->unsimplified, i,
1760 cloog_constraint_invalid(), level, next,
1761 infos);
1762 equality = 1 ;
1763 } else if (cloog_constraint_is_valid(i =
1764 cloog_constraint_set_defining_inequalities(constraints,
1765 level, &j, infos->names->nb_parameters))) {
1766 empty_loop = !insert_equation(loop->unsimplified, i, j, level, next,
1767 infos);
1768 } else
1769 empty_loop = !insert_for(loop->unsimplified, constraints, level,
1770 loop->otl, next, infos);
1773 if (!empty_loop) {
1774 /* Finally, if there is an included statement block, print it. */
1775 insert_block(loop->unsimplified, loop->block, level+equality, next, infos);
1777 /* Go to the next level. */
1778 if (loop->inner != NULL)
1779 insert_loop(loop->inner, level+1, next, infos);
1782 if (level)
1783 cloog_equal_del(infos->equal,level);
1784 cloog_constraint_set_free(constraints);
1786 /* Go to the next loop on the same level. */
1787 while (*top)
1788 top = &(*top)->next;
1789 if (loop->next != NULL)
1790 insert_loop(loop->next, level, &top,infos);
1794 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1795 CloogOptions *options)
1797 CloogInfos *infos = ALLOC(CloogInfos);
1798 int nb_levels;
1799 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1800 struct clast_stmt **next = &root->next;
1802 infos->state = options->state;
1803 infos->names = program->names;
1804 infos->options = options;
1805 infos->scaldims = program->scaldims;
1806 infos->nb_scattdims = program->nb_scattdims;
1808 /* Allocation for the array of strides, there is a +1 since the statement can
1809 * be included inside an external loop without iteration domain.
1811 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1812 infos->stride = ALLOCN(CloogStride *, nb_levels);
1814 infos->equal = cloog_equal_alloc(nb_levels,
1815 nb_levels, program->names->nb_parameters);
1817 insert_loop(program->loop, 0, &next, infos);
1819 cloog_equal_free(infos->equal);
1821 free(infos->stride);
1822 free(infos);
1824 return root;
1828 struct clast_stmt *cloog_clast_create_from_input(CloogInput *input,
1829 CloogOptions *options)
1831 CloogProgram *program;
1832 struct clast_stmt *root;
1834 program = cloog_program_alloc(input->context, input->ud, options);
1835 free(input);
1837 program = cloog_program_generate(program, options);
1839 root = cloog_clast_create(program, options);
1840 cloog_program_free(program);
1842 return root;