CLooG 0.18.4
[cloog.git] / source / clast.c
bloba4fb958b28c3b2935ac6e31721484753805fa7b8
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 stride_level; /**< Number of valid entries in stride array. */
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, int no_earlier,
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(CloogDomain *domain, CloogConstraint *upper,
56 CloogConstraint *lower, int level,
57 struct clast_stmt ***next, CloogInfos *infos);
58 static int insert_for(CloogDomain *domain, CloogConstraintSet *constraints,
59 int level, int otl, struct clast_stmt ***next,
60 CloogInfos *infos);
61 static void insert_block(CloogDomain *domain, CloogBlock *block, int level,
62 struct clast_stmt ***next, CloogInfos *infos);
63 static void insert_loop(CloogLoop * loop, int level,
64 struct clast_stmt ***next, CloogInfos *infos);
67 struct clast_name *new_clast_name(const char *name)
69 struct clast_name *n = malloc(sizeof(struct clast_name));
70 n->expr.type = clast_expr_name;
71 n->name = name;
72 return n;
75 struct clast_term *new_clast_term(cloog_int_t c, struct clast_expr *v)
77 struct clast_term *t = malloc(sizeof(struct clast_term));
78 t->expr.type = clast_expr_term;
79 cloog_int_init(t->val);
80 cloog_int_set(t->val, c);
81 t->var = v;
82 return t;
85 struct clast_binary *new_clast_binary(enum clast_bin_type t,
86 struct clast_expr *lhs, cloog_int_t rhs)
88 struct clast_binary *b = malloc(sizeof(struct clast_binary));
89 b->expr.type = clast_expr_bin;
90 b->type = t;
91 b->LHS = lhs;
92 cloog_int_init(b->RHS);
93 cloog_int_set(b->RHS, rhs);
94 return b;
97 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
99 int i;
100 struct clast_reduction *r;
101 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
102 r->expr.type = clast_expr_red;
103 r->type = t;
104 r->n = n;
105 for (i = 0; i < n; ++i)
106 r->elts[i] = NULL;
107 return r;
110 static void free_clast_root(struct clast_stmt *s);
112 const struct clast_stmt_op stmt_root = { free_clast_root };
114 static void free_clast_root(struct clast_stmt *s)
116 struct clast_root *r = (struct clast_root *)s;
117 assert(CLAST_STMT_IS_A(s, stmt_root));
118 cloog_names_free(r->names);
119 free(r);
122 struct clast_root *new_clast_root(CloogNames *names)
124 struct clast_root *r = malloc(sizeof(struct clast_root));
125 r->stmt.op = &stmt_root;
126 r->stmt.next = NULL;
127 r->names = cloog_names_copy(names);
128 return r;
131 static void free_clast_assignment(struct clast_stmt *s);
133 const struct clast_stmt_op stmt_ass = { free_clast_assignment };
135 static void free_clast_assignment(struct clast_stmt *s)
137 struct clast_assignment *a = (struct clast_assignment *)s;
138 assert(CLAST_STMT_IS_A(s, stmt_ass));
139 free_clast_expr(a->RHS);
140 free(a);
143 struct clast_assignment *new_clast_assignment(const char *lhs,
144 struct clast_expr *rhs)
146 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
147 a->stmt.op = &stmt_ass;
148 a->stmt.next = NULL;
149 a->LHS = lhs;
150 a->RHS = rhs;
151 return a;
154 static void free_clast_user_stmt(struct clast_stmt *s);
156 const struct clast_stmt_op stmt_user = { free_clast_user_stmt };
158 static void free_clast_user_stmt(struct clast_stmt *s)
160 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
161 assert(CLAST_STMT_IS_A(s, stmt_user));
162 cloog_domain_free(u->domain);
163 cloog_statement_free(u->statement);
164 cloog_clast_free(u->substitutions);
165 free(u);
168 struct clast_user_stmt *new_clast_user_stmt(CloogDomain *domain,
169 CloogStatement *stmt, struct clast_stmt *subs)
171 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
172 u->stmt.op = &stmt_user;
173 u->stmt.next = NULL;
174 u->domain = cloog_domain_copy(domain);
175 u->statement = cloog_statement_copy(stmt);
176 u->substitutions = subs;
177 return u;
180 static void free_clast_block(struct clast_stmt *b);
182 const struct clast_stmt_op stmt_block = { free_clast_block };
184 static void free_clast_block(struct clast_stmt *s)
186 struct clast_block *b = (struct clast_block *)s;
187 assert(CLAST_STMT_IS_A(s, stmt_block));
188 cloog_clast_free(b->body);
189 free(b);
192 struct clast_block *new_clast_block()
194 struct clast_block *b = malloc(sizeof(struct clast_block));
195 b->stmt.op = &stmt_block;
196 b->stmt.next = NULL;
197 b->body = NULL;
198 return b;
201 static void free_clast_for(struct clast_stmt *s);
203 const struct clast_stmt_op stmt_for = { free_clast_for };
205 static void free_clast_for(struct clast_stmt *s)
207 struct clast_for *f = (struct clast_for *)s;
208 assert(CLAST_STMT_IS_A(s, stmt_for));
209 cloog_domain_free(f->domain);
210 free_clast_expr(f->LB);
211 free_clast_expr(f->UB);
212 cloog_int_clear(f->stride);
213 cloog_clast_free(f->body);
214 if (f->private_vars) free(f->private_vars);
215 if (f->reduction_vars) free(f->reduction_vars);
216 if (f->time_var_name) free(f->time_var_name);
217 free(f);
220 struct clast_for *new_clast_for(CloogDomain *domain, const char *it,
221 struct clast_expr *LB, struct clast_expr *UB,
222 CloogStride *stride)
224 struct clast_for *f = malloc(sizeof(struct clast_for));
225 f->stmt.op = &stmt_for;
226 f->stmt.next = NULL;
227 f->domain = cloog_domain_copy(domain);
228 f->iterator = it;
229 f->LB = LB;
230 f->UB = UB;
231 f->body = NULL;
232 f->parallel = CLAST_PARALLEL_NOT;
233 f->private_vars = NULL;
234 f->reduction_vars = NULL;
235 f->time_var_name = NULL;
236 cloog_int_init(f->stride);
237 if (stride)
238 cloog_int_set(f->stride, stride->stride);
239 else
240 cloog_int_set_si(f->stride, 1);
241 return f;
244 static void free_clast_guard(struct clast_stmt *s);
246 const struct clast_stmt_op stmt_guard = { free_clast_guard };
248 static void free_clast_guard(struct clast_stmt *s)
250 int i;
251 struct clast_guard *g = (struct clast_guard *)s;
252 assert(CLAST_STMT_IS_A(s, stmt_guard));
253 cloog_clast_free(g->then);
254 for (i = 0; i < g->n; ++i) {
255 free_clast_expr(g->eq[i].LHS);
256 free_clast_expr(g->eq[i].RHS);
258 free(g);
261 struct clast_guard *new_clast_guard(int n)
263 int i;
264 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
265 (n-1) * sizeof(struct clast_equation));
266 g->stmt.op = &stmt_guard;
267 g->stmt.next = NULL;
268 g->then = NULL;
269 g->n = n;
270 for (i = 0; i < n; ++i) {
271 g->eq[i].LHS = NULL;
272 g->eq[i].RHS = NULL;
274 return g;
277 void free_clast_name(struct clast_name *n)
279 free(n);
282 void free_clast_term(struct clast_term *t)
284 cloog_int_clear(t->val);
285 free_clast_expr(t->var);
286 free(t);
289 void free_clast_binary(struct clast_binary *b)
291 cloog_int_clear(b->RHS);
292 free_clast_expr(b->LHS);
293 free(b);
296 void free_clast_reduction(struct clast_reduction *r)
298 int i;
299 for (i = 0; i < r->n; ++i)
300 free_clast_expr(r->elts[i]);
301 free(r);
304 void free_clast_expr(struct clast_expr *e)
306 if (!e)
307 return;
308 switch (e->type) {
309 case clast_expr_name:
310 free_clast_name((struct clast_name*) e);
311 break;
312 case clast_expr_term:
313 free_clast_term((struct clast_term*) e);
314 break;
315 case clast_expr_red:
316 free_clast_reduction((struct clast_reduction*) e);
317 break;
318 case clast_expr_bin:
319 free_clast_binary((struct clast_binary*) e);
320 break;
321 default:
322 assert(0);
326 void free_clast_stmt(struct clast_stmt *s)
328 assert(s->op);
329 assert(s->op->free);
330 s->op->free(s);
333 void cloog_clast_free(struct clast_stmt *s)
335 struct clast_stmt *next;
336 while (s) {
337 next = s->next;
338 free_clast_stmt(s);
339 s = next;
343 static int clast_name_cmp(struct clast_name *n1, struct clast_name *n2)
345 return n1->name == n2->name ? 0 : strcmp(n1->name, n2->name);
348 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
350 int c;
351 if (!t1->var && t2->var)
352 return -1;
353 if (t1->var && !t2->var)
354 return 1;
355 c = clast_expr_cmp(t1->var, t2->var);
356 if (c)
357 return c;
358 return cloog_int_cmp(t1->val, t2->val);
361 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
363 int c;
365 if (b1->type != b2->type)
366 return b1->type - b2->type;
367 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
368 return c;
369 return clast_expr_cmp(b1->LHS, b2->LHS);
372 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
374 int i;
375 int c;
377 if (r1->n == 1 && r2->n == 1)
378 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
379 if (r1->type != r2->type)
380 return r1->type - r2->type;
381 if (r1->n != r2->n)
382 return r1->n - r2->n;
383 for (i = 0; i < r1->n; ++i)
384 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
385 return c;
386 return 0;
389 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
391 if (!e1 && !e2)
392 return 0;
393 if (!e1)
394 return -1;
395 if (!e2)
396 return 1;
397 if (e1->type != e2->type)
398 return e1->type - e2->type;
399 switch (e1->type) {
400 case clast_expr_name:
401 return clast_name_cmp((struct clast_name*) e1,
402 (struct clast_name*) e2);
403 case clast_expr_term:
404 return clast_term_cmp((struct clast_term*) e1,
405 (struct clast_term*) e2);
406 case clast_expr_bin:
407 return clast_binary_cmp((struct clast_binary*) e1,
408 (struct clast_binary*) e2);
409 case clast_expr_red:
410 return clast_reduction_cmp((struct clast_reduction*) e1,
411 (struct clast_reduction*) e2);
412 default:
413 assert(0);
417 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
419 return clast_expr_cmp(e1, e2) == 0;
423 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
425 int clast_expr_is_bigger_constant(struct clast_expr *e1, struct clast_expr *e2)
427 struct clast_term *t1, *t2;
428 struct clast_reduction *r;
430 if (!e1 || !e2)
431 return 0;
432 if (e1->type == clast_expr_red) {
433 r = (struct clast_reduction *)e1;
434 return r->n == 1 && clast_expr_is_bigger_constant(r->elts[0], e2);
436 if (e2->type == clast_expr_red) {
437 r = (struct clast_reduction *)e2;
438 return r->n == 1 && clast_expr_is_bigger_constant(e1, r->elts[0]);
440 if (e1->type != clast_expr_term || e2->type != clast_expr_term)
441 return 0;
442 t1 = (struct clast_term *)e1;
443 t2 = (struct clast_term *)e2;
444 if (t1->var || t2->var)
445 return 0;
446 return cloog_int_gt(t1->val, t2->val);
449 static int qsort_expr_cmp(const void *p1, const void *p2)
451 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
454 static void clast_reduction_sort(struct clast_reduction *r)
456 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
459 static int qsort_eq_cmp(const void *p1, const void *p2)
461 struct clast_equation *eq1 = (struct clast_equation *)p1;
462 struct clast_equation *eq2 = (struct clast_equation *)p2;
463 int cmp;
465 cmp = clast_expr_cmp(eq1->LHS, eq2->LHS);
466 if (cmp)
467 return cmp;
469 cmp = clast_expr_cmp(eq1->RHS, eq2->RHS);
470 if (cmp)
471 return cmp;
473 return eq1->sign - eq2->sign;
477 * Sort equations in a clast_guard.
479 static void clast_guard_sort(struct clast_guard *g)
481 qsort(&g->eq[0], g->n, sizeof(struct clast_equation), qsort_eq_cmp);
486 * Construct a (deep) copy of an expression clast.
488 static struct clast_expr *clast_expr_copy(struct clast_expr *e)
490 if (!e)
491 return NULL;
492 switch (e->type) {
493 case clast_expr_name: {
494 struct clast_name* n = (struct clast_name*) e;
495 return &new_clast_name(n->name)->expr;
497 case clast_expr_term: {
498 struct clast_term* t = (struct clast_term*) e;
499 return &new_clast_term(t->val, clast_expr_copy(t->var))->expr;
501 case clast_expr_red: {
502 int i;
503 struct clast_reduction *r = (struct clast_reduction*) e;
504 struct clast_reduction *r2 = new_clast_reduction(r->type, r->n);
505 for (i = 0; i < r->n; ++i)
506 r2->elts[i] = clast_expr_copy(r->elts[i]);
507 return &r2->expr;
509 case clast_expr_bin: {
510 struct clast_binary *b = (struct clast_binary*) e;
511 return &new_clast_binary(b->type, clast_expr_copy(b->LHS), b->RHS)->expr;
513 default:
514 assert(0);
519 /******************************************************************************
520 * Equalities spreading functions *
521 ******************************************************************************/
525 * clast_equal_allow function:
526 * This function checks whether the options allow us to spread the equality or
527 * not. It returns 1 if so, 0 otherwise.
528 * - equal is the matrix of equalities,
529 * - level is the column number in equal of the element which is 'equal to',
530 * - line is the line number in equal of the constraint we want to study,
531 * - the infos structure gives the user all options on code printing and more.
533 * - October 27th 2005: first version (extracted from old pprint_equal_add).
535 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
536 CloogInfos *infos)
538 if (level < infos->options->fsp)
539 return 0 ;
541 if ((cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
542 !infos->options->esp)
543 return 0 ;
545 return 1 ;
550 * clast_equal_add function:
551 * This function updates the row (level-1) of the equality matrix (equal) with
552 * the row that corresponds to the row (line) of the matrix (matrix). It returns
553 * 1 if the row can be updated, 0 otherwise.
554 * - equal is the matrix of equalities,
555 * - matrix is the matrix of constraints,
556 * - level is the column number in matrix of the element which is 'equal to',
557 * - line is the line number in matrix of the constraint we want to study,
558 * - the infos structure gives the user all options on code printing and more.
560 static int clast_equal_add(CloogEqualities *equal,
561 CloogConstraintSet *constraints,
562 int level, CloogConstraint *constraint,
563 CloogInfos *infos)
565 cloog_equal_add(equal, constraints, level, constraint,
566 infos->names->nb_parameters);
568 return clast_equal_allow(equal, level, level-1, infos);
574 * clast_equal function:
575 * This function prints the substitution data of a statement into a clast_stmt.
576 * Using this function instead of pprint_equal is useful for generating
577 * a compilable pseudo-code by using preprocessor macro for each statement.
578 * By opposition to pprint_equal, the result is less human-readable. For
579 * instance this function will print (i,i+3,k,3) where pprint_equal would
580 * return (j=i+3,l=3).
581 * - level is the number of loops enclosing the statement,
582 * - the infos structure gives the user all options on code printing and more.
584 * - March 12th 2004: first version.
585 * - November 21th 2005: (debug) now works well with GMP version.
587 static struct clast_stmt *clast_equal(int level, CloogInfos *infos)
589 int i ;
590 struct clast_expr *e;
591 struct clast_stmt *a = NULL;
592 struct clast_stmt **next = &a;
593 CloogEqualities *equal = infos->equal;
594 CloogConstraint *equal_constraint;
596 for (i=infos->names->nb_scattering;i<level-1;i++)
597 { if (cloog_equal_type(equal, i+1)) {
598 equal_constraint = cloog_equal_constraint(equal, i);
599 e = clast_bound_from_constraint(equal_constraint, i+1, infos->names);
600 cloog_constraint_release(equal_constraint);
601 } else {
602 e = &new_clast_term(infos->state->one, &new_clast_name(
603 cloog_names_name_at_level(infos->names, i+1))->expr)->expr;
605 *next = &new_clast_assignment(NULL, e)->stmt;
606 next = &(*next)->next;
609 return a;
614 * clast_bound_from_constraint function:
615 * This function returns a clast_expr containing the printing of the
616 * 'right part' of a constraint according to an element.
617 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
618 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
619 * function should return 'ceild(3*i+M,2)'.
620 * - matrix is the polyhedron containing all the constraints,
621 * - line_num is the line number in domain of the constraint we want to print,
622 * - level is the column number in domain of the element we want to use,
623 * - names structure gives the user some options about code printing,
624 * the number of parameters in domain (nb_par), and the arrays of iterator
625 * names and parameters (iters and params).
627 * - November 2nd 2001: first version.
628 * - June 27th 2003: 64 bits version ready.
630 struct clast_expr *clast_bound_from_constraint(CloogConstraint *constraint,
631 int level, CloogNames *names)
633 int i, sign, nb_elts=0, len;
634 cloog_int_t *line, numerator, denominator, temp, division;
635 struct clast_expr *e = NULL;
636 struct cloog_vec *line_vector;
638 len = cloog_constraint_total_dimension(constraint) + 2;
639 line_vector = cloog_vec_alloc(len);
640 line = line_vector->p;
641 cloog_constraint_copy_coefficients(constraint, line+1);
642 cloog_int_init(temp);
643 cloog_int_init(numerator);
644 cloog_int_init(denominator);
646 if (!cloog_int_is_zero(line[level])) {
647 struct clast_reduction *r;
648 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
649 sign = -cloog_int_sgn(line[level]);
651 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
652 if (i != level && !cloog_int_is_zero(line[i]))
653 nb_elts++;
654 r = new_clast_reduction(clast_red_sum, nb_elts);
655 nb_elts = 0;
657 /* First, we have to print the iterators and the parameters. */
658 for (i = 1; i <= len - 2; i++) {
659 struct clast_expr *v;
661 if (i == level || cloog_int_is_zero(line[i]))
662 continue;
664 v = cloog_constraint_variable_expr(constraint, i, names);
666 if (sign == -1)
667 cloog_int_neg(temp,line[i]);
668 else
669 cloog_int_set(temp,line[i]);
671 r->elts[nb_elts++] = &new_clast_term(temp, v)->expr;
674 if (sign == -1) {
675 cloog_int_neg(numerator, line[len - 1]);
676 cloog_int_set(denominator, line[level]);
678 else {
679 cloog_int_set(numerator, line[len - 1]);
680 cloog_int_neg(denominator, line[level]);
683 /* Finally, the constant, and the final printing. */
684 if (nb_elts) {
685 if (!cloog_int_is_zero(numerator))
686 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
688 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
689 { if (!cloog_constraint_is_equality(constraint))
690 { if (cloog_int_is_pos(line[level]))
691 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
692 else
693 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
694 } else
695 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
697 else
698 e = &r->expr;
699 } else {
700 free_clast_reduction(r);
701 if (cloog_int_is_zero(numerator))
702 e = &new_clast_term(numerator, NULL)->expr;
703 else
704 { if (!cloog_int_is_one(denominator))
705 { if (!cloog_constraint_is_equality(constraint)) { /* useful? */
706 if (cloog_int_is_divisible_by(numerator, denominator)) {
707 cloog_int_divexact(temp, numerator, denominator);
708 e = &new_clast_term(temp, NULL)->expr;
710 else {
711 cloog_int_init(division);
712 cloog_int_tdiv_q(division, numerator, denominator);
713 if (cloog_int_is_neg(numerator)) {
714 if (cloog_int_is_pos(line[level])) {
715 /* nb<0 need max */
716 e = &new_clast_term(division, NULL)->expr;
717 } else {
718 /* nb<0 need min */
719 cloog_int_sub_ui(temp, division, 1);
720 e = &new_clast_term(temp, NULL)->expr;
723 else
724 { if (cloog_int_is_pos(line[level]))
725 { /* nb>0 need max */
726 cloog_int_add_ui(temp, division, 1);
727 e = &new_clast_term(temp, NULL)->expr;
729 else
730 /* nb>0 need min */
731 e = &new_clast_term(division, NULL)->expr;
733 cloog_int_clear(division);
736 else
737 e = &new_clast_binary(clast_bin_div,
738 &new_clast_term(numerator, NULL)->expr,
739 denominator)->expr;
741 else
742 e = &new_clast_term(numerator, NULL)->expr;
747 cloog_vec_free(line_vector);
749 cloog_int_clear(temp);
750 cloog_int_clear(numerator);
751 cloog_int_clear(denominator);
753 return e;
757 /* Temporary structure for communication between clast_minmax and
758 * its cloog_constraint_set_foreach_constraint callback functions.
760 struct clast_minmax_data {
761 int level;
762 int max;
763 int guard;
764 int lower_bound;
765 int no_earlier;
766 CloogInfos *infos;
767 int n;
768 struct clast_reduction *r;
772 /* Should constraint "c" be considered by clast_minmax?
774 * If d->no_earlier is set, then the constraint may not involve
775 * any earlier variables.
777 static int valid_bound(CloogConstraint *c, struct clast_minmax_data *d)
779 int i;
781 if (d->max && !cloog_constraint_is_lower_bound(c, d->level - 1))
782 return 0;
783 if (!d->max && !cloog_constraint_is_upper_bound(c, d->level - 1))
784 return 0;
785 if (cloog_constraint_is_equality(c))
786 return 0;
787 if (d->guard && cloog_constraint_involves(c, d->guard - 1))
788 return 0;
790 if (d->no_earlier)
791 for (i = 0; i < d->level - 1; ++i)
792 if (cloog_constraint_involves(c, i))
793 return 0;
795 return 1;
799 /* Increment n for each bound that should be considered by clast_minmax.
801 static int count_bounds(CloogConstraint *c, void *user)
803 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
805 if (!valid_bound(c, d))
806 return 0;
808 d->n++;
810 return 0;
814 /* Update the given lower bound based on stride information,
815 * for those cases where the stride offset is represented by
816 * a constraint.
817 * Note that cloog_loop_stride may have already performed a
818 * similar update of the lower bounds, but the updated lower
819 * bounds may have been eliminated because they are redundant
820 * by definition. On the other hand, performing the update
821 * on an already updated constraint is an identity operation
822 * and is therefore harmless.
824 static CloogConstraint *update_lower_bound_c(CloogConstraint *c, int level,
825 CloogStride *stride)
827 if (!stride->constraint)
828 return c;
829 return cloog_constraint_stride_lower_bound(c, level, stride);
833 /* Update the given lower bound based on stride information.
834 * If the stride offset is represented by a constraint,
835 * then we have already performed the update in update_lower_bound_c.
836 * Otherwise, the original lower bound is known to be a constant.
837 * If the bound has already been updated and it just happens
838 * to be a constant, then this function performs an identity
839 * operation on the constant.
841 static void update_lower_bound(struct clast_expr *expr, int level,
842 CloogStride *stride)
844 struct clast_term *t;
845 if (stride->constraint)
846 return;
847 if (expr->type != clast_expr_term)
848 return;
849 t = (struct clast_term *)expr;
850 if (t->var)
851 return;
852 cloog_int_sub(t->val, t->val, stride->offset);
853 cloog_int_cdiv_q(t->val, t->val, stride->stride);
854 cloog_int_mul(t->val, t->val, stride->stride);
855 cloog_int_add(t->val, t->val, stride->offset);
859 /* Add all relevant bounds to r->elts and update lower bounds
860 * based on stride information.
862 static int collect_bounds(CloogConstraint *c, void *user)
864 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
866 if (!valid_bound(c, d))
867 return 0;
869 c = cloog_constraint_copy(c);
871 if (d->lower_bound && d->infos->stride[d->level - 1])
872 c = update_lower_bound_c(c, d->level, d->infos->stride[d->level - 1]);
874 d->r->elts[d->n] = clast_bound_from_constraint(c, d->level,
875 d->infos->names);
876 if (d->lower_bound && d->infos->stride[d->level - 1]) {
877 update_lower_bound(d->r->elts[d->n], d->level,
878 d->infos->stride[d->level - 1]);
881 cloog_constraint_release(c);
883 d->n++;
885 return 0;
890 * clast_minmax function:
891 * This function returns a clast_expr containing the printing of a minimum or a
892 * maximum of the 'right parts' of all constraints according to an element.
893 * For instance consider the constraints:
894 * -3*i +2*j -M >= 0
895 * 2*i +j >= 0
896 * -i -j +2*M >= 0
897 * if we are looking for the minimum for the element j, the function should
898 * return 'max(ceild(3*i+M,2),-2*i)'.
899 * - constraints is the constraints,
900 * - level is the column number in domain of the element we want to use,
901 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
902 * - guard is set to 0 if there is no guard, and set to the level of the element
903 * with a guard otherwise (then the function gives the max or the min only
904 * for the constraint where the guarded coefficient is 0),
905 * - lower is set to 1 if the maximum is to be used a lower bound on a loop
906 * - no_earlier is set if no constraints should be used that involve
907 * earlier dimensions,
908 * - the infos structure gives the user some options about code printing,
909 * the number of parameters in domain (nb_par), and the arrays of iterator
910 * names and parameters (iters and params).
912 * - November 2nd 2001: first version.
914 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
915 int level, int max, int guard,
916 int lower_bound, int no_earlier,
917 CloogInfos *infos)
919 struct clast_minmax_data data = { level, max, guard, lower_bound,
920 no_earlier, infos };
922 data.n = 0;
924 cloog_constraint_set_foreach_constraint(constraints, count_bounds, &data);
926 if (!data.n)
927 return NULL;
928 data.r = new_clast_reduction(max ? clast_red_max : clast_red_min, data.n);
930 data.n = 0;
931 cloog_constraint_set_foreach_constraint(constraints, collect_bounds, &data);
933 clast_reduction_sort(data.r);
934 return &data.r->expr;
939 * Insert modulo guards defined by existentially quantified dimensions,
940 * not involving the given level.
942 * This function is called from within insert_guard.
943 * Any constraint used in constructing a modulo guard is removed
944 * from the constraint set to avoid insert_guard
945 * adding a duplicate (pair of) constraint(s).
947 * Return the updated CloogConstraintSet.
949 static CloogConstraintSet *insert_extra_modulo_guards(
950 CloogConstraintSet *constraints, int level,
951 struct clast_stmt ***next, CloogInfos *infos)
953 int i;
954 int nb_iter;
955 int total_dim;
956 CloogConstraint *upper, *lower;
958 total_dim = cloog_constraint_set_total_dimension(constraints);
959 nb_iter = cloog_constraint_set_n_iterators(constraints,
960 infos->names->nb_parameters);
962 for (i = total_dim - infos->names->nb_parameters; i >= nb_iter + 1; i--) {
963 if (cloog_constraint_is_valid(upper =
964 cloog_constraint_set_defining_equality(constraints, i))) {
965 if (!level || (nb_iter < level) ||
966 !cloog_constraint_involves(upper, level-1)) {
967 insert_modulo_guard(upper,
968 cloog_constraint_invalid(), i, next, infos);
969 constraints = cloog_constraint_set_drop_constraint(constraints,
970 upper);
972 cloog_constraint_release(upper);
973 } else if (cloog_constraint_is_valid(upper =
974 cloog_constraint_set_defining_inequalities(constraints,
975 i, &lower, infos->names->nb_parameters))) {
976 if (!level || (nb_iter < level) ||
977 !cloog_constraint_involves(upper, level-1)) {
978 insert_modulo_guard(upper, lower, i, next, infos);
979 constraints = cloog_constraint_set_drop_constraint(constraints,
980 upper);
981 constraints = cloog_constraint_set_drop_constraint(constraints,
982 lower);
984 cloog_constraint_release(upper);
985 cloog_constraint_release(lower);
989 return constraints;
993 /* Temporary structure for communication between insert_guard and
994 * its cloog_constraint_set_foreach_constraint callback function.
996 struct clast_guard_data {
997 int level;
998 CloogInfos *infos;
999 int n;
1000 int i;
1001 int nb_iter;
1002 CloogConstraintSet *copy;
1003 struct clast_guard *g;
1005 int min;
1006 int max;
1010 static int guard_count_bounds(CloogConstraint *c, void *user)
1012 struct clast_guard_data *d = (struct clast_guard_data *) user;
1014 d->n++;
1016 return 0;
1020 /* Insert a guard, if necesessary, for constraint j.
1022 * If the constraint involves any earlier dimensions, then we have
1023 * already considered it during a previous iteration over the constraints.
1025 * If we have already generated a min [max] for the current level d->i
1026 * and if the current constraint is an upper [lower] bound, then we
1027 * can skip the constraint as it will already have been used
1028 * in that previously generated min [max].
1030 static int insert_guard_constraint(CloogConstraint *j, void *user)
1032 int i;
1033 struct clast_guard_data *d = (struct clast_guard_data *) user;
1034 int minmax = -1;
1035 int individual_constraint;
1036 struct clast_expr *v;
1037 struct clast_term *t;
1039 if (!cloog_constraint_involves(j, d->i - 1))
1040 return 0;
1042 for (i = 0; i < d->i - 1; ++i)
1043 if (cloog_constraint_involves(j, i))
1044 return 0;
1046 if (d->level && d->nb_iter >= d->level &&
1047 cloog_constraint_involves(j, d->level - 1))
1048 return 0;
1050 individual_constraint = !d->level || cloog_constraint_is_equality(j);
1051 if (!individual_constraint) {
1052 if (d->max && cloog_constraint_is_lower_bound(j, d->i - 1))
1053 return 0;
1054 if (d->min && cloog_constraint_is_upper_bound(j, d->i - 1))
1055 return 0;
1058 v = cloog_constraint_variable_expr(j, d->i, d->infos->names);
1059 d->g->eq[d->n].LHS = &(t = new_clast_term(d->infos->state->one, v))->expr;
1060 if (individual_constraint) {
1061 /* put the "denominator" in the LHS */
1062 cloog_constraint_coefficient_get(j, d->i - 1, &t->val);
1063 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->one);
1064 if (cloog_int_is_neg(t->val)) {
1065 cloog_int_neg(t->val, t->val);
1066 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->negone);
1068 if (d->level || cloog_constraint_is_equality(j))
1069 d->g->eq[d->n].sign = 0;
1070 else if (cloog_constraint_is_lower_bound(j, d->i - 1))
1071 d->g->eq[d->n].sign = 1;
1072 else
1073 d->g->eq[d->n].sign = -1;
1074 d->g->eq[d->n].RHS = clast_bound_from_constraint(j, d->i, d->infos->names);
1075 } else {
1076 int guarded;
1078 if (cloog_constraint_is_lower_bound(j, d->i - 1)) {
1079 minmax = 1;
1080 d->max = 1;
1081 d->g->eq[d->n].sign = 1;
1082 } else {
1083 minmax = 0;
1084 d->min = 1;
1085 d->g->eq[d->n].sign = -1;
1088 guarded = (d->nb_iter >= d->level) ? d->level : 0 ;
1089 d->g->eq[d->n].RHS = clast_minmax(d->copy, d->i, minmax, guarded, 0, 1,
1090 d->infos);
1092 d->n++;
1094 return 0;
1099 * insert_guard function:
1100 * This function inserts a guard in the clast.
1101 * A guard on an element (level) is :
1102 * -> the conjunction of all the existing constraints where the coefficient of
1103 * this element is 0 if the element is an iterator,
1104 * -> the conjunction of all the existing constraints if the element isn't an
1105 * iterator.
1106 * For instance, considering these constraints and the element j:
1107 * -3*i +2*j -M >= 0
1108 * 2*i +M >= 0
1109 * this function should return 'if (2*i+M>=0) {'.
1110 * - matrix is the polyhedron containing all the constraints,
1111 * - level is the column number of the element in matrix we want to use,
1112 * - the infos structure gives the user some options about code printing,
1113 * the number of parameters in matrix (nb_par), and the arrays of iterator
1114 * names and parameters (iters and params).
1116 * - November 3rd 2001: first version.
1117 * - November 14th 2001: a lot of 'purifications'.
1118 * - July 31th 2002: (debug) some guard parts are no more redundants.
1119 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
1120 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
1121 * (the need came from loop_simplify that may result in
1122 * domain unions, now it should be fixed directly in
1123 * cloog_loop_simplify).
1125 static void insert_guard(CloogConstraintSet *constraints, int level,
1126 struct clast_stmt ***next, CloogInfos *infos)
1128 int total_dim;
1129 struct clast_guard_data data = { level, infos, 0 };
1131 if (!constraints)
1132 return;
1134 data.copy = cloog_constraint_set_copy(constraints);
1136 data.copy = insert_extra_modulo_guards(data.copy, level, next, infos);
1138 cloog_constraint_set_foreach_constraint(constraints,
1139 guard_count_bounds, &data);
1141 data.g = new_clast_guard(data.n);
1142 data.n = 0;
1144 /* Well, it looks complicated because I wanted to have a particular, more
1145 * readable, ordering, obviously this function may be far much simpler !
1147 data.nb_iter = cloog_constraint_set_n_iterators(constraints,
1148 infos->names->nb_parameters);
1150 /* We search for guard parts. */
1151 total_dim = cloog_constraint_set_total_dimension(constraints);
1152 for (data.i = 1; data.i <= total_dim; data.i++) {
1153 data.min = 0;
1154 data.max = 0;
1155 cloog_constraint_set_foreach_constraint(data.copy,
1156 insert_guard_constraint, &data);
1159 cloog_constraint_set_free(data.copy);
1161 data.g->n = data.n;
1162 if (data.n) {
1163 clast_guard_sort(data.g);
1164 **next = &data.g->stmt;
1165 *next = &data.g->then;
1166 } else
1167 free_clast_stmt(&data.g->stmt);
1171 * Check if the constant "cst" satisfies the modulo guard that
1172 * would be introduced by insert_computed_modulo_guard.
1173 * The constant is assumed to have been reduced prior to calling
1174 * this function.
1176 static int constant_modulo_guard_is_satisfied(CloogConstraint *lower,
1177 cloog_int_t bound, cloog_int_t cst)
1179 if (cloog_constraint_is_valid(lower))
1180 return cloog_int_le(cst, bound);
1181 else
1182 return cloog_int_is_zero(cst);
1186 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
1187 * depending on whether lower represents a valid constraint.
1189 static void insert_computed_modulo_guard(struct clast_reduction *r,
1190 CloogConstraint *lower, cloog_int_t mod, cloog_int_t bound,
1191 struct clast_stmt ***next)
1193 struct clast_expr *e;
1194 struct clast_guard *g;
1196 e = &new_clast_binary(clast_bin_mod, &r->expr, mod)->expr;
1197 g = new_clast_guard(1);
1198 if (!cloog_constraint_is_valid(lower)) {
1199 g->eq[0].LHS = e;
1200 cloog_int_set_si(bound, 0);
1201 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1202 g->eq[0].sign = 0;
1203 } else {
1204 g->eq[0].LHS = e;
1205 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1206 g->eq[0].sign = -1;
1209 **next = &g->stmt;
1210 *next = &g->then;
1214 /* Try and eliminate coefficients from a modulo constraint based on
1215 * stride information of an earlier level.
1216 * The modulo of the constraint being constructed is "m".
1217 * The stride information at level "level" is given by "stride"
1218 * and indicated that the iterator i at level "level" is equal to
1219 * some expression modulo stride->stride.
1220 * If stride->stride is a multiple of "m' then i is also equal to
1221 * the expression modulo m and so we can eliminate the coefficient of i.
1223 * If stride->constraint is NULL, then i has a constant value modulo m, stored
1224 * stride->offset. We simply multiply this constant with the coefficient
1225 * of i and add the result to the constant term, reducing it modulo m.
1227 * If stride->constraint is not NULL, then it is a constraint of the form
1229 * e + k i = s a
1231 * with s equal to stride->stride, e an expression in terms of the
1232 * parameters and earlier iterators and a some arbitrary expression
1233 * in terms of existentially quantified variables.
1234 * stride->factor is a value f such that f * k = -1 mod s.
1235 * Adding stride->constraint f * c times to the current modulo constraint,
1236 * with c the coefficient of i eliminates i in favor of parameters and
1237 * earlier variables.
1239 static void eliminate_using_stride_constraint(cloog_int_t *line, int len,
1240 int nb_iter, CloogStride *stride, int level, cloog_int_t m)
1242 if (!stride)
1243 return;
1244 if (!cloog_int_is_divisible_by(stride->stride, m))
1245 return;
1247 if (stride->constraint) {
1248 int i, s_len;
1249 cloog_int_t t, v;
1251 cloog_int_init(t);
1252 cloog_int_init(v);
1253 cloog_int_mul(t, line[level], stride->factor);
1254 for (i = 1; i < level; ++i) {
1255 cloog_constraint_coefficient_get(stride->constraint,
1256 i - 1, &v);
1257 cloog_int_addmul(line[i], t, v);
1258 cloog_int_fdiv_r(line[i], line[i], m);
1260 s_len = cloog_constraint_total_dimension(stride->constraint)+2;
1261 for (i = nb_iter + 1; i <= len - 2; ++i) {
1262 cloog_constraint_coefficient_get(stride->constraint,
1263 i - (len - s_len) - 1, &v);
1264 cloog_int_addmul(line[i], t, v);
1265 cloog_int_fdiv_r(line[i], line[i], m);
1267 cloog_constraint_constant_get(stride->constraint, &v);
1268 cloog_int_addmul(line[len - 1], t, v);
1269 cloog_int_fdiv_r(line[len - 1], line[len - 1], m);
1270 cloog_int_clear(v);
1271 cloog_int_clear(t);
1272 } else {
1273 cloog_int_addmul(line[len - 1], line[level], stride->offset);
1274 cloog_int_fdiv_r(line[len - 1], line[len - 1], m);
1277 cloog_int_set_si(line[level], 0);
1281 /* Temporary structure for communication between insert_modulo_guard and
1282 * its cloog_constraint_set_foreach_constraint callback function.
1284 struct clast_modulo_guard_data {
1285 CloogConstraint *lower;
1286 int level;
1287 struct clast_stmt ***next;
1288 CloogInfos *infos;
1289 int empty;
1290 cloog_int_t val, bound;
1294 /* Insert a modulo guard for constraint c.
1295 * The constraint may be either an equality or an inequality.
1296 * Since this function returns -1, it is only called on a single constraint.
1297 * In case of an inequality, the constraint is usually an upper bound
1298 * on d->level. However, if this variable is an existentially
1299 * quantified variable, the upper bound constraint may get removed
1300 * as trivially holding and then this function is called with
1301 * a lower bound instead. In this case, we need to adjust the constraint
1302 * based on the sum of the constant terms of the lower and upper bound
1303 * stored in d->bound.
1305 static int insert_modulo_guard_constraint(CloogConstraint *c, void *user)
1307 struct clast_modulo_guard_data *d = (struct clast_modulo_guard_data *) user;
1308 int level = d->level;
1309 CloogInfos *infos = d->infos;
1310 int i, nb_elts = 0, len, nb_iter, nb_par;
1311 int constant;
1312 struct cloog_vec *line_vector;
1313 cloog_int_t *line;
1315 len = cloog_constraint_total_dimension(c) + 2;
1316 nb_par = infos->names->nb_parameters;
1317 nb_iter = len - 2 - nb_par;
1319 line_vector = cloog_vec_alloc(len);
1320 line = line_vector->p;
1321 cloog_constraint_copy_coefficients(c, line + 1);
1323 if (cloog_int_is_pos(line[level])) {
1324 cloog_seq_neg(line + 1, line + 1, len - 1);
1325 if (!cloog_constraint_is_equality(c))
1326 cloog_int_add(line[len - 1], line[len - 1], d->bound);
1328 cloog_int_neg(line[level], line[level]);
1329 assert(cloog_int_is_pos(line[level]));
1331 nb_elts = 0;
1332 for (i = 1; i <= len-1; ++i) {
1333 if (i == level)
1334 continue;
1335 cloog_int_fdiv_r(line[i], line[i], line[level]);
1336 if (cloog_int_is_zero(line[i]))
1337 continue;
1338 if (i == len-1)
1339 continue;
1341 nb_elts++;
1344 if (nb_elts || !cloog_int_is_zero(line[len-1])) {
1345 struct clast_reduction *r;
1346 const char *name;
1348 r = new_clast_reduction(clast_red_sum, nb_elts + 1);
1349 nb_elts = 0;
1351 /* First, the modulo guard : the iterators... */
1352 i = level - 1;
1353 if (i > infos->stride_level)
1354 i = infos->stride_level;
1355 for (; i >= 1; --i)
1356 eliminate_using_stride_constraint(line, len, nb_iter,
1357 infos->stride[i - 1], i, line[level]);
1358 for (i=1;i<=nb_iter;i++) {
1359 if (i == level || cloog_int_is_zero(line[i]))
1360 continue;
1362 name = cloog_names_name_at_level(infos->names, i);
1364 r->elts[nb_elts++] = &new_clast_term(line[i],
1365 &new_clast_name(name)->expr)->expr;
1368 /* ...the parameters... */
1369 for (i=nb_iter+1;i<=len-2;i++) {
1370 if (cloog_int_is_zero(line[i]))
1371 continue;
1373 name = infos->names->parameters[i-nb_iter-1] ;
1374 r->elts[nb_elts++] = &new_clast_term(line[i],
1375 &new_clast_name(name)->expr)->expr;
1378 constant = nb_elts == 0;
1379 /* ...the constant. */
1380 if (!cloog_int_is_zero(line[len-1]))
1381 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1383 /* our initial computation may have been an overestimate */
1384 r->n = nb_elts;
1386 if (constant) {
1387 d->empty = !constant_modulo_guard_is_satisfied(d->lower, d->bound,
1388 line[len - 1]);
1389 free_clast_reduction(r);
1390 } else
1391 insert_computed_modulo_guard(r, d->lower, line[level], d->bound,
1392 d->next);
1395 cloog_vec_free(line_vector);
1397 return -1;
1402 * insert_modulo_guard:
1403 * This function inserts a modulo guard corresponding to an equality
1404 * or a pair of inequalities.
1405 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
1407 * See insert_equation.
1408 * - matrix is the polyhedron containing all the constraints,
1409 * - upper and lower are the line numbers of the constraint in matrix
1410 * we want to print; in particular, if we want to print an equality,
1411 * then lower == -1 and upper is the row of the equality; if we want
1412 * to print an inequality, then upper is the row of the upper bound
1413 * and lower in the row of the lower bound
1414 * - level is the column number of the element in matrix we want to use,
1415 * - the infos structure gives the user some options about code printing,
1416 * the number of parameters in matrix (nb_par), and the arrays of iterator
1417 * names and parameters (iters and params).
1419 static int insert_modulo_guard(CloogConstraint *upper,
1420 CloogConstraint *lower, int level,
1421 struct clast_stmt ***next, CloogInfos *infos)
1423 int nb_par;
1424 CloogConstraintSet *set;
1425 struct clast_modulo_guard_data data = { lower, level, next, infos, 0 };
1427 cloog_int_init(data.val);
1428 cloog_constraint_coefficient_get(upper, level-1, &data.val);
1429 if (cloog_int_is_one(data.val) || cloog_int_is_neg_one(data.val)) {
1430 cloog_int_clear(data.val);
1431 return 1;
1434 nb_par = infos->names->nb_parameters;
1436 cloog_int_init(data.bound);
1437 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1438 if (cloog_constraint_is_valid(lower)) {
1439 cloog_constraint_constant_get(upper, &data.val);
1440 cloog_constraint_constant_get(lower, &data.bound);
1441 cloog_int_add(data.bound, data.val, data.bound);
1442 cloog_constraint_coefficient_get(lower, level-1, &data.val);
1443 cloog_int_sub_ui(data.val, data.val, 1);
1444 if (cloog_int_eq(data.val, data.bound)) {
1445 cloog_int_clear(data.val);
1446 cloog_int_clear(data.bound);
1447 return 1;
1451 if (cloog_constraint_needs_reduction(upper, level)) {
1452 set = cloog_constraint_set_for_reduction(upper, lower);
1453 set = cloog_constraint_set_reduce(set, level, infos->equal,
1454 nb_par, &data.bound);
1455 cloog_constraint_set_foreach_constraint(set,
1456 insert_modulo_guard_constraint, &data);
1457 cloog_constraint_set_free(set);
1458 } else
1459 insert_modulo_guard_constraint(upper, &data);
1461 cloog_int_clear(data.val);
1462 cloog_int_clear(data.bound);
1464 return !data.empty;
1469 * We found an equality or a pair of inequalities identifying
1470 * a loop with a single iteration, but the user wants us to generate
1471 * a loop anyway, so we do it here.
1473 static int insert_equation_as_loop(CloogDomain *domain, CloogConstraint *upper,
1474 CloogConstraint *lower, int level, struct clast_stmt ***next,
1475 CloogInfos *infos)
1477 const char *iterator = cloog_names_name_at_level(infos->names, level);
1478 struct clast_expr *e1, *e2;
1479 struct clast_for *f;
1481 e2 = clast_bound_from_constraint(upper, level, infos->names);
1482 if (!cloog_constraint_is_valid(lower))
1483 e1 = clast_expr_copy(e2);
1484 else
1485 e1 = clast_bound_from_constraint(lower, level, infos->names);
1487 f = new_clast_for(domain, iterator, e1, e2, infos->stride[level-1]);
1488 **next = &f->stmt;
1489 *next = &f->body;
1491 cloog_constraint_release(lower);
1492 cloog_constraint_release(upper);
1493 return 1;
1498 * insert_equation function:
1499 * This function inserts an equality
1500 * constraint according to an element in the clast.
1501 * Returns 1 if the calling function should recurse into inner loops.
1503 * An equality can be preceded by a 'modulo guard'.
1504 * For instance, consider the constraint i -2*j = 0 and the
1505 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1506 * - matrix is the polyhedron containing all the constraints,
1507 * - num is the line number of the constraint in matrix we want to print,
1508 * - level is the column number of the element in matrix we want to use,
1509 * - the infos structure gives the user some options about code printing,
1510 * the number of parameters in matrix (nb_par), and the arrays of iterator
1511 * names and parameters (iters and params).
1513 * - November 13th 2001: first version.
1514 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1515 * modulo is 0, compare vivien or vivien2 with a previous
1516 * version for an idea).
1517 * - June 29th 2003: non-unit strides support.
1518 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1519 * it was previously included in a stride calculation.
1521 static int insert_equation(CloogDomain *domain, CloogConstraint *upper,
1522 CloogConstraint *lower, int level, struct clast_stmt
1523 ***next, CloogInfos *infos)
1525 struct clast_expr *e;
1526 struct clast_assignment *ass;
1528 if (!infos->options->otl)
1529 return insert_equation_as_loop(domain, upper, lower, level, next, infos);
1531 if (!insert_modulo_guard(upper, lower, level, next, infos)) {
1532 cloog_constraint_release(lower);
1533 cloog_constraint_release(upper);
1535 return 0;
1538 if (cloog_constraint_is_valid(lower) ||
1539 !clast_equal_add(infos->equal, NULL, level, upper, infos))
1540 { /* Finally, the equality. */
1542 /* If we have to make a block by dimension, we start the block. Function
1543 * pprint knows if there is an equality, if this is the case, it checks
1544 * for the same following condition to close the brace.
1546 if (infos->options->block) {
1547 struct clast_block *b = new_clast_block();
1548 **next = &b->stmt;
1549 *next = &b->body;
1552 e = clast_bound_from_constraint(upper, level, infos->names);
1553 ass = new_clast_assignment(cloog_names_name_at_level(infos->names, level), e);
1555 **next = &ass->stmt;
1556 *next = &(**next)->next;
1559 cloog_constraint_release(lower);
1560 cloog_constraint_release(upper);
1562 return 1;
1567 * Insert a loop that is executed exactly once as an assignment.
1568 * In particular, the loop
1570 * for (i = e; i <= e; ++i) {
1571 * S;
1574 * is generated as
1576 * i = e;
1577 * S;
1580 static void insert_otl_for(CloogConstraintSet *constraints, int level,
1581 struct clast_expr *e, struct clast_stmt ***next, CloogInfos *infos)
1583 const char *iterator;
1585 iterator = cloog_names_name_at_level(infos->names, level);
1587 if (!clast_equal_add(infos->equal, constraints, level,
1588 cloog_constraint_invalid(), infos)) {
1589 struct clast_assignment *ass;
1590 if (infos->options->block) {
1591 struct clast_block *b = new_clast_block();
1592 **next = &b->stmt;
1593 *next = &b->body;
1595 ass = new_clast_assignment(iterator, e);
1596 **next = &ass->stmt;
1597 *next = &(**next)->next;
1598 } else {
1599 free_clast_expr(e);
1605 * Insert a loop that is executed at most once as an assignment followed
1606 * by a guard. In particular, the loop
1608 * for (i = e1; i <= e2; ++i) {
1609 * S;
1612 * is generated as
1614 * i = e1;
1615 * if (i <= e2) {
1616 * S;
1620 static void insert_guarded_otl_for(CloogConstraintSet *constraints, int level,
1621 struct clast_expr *e1, struct clast_expr *e2,
1622 struct clast_stmt ***next, CloogInfos *infos)
1624 const char *iterator;
1625 struct clast_assignment *ass;
1626 struct clast_guard *guard;
1628 iterator = cloog_names_name_at_level(infos->names, level);
1630 if (infos->options->block) {
1631 struct clast_block *b = new_clast_block();
1632 **next = &b->stmt;
1633 *next = &b->body;
1635 ass = new_clast_assignment(iterator, e1);
1636 **next = &ass->stmt;
1637 *next = &(**next)->next;
1639 guard = new_clast_guard(1);
1640 guard->eq[0].sign = -1;
1641 guard->eq[0].LHS = &new_clast_term(infos->state->one,
1642 &new_clast_name(iterator)->expr)->expr;
1643 guard->eq[0].RHS = e2;
1645 **next = &guard->stmt;
1646 *next = &guard->then;
1651 * insert_for function:
1652 * This function inserts a for loop in the clast.
1653 * Returns 1 if the calling function should recurse into inner loops.
1655 * A loop header according to an element is the conjunction of a minimum and a
1656 * maximum on a given element (they give the loop bounds).
1657 * For instance, considering these constraints and the element j:
1658 * i + j -9*M >= 0
1659 * -j +5*M >= 0
1660 * j -4*M >= 0
1661 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1662 * - constraints contains all constraints,
1663 * - level is the column number of the element in matrix we want to use,
1664 * - otl is set if the loop is executed at most once,
1665 * - the infos structure gives the user some options about code printing,
1666 * the number of parameters in matrix (nb_par), and the arrays of iterator
1667 * names and parameters (iters and params).
1669 static int insert_for(CloogDomain *domain, CloogConstraintSet *constraints,
1670 int level, int otl, struct clast_stmt ***next,
1671 CloogInfos *infos)
1673 const char *iterator;
1674 struct clast_expr *e1;
1675 struct clast_expr *e2;
1677 e1 = clast_minmax(constraints, level, 1, 0, 1, 0, infos);
1678 e2 = clast_minmax(constraints, level, 0, 0, 0, 0, infos);
1680 if (clast_expr_is_bigger_constant(e1, e2)) {
1681 free_clast_expr(e1);
1682 free_clast_expr(e2);
1683 return 0;
1686 /* If min and max are not equal there is a 'for' else, there is a '='.
1687 * In the special case e1 = e2 = NULL, this is an infinite loop
1688 * so this is not a '='.
1690 if (e1 && e2 && infos->options->otl && clast_expr_equal(e1, e2)) {
1691 free_clast_expr(e2);
1692 insert_otl_for(constraints, level, e1, next, infos);
1693 } else if (otl) {
1694 insert_guarded_otl_for(constraints, level, e1, e2, next, infos);
1695 } else {
1696 struct clast_for *f;
1697 iterator = cloog_names_name_at_level(infos->names, level);
1699 f = new_clast_for(domain, iterator, e1, e2, infos->stride[level-1]);
1700 **next = &f->stmt;
1701 *next = &f->body;
1704 return 1;
1709 * insert_block function:
1710 * This function inserts a statement block.
1711 * - block is the statement block,
1712 * - level is the number of loops enclosing the statement,
1713 * - the infos structure gives the user some options about code printing,
1714 * the number of parameters in domain (nb_par), and the arrays of iterator
1715 * names and parameters (iters and params).
1717 * - September 21th 2003: first version (pick from pprint function).
1719 static void insert_block(CloogDomain *domain, CloogBlock *block, int level,
1720 struct clast_stmt ***next, CloogInfos *infos)
1722 CloogStatement * statement ;
1723 struct clast_stmt *subs;
1725 if (!block)
1726 return;
1728 for (statement = block->statement; statement; statement = statement->next) {
1729 CloogStatement *s_next = statement->next;
1731 subs = clast_equal(level,infos);
1733 statement->next = NULL;
1734 **next = &new_clast_user_stmt(domain, statement, subs)->stmt;
1735 statement->next = s_next;
1736 *next = &(**next)->next;
1742 * insert_loop function:
1743 * This function converts the content of a CloogLoop structure (loop) into a
1744 * clast_stmt (inserted at **next).
1745 * The iterator (level) of
1746 * the current loop is given by 'level': this is the column number of the
1747 * domain corresponding to the current loop iterator. The data of a loop are
1748 * written in this order:
1749 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1750 * depend on the iterator (when the entry in the column 'level' is 0).
1751 * 2. The iteration domain of the iterator, given by the constraints in the
1752 * domain depending on the iterator, i.e.:
1753 * * an equality if the iterator has only one value (possibly preceded by
1754 * a guard verifying if this value is integral), *OR*
1755 * * a loop from the minimum possible value of the iterator to the maximum
1756 * possible value.
1757 * 3. The included statement block.
1758 * 4. The inner loops (recursive call).
1759 * 5. The following loops (recursive call).
1760 * - level is the recursion level or the iteration level that we are printing,
1761 * - the infos structure gives the user some options about code printing,
1762 * the number of parameters in domain (nb_par), and the arrays of iterator
1763 * names and parameters (iters and params).
1765 * - November 2nd 2001: first version.
1766 * - March 6th 2003: infinite domain support.
1767 * - April 19th 2003: (debug) NULL loop support.
1768 * - June 29th 2003: non-unit strides support.
1769 * - April 28th 2005: (debug) level is level+equality when print statement!
1770 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1771 * added to avoid iteration duplication (see DaeGon Kim
1772 * bug in cloog_program_generate). Try vasilache.cloog
1773 * with and without the call to cloog_polylib_matrix_normalize,
1774 * using -f 8 -l 9 options for an idea.
1775 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1776 * - October 16th 2005: (debug) scalar value is saved for next loops.
1778 static void insert_loop(CloogLoop * loop, int level,
1779 struct clast_stmt ***next, CloogInfos *infos)
1781 int equality = 0;
1782 CloogConstraintSet *constraints, *temp;
1783 struct clast_stmt **top = *next;
1784 CloogConstraint *i, *j;
1785 int empty_loop = 0;
1787 /* It can happen that loop be NULL when an input polyhedron is empty. */
1788 if (loop == NULL)
1789 return;
1791 /* The constraints do not always have a shape that allows us to generate code from it,
1792 * thus we normalize it, we also simplify it with the equalities.
1794 temp = cloog_domain_constraints(loop->domain);
1795 cloog_constraint_set_normalize(temp,level);
1796 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1797 infos->names->nb_parameters);
1798 cloog_constraint_set_free(temp);
1799 if (level) {
1800 infos->stride[level - 1] = loop->stride;
1801 infos->stride_level++;
1804 /* First of all we have to print the guard. */
1805 insert_guard(constraints,level, next, infos);
1807 if (level && cloog_constraint_set_contains_level(constraints, level,
1808 infos->names->nb_parameters)) {
1809 /* We scan all the constraints to know in which case we are :
1810 * [[if] equation] or [for].
1812 if (cloog_constraint_is_valid(i =
1813 cloog_constraint_set_defining_equality(constraints, level))) {
1814 empty_loop = !insert_equation(loop->unsimplified, i,
1815 cloog_constraint_invalid(), level, next,
1816 infos);
1817 equality = 1 ;
1818 } else if (cloog_constraint_is_valid(i =
1819 cloog_constraint_set_defining_inequalities(constraints,
1820 level, &j, infos->names->nb_parameters))) {
1821 empty_loop = !insert_equation(loop->unsimplified, i, j, level, next,
1822 infos);
1823 } else
1824 empty_loop = !insert_for(loop->unsimplified, constraints, level,
1825 loop->otl, next, infos);
1828 if (!empty_loop) {
1829 /* Finally, if there is an included statement block, print it. */
1830 insert_block(loop->unsimplified, loop->block, level+equality, next, infos);
1832 /* Go to the next level. */
1833 if (loop->inner != NULL)
1834 insert_loop(loop->inner, level+1, next, infos);
1837 if (level) {
1838 cloog_equal_del(infos->equal,level);
1839 infos->stride_level--;
1841 cloog_constraint_set_free(constraints);
1843 /* Go to the next loop on the same level. */
1844 while (*top)
1845 top = &(*top)->next;
1846 if (loop->next != NULL)
1847 insert_loop(loop->next, level, &top,infos);
1851 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1852 CloogOptions *options)
1854 CloogInfos *infos = ALLOC(CloogInfos);
1855 int nb_levels;
1856 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1857 struct clast_stmt **next = &root->next;
1859 infos->state = options->state;
1860 infos->names = program->names;
1861 infos->options = options;
1862 infos->scaldims = program->scaldims;
1863 infos->nb_scattdims = program->nb_scattdims;
1865 /* Allocation for the array of strides, there is a +1 since the statement can
1866 * be included inside an external loop without iteration domain.
1868 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1869 infos->stride = ALLOCN(CloogStride *, nb_levels);
1870 infos->stride_level = 0;
1872 infos->equal = cloog_equal_alloc(nb_levels,
1873 nb_levels, program->names->nb_parameters);
1875 insert_loop(program->loop, 0, &next, infos);
1877 cloog_equal_free(infos->equal);
1879 free(infos->stride);
1880 free(infos);
1882 return root;
1886 struct clast_stmt *cloog_clast_create_from_input(CloogInput *input,
1887 CloogOptions *options)
1889 CloogProgram *program;
1890 struct clast_stmt *root;
1892 program = cloog_program_alloc(input->context, input->ud, options);
1893 free(input);
1895 program = cloog_program_generate(program, options);
1897 root = cloog_clast_create(program, options);
1898 cloog_program_free(program);
1900 return root;
1903 /* Adds to the list if not already in it */
1904 static int add_if_new(void **list, int num, void *new, int size)
1906 int i;
1908 for (i=0; i<num; i++) {
1909 if (!memcmp((*list) + i*size, new, size)) break;
1912 if (i==num) {
1913 *list = realloc(*list, (num+1)*size);
1914 memcpy(*list + num*size, new, size);
1915 return 1;
1918 return 0;
1922 /* Concatenates all elements of list2 that are not in list1;
1923 * Returns the new size of the list */
1924 int concat_if_new(void **list1, int num1, void *list2, int num2, int size)
1926 int i, ret;
1928 for (i=0; i<num2; i++) {
1929 ret = add_if_new(list1, num1, (char *)list2 + i*size, size);
1930 if (ret) num1++;
1933 return num1;
1936 /* Compares list1 to list2
1937 * Returns 0 if both have the same elements; returns -1 if all elements of
1938 * list1 are strictly contained in list2; 1 otherwise
1940 int list_compare(const int *list1, int num1, const int *list2, int num2)
1942 int i, j;
1944 for (i=0; i<num1; i++) {
1945 for (j=0; j<num2; j++) {
1946 if (list1[i] == list2[j]) break;
1948 if (j==num2) break;
1950 if (i==num1) {
1951 if (num1 == num2) {
1952 return 0;
1954 return -1;
1957 return 1;
1963 * A multi-purpose function to traverse and get information on Clast
1964 * loops
1966 * node: clast node where processing should start
1968 * Returns:
1969 * A list of loops under clast_stmt 'node' filtered in two ways: (1) it contains
1970 * statements appearing in 'stmts_filter', (2) loop iterator's name is 'iter'
1971 * If iter' is set to NULL, no filtering based on iterator name is done
1973 * iter: loop iterator name
1974 * stmts_filter: list of statement numbers for filtering (1-indexed)
1975 * nstmts_filter: number of statements in stmts_filter
1977 * FilterType: match exact (i.e., loops containing only and all those statements
1978 * in stmts_filter) or subset, i.e., loops which have only those statements
1979 * that appear in stmts_filter
1981 * To disable all filtering, set 'iter' to NULL, provide all statement
1982 * numbers in 'stmts_filter' and set FilterType to subset
1984 * Return fields
1986 * stmts: an array of statement numbers under node
1987 * nstmts: number of stmt numbers pointed to by stmts
1988 * loops: list of clast loops
1989 * nloops: number of clast loops in loops
1992 void clast_filter(struct clast_stmt *node,
1993 ClastFilter filter,
1994 struct clast_for ***loops, int *nloops,
1995 int **stmts, int *nstmts)
1997 int num_next_stmts, num_next_loops, ret, *stmts_next;
1998 struct clast_for **loops_next;
2000 *loops = NULL;
2001 *nloops = 0;
2002 *nstmts = 0;
2003 *stmts = NULL;
2005 if (node == NULL) {
2006 return;
2009 ClastFilterType filter_type = filter.filter_type;
2010 const char *iter = filter.iter;
2011 int nstmts_filter = filter.nstmts_filter;
2012 const int *stmts_filter = filter.stmts_filter;
2014 if (CLAST_STMT_IS_A(node, stmt_root)) {
2015 // printf("root stmt\n");
2016 struct clast_root *root = (struct clast_root *) node;
2017 clast_filter((root->stmt).next, filter, &loops_next,
2018 &num_next_loops, &stmts_next, &num_next_stmts);
2019 *nstmts = concat_if_new((void **)stmts, *nstmts, stmts_next, num_next_stmts, sizeof(int));
2020 *nloops = concat_if_new((void **)loops, *nloops, loops_next, num_next_loops,
2021 sizeof(struct clast_stmt *));
2022 free(loops_next);
2023 free(stmts_next);
2026 if (CLAST_STMT_IS_A(node, stmt_guard)) {
2027 // printf("guard stmt\n");
2028 struct clast_guard *guard = (struct clast_guard *) node;
2029 clast_filter(guard->then, filter, &loops_next,
2030 &num_next_loops, &stmts_next, &num_next_stmts);
2031 *nstmts = concat_if_new((void **)stmts, *nstmts, stmts_next, num_next_stmts, sizeof(int));
2032 *nloops = concat_if_new((void **)loops, *nloops, loops_next, num_next_loops,
2033 sizeof(struct clast_stmt *));
2034 free(loops_next);
2035 free(stmts_next);
2036 clast_filter((guard->stmt).next, filter, &loops_next,
2037 &num_next_loops, &stmts_next, &num_next_stmts);
2038 *nstmts = concat_if_new((void **)stmts, *nstmts, stmts_next, num_next_stmts, sizeof(int));
2039 *nloops = concat_if_new((void **)loops, *nloops, loops_next, num_next_loops,
2040 sizeof(struct clast_stmt *));
2041 free(loops_next);
2042 free(stmts_next);
2045 if (CLAST_STMT_IS_A(node, stmt_user)) {
2046 struct clast_user_stmt *user_stmt = (struct clast_user_stmt *) node;
2047 // printf("user stmt: S%d\n", user_stmt->statement->number);
2048 ret = add_if_new((void **)stmts, *nstmts, &user_stmt->statement->number, sizeof(int));
2049 if (ret) (*nstmts)++;
2050 clast_filter((user_stmt->stmt).next, filter, &loops_next,
2051 &num_next_loops, &stmts_next, &num_next_stmts);
2052 *nstmts = concat_if_new((void **)stmts, *nstmts, stmts_next, num_next_stmts, sizeof(int));
2053 *nloops = concat_if_new((void **)loops, *nloops, loops_next, num_next_loops,
2054 sizeof(struct clast_stmt *));
2055 free(loops_next);
2056 free(stmts_next);
2058 if (CLAST_STMT_IS_A(node, stmt_for)) {
2059 struct clast_for *for_stmt = (struct clast_for *) node;
2060 clast_filter(for_stmt->body, filter, &loops_next,
2061 &num_next_loops, &stmts_next, &num_next_stmts);
2062 *nstmts = concat_if_new((void **)stmts, *nstmts, stmts_next, num_next_stmts, sizeof(int));
2063 *nloops = concat_if_new((void **)loops, *nloops, loops_next, num_next_loops,
2064 sizeof(struct clast_stmt *));
2066 if (iter == NULL || !strcmp(for_stmt->iterator, iter)) {
2067 if (stmts_filter == NULL ||
2068 (filter_type == subset && list_compare(stmts_next, num_next_stmts,
2069 stmts_filter, nstmts_filter) <= 0)
2070 || (filter_type == exact && list_compare(stmts_next, num_next_stmts,
2071 stmts_filter, nstmts_filter) == 0 )) {
2072 ret = add_if_new((void **)loops, *nloops, &for_stmt, sizeof(struct clast_for *));
2073 if (ret) (*nloops)++;
2076 free(loops_next);
2077 free(stmts_next);
2079 clast_filter((for_stmt->stmt).next, filter, &loops_next,
2080 &num_next_loops, &stmts_next, &num_next_stmts);
2081 *nstmts = concat_if_new((void **)stmts, *nstmts, stmts_next, num_next_stmts, sizeof(int));
2082 *nloops = concat_if_new((void **)loops, *nloops, loops_next, num_next_loops,
2083 sizeof(struct clast_stmt *));
2084 free(loops_next);
2085 free(stmts_next);