add cloog_union_domain_from_isl_union_set
[cloog.git] / source / clast.c
blobefb3143d7690c6a4a1de563f46819841c9a5d337
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 cloog_int_t *stride; /**< The stride for each iterator. */
20 cloog_int_t *offset; /**< The offset for each iterator. */
21 int nb_scattdims ; /**< Scattering dimension number. */
22 int * scaldims ; /**< Boolean array saying whether a given
23 * scattering dimension is scalar or not.
25 CloogNames * names ; /**< Names of iterators and parameters. */
26 CloogOptions * options ; /**< Options on CLooG's behaviour. */
27 CloogEqualities *equal; /**< Matrix of equalities. */
28 } ;
30 typedef struct clooginfos CloogInfos ;
32 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2);
33 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2);
34 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2);
35 static int clast_reduction_cmp(struct clast_reduction *r1,
36 struct clast_reduction *r2);
38 static struct clast_expr *clast_expr_copy(struct clast_expr *e);
40 static int clast_equal_add(CloogEqualities *equal,
41 CloogConstraintSet *constraints,
42 int level, CloogConstraint *constraint,
43 CloogInfos *infos);
45 static struct clast_stmt *clast_equal(int level, CloogInfos *infos);
46 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
47 int level, int max, int guard,
48 int lower_bound,
49 CloogInfos *infos);
50 static void insert_guard(CloogConstraintSet *constraints, int level,
51 struct clast_stmt ***next, CloogInfos *infos);
52 static int insert_modulo_guard(CloogConstraint *upper,
53 CloogConstraint *lower, int level,
54 struct clast_stmt ***next, CloogInfos *infos);
55 static int insert_equation(CloogConstraint *upper, CloogConstraint *lower,
56 int level, struct clast_stmt ***next, CloogInfos *infos);
57 static int insert_for(CloogConstraintSet *constraints, int level, int otl,
58 struct clast_stmt ***next, CloogInfos *infos);
59 static void insert_block(CloogBlock *block, int level,
60 struct clast_stmt ***next, CloogInfos *infos);
61 static void insert_loop(CloogLoop * loop, int level,
62 struct clast_stmt ***next, CloogInfos *infos);
65 struct clast_name *new_clast_name(const char *name)
67 struct clast_name *n = malloc(sizeof(struct clast_name));
68 n->expr.type = clast_expr_name;
69 n->name = name;
70 return n;
73 struct clast_term *new_clast_term(cloog_int_t c, struct clast_expr *v)
75 struct clast_term *t = malloc(sizeof(struct clast_term));
76 t->expr.type = clast_expr_term;
77 cloog_int_init(t->val);
78 cloog_int_set(t->val, c);
79 t->var = v;
80 return t;
83 struct clast_binary *new_clast_binary(enum clast_bin_type t,
84 struct clast_expr *lhs, cloog_int_t rhs)
86 struct clast_binary *b = malloc(sizeof(struct clast_binary));
87 b->expr.type = clast_expr_bin;
88 b->type = t;
89 b->LHS = lhs;
90 cloog_int_init(b->RHS);
91 cloog_int_set(b->RHS, rhs);
92 return b;
95 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
97 int i;
98 struct clast_reduction *r;
99 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
100 r->expr.type = clast_expr_red;
101 r->type = t;
102 r->n = n;
103 for (i = 0; i < n; ++i)
104 r->elts[i] = NULL;
105 return r;
108 static void free_clast_root(struct clast_stmt *s);
110 const struct clast_stmt_op stmt_root = { free_clast_root };
112 static void free_clast_root(struct clast_stmt *s)
114 struct clast_root *r = (struct clast_root *)s;
115 assert(CLAST_STMT_IS_A(s, stmt_root));
116 cloog_names_free(r->names);
117 free(r);
120 struct clast_root *new_clast_root(CloogNames *names)
122 struct clast_root *r = malloc(sizeof(struct clast_root));
123 r->stmt.op = &stmt_root;
124 r->stmt.next = NULL;
125 r->names = cloog_names_copy(names);
126 return r;
129 static void free_clast_assignment(struct clast_stmt *s);
131 const struct clast_stmt_op stmt_ass = { free_clast_assignment };
133 static void free_clast_assignment(struct clast_stmt *s)
135 struct clast_assignment *a = (struct clast_assignment *)s;
136 assert(CLAST_STMT_IS_A(s, stmt_ass));
137 free_clast_expr(a->RHS);
138 free(a);
141 struct clast_assignment *new_clast_assignment(const char *lhs,
142 struct clast_expr *rhs)
144 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
145 a->stmt.op = &stmt_ass;
146 a->stmt.next = NULL;
147 a->LHS = lhs;
148 a->RHS = rhs;
149 return a;
152 static void free_clast_user_stmt(struct clast_stmt *s);
154 const struct clast_stmt_op stmt_user = { free_clast_user_stmt };
156 static void free_clast_user_stmt(struct clast_stmt *s)
158 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
159 assert(CLAST_STMT_IS_A(s, stmt_user));
160 cloog_statement_free(u->statement);
161 cloog_clast_free(u->substitutions);
162 free(u);
165 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
166 struct clast_stmt *subs)
168 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
169 u->stmt.op = &stmt_user;
170 u->stmt.next = NULL;
171 u->statement = cloog_statement_copy(stmt);
172 u->substitutions = subs;
173 return u;
176 static void free_clast_block(struct clast_stmt *b);
178 const struct clast_stmt_op stmt_block = { free_clast_block };
180 static void free_clast_block(struct clast_stmt *s)
182 struct clast_block *b = (struct clast_block *)s;
183 assert(CLAST_STMT_IS_A(s, stmt_block));
184 cloog_clast_free(b->body);
185 free(b);
188 struct clast_block *new_clast_block()
190 struct clast_block *b = malloc(sizeof(struct clast_block));
191 b->stmt.op = &stmt_block;
192 b->stmt.next = NULL;
193 b->body = NULL;
194 return b;
197 static void free_clast_for(struct clast_stmt *s);
199 const struct clast_stmt_op stmt_for = { free_clast_for };
201 static void free_clast_for(struct clast_stmt *s)
203 struct clast_for *f = (struct clast_for *)s;
204 assert(CLAST_STMT_IS_A(s, stmt_for));
205 free_clast_expr(f->LB);
206 free_clast_expr(f->UB);
207 cloog_int_clear(f->stride);
208 cloog_clast_free(f->body);
209 free(f);
212 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
213 struct clast_expr *UB, cloog_int_t stride)
215 struct clast_for *f = malloc(sizeof(struct clast_for));
216 f->stmt.op = &stmt_for;
217 f->stmt.next = NULL;
218 f->iterator = it;
219 f->LB = LB;
220 f->UB = UB;
221 f->body = NULL;
222 cloog_int_init(f->stride);
223 cloog_int_set(f->stride, stride);
224 return f;
227 static void free_clast_guard(struct clast_stmt *s);
229 const struct clast_stmt_op stmt_guard = { free_clast_guard };
231 static void free_clast_guard(struct clast_stmt *s)
233 int i;
234 struct clast_guard *g = (struct clast_guard *)s;
235 assert(CLAST_STMT_IS_A(s, stmt_guard));
236 cloog_clast_free(g->then);
237 for (i = 0; i < g->n; ++i) {
238 free_clast_expr(g->eq[i].LHS);
239 free_clast_expr(g->eq[i].RHS);
241 free(g);
244 struct clast_guard *new_clast_guard(int n)
246 int i;
247 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
248 (n-1) * sizeof(struct clast_equation));
249 g->stmt.op = &stmt_guard;
250 g->stmt.next = NULL;
251 g->then = NULL;
252 g->n = n;
253 for (i = 0; i < n; ++i) {
254 g->eq[i].LHS = NULL;
255 g->eq[i].RHS = NULL;
257 return g;
260 void free_clast_name(struct clast_name *n)
262 free(n);
265 void free_clast_term(struct clast_term *t)
267 cloog_int_clear(t->val);
268 free_clast_expr(t->var);
269 free(t);
272 void free_clast_binary(struct clast_binary *b)
274 cloog_int_clear(b->RHS);
275 free_clast_expr(b->LHS);
276 free(b);
279 void free_clast_reduction(struct clast_reduction *r)
281 int i;
282 for (i = 0; i < r->n; ++i)
283 free_clast_expr(r->elts[i]);
284 free(r);
287 void free_clast_expr(struct clast_expr *e)
289 if (!e)
290 return;
291 switch (e->type) {
292 case clast_expr_name:
293 free_clast_name((struct clast_name*) e);
294 break;
295 case clast_expr_term:
296 free_clast_term((struct clast_term*) e);
297 break;
298 case clast_expr_red:
299 free_clast_reduction((struct clast_reduction*) e);
300 break;
301 case clast_expr_bin:
302 free_clast_binary((struct clast_binary*) e);
303 break;
304 default:
305 assert(0);
309 void free_clast_stmt(struct clast_stmt *s)
311 assert(s->op);
312 assert(s->op->free);
313 s->op->free(s);
316 void cloog_clast_free(struct clast_stmt *s)
318 struct clast_stmt *next;
319 while (s) {
320 next = s->next;
321 free_clast_stmt(s);
322 s = next;
326 static int clast_name_cmp(struct clast_name *n1, struct clast_name *n2)
328 return n1->name == n2->name ? 0 : strcmp(n1->name, n2->name);
331 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
333 int c;
334 if (!t1->var && t2->var)
335 return -1;
336 if (t1->var && !t2->var)
337 return 1;
338 c = clast_expr_cmp(t1->var, t2->var);
339 if (c)
340 return c;
341 return cloog_int_cmp(t1->val, t2->val);
344 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
346 int c;
348 if (b1->type != b2->type)
349 return b1->type - b2->type;
350 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
351 return c;
352 return clast_expr_cmp(b1->LHS, b2->LHS);
355 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
357 int i;
358 int c;
360 if (r1->n == 1 && r2->n == 1)
361 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
362 if (r1->type != r2->type)
363 return r1->type - r2->type;
364 if (r1->n != r2->n)
365 return r1->n - r2->n;
366 for (i = 0; i < r1->n; ++i)
367 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
368 return c;
369 return 0;
372 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
374 if (!e1 && !e2)
375 return 0;
376 if (!e1)
377 return -1;
378 if (!e2)
379 return 1;
380 if (e1->type != e2->type)
381 return e1->type - e2->type;
382 switch (e1->type) {
383 case clast_expr_name:
384 return clast_name_cmp((struct clast_name*) e1,
385 (struct clast_name*) e2);
386 case clast_expr_term:
387 return clast_term_cmp((struct clast_term*) e1,
388 (struct clast_term*) e2);
389 case clast_expr_bin:
390 return clast_binary_cmp((struct clast_binary*) e1,
391 (struct clast_binary*) e2);
392 case clast_expr_red:
393 return clast_reduction_cmp((struct clast_reduction*) e1,
394 (struct clast_reduction*) e2);
395 default:
396 assert(0);
400 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
402 return clast_expr_cmp(e1, e2) == 0;
406 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
408 int clast_expr_is_bigger_constant(struct clast_expr *e1, struct clast_expr *e2)
410 struct clast_term *t1, *t2;
411 struct clast_reduction *r;
413 if (!e1 || !e2)
414 return 0;
415 if (e1->type == clast_expr_red) {
416 r = (struct clast_reduction *)e1;
417 return r->n == 1 && clast_expr_is_bigger_constant(r->elts[0], e2);
419 if (e2->type == clast_expr_red) {
420 r = (struct clast_reduction *)e2;
421 return r->n == 1 && clast_expr_is_bigger_constant(e1, r->elts[0]);
423 if (e1->type != clast_expr_term || e2->type != clast_expr_term)
424 return 0;
425 t1 = (struct clast_term *)e1;
426 t2 = (struct clast_term *)e2;
427 if (t1->var || t2->var)
428 return 0;
429 return cloog_int_gt(t1->val, t2->val);
432 static int qsort_expr_cmp(const void *p1, const void *p2)
434 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
437 static void clast_reduction_sort(struct clast_reduction *r)
439 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
442 static int qsort_eq_cmp(const void *p1, const void *p2)
444 struct clast_equation *eq1 = (struct clast_equation *)p1;
445 struct clast_equation *eq2 = (struct clast_equation *)p2;
446 int cmp;
448 cmp = clast_expr_cmp(eq1->LHS, eq2->LHS);
449 if (cmp)
450 return cmp;
452 cmp = clast_expr_cmp(eq1->RHS, eq2->RHS);
453 if (cmp)
454 return cmp;
456 return eq1->sign - eq2->sign;
460 * Sort equations in a clast_guard.
462 static void clast_guard_sort(struct clast_guard *g)
464 qsort(&g->eq[0], g->n, sizeof(struct clast_equation), qsort_eq_cmp);
469 * Construct a (deep) copy of an expression clast.
471 static struct clast_expr *clast_expr_copy(struct clast_expr *e)
473 if (!e)
474 return NULL;
475 switch (e->type) {
476 case clast_expr_name: {
477 struct clast_name* n = (struct clast_name*) e;
478 return &new_clast_name(n->name)->expr;
480 case clast_expr_term: {
481 struct clast_term* t = (struct clast_term*) e;
482 return &new_clast_term(t->val, clast_expr_copy(t->var))->expr;
484 case clast_expr_red: {
485 int i;
486 struct clast_reduction *r = (struct clast_reduction*) e;
487 struct clast_reduction *r2 = new_clast_reduction(r->type, r->n);
488 for (i = 0; i < r->n; ++i)
489 r2->elts[i] = clast_expr_copy(r->elts[i]);
490 return &r2->expr;
492 case clast_expr_bin: {
493 struct clast_binary *b = (struct clast_binary*) e;
494 return &new_clast_binary(b->type, clast_expr_copy(b->LHS), b->RHS)->expr;
496 default:
497 assert(0);
502 /******************************************************************************
503 * Equalities spreading functions *
504 ******************************************************************************/
508 * clast_equal_allow function:
509 * This function checks whether the options allow us to spread the equality or
510 * not. It returns 1 if so, 0 otherwise.
511 * - equal is the matrix of equalities,
512 * - level is the column number in equal of the element which is 'equal to',
513 * - line is the line number in equal of the constraint we want to study,
514 * - the infos structure gives the user all options on code printing and more.
516 * - October 27th 2005: first version (extracted from old pprint_equal_add).
518 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
519 CloogInfos *infos)
521 if (level < infos->options->fsp)
522 return 0 ;
524 if ((cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
525 !infos->options->esp)
526 return 0 ;
528 return 1 ;
533 * clast_equal_add function:
534 * This function updates the row (level-1) of the equality matrix (equal) with
535 * the row that corresponds to the row (line) of the matrix (matrix). It returns
536 * 1 if the row can be updated, 0 otherwise.
537 * - equal is the matrix of equalities,
538 * - matrix is the matrix of constraints,
539 * - level is the column number in matrix of the element which is 'equal to',
540 * - line is the line number in matrix of the constraint we want to study,
541 * - the infos structure gives the user all options on code printing and more.
543 static int clast_equal_add(CloogEqualities *equal,
544 CloogConstraintSet *constraints,
545 int level, CloogConstraint *constraint,
546 CloogInfos *infos)
548 cloog_equal_add(equal, constraints, level, constraint,
549 infos->names->nb_parameters);
551 return clast_equal_allow(equal, level, level-1, infos);
557 * clast_equal function:
558 * This function prints the substitution data of a statement into a clast_stmt.
559 * Using this function instead of pprint_equal is useful for generating
560 * a compilable pseudo-code by using preprocessor macro for each statement.
561 * By opposition to pprint_equal, the result is less human-readable. For
562 * instance this function will print (i,i+3,k,3) where pprint_equal would
563 * return (j=i+3,l=3).
564 * - level is the number of loops enclosing the statement,
565 * - the infos structure gives the user all options on code printing and more.
567 * - March 12th 2004: first version.
568 * - November 21th 2005: (debug) now works well with GMP version.
570 static struct clast_stmt *clast_equal(int level, CloogInfos *infos)
572 int i ;
573 struct clast_expr *e;
574 struct clast_stmt *a = NULL;
575 struct clast_stmt **next = &a;
576 CloogEqualities *equal = infos->equal;
577 CloogConstraint *equal_constraint;
579 for (i=infos->names->nb_scattering;i<level-1;i++)
580 { if (cloog_equal_type(equal, i+1)) {
581 equal_constraint = cloog_equal_constraint(equal, i);
582 e = clast_bound_from_constraint(equal_constraint, i+1, infos->names);
583 cloog_constraint_release(equal_constraint);
584 } else {
585 e = &new_clast_term(infos->state->one, &new_clast_name(
586 cloog_names_name_at_level(infos->names, i+1))->expr)->expr;
588 *next = &new_clast_assignment(NULL, e)->stmt;
589 next = &(*next)->next;
592 return a;
597 * clast_bound_from_constraint function:
598 * This function returns a clast_expr containing the printing of the
599 * 'right part' of a constraint according to an element.
600 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
601 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
602 * function should return 'ceild(3*i+M,2)'.
603 * - matrix is the polyhedron containing all the constraints,
604 * - line_num is the line number in domain of the constraint we want to print,
605 * - level is the column number in domain of the element we want to use,
606 * - names structure gives the user some options about code printing,
607 * the number of parameters in domain (nb_par), and the arrays of iterator
608 * names and parameters (iters and params).
610 * - November 2nd 2001: first version.
611 * - June 27th 2003: 64 bits version ready.
613 struct clast_expr *clast_bound_from_constraint(CloogConstraint *constraint,
614 int level, CloogNames *names)
616 int i, sign, nb_elts=0, len;
617 cloog_int_t *line, numerator, denominator, temp, division;
618 struct clast_expr *e = NULL;
619 struct cloog_vec *line_vector;
621 len = cloog_constraint_total_dimension(constraint) + 2;
622 line_vector = cloog_vec_alloc(len);
623 line = line_vector->p;
624 cloog_constraint_copy_coefficients(constraint, line+1);
625 cloog_int_init(temp);
626 cloog_int_init(numerator);
627 cloog_int_init(denominator);
629 if (!cloog_int_is_zero(line[level])) {
630 struct clast_reduction *r;
631 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
632 sign = -cloog_int_sgn(line[level]);
634 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
635 if (i != level && !cloog_int_is_zero(line[i]))
636 nb_elts++;
637 r = new_clast_reduction(clast_red_sum, nb_elts);
638 nb_elts = 0;
640 /* First, we have to print the iterators and the parameters. */
641 for (i = 1; i <= len - 2; i++) {
642 struct clast_expr *v;
644 if (i == level || cloog_int_is_zero(line[i]))
645 continue;
647 v = cloog_constraint_variable_expr(constraint, i, names);
649 if (sign == -1)
650 cloog_int_neg(temp,line[i]);
651 else
652 cloog_int_set(temp,line[i]);
654 r->elts[nb_elts++] = &new_clast_term(temp, v)->expr;
657 if (sign == -1) {
658 cloog_int_neg(numerator, line[len - 1]);
659 cloog_int_set(denominator, line[level]);
661 else {
662 cloog_int_set(numerator, line[len - 1]);
663 cloog_int_neg(denominator, line[level]);
666 /* Finally, the constant, and the final printing. */
667 if (nb_elts) {
668 if (!cloog_int_is_zero(numerator))
669 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
671 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
672 { if (!cloog_constraint_is_equality(constraint))
673 { if (cloog_int_is_pos(line[level]))
674 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
675 else
676 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
677 } else
678 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
680 else
681 e = &r->expr;
682 } else {
683 free_clast_reduction(r);
684 if (cloog_int_is_zero(numerator))
685 e = &new_clast_term(numerator, NULL)->expr;
686 else
687 { if (!cloog_int_is_one(denominator))
688 { if (!cloog_constraint_is_equality(constraint)) { /* useful? */
689 if (cloog_int_is_divisible_by(numerator, denominator)) {
690 cloog_int_divexact(temp, numerator, denominator);
691 e = &new_clast_term(temp, NULL)->expr;
693 else {
694 cloog_int_init(division);
695 cloog_int_tdiv_q(division, numerator, denominator);
696 if (cloog_int_is_neg(numerator)) {
697 if (cloog_int_is_pos(line[level])) {
698 /* nb<0 need max */
699 e = &new_clast_term(division, NULL)->expr;
700 } else {
701 /* nb<0 need min */
702 cloog_int_sub_ui(temp, division, 1);
703 e = &new_clast_term(temp, NULL)->expr;
706 else
707 { if (cloog_int_is_pos(line[level]))
708 { /* nb>0 need max */
709 cloog_int_add_ui(temp, division, 1);
710 e = &new_clast_term(temp, NULL)->expr;
712 else
713 /* nb>0 need min */
714 e = &new_clast_term(division, NULL)->expr;
716 cloog_int_clear(division);
719 else
720 e = &new_clast_binary(clast_bin_div,
721 &new_clast_term(numerator, NULL)->expr,
722 denominator)->expr;
724 else
725 e = &new_clast_term(numerator, NULL)->expr;
730 cloog_vec_free(line_vector);
732 cloog_int_clear(temp);
733 cloog_int_clear(numerator);
734 cloog_int_clear(denominator);
736 return e;
740 /* Temporary structure for communication between clast_minmax and
741 * its cloog_constraint_set_foreach_constraint callback functions.
743 struct clast_minmax_data {
744 int level;
745 int max;
746 int guard;
747 int lower_bound;
748 CloogInfos *infos;
749 int n;
750 struct clast_reduction *r;
754 /* Should constraint "c" be considered by clast_minmax?
756 static int valid_bound(CloogConstraint *c, struct clast_minmax_data *d)
758 if (d->max && !cloog_constraint_is_lower_bound(c, d->level - 1))
759 return 0;
760 if (!d->max && !cloog_constraint_is_upper_bound(c, d->level - 1))
761 return 0;
762 if (cloog_constraint_is_equality(c))
763 return 0;
764 if (d->guard && cloog_constraint_involves(c, d->guard - 1))
765 return 0;
767 return 1;
771 /* Increment n for each bound that should be considered by clast_minmax.
773 static int count_bounds(CloogConstraint *c, void *user)
775 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
777 if (!valid_bound(c, d))
778 return 0;
780 d->n++;
782 return 0;
786 /* Update the given lower bound based on stride information.
787 * In some backends, the lower bounds are updated from within
788 * cloog_loop_stride, but other backends leave the updating to
789 * this function. In the later case, the original lower bound
790 * is known to be a constant.
791 * If the bound turns out not to be a constant, we know we
792 * are in the former case and nothing needs to be done.
793 * If the bound has already been updated and it just happens
794 * to be a constant, then this function performs an identity
795 * operation on the constant.
797 static void update_lower_bound(struct clast_expr *expr, int level,
798 CloogInfos *infos)
800 struct clast_term *t;
801 if (expr->type != clast_expr_term)
802 return;
803 t = (struct clast_term *)expr;
804 if (t->var)
805 return;
806 cloog_int_sub(t->val, t->val, infos->offset[level - 1]);
807 cloog_int_cdiv_q(t->val, t->val, infos->stride[level - 1]);
808 cloog_int_mul(t->val, t->val, infos->stride[level - 1]);
809 cloog_int_add(t->val, t->val, infos->offset[level - 1]);
813 /* Add all relevant bounds to r->elts and update lower bounds
814 * based on stride information.
816 static int collect_bounds(CloogConstraint *c, void *user)
818 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
820 if (!valid_bound(c, d))
821 return 0;
823 d->r->elts[d->n] = clast_bound_from_constraint(c, d->level,
824 d->infos->names);
825 if (d->lower_bound && !cloog_int_is_one(d->infos->stride[d->level - 1]) &&
826 !cloog_int_is_zero(d->infos->stride[d->level - 1])) {
827 update_lower_bound(d->r->elts[d->n], d->level, d->infos);
830 d->n++;
832 return 0;
837 * clast_minmax function:
838 * This function returns a clast_expr containing the printing of a minimum or a
839 * maximum of the 'right parts' of all constraints according to an element.
840 * For instance consider the constraints:
841 * -3*i +2*j -M >= 0
842 * 2*i +j >= 0
843 * -i -j +2*M >= 0
844 * if we are looking for the minimum for the element j, the function should
845 * return 'max(ceild(3*i+M,2),-2*i)'.
846 * - constraints is the constraints,
847 * - level is the column number in domain of the element we want to use,
848 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
849 * - guard is set to 0 if there is no guard, and set to the level of the element
850 * with a guard otherwise (then the function gives the max or the min only
851 * for the constraint where the guarded coefficient is 0),
852 * - lower is set to 1 if the maximum is to be used a lower bound on a loop
853 * - the infos structure gives the user some options about code printing,
854 * the number of parameters in domain (nb_par), and the arrays of iterator
855 * names and parameters (iters and params).
857 * - November 2nd 2001: first version.
859 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
860 int level, int max, int guard,
861 int lower_bound,
862 CloogInfos *infos)
864 struct clast_minmax_data data = { level, max, guard, lower_bound, infos };
866 data.n = 0;
868 cloog_constraint_set_foreach_constraint(constraints, count_bounds, &data);
870 if (!data.n)
871 return NULL;
872 data.r = new_clast_reduction(max ? clast_red_max : clast_red_min, data.n);
874 data.n = 0;
875 cloog_constraint_set_foreach_constraint(constraints, collect_bounds, &data);
877 clast_reduction_sort(data.r);
878 return &data.r->expr;
883 * Insert modulo guards defined by existentially quantified dimensions,
884 * not involving the given level.
886 * This function is called from within insert_guard or insert_for.
887 * Any constraint used in constructing * a modulo guard is removed
888 * from the constraint set to avoid insert_guard or insert_for
889 * adding a duplicate (pair of) constraint(s).
891 static void insert_extra_modulo_guards(CloogConstraintSet *constraints,
892 int level, struct clast_stmt ***next, CloogInfos *infos)
894 int i;
895 int nb_iter;
896 int total_dim;
897 CloogConstraint *upper, *lower;
899 total_dim = cloog_constraint_set_total_dimension(constraints);
900 nb_iter = cloog_constraint_set_n_iterators(constraints,
901 infos->names->nb_parameters);
903 for (i = total_dim - infos->names->nb_parameters; i >= nb_iter + 1; i--) {
904 if (cloog_constraint_is_valid(upper =
905 cloog_constraint_set_defining_equality(constraints, i))) {
906 if (!level || (nb_iter < level) ||
907 !cloog_constraint_involves(upper, level-1)) {
908 insert_modulo_guard(upper,
909 cloog_constraint_invalid(), i, next, infos);
910 cloog_constraint_clear(upper);
912 cloog_constraint_release(upper);
913 } else if (cloog_constraint_is_valid(upper =
914 cloog_constraint_set_defining_inequalities(constraints,
915 i, &lower, infos->names->nb_parameters))) {
916 if (!level || (nb_iter < level) ||
917 !cloog_constraint_involves(upper, level-1)) {
918 insert_modulo_guard(upper, lower, i, next, infos);
919 cloog_constraint_clear(upper);
920 cloog_constraint_clear(lower);
922 cloog_constraint_release(upper);
923 cloog_constraint_release(lower);
929 static int clear_lower_bound_at_level(CloogConstraint *c, void *user)
931 int level = *(int *)user;
933 if (cloog_constraint_is_lower_bound(c, level - 1))
934 cloog_constraint_clear(c);
936 return 0;
940 static int clear_upper_bound_at_level(CloogConstraint *c, void *user)
942 int level = *(int *)user;
944 if (cloog_constraint_is_upper_bound(c, level - 1))
945 cloog_constraint_clear(c);
947 return 0;
951 /* Temporary structure for communication between insert_guard and
952 * its cloog_constraint_set_foreach_constraint callback function.
954 struct clast_guard_data {
955 int level;
956 CloogInfos *infos;
957 int n;
958 int i;
959 int nb_iter;
960 CloogConstraintSet *copy;
961 struct clast_guard *g;
965 static int guard_count_bounds(CloogConstraint *c, void *user)
967 struct clast_guard_data *d = (struct clast_guard_data *) user;
969 d->n++;
971 return 0;
975 /* Insert a guard, if necesessary, for constraint j.
977 static int insert_guard_constraint(CloogConstraint *j, void *user)
979 struct clast_guard_data *d = (struct clast_guard_data *) user;
980 int minmax = -1;
981 struct clast_expr *v;
982 struct clast_term *t;
984 if (!cloog_constraint_involves(j, d->i - 1))
985 return 0;
987 if (d->level && d->nb_iter >= d->level &&
988 cloog_constraint_involves(j, d->level - 1))
989 return 0;
991 v = cloog_constraint_variable_expr(j, d->i, d->infos->names);
992 d->g->eq[d->n].LHS = &(t = new_clast_term(d->infos->state->one, v))->expr;
993 if (!d->level || cloog_constraint_is_equality(j)) {
994 /* put the "denominator" in the LHS */
995 cloog_constraint_coefficient_get(j, d->i - 1, &t->val);
996 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->one);
997 if (cloog_int_is_neg(t->val)) {
998 cloog_int_neg(t->val, t->val);
999 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->negone);
1001 if (d->level || cloog_constraint_is_equality(j))
1002 d->g->eq[d->n].sign = 0;
1003 else if (cloog_constraint_is_lower_bound(j, d->i - 1))
1004 d->g->eq[d->n].sign = 1;
1005 else
1006 d->g->eq[d->n].sign = -1;
1007 d->g->eq[d->n].RHS = clast_bound_from_constraint(j, d->i, d->infos->names);
1008 } else {
1009 int guarded;
1011 if (cloog_constraint_is_lower_bound(j, d->i - 1)) {
1012 minmax = 1;
1013 d->g->eq[d->n].sign = 1;
1014 } else {
1015 minmax = 0;
1016 d->g->eq[d->n].sign = -1;
1019 guarded = (d->nb_iter >= d->level) ? d->level : 0 ;
1020 d->g->eq[d->n].RHS = clast_minmax(d->copy, d->i, minmax, guarded, 0,
1021 d->infos);
1023 d->n++;
1025 /* 'elimination' of the current constraint, this avoid to use one
1026 * constraint more than once. The current line is always eliminated,
1027 * and the next lines if they are in a min or a max.
1029 cloog_constraint_clear(j);
1031 if (minmax == -1)
1032 return 0;
1033 if (minmax == 1)
1034 cloog_constraint_set_foreach_constraint(d->copy,
1035 clear_lower_bound_at_level, &d->i);
1036 else if (minmax == 0)
1037 cloog_constraint_set_foreach_constraint(d->copy,
1038 clear_upper_bound_at_level, &d->i);
1040 return 0;
1045 * insert_guard function:
1046 * This function inserts a guard in the clast.
1047 * A guard on an element (level) is :
1048 * -> the conjunction of all the existing constraints where the coefficient of
1049 * this element is 0 if the element is an iterator,
1050 * -> the conjunction of all the existing constraints if the element isn't an
1051 * iterator.
1052 * For instance, considering these constraints and the element j:
1053 * -3*i +2*j -M >= 0
1054 * 2*i +M >= 0
1055 * this function should return 'if (2*i+M>=0) {'.
1056 * - matrix is the polyhedron containing all the constraints,
1057 * - level is the column number of the element in matrix we want to use,
1058 * - the infos structure gives the user some options about code printing,
1059 * the number of parameters in matrix (nb_par), and the arrays of iterator
1060 * names and parameters (iters and params).
1062 * - November 3rd 2001: first version.
1063 * - November 14th 2001: a lot of 'purifications'.
1064 * - July 31th 2002: (debug) some guard parts are no more redundants.
1065 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
1066 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
1067 * (the need came from loop_simplify that may result in
1068 * domain unions, now it should be fixed directly in
1069 * cloog_loop_simplify).
1071 static void insert_guard(CloogConstraintSet *constraints, int level,
1072 struct clast_stmt ***next, CloogInfos *infos)
1074 int total_dim;
1075 struct clast_guard_data data = { level, infos, 0 };
1077 if (!constraints)
1078 return;
1080 data.copy = cloog_constraint_set_copy(constraints);
1082 insert_extra_modulo_guards(data.copy, level, next, infos);
1084 cloog_constraint_set_foreach_constraint(constraints,
1085 guard_count_bounds, &data);
1087 data.g = new_clast_guard(data.n);
1088 data.n = 0;
1090 /* Well, it looks complicated because I wanted to have a particular, more
1091 * readable, ordering, obviously this function may be far much simpler !
1093 data.nb_iter = cloog_constraint_set_n_iterators(constraints,
1094 infos->names->nb_parameters);
1096 /* We search for guard parts. */
1097 total_dim = cloog_constraint_set_total_dimension(constraints);
1098 for (data.i = 1; data.i <= total_dim; data.i++)
1099 cloog_constraint_set_foreach_constraint(data.copy,
1100 insert_guard_constraint, &data);
1102 cloog_constraint_set_free(data.copy);
1104 data.g->n = data.n;
1105 if (data.n) {
1106 clast_guard_sort(data.g);
1107 **next = &data.g->stmt;
1108 *next = &data.g->then;
1109 } else
1110 free_clast_stmt(&data.g->stmt);
1114 * Check if the constant "cst" satisfies the modulo guard that
1115 * would be introduced by insert_computed_modulo_guard.
1116 * The constant is assumed to have been reduced prior to calling
1117 * this function.
1119 static int constant_modulo_guard_is_satisfied(CloogConstraint *lower,
1120 cloog_int_t bound, cloog_int_t cst)
1122 if (cloog_constraint_is_valid(lower))
1123 return cloog_int_le(cst, bound);
1124 else
1125 return cloog_int_is_zero(cst);
1129 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
1130 * depending on whether lower represents a valid constraint.
1132 static void insert_computed_modulo_guard(struct clast_reduction *r,
1133 CloogConstraint *lower, cloog_int_t mod, cloog_int_t bound,
1134 struct clast_stmt ***next)
1136 struct clast_expr *e;
1137 struct clast_guard *g;
1139 e = &new_clast_binary(clast_bin_mod, &r->expr, mod)->expr;
1140 g = new_clast_guard(1);
1141 if (!cloog_constraint_is_valid(lower)) {
1142 g->eq[0].LHS = e;
1143 cloog_int_set_si(bound, 0);
1144 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1145 g->eq[0].sign = 0;
1146 } else {
1147 g->eq[0].LHS = e;
1148 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1149 g->eq[0].sign = -1;
1152 **next = &g->stmt;
1153 *next = &g->then;
1157 /* Temporary structure for communication between insert_modulo_guard and
1158 * its cloog_constraint_set_foreach_constraint callback function.
1160 struct clast_modulo_guard_data {
1161 CloogConstraint *lower;
1162 int level;
1163 struct clast_stmt ***next;
1164 CloogInfos *infos;
1165 int empty;
1166 cloog_int_t val, bound;
1170 /* Insert a modulo guard for constraint c.
1172 static int insert_modulo_guard_constraint(CloogConstraint *c, void *user)
1174 struct clast_modulo_guard_data *d = (struct clast_modulo_guard_data *) user;
1175 int level = d->level;
1176 CloogInfos *infos = d->infos;
1177 int i, nb_elts = 0, len, len2, nb_iter, nb_par;
1178 int constant;
1179 struct cloog_vec *line_vector;
1180 cloog_int_t *line;
1182 len = cloog_constraint_total_dimension(c) + 2;
1183 len2 = cloog_equal_total_dimension(infos->equal) + 2;
1184 nb_par = infos->names->nb_parameters;
1185 nb_iter = len - 2 - nb_par;
1187 line_vector = cloog_vec_alloc(len);
1188 line = line_vector->p;
1189 cloog_constraint_copy_coefficients(c, line + 1);
1191 if (cloog_int_is_pos(line[level]))
1192 cloog_seq_neg(line + 1, line + 1, len - 1);
1193 cloog_int_neg(line[level], line[level]);
1194 assert(cloog_int_is_pos(line[level]));
1196 nb_elts = 0;
1197 for (i = 1; i <= len-1; ++i) {
1198 if (i == level)
1199 continue;
1200 cloog_int_fdiv_r(line[i], line[i], line[level]);
1201 if (cloog_int_is_zero(line[i]))
1202 continue;
1203 if (i == len-1)
1204 continue;
1206 nb_elts++;
1209 if (nb_elts || !cloog_int_is_zero(line[len-1])) {
1210 struct clast_reduction *r;
1211 const char *name;
1213 r = new_clast_reduction(clast_red_sum, nb_elts + 1);
1214 nb_elts = 0;
1216 /* First, the modulo guard : the iterators... */
1217 for (i=1;i<=nb_iter;i++) {
1218 if (i == level || cloog_int_is_zero(line[i]))
1219 continue;
1220 if (cloog_int_is_divisible_by(infos->stride[i-1], line[level])) {
1221 cloog_int_addmul(line[len-1], line[i], infos->offset[i-1]);
1222 cloog_int_fdiv_r(line[len-1], line[len-1], line[level]);
1223 continue;
1226 name = cloog_names_name_at_level(infos->names, i);
1228 r->elts[nb_elts++] = &new_clast_term(line[i],
1229 &new_clast_name(name)->expr)->expr;
1232 /* ...the parameters... */
1233 for (i=nb_iter+1;i<=len-2;i++) {
1234 if (cloog_int_is_zero(line[i]))
1235 continue;
1237 name = infos->names->parameters[i-nb_iter-1] ;
1238 r->elts[nb_elts++] = &new_clast_term(line[i],
1239 &new_clast_name(name)->expr)->expr;
1242 constant = nb_elts == 0;
1243 /* ...the constant. */
1244 if (!cloog_int_is_zero(line[len-1]))
1245 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1247 /* our initial computation may have been an overestimate */
1248 r->n = nb_elts;
1250 if (constant) {
1251 d->empty = !constant_modulo_guard_is_satisfied(d->lower, d->bound,
1252 line[len - 1]);
1253 free_clast_reduction(r);
1254 } else
1255 insert_computed_modulo_guard(r, d->lower, line[level], d->bound,
1256 d->next);
1259 cloog_vec_free(line_vector);
1261 return -1;
1266 * insert_modulo_guard:
1267 * This function inserts a modulo guard corresponding to an equality
1268 * or a pair of inequalities.
1269 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
1271 * See insert_equation.
1272 * - matrix is the polyhedron containing all the constraints,
1273 * - upper and lower are the line numbers of the constraint in matrix
1274 * we want to print; in particular, if we want to print an equality,
1275 * then lower == -1 and upper is the row of the equality; if we want
1276 * to print an inequality, then upper is the row of the upper bound
1277 * and lower in the row of the lower bound
1278 * - level is the column number of the element in matrix we want to use,
1279 * - the infos structure gives the user some options about code printing,
1280 * the number of parameters in matrix (nb_par), and the arrays of iterator
1281 * names and parameters (iters and params).
1283 static int insert_modulo_guard(CloogConstraint *upper,
1284 CloogConstraint *lower, int level,
1285 struct clast_stmt ***next, CloogInfos *infos)
1287 int nb_par;
1288 CloogConstraintSet *set;
1289 struct clast_modulo_guard_data data = { lower, level, next, infos, 0 };
1291 cloog_int_init(data.val);
1292 cloog_constraint_coefficient_get(upper, level-1, &data.val);
1293 if (cloog_int_is_one(data.val) || cloog_int_is_neg_one(data.val)) {
1294 cloog_int_clear(data.val);
1295 return 1;
1298 nb_par = infos->names->nb_parameters;
1300 cloog_int_init(data.bound);
1301 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1302 if (cloog_constraint_is_valid(lower)) {
1303 cloog_constraint_constant_get(upper, &data.val);
1304 cloog_constraint_constant_get(lower, &data.bound);
1305 cloog_int_add(data.bound, data.val, data.bound);
1306 cloog_constraint_coefficient_get(lower, level-1, &data.val);
1307 cloog_int_sub_ui(data.val, data.val, 1);
1308 if (cloog_int_eq(data.val, data.bound)) {
1309 cloog_int_clear(data.val);
1310 cloog_int_clear(data.bound);
1311 return 1;
1315 set = cloog_constraint_set_for_reduction(upper, lower);
1316 set = cloog_constraint_set_reduce(set, level, infos->equal, nb_par, &data.bound);
1317 cloog_constraint_set_foreach_constraint(set,
1318 insert_modulo_guard_constraint, &data);
1320 cloog_constraint_set_free(set);
1321 cloog_int_clear(data.val);
1322 cloog_int_clear(data.bound);
1324 return !data.empty;
1329 * We found an equality or a pair of inequalities identifying
1330 * a loop with a single iteration, but the user wants us to generate
1331 * a loop anyway, so we do it here.
1333 static int insert_equation_as_loop(CloogConstraint *upper,
1334 CloogConstraint *lower, int level, struct clast_stmt ***next,
1335 CloogInfos *infos)
1337 const char *iterator = cloog_names_name_at_level(infos->names, level);
1338 struct clast_expr *e1, *e2;
1339 struct clast_for *f;
1341 e2 = clast_bound_from_constraint(upper, level, infos->names);
1342 if (!cloog_constraint_is_valid(lower))
1343 e1 = clast_expr_copy(e2);
1344 else
1345 e1 = clast_bound_from_constraint(lower, level, infos->names);
1346 f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1347 **next = &f->stmt;
1348 *next = &f->body;
1350 cloog_constraint_release(lower);
1351 cloog_constraint_release(upper);
1352 return 1;
1357 * insert_equation function:
1358 * This function inserts an equality
1359 * constraint according to an element in the clast.
1360 * Returns 1 if the calling function should recurse into inner loops.
1362 * An equality can be preceded by a 'modulo guard'.
1363 * For instance, consider the constraint i -2*j = 0 and the
1364 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1365 * - matrix is the polyhedron containing all the constraints,
1366 * - num is the line number of the constraint in matrix we want to print,
1367 * - level is the column number of the element in matrix we want to use,
1368 * - the infos structure gives the user some options about code printing,
1369 * the number of parameters in matrix (nb_par), and the arrays of iterator
1370 * names and parameters (iters and params).
1372 * - November 13th 2001: first version.
1373 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1374 * modulo is 0, compare vivien or vivien2 with a previous
1375 * version for an idea).
1376 * - June 29th 2003: non-unit strides support.
1377 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1378 * it was previously included in a stride calculation.
1380 static int insert_equation(CloogConstraint *upper, CloogConstraint *lower,
1381 int level, struct clast_stmt ***next, CloogInfos *infos)
1383 struct clast_expr *e;
1384 struct clast_assignment *ass;
1386 if (!infos->options->otl)
1387 return insert_equation_as_loop(upper, lower, level, next, infos);
1389 if (!insert_modulo_guard(upper, lower, level, next, infos)) {
1390 cloog_constraint_release(lower);
1391 cloog_constraint_release(upper);
1393 return 0;
1396 if (cloog_constraint_is_valid(lower) ||
1397 !clast_equal_add(infos->equal, NULL, level, upper, infos))
1398 { /* Finally, the equality. */
1400 /* If we have to make a block by dimension, we start the block. Function
1401 * pprint knows if there is an equality, if this is the case, it checks
1402 * for the same following condition to close the brace.
1404 if (infos->options->block) {
1405 struct clast_block *b = new_clast_block();
1406 **next = &b->stmt;
1407 *next = &b->body;
1410 e = clast_bound_from_constraint(upper, level, infos->names);
1411 ass = new_clast_assignment(cloog_names_name_at_level(infos->names, level), e);
1413 **next = &ass->stmt;
1414 *next = &(**next)->next;
1417 cloog_constraint_release(lower);
1418 cloog_constraint_release(upper);
1420 return 1;
1425 * Insert a loop that is executed exactly once as an assignment.
1426 * In particular, the loop
1428 * for (i = e; i <= e; ++i) {
1429 * S;
1432 * is generated as
1434 * i = e;
1435 * S;
1438 static void insert_otl_for(CloogConstraintSet *constraints, int level,
1439 struct clast_expr *e, struct clast_stmt ***next, CloogInfos *infos)
1441 const char *iterator;
1443 iterator = cloog_names_name_at_level(infos->names, level);
1445 if (!clast_equal_add(infos->equal, constraints, level,
1446 cloog_constraint_invalid(), infos)) {
1447 struct clast_assignment *ass;
1448 if (infos->options->block) {
1449 struct clast_block *b = new_clast_block();
1450 **next = &b->stmt;
1451 *next = &b->body;
1453 ass = new_clast_assignment(iterator, e);
1454 **next = &ass->stmt;
1455 *next = &(**next)->next;
1456 } else {
1457 free_clast_expr(e);
1463 * Insert a loop that is executed at most once as an assignment followed
1464 * by a guard. In particular, the loop
1466 * for (i = e1; i <= e2; ++i) {
1467 * S;
1470 * is generated as
1472 * i = e1;
1473 * if (i <= e2) {
1474 * S;
1478 static void insert_guarded_otl_for(CloogConstraintSet *constraints, int level,
1479 struct clast_expr *e1, struct clast_expr *e2,
1480 struct clast_stmt ***next, CloogInfos *infos)
1482 const char *iterator;
1483 struct clast_assignment *ass;
1484 struct clast_guard *guard;
1486 iterator = cloog_names_name_at_level(infos->names, level);
1488 if (infos->options->block) {
1489 struct clast_block *b = new_clast_block();
1490 **next = &b->stmt;
1491 *next = &b->body;
1493 ass = new_clast_assignment(iterator, e1);
1494 **next = &ass->stmt;
1495 *next = &(**next)->next;
1497 guard = new_clast_guard(1);
1498 guard->eq[0].sign = -1;
1499 guard->eq[0].LHS = &new_clast_term(infos->state->one,
1500 &new_clast_name(iterator)->expr)->expr;
1501 guard->eq[0].RHS = e2;
1503 **next = &guard->stmt;
1504 *next = &guard->then;
1509 * insert_for function:
1510 * This function inserts a for loop in the clast.
1511 * Returns 1 if the calling function should recurse into inner loops.
1513 * A loop header according to an element is the conjunction of a minimum and a
1514 * maximum on a given element (they give the loop bounds).
1515 * For instance, considering these constraints and the element j:
1516 * i + j -9*M >= 0
1517 * -j +5*M >= 0
1518 * j -4*M >= 0
1519 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1520 * If the given element is involved in modulo guards defined by
1521 * existentially quantified variables, then these guards should be
1522 * inserted inside the for loop. However, the constraints involved
1523 * in this guard should not be used in determining the lower and upper
1524 * bound of the loop. We therefore insert the guards first (which
1525 * removes the corresponding constraints from the constraint set)
1526 * and then reattach the guard inside the loop.
1527 * - constraints contains all constraints,
1528 * - level is the column number of the element in matrix we want to use,
1529 * - otl is set if the loop is executed at most once,
1530 * - the infos structure gives the user some options about code printing,
1531 * the number of parameters in matrix (nb_par), and the arrays of iterator
1532 * names and parameters (iters and params).
1534 static int insert_for(CloogConstraintSet *constraints, int level, int otl,
1535 struct clast_stmt ***next, CloogInfos *infos)
1537 const char *iterator;
1538 struct clast_expr *e1;
1539 struct clast_expr *e2;
1541 e1 = clast_minmax(constraints, level, 1, 0, 1, infos);
1542 e2 = clast_minmax(constraints, level, 0, 0, 0, infos);
1544 if (clast_expr_is_bigger_constant(e1, e2)) {
1545 free_clast_expr(e1);
1546 free_clast_expr(e2);
1547 return 0;
1550 /* If min and max are not equal there is a 'for' else, there is a '='.
1551 * In the special case e1 = e2 = NULL, this is an infinite loop
1552 * so this is not a '='.
1554 if (e1 && e2 && infos->options->otl && clast_expr_equal(e1, e2)) {
1555 free_clast_expr(e2);
1556 insert_otl_for(constraints, level, e1, next, infos);
1557 } else if (otl) {
1558 insert_guarded_otl_for(constraints, level, e1, e2, next, infos);
1559 } else {
1560 struct clast_for *f;
1561 iterator = cloog_names_name_at_level(infos->names, level);
1562 f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1563 **next = &f->stmt;
1564 *next = &f->body;
1567 insert_extra_modulo_guards(constraints, 0, next, infos);
1569 return 1;
1574 * insert_block function:
1575 * This function inserts a statement block.
1576 * - block is the statement block,
1577 * - level is the number of loops enclosing the statement,
1578 * - the infos structure gives the user some options about code printing,
1579 * the number of parameters in domain (nb_par), and the arrays of iterator
1580 * names and parameters (iters and params).
1582 * - September 21th 2003: first version (pick from pprint function).
1584 static void insert_block(CloogBlock *block, int level,
1585 struct clast_stmt ***next, CloogInfos *infos)
1587 CloogStatement * statement ;
1588 struct clast_stmt *subs;
1590 if (!block)
1591 return;
1593 for (statement = block->statement; statement; statement = statement->next) {
1594 CloogStatement *s_next = statement->next;
1596 subs = clast_equal(level,infos);
1598 statement->next = NULL;
1599 **next = &new_clast_user_stmt(statement, subs)->stmt;
1600 statement->next = s_next;
1601 *next = &(**next)->next;
1607 * insert_loop function:
1608 * This function converts the content of a CloogLoop structure (loop) into a
1609 * clast_stmt (inserted at **next).
1610 * The iterator (level) of
1611 * the current loop is given by 'level': this is the column number of the
1612 * domain corresponding to the current loop iterator. The data of a loop are
1613 * written in this order:
1614 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1615 * depend on the iterator (when the entry in the column 'level' is 0).
1616 * 2. The iteration domain of the iterator, given by the constraints in the
1617 * domain depending on the iterator, i.e.:
1618 * * an equality if the iterator has only one value (possibly preceded by
1619 * a guard verifying if this value is integral), *OR*
1620 * * a loop from the minimum possible value of the iterator to the maximum
1621 * possible value.
1622 * 3. The included statement block.
1623 * 4. The inner loops (recursive call).
1624 * 5. The following loops (recursive call).
1625 * - level is the recursion level or the iteration level that we are printing,
1626 * - the infos structure gives the user some options about code printing,
1627 * the number of parameters in domain (nb_par), and the arrays of iterator
1628 * names and parameters (iters and params).
1630 * - November 2nd 2001: first version.
1631 * - March 6th 2003: infinite domain support.
1632 * - April 19th 2003: (debug) NULL loop support.
1633 * - June 29th 2003: non-unit strides support.
1634 * - April 28th 2005: (debug) level is level+equality when print statement!
1635 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1636 * added to avoid iteration duplication (see DaeGon Kim
1637 * bug in cloog_program_generate). Try vasilache.cloog
1638 * with and without the call to cloog_polylib_matrix_normalize,
1639 * using -f 8 -l 9 options for an idea.
1640 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1641 * - October 16th 2005: (debug) scalar value is saved for next loops.
1643 static void insert_loop(CloogLoop * loop, int level,
1644 struct clast_stmt ***next, CloogInfos *infos)
1646 int equality = 0;
1647 CloogConstraintSet *constraints, *temp;
1648 struct clast_stmt **top = *next;
1649 CloogConstraint *i, *j;
1650 int empty_loop = 0;
1652 /* It can happen that loop be NULL when an input polyhedron is empty. */
1653 if (loop == NULL)
1654 return;
1656 /* The constraints do not always have a shape that allows us to generate code from it,
1657 * thus we normalize it, we also simplify it with the equalities.
1659 temp = cloog_domain_constraints(loop->domain);
1660 cloog_constraint_set_normalize(temp,level);
1661 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1662 infos->names->nb_parameters);
1663 cloog_constraint_set_free(temp);
1664 if (level) {
1665 cloog_int_set(infos->stride[level-1], loop->stride);
1666 cloog_int_set(infos->offset[level-1], loop->offset);
1669 /* First of all we have to print the guard. */
1670 insert_guard(constraints,level, next, infos);
1672 if (level && cloog_constraint_set_contains_level(constraints, level,
1673 infos->names->nb_parameters)) {
1674 /* We scan all the constraints to know in which case we are :
1675 * [[if] equation] or [for].
1677 if (cloog_constraint_is_valid(i =
1678 cloog_constraint_set_defining_equality(constraints, level))) {
1679 empty_loop = !insert_equation(i, cloog_constraint_invalid(),
1680 level, next, infos);
1681 equality = 1 ;
1682 } else if (cloog_constraint_is_valid(i =
1683 cloog_constraint_set_defining_inequalities(constraints,
1684 level, &j, infos->names->nb_parameters))) {
1685 empty_loop = !insert_equation(i, j, level, next, infos);
1686 } else
1687 empty_loop = !insert_for(constraints, level, loop->otl, next, infos);
1690 if (!empty_loop) {
1691 /* Finally, if there is an included statement block, print it. */
1692 insert_block(loop->block, level+equality, next, infos);
1694 /* Go to the next level. */
1695 if (loop->inner != NULL)
1696 insert_loop(loop->inner, level+1, next, infos);
1699 if (level)
1700 cloog_equal_del(infos->equal,level);
1701 cloog_constraint_set_free(constraints);
1703 /* Go to the next loop on the same level. */
1704 while (*top)
1705 top = &(*top)->next;
1706 if (loop->next != NULL)
1707 insert_loop(loop->next, level, &top,infos);
1711 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1712 CloogOptions *options)
1714 CloogInfos *infos = ALLOC(CloogInfos);
1715 int i, nb_levels;
1716 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1717 struct clast_stmt **next = &root->next;
1719 infos->state = options->state;
1720 infos->names = program->names;
1721 infos->options = options;
1722 infos->scaldims = program->scaldims;
1723 infos->nb_scattdims = program->nb_scattdims;
1725 /* Allocation for the array of strides, there is a +1 since the statement can
1726 * be included inside an external loop without iteration domain.
1728 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1729 infos->stride = ALLOCN(cloog_int_t, nb_levels);
1730 infos->offset = ALLOCN(cloog_int_t, nb_levels);
1731 for (i = 0; i < nb_levels; ++i) {
1732 cloog_int_init(infos->stride[i]);
1733 cloog_int_init(infos->offset[i]);
1736 infos->equal = cloog_equal_alloc(nb_levels,
1737 nb_levels, program->names->nb_parameters);
1739 insert_loop(program->loop, 0, &next, infos);
1741 cloog_equal_free(infos->equal);
1743 for (i = 0; i < nb_levels; ++i) {
1744 cloog_int_clear(infos->stride[i]);
1745 cloog_int_clear(infos->offset[i]);
1747 free(infos->stride);
1748 free(infos->offset);
1749 free(infos);
1751 return root;
1755 struct clast_stmt *cloog_clast_create_from_input(CloogInput *input,
1756 CloogOptions *options)
1758 CloogProgram *program;
1759 struct clast_stmt *root;
1761 program = cloog_program_alloc(input->context, input->ud, options);
1762 free(input);
1764 program = cloog_program_generate(program, options);
1766 root = cloog_clast_create(program, options);
1767 cloog_program_free(program);
1769 return root;