source/clast.c: clean up insert_for
[cloog.git] / source / clast.c
blob3692d8d3d6009430a8242dff717af70780e3d74f
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 CloogInfos *infos);
49 static void insert_guard(CloogConstraintSet *constraints, int level,
50 struct clast_stmt ***next, CloogInfos *infos);
51 static int insert_modulo_guard(CloogConstraint *upper,
52 CloogConstraint *lower, int level,
53 struct clast_stmt ***next, CloogInfos *infos);
54 static int insert_equation(CloogConstraint *upper, CloogConstraint *lower,
55 int level, struct clast_stmt ***next, CloogInfos *infos);
56 static int insert_for(CloogConstraintSet *constraints, int level,
57 struct clast_stmt ***next, CloogInfos *infos);
58 static void insert_block(CloogBlock *block, int level,
59 struct clast_stmt ***next, CloogInfos *infos);
60 static void insert_loop(CloogLoop * loop, int level,
61 struct clast_stmt ***next, CloogInfos *infos);
64 struct clast_name *new_clast_name(const char *name)
66 struct clast_name *n = malloc(sizeof(struct clast_name));
67 n->expr.type = clast_expr_name;
68 n->name = name;
69 return n;
72 struct clast_term *new_clast_term(cloog_int_t c, struct clast_expr *v)
74 struct clast_term *t = malloc(sizeof(struct clast_term));
75 t->expr.type = clast_expr_term;
76 cloog_int_init(t->val);
77 cloog_int_set(t->val, c);
78 t->var = v;
79 return t;
82 struct clast_binary *new_clast_binary(enum clast_bin_type t,
83 struct clast_expr *lhs, cloog_int_t rhs)
85 struct clast_binary *b = malloc(sizeof(struct clast_binary));
86 b->expr.type = clast_expr_bin;
87 b->type = t;
88 b->LHS = lhs;
89 cloog_int_init(b->RHS);
90 cloog_int_set(b->RHS, rhs);
91 return b;
94 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
96 int i;
97 struct clast_reduction *r;
98 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
99 r->expr.type = clast_expr_red;
100 r->type = t;
101 r->n = n;
102 for (i = 0; i < n; ++i)
103 r->elts[i] = NULL;
104 return r;
107 static void free_clast_root(struct clast_stmt *s);
109 const struct clast_stmt_op stmt_root = { free_clast_root };
111 static void free_clast_root(struct clast_stmt *s)
113 struct clast_root *r = (struct clast_root *)s;
114 assert(CLAST_STMT_IS_A(s, stmt_root));
115 cloog_names_free(r->names);
116 free(r);
119 struct clast_root *new_clast_root(CloogNames *names)
121 struct clast_root *r = malloc(sizeof(struct clast_root));
122 r->stmt.op = &stmt_root;
123 r->stmt.next = NULL;
124 r->names = cloog_names_copy(names);
125 return r;
128 static void free_clast_assignment(struct clast_stmt *s);
130 const struct clast_stmt_op stmt_ass = { free_clast_assignment };
132 static void free_clast_assignment(struct clast_stmt *s)
134 struct clast_assignment *a = (struct clast_assignment *)s;
135 assert(CLAST_STMT_IS_A(s, stmt_ass));
136 free_clast_expr(a->RHS);
137 free(a);
140 struct clast_assignment *new_clast_assignment(const char *lhs,
141 struct clast_expr *rhs)
143 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
144 a->stmt.op = &stmt_ass;
145 a->stmt.next = NULL;
146 a->LHS = lhs;
147 a->RHS = rhs;
148 return a;
151 static void free_clast_user_stmt(struct clast_stmt *s);
153 const struct clast_stmt_op stmt_user = { free_clast_user_stmt };
155 static void free_clast_user_stmt(struct clast_stmt *s)
157 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
158 assert(CLAST_STMT_IS_A(s, stmt_user));
159 cloog_statement_free(u->statement);
160 cloog_clast_free(u->substitutions);
161 free(u);
164 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
165 struct clast_stmt *subs)
167 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
168 u->stmt.op = &stmt_user;
169 u->stmt.next = NULL;
170 u->statement = cloog_statement_copy(stmt);
171 u->substitutions = subs;
172 return u;
175 static void free_clast_block(struct clast_stmt *b);
177 const struct clast_stmt_op stmt_block = { free_clast_block };
179 static void free_clast_block(struct clast_stmt *s)
181 struct clast_block *b = (struct clast_block *)s;
182 assert(CLAST_STMT_IS_A(s, stmt_block));
183 cloog_clast_free(b->body);
184 free(b);
187 struct clast_block *new_clast_block()
189 struct clast_block *b = malloc(sizeof(struct clast_block));
190 b->stmt.op = &stmt_block;
191 b->stmt.next = NULL;
192 b->body = NULL;
193 return b;
196 static void free_clast_for(struct clast_stmt *s);
198 const struct clast_stmt_op stmt_for = { free_clast_for };
200 static void free_clast_for(struct clast_stmt *s)
202 struct clast_for *f = (struct clast_for *)s;
203 assert(CLAST_STMT_IS_A(s, stmt_for));
204 free_clast_expr(f->LB);
205 free_clast_expr(f->UB);
206 cloog_int_clear(f->stride);
207 cloog_clast_free(f->body);
208 free(f);
211 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
212 struct clast_expr *UB, cloog_int_t stride)
214 struct clast_for *f = malloc(sizeof(struct clast_for));
215 f->stmt.op = &stmt_for;
216 f->stmt.next = NULL;
217 f->iterator = it;
218 f->LB = LB;
219 f->UB = UB;
220 f->body = NULL;
221 cloog_int_init(f->stride);
222 cloog_int_set(f->stride, stride);
223 return f;
226 static void free_clast_guard(struct clast_stmt *s);
228 const struct clast_stmt_op stmt_guard = { free_clast_guard };
230 static void free_clast_guard(struct clast_stmt *s)
232 int i;
233 struct clast_guard *g = (struct clast_guard *)s;
234 assert(CLAST_STMT_IS_A(s, stmt_guard));
235 cloog_clast_free(g->then);
236 for (i = 0; i < g->n; ++i) {
237 free_clast_expr(g->eq[i].LHS);
238 free_clast_expr(g->eq[i].RHS);
240 free(g);
243 struct clast_guard *new_clast_guard(int n)
245 int i;
246 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
247 (n-1) * sizeof(struct clast_equation));
248 g->stmt.op = &stmt_guard;
249 g->stmt.next = NULL;
250 g->then = NULL;
251 g->n = n;
252 for (i = 0; i < n; ++i) {
253 g->eq[i].LHS = NULL;
254 g->eq[i].RHS = NULL;
256 return g;
259 void free_clast_name(struct clast_name *n)
261 free(n);
264 void free_clast_term(struct clast_term *t)
266 cloog_int_clear(t->val);
267 free_clast_expr(t->var);
268 free(t);
271 void free_clast_binary(struct clast_binary *b)
273 cloog_int_clear(b->RHS);
274 free_clast_expr(b->LHS);
275 free(b);
278 void free_clast_reduction(struct clast_reduction *r)
280 int i;
281 for (i = 0; i < r->n; ++i)
282 free_clast_expr(r->elts[i]);
283 free(r);
286 void free_clast_expr(struct clast_expr *e)
288 if (!e)
289 return;
290 switch (e->type) {
291 case clast_expr_name:
292 free_clast_name((struct clast_name*) e);
293 break;
294 case clast_expr_term:
295 free_clast_term((struct clast_term*) e);
296 break;
297 case clast_expr_red:
298 free_clast_reduction((struct clast_reduction*) e);
299 break;
300 case clast_expr_bin:
301 free_clast_binary((struct clast_binary*) e);
302 break;
303 default:
304 assert(0);
308 void free_clast_stmt(struct clast_stmt *s)
310 assert(s->op);
311 assert(s->op->free);
312 s->op->free(s);
315 void cloog_clast_free(struct clast_stmt *s)
317 struct clast_stmt *next;
318 while (s) {
319 next = s->next;
320 free_clast_stmt(s);
321 s = next;
325 static int clast_name_cmp(struct clast_name *n1, struct clast_name *n2)
327 return n1->name == n2->name ? 0 : strcmp(n1->name, n2->name);
330 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
332 int c;
333 if (!t1->var && t2->var)
334 return -1;
335 if (t1->var && !t2->var)
336 return 1;
337 c = clast_expr_cmp(t1->var, t2->var);
338 if (c)
339 return c;
340 return cloog_int_cmp(t1->val, t2->val);
343 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
345 int c;
347 if (b1->type != b2->type)
348 return b1->type - b2->type;
349 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
350 return c;
351 return clast_expr_cmp(b1->LHS, b2->LHS);
354 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
356 int i;
357 int c;
359 if (r1->n == 1 && r2->n == 1)
360 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
361 if (r1->type != r2->type)
362 return r1->type - r2->type;
363 if (r1->n != r2->n)
364 return r1->n - r2->n;
365 for (i = 0; i < r1->n; ++i)
366 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
367 return c;
368 return 0;
371 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
373 if (!e1 && !e2)
374 return 0;
375 if (!e1)
376 return -1;
377 if (!e2)
378 return 1;
379 if (e1->type != e2->type)
380 return e1->type - e2->type;
381 switch (e1->type) {
382 case clast_expr_name:
383 return clast_name_cmp((struct clast_name*) e1,
384 (struct clast_name*) e2);
385 case clast_expr_term:
386 return clast_term_cmp((struct clast_term*) e1,
387 (struct clast_term*) e2);
388 case clast_expr_bin:
389 return clast_binary_cmp((struct clast_binary*) e1,
390 (struct clast_binary*) e2);
391 case clast_expr_red:
392 return clast_reduction_cmp((struct clast_reduction*) e1,
393 (struct clast_reduction*) e2);
394 default:
395 assert(0);
399 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
401 return clast_expr_cmp(e1, e2) == 0;
405 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
407 int clast_expr_is_bigger_constant(struct clast_expr *e1, struct clast_expr *e2)
409 struct clast_term *t1, *t2;
410 struct clast_reduction *r;
412 if (!e1 || !e2)
413 return 0;
414 if (e1->type == clast_expr_red) {
415 r = (struct clast_reduction *)e1;
416 return r->n == 1 && clast_expr_is_bigger_constant(r->elts[0], e2);
418 if (e2->type == clast_expr_red) {
419 r = (struct clast_reduction *)e2;
420 return r->n == 1 && clast_expr_is_bigger_constant(e1, r->elts[0]);
422 if (e1->type != clast_expr_term || e2->type != clast_expr_term)
423 return 0;
424 t1 = (struct clast_term *)e1;
425 t2 = (struct clast_term *)e2;
426 if (t1->var || t2->var)
427 return 0;
428 return cloog_int_gt(t1->val, t2->val);
431 static int qsort_expr_cmp(const void *p1, const void *p2)
433 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
436 static void clast_reduction_sort(struct clast_reduction *r)
438 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
441 static int qsort_eq_cmp(const void *p1, const void *p2)
443 struct clast_equation *eq1 = (struct clast_equation *)p1;
444 struct clast_equation *eq2 = (struct clast_equation *)p2;
445 int cmp;
447 cmp = clast_expr_cmp(eq1->LHS, eq2->LHS);
448 if (cmp)
449 return cmp;
451 cmp = clast_expr_cmp(eq1->RHS, eq2->RHS);
452 if (cmp)
453 return cmp;
455 return eq1->sign - eq2->sign;
459 * Sort equations in a clast_guard.
461 static void clast_guard_sort(struct clast_guard *g)
463 qsort(&g->eq[0], g->n, sizeof(struct clast_equation), qsort_eq_cmp);
468 * Construct a (deep) copy of an expression clast.
470 static struct clast_expr *clast_expr_copy(struct clast_expr *e)
472 if (!e)
473 return NULL;
474 switch (e->type) {
475 case clast_expr_name: {
476 struct clast_name* n = (struct clast_name*) e;
477 return &new_clast_name(n->name)->expr;
479 case clast_expr_term: {
480 struct clast_term* t = (struct clast_term*) e;
481 return &new_clast_term(t->val, clast_expr_copy(t->var))->expr;
483 case clast_expr_red: {
484 int i;
485 struct clast_reduction *r = (struct clast_reduction*) e;
486 struct clast_reduction *r2 = new_clast_reduction(r->type, r->n);
487 for (i = 0; i < r->n; ++i)
488 r2->elts[i] = clast_expr_copy(r->elts[i]);
489 return &r2->expr;
491 case clast_expr_bin: {
492 struct clast_binary *b = (struct clast_binary*) e;
493 return &new_clast_binary(b->type, clast_expr_copy(b->LHS), b->RHS)->expr;
495 default:
496 assert(0);
501 /******************************************************************************
502 * Equalities spreading functions *
503 ******************************************************************************/
507 * clast_equal_allow function:
508 * This function checks whether the options allow us to spread the equality or
509 * not. It returns 1 if so, 0 otherwise.
510 * - equal is the matrix of equalities,
511 * - level is the column number in equal of the element which is 'equal to',
512 * - line is the line number in equal of the constraint we want to study,
513 * - the infos structure gives the user all options on code printing and more.
515 * - October 27th 2005: first version (extracted from old pprint_equal_add).
517 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
518 CloogInfos *infos)
520 if (level < infos->options->fsp)
521 return 0 ;
523 if ((cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
524 !infos->options->esp)
525 return 0 ;
527 return 1 ;
532 * clast_equal_add function:
533 * This function updates the row (level-1) of the equality matrix (equal) with
534 * the row that corresponds to the row (line) of the matrix (matrix). It returns
535 * 1 if the row can be updated, 0 otherwise.
536 * - equal is the matrix of equalities,
537 * - matrix is the matrix of constraints,
538 * - level is the column number in matrix of the element which is 'equal to',
539 * - line is the line number in matrix of the constraint we want to study,
540 * - the infos structure gives the user all options on code printing and more.
542 static int clast_equal_add(CloogEqualities *equal,
543 CloogConstraintSet *constraints,
544 int level, CloogConstraint *constraint,
545 CloogInfos *infos)
547 cloog_equal_add(equal, constraints, level, constraint,
548 infos->names->nb_parameters);
550 return clast_equal_allow(equal, level, level-1, infos);
556 * clast_equal function:
557 * This function prints the substitution data of a statement into a clast_stmt.
558 * Using this function instead of pprint_equal is useful for generating
559 * a compilable pseudo-code by using preprocessor macro for each statement.
560 * By opposition to pprint_equal, the result is less human-readable. For
561 * instance this function will print (i,i+3,k,3) where pprint_equal would
562 * return (j=i+3,l=3).
563 * - level is the number of loops enclosing the statement,
564 * - the infos structure gives the user all options on code printing and more.
566 * - March 12th 2004: first version.
567 * - November 21th 2005: (debug) now works well with GMP version.
569 static struct clast_stmt *clast_equal(int level, CloogInfos *infos)
571 int i ;
572 struct clast_expr *e;
573 struct clast_stmt *a = NULL;
574 struct clast_stmt **next = &a;
575 CloogEqualities *equal = infos->equal;
576 CloogConstraint *equal_constraint;
578 for (i=infos->names->nb_scattering;i<level-1;i++)
579 { if (cloog_equal_type(equal, i+1)) {
580 equal_constraint = cloog_equal_constraint(equal, i);
581 e = clast_bound_from_constraint(equal_constraint, i+1, infos->names);
582 cloog_constraint_release(equal_constraint);
583 } else {
584 e = &new_clast_term(infos->state->one, &new_clast_name(
585 cloog_names_name_at_level(infos->names, i+1))->expr)->expr;
587 *next = &new_clast_assignment(NULL, e)->stmt;
588 next = &(*next)->next;
591 return a;
596 * clast_bound_from_constraint function:
597 * This function returns a clast_expr containing the printing of the
598 * 'right part' of a constraint according to an element.
599 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
600 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
601 * function should return 'ceild(3*i+M,2)'.
602 * - matrix is the polyhedron containing all the constraints,
603 * - line_num is the line number in domain of the constraint we want to print,
604 * - level is the column number in domain of the element we want to use,
605 * - names structure gives the user some options about code printing,
606 * the number of parameters in domain (nb_par), and the arrays of iterator
607 * names and parameters (iters and params).
609 * - November 2nd 2001: first version.
610 * - June 27th 2003: 64 bits version ready.
612 struct clast_expr *clast_bound_from_constraint(CloogConstraint *constraint,
613 int level, CloogNames *names)
615 int i, sign, nb_elts=0, len;
616 cloog_int_t *line, numerator, denominator, temp, division;
617 struct clast_expr *e = NULL;
618 struct cloog_vec *line_vector;
620 len = cloog_constraint_total_dimension(constraint) + 2;
621 line_vector = cloog_vec_alloc(len);
622 line = line_vector->p;
623 cloog_constraint_copy_coefficients(constraint, line+1);
624 cloog_int_init(temp);
625 cloog_int_init(numerator);
626 cloog_int_init(denominator);
628 if (!cloog_int_is_zero(line[level])) {
629 struct clast_reduction *r;
630 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
631 sign = -cloog_int_sgn(line[level]);
633 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
634 if (i != level && !cloog_int_is_zero(line[i]))
635 nb_elts++;
636 r = new_clast_reduction(clast_red_sum, nb_elts);
637 nb_elts = 0;
639 /* First, we have to print the iterators and the parameters. */
640 for (i = 1; i <= len - 2; i++) {
641 struct clast_expr *v;
643 if (i == level || cloog_int_is_zero(line[i]))
644 continue;
646 v = cloog_constraint_variable_expr(constraint, i, names);
648 if (sign == -1)
649 cloog_int_neg(temp,line[i]);
650 else
651 cloog_int_set(temp,line[i]);
653 r->elts[nb_elts++] = &new_clast_term(temp, v)->expr;
656 if (sign == -1) {
657 cloog_int_neg(numerator, line[len - 1]);
658 cloog_int_set(denominator, line[level]);
660 else {
661 cloog_int_set(numerator, line[len - 1]);
662 cloog_int_neg(denominator, line[level]);
665 /* Finally, the constant, and the final printing. */
666 if (nb_elts) {
667 if (!cloog_int_is_zero(numerator))
668 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
670 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
671 { if (!cloog_constraint_is_equality(constraint))
672 { if (cloog_int_is_pos(line[level]))
673 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
674 else
675 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
676 } else
677 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
679 else
680 e = &r->expr;
681 } else {
682 free_clast_reduction(r);
683 if (cloog_int_is_zero(numerator))
684 e = &new_clast_term(numerator, NULL)->expr;
685 else
686 { if (!cloog_int_is_one(denominator))
687 { if (!cloog_constraint_is_equality(constraint)) { /* useful? */
688 if (cloog_int_is_divisible_by(numerator, denominator)) {
689 cloog_int_divexact(temp, numerator, denominator);
690 e = &new_clast_term(temp, NULL)->expr;
692 else {
693 cloog_int_init(division);
694 cloog_int_tdiv_q(division, numerator, denominator);
695 if (cloog_int_is_neg(numerator)) {
696 if (cloog_int_is_pos(line[level])) {
697 /* nb<0 need max */
698 e = &new_clast_term(division, NULL)->expr;
699 } else {
700 /* nb<0 need min */
701 cloog_int_sub_ui(temp, division, 1);
702 e = &new_clast_term(temp, NULL)->expr;
705 else
706 { if (cloog_int_is_pos(line[level]))
707 { /* nb>0 need max */
708 cloog_int_add_ui(temp, division, 1);
709 e = &new_clast_term(temp, NULL)->expr;
711 else
712 /* nb>0 need min */
713 e = &new_clast_term(division, NULL)->expr;
715 cloog_int_clear(division);
718 else
719 e = &new_clast_binary(clast_bin_div,
720 &new_clast_term(numerator, NULL)->expr,
721 denominator)->expr;
723 else
724 e = &new_clast_term(numerator, NULL)->expr;
729 cloog_vec_free(line_vector);
731 cloog_int_clear(temp);
732 cloog_int_clear(numerator);
733 cloog_int_clear(denominator);
735 return e;
739 /* Temporary structure for communication between clast_minmax and
740 * its cloog_constraint_set_foreach_constraint callback functions.
742 struct clast_minmax_data {
743 int level;
744 int max;
745 int guard;
746 CloogInfos *infos;
747 int n;
748 struct clast_reduction *r;
752 /* Should constraint "c" be considered by clast_minmax?
754 static int valid_bound(CloogConstraint *c, struct clast_minmax_data *d)
756 if (d->max && !cloog_constraint_is_lower_bound(c, d->level - 1))
757 return 0;
758 if (!d->max && !cloog_constraint_is_upper_bound(c, d->level - 1))
759 return 0;
760 if (cloog_constraint_is_equality(c))
761 return 0;
762 if (d->guard && cloog_constraint_involves(c, d->guard - 1))
763 return 0;
765 return 1;
769 /* Increment n for each bound that should be considered by clast_minmax.
771 static int count_bounds(CloogConstraint *c, void *user)
773 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
775 if (!valid_bound(c, d))
776 return 0;
778 d->n++;
780 return 0;
784 /* Update the given lower bound based on stride information.
785 * In some backends, the lower bounds are updated from within
786 * cloog_loop_stride, but other backends leave the updating to
787 * this function. In the later case, the original lower bound
788 * is known to be a constant.
789 * If the bound turns out not to be a constant, we know we
790 * are in the former case and nothing needs to be done.
791 * If the bound has already been updated and it just happens
792 * to be a constant, then this function performs an identity
793 * operation on the constant.
795 static void update_lower_bound(struct clast_expr *expr, int level,
796 CloogInfos *infos)
798 struct clast_term *t;
799 if (expr->type != clast_expr_term)
800 return;
801 t = (struct clast_term *)expr;
802 if (t->var)
803 return;
804 cloog_int_sub(t->val, t->val, infos->offset[level - 1]);
805 cloog_int_cdiv_q(t->val, t->val, infos->stride[level - 1]);
806 cloog_int_mul(t->val, t->val, infos->stride[level - 1]);
807 cloog_int_add(t->val, t->val, infos->offset[level - 1]);
811 /* Add all relevant bounds to r->elts and update lower bounds
812 * based on stride information.
814 static int collect_bounds(CloogConstraint *c, void *user)
816 struct clast_minmax_data *d = (struct clast_minmax_data *) user;
818 if (!valid_bound(c, d))
819 return 0;
821 d->r->elts[d->n] = clast_bound_from_constraint(c, d->level,
822 d->infos->names);
823 if (d->max && !cloog_int_is_one(d->infos->stride[d->level - 1]) &&
824 !cloog_int_is_zero(d->infos->stride[d->level - 1])) {
825 update_lower_bound(d->r->elts[d->n], d->level, d->infos);
828 d->n++;
830 return 0;
835 * clast_minmax function:
836 * This function returns a clast_expr containing the printing of a minimum or a
837 * maximum of the 'right parts' of all constraints according to an element.
838 * For instance consider the constraints:
839 * -3*i +2*j -M >= 0
840 * 2*i +j >= 0
841 * -i -j +2*M >= 0
842 * if we are looking for the minimum for the element j, the function should
843 * return 'max(ceild(3*i+M,2),-2*i)'.
844 * - constraints is the constraints,
845 * - level is the column number in domain of the element we want to use,
846 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
847 * - guard is set to 0 if there is no guard, and set to the level of the element
848 * with a guard otherwise (then the function gives the max or the min only
849 * for the constraint where the guarded coefficient is 0),
850 * - the infos structure gives the user some options about code printing,
851 * the number of parameters in domain (nb_par), and the arrays of iterator
852 * names and parameters (iters and params).
854 * - November 2nd 2001: first version.
856 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
857 int level, int max, int guard,
858 CloogInfos *infos)
860 struct clast_minmax_data data = { level, max, guard, infos };
862 data.n = 0;
864 cloog_constraint_set_foreach_constraint(constraints, count_bounds, &data);
866 if (!data.n)
867 return NULL;
868 data.r = new_clast_reduction(max ? clast_red_max : clast_red_min, data.n);
870 data.n = 0;
871 cloog_constraint_set_foreach_constraint(constraints, collect_bounds, &data);
873 clast_reduction_sort(data.r);
874 return &data.r->expr;
879 * Insert modulo guards defined by existentially quantified dimensions,
880 * not involving the given level.
882 * This function is called from within insert_guard or insert_for.
883 * Any constraint used in constructing * a modulo guard is removed
884 * from the constraint set to avoid insert_guard or insert_for
885 * adding a duplicate (pair of) constraint(s).
887 static void insert_extra_modulo_guards(CloogConstraintSet *constraints,
888 int level, struct clast_stmt ***next, CloogInfos *infos)
890 int i;
891 int nb_iter;
892 int total_dim;
893 CloogConstraint *upper, *lower;
895 total_dim = cloog_constraint_set_total_dimension(constraints);
896 nb_iter = cloog_constraint_set_n_iterators(constraints,
897 infos->names->nb_parameters);
899 for (i = total_dim - infos->names->nb_parameters; i >= nb_iter + 1; i--) {
900 if (cloog_constraint_is_valid(upper =
901 cloog_constraint_set_defining_equality(constraints, i))) {
902 if (!level || (nb_iter < level) ||
903 !cloog_constraint_involves(upper, level-1)) {
904 insert_modulo_guard(upper,
905 cloog_constraint_invalid(), i, next, infos);
906 cloog_constraint_clear(upper);
908 cloog_constraint_release(upper);
909 } else if (cloog_constraint_is_valid(upper =
910 cloog_constraint_set_defining_inequalities(constraints,
911 i, &lower, infos->names->nb_parameters))) {
912 if (!level || (nb_iter < level) ||
913 !cloog_constraint_involves(upper, level-1)) {
914 insert_modulo_guard(upper, lower, i, next, infos);
915 cloog_constraint_clear(upper);
916 cloog_constraint_clear(lower);
918 cloog_constraint_release(upper);
919 cloog_constraint_release(lower);
925 static int clear_lower_bound_at_level(CloogConstraint *c, void *user)
927 int level = *(int *)user;
929 if (cloog_constraint_is_lower_bound(c, level - 1))
930 cloog_constraint_clear(c);
932 return 0;
936 static int clear_upper_bound_at_level(CloogConstraint *c, void *user)
938 int level = *(int *)user;
940 if (cloog_constraint_is_upper_bound(c, level - 1))
941 cloog_constraint_clear(c);
943 return 0;
947 /* Temporary structure for communication between insert_guard and
948 * its cloog_constraint_set_foreach_constraint callback function.
950 struct clast_guard_data {
951 int level;
952 CloogInfos *infos;
953 int n;
954 int i;
955 int nb_iter;
956 CloogConstraintSet *copy;
957 struct clast_guard *g;
961 static int guard_count_bounds(CloogConstraint *c, void *user)
963 struct clast_guard_data *d = (struct clast_guard_data *) user;
965 d->n++;
967 return 0;
971 /* Insert a guard, if necesessary, for constraint j.
973 static int insert_guard_constraint(CloogConstraint *j, void *user)
975 struct clast_guard_data *d = (struct clast_guard_data *) user;
976 int minmax = -1;
977 struct clast_expr *v;
978 struct clast_term *t;
980 if (!cloog_constraint_involves(j, d->i - 1))
981 return 0;
983 if (d->level && d->nb_iter >= d->level &&
984 cloog_constraint_involves(j, d->level - 1))
985 return 0;
987 v = cloog_constraint_variable_expr(j, d->i, d->infos->names);
988 d->g->eq[d->n].LHS = &(t = new_clast_term(d->infos->state->one, v))->expr;
989 if (!d->level || cloog_constraint_is_equality(j)) {
990 /* put the "denominator" in the LHS */
991 cloog_constraint_coefficient_get(j, d->i - 1, &t->val);
992 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->one);
993 if (cloog_int_is_neg(t->val)) {
994 cloog_int_neg(t->val, t->val);
995 cloog_constraint_coefficient_set(j, d->i - 1, d->infos->state->negone);
997 if (d->level || cloog_constraint_is_equality(j))
998 d->g->eq[d->n].sign = 0;
999 else if (cloog_constraint_is_lower_bound(j, d->i - 1))
1000 d->g->eq[d->n].sign = 1;
1001 else
1002 d->g->eq[d->n].sign = -1;
1003 d->g->eq[d->n].RHS = clast_bound_from_constraint(j, d->i, d->infos->names);
1004 } else {
1005 int guarded;
1007 if (cloog_constraint_is_lower_bound(j, d->i - 1)) {
1008 minmax = 1;
1009 d->g->eq[d->n].sign = 1;
1010 } else {
1011 minmax = 0;
1012 d->g->eq[d->n].sign = -1;
1015 guarded = (d->nb_iter >= d->level) ? d->level : 0 ;
1016 d->g->eq[d->n].RHS = clast_minmax(d->copy, d->i,minmax,guarded,d->infos);
1018 d->n++;
1020 /* 'elimination' of the current constraint, this avoid to use one
1021 * constraint more than once. The current line is always eliminated,
1022 * and the next lines if they are in a min or a max.
1024 cloog_constraint_clear(j);
1026 if (minmax == -1)
1027 return 0;
1028 if (minmax == 1)
1029 cloog_constraint_set_foreach_constraint(d->copy,
1030 clear_lower_bound_at_level, &d->i);
1031 else if (minmax == 0)
1032 cloog_constraint_set_foreach_constraint(d->copy,
1033 clear_upper_bound_at_level, &d->i);
1035 return 0;
1040 * insert_guard function:
1041 * This function inserts a guard in the clast.
1042 * A guard on an element (level) is :
1043 * -> the conjunction of all the existing constraints where the coefficient of
1044 * this element is 0 if the element is an iterator,
1045 * -> the conjunction of all the existing constraints if the element isn't an
1046 * iterator.
1047 * For instance, considering these constraints and the element j:
1048 * -3*i +2*j -M >= 0
1049 * 2*i +M >= 0
1050 * this function should return 'if (2*i+M>=0) {'.
1051 * - matrix is the polyhedron containing all the constraints,
1052 * - level is the column number of the element in matrix we want to use,
1053 * - the infos structure gives the user some options about code printing,
1054 * the number of parameters in matrix (nb_par), and the arrays of iterator
1055 * names and parameters (iters and params).
1057 * - November 3rd 2001: first version.
1058 * - November 14th 2001: a lot of 'purifications'.
1059 * - July 31th 2002: (debug) some guard parts are no more redundants.
1060 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
1061 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
1062 * (the need came from loop_simplify that may result in
1063 * domain unions, now it should be fixed directly in
1064 * cloog_loop_simplify).
1066 static void insert_guard(CloogConstraintSet *constraints, int level,
1067 struct clast_stmt ***next, CloogInfos *infos)
1069 int total_dim;
1070 struct clast_guard_data data = { level, infos, 0 };
1072 if (!constraints)
1073 return;
1075 data.copy = cloog_constraint_set_copy(constraints);
1077 insert_extra_modulo_guards(data.copy, level, next, infos);
1079 cloog_constraint_set_foreach_constraint(constraints,
1080 guard_count_bounds, &data);
1082 data.g = new_clast_guard(data.n);
1083 data.n = 0;
1085 /* Well, it looks complicated because I wanted to have a particular, more
1086 * readable, ordering, obviously this function may be far much simpler !
1088 data.nb_iter = cloog_constraint_set_n_iterators(constraints,
1089 infos->names->nb_parameters);
1091 /* We search for guard parts. */
1092 total_dim = cloog_constraint_set_total_dimension(constraints);
1093 for (data.i = 1; data.i <= total_dim; data.i++)
1094 cloog_constraint_set_foreach_constraint(data.copy,
1095 insert_guard_constraint, &data);
1097 cloog_constraint_set_free(data.copy);
1099 data.g->n = data.n;
1100 if (data.n) {
1101 clast_guard_sort(data.g);
1102 **next = &data.g->stmt;
1103 *next = &data.g->then;
1104 } else
1105 free_clast_stmt(&data.g->stmt);
1109 * Check if the constant "cst" satisfies the modulo guard that
1110 * would be introduced by insert_computed_modulo_guard.
1111 * The constant is assumed to have been reduced prior to calling
1112 * this function.
1114 static int constant_modulo_guard_is_satisfied(CloogConstraint *lower,
1115 cloog_int_t bound, cloog_int_t cst)
1117 if (cloog_constraint_is_valid(lower))
1118 return cloog_int_le(cst, bound);
1119 else
1120 return cloog_int_is_zero(cst);
1124 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
1125 * depending on whether lower represents a valid constraint.
1127 static void insert_computed_modulo_guard(struct clast_reduction *r,
1128 CloogConstraint *lower, cloog_int_t mod, cloog_int_t bound,
1129 struct clast_stmt ***next)
1131 struct clast_expr *e;
1132 struct clast_guard *g;
1134 e = &new_clast_binary(clast_bin_mod, &r->expr, mod)->expr;
1135 g = new_clast_guard(1);
1136 if (!cloog_constraint_is_valid(lower)) {
1137 g->eq[0].LHS = e;
1138 cloog_int_set_si(bound, 0);
1139 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1140 g->eq[0].sign = 0;
1141 } else {
1142 g->eq[0].LHS = e;
1143 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
1144 g->eq[0].sign = -1;
1147 **next = &g->stmt;
1148 *next = &g->then;
1152 /* Temporary structure for communication between insert_modulo_guard and
1153 * its cloog_constraint_set_foreach_constraint callback function.
1155 struct clast_modulo_guard_data {
1156 CloogConstraint *lower;
1157 int level;
1158 struct clast_stmt ***next;
1159 CloogInfos *infos;
1160 int empty;
1161 cloog_int_t val, bound;
1165 /* Insert a modulo guard for constraint c.
1167 static int insert_modulo_guard_constraint(CloogConstraint *c, void *user)
1169 struct clast_modulo_guard_data *d = (struct clast_modulo_guard_data *) user;
1170 int level = d->level;
1171 CloogInfos *infos = d->infos;
1172 int i, nb_elts = 0, len, len2, nb_iter, nb_par;
1173 int constant;
1174 struct cloog_vec *line_vector;
1175 cloog_int_t *line;
1177 len = cloog_constraint_total_dimension(c) + 2;
1178 len2 = cloog_equal_total_dimension(infos->equal) + 2;
1179 nb_par = infos->names->nb_parameters;
1180 nb_iter = len - 2 - nb_par;
1182 line_vector = cloog_vec_alloc(len);
1183 line = line_vector->p;
1184 cloog_constraint_copy_coefficients(c, line + 1);
1186 if (cloog_int_is_pos(line[level]))
1187 cloog_seq_neg(line + 1, line + 1, len - 1);
1188 cloog_int_neg(line[level], line[level]);
1189 assert(cloog_int_is_pos(line[level]));
1191 nb_elts = 0;
1192 for (i = 1; i <= len-1; ++i) {
1193 if (i == level)
1194 continue;
1195 cloog_int_fdiv_r(line[i], line[i], line[level]);
1196 if (cloog_int_is_zero(line[i]))
1197 continue;
1198 if (i == len-1)
1199 continue;
1201 nb_elts++;
1204 if (nb_elts || !cloog_int_is_zero(line[len-1])) {
1205 struct clast_reduction *r;
1206 const char *name;
1208 r = new_clast_reduction(clast_red_sum, nb_elts + 1);
1209 nb_elts = 0;
1211 /* First, the modulo guard : the iterators... */
1212 for (i=1;i<=nb_iter;i++) {
1213 if (i == level || cloog_int_is_zero(line[i]))
1214 continue;
1215 if (cloog_int_is_divisible_by(infos->stride[i-1], line[level])) {
1216 cloog_int_addmul(line[len-1], line[i], infos->offset[i-1]);
1217 cloog_int_fdiv_r(line[len-1], line[len-1], line[level]);
1218 continue;
1221 name = cloog_names_name_at_level(infos->names, i);
1223 r->elts[nb_elts++] = &new_clast_term(line[i],
1224 &new_clast_name(name)->expr)->expr;
1227 /* ...the parameters... */
1228 for (i=nb_iter+1;i<=len-2;i++) {
1229 if (cloog_int_is_zero(line[i]))
1230 continue;
1232 name = infos->names->parameters[i-nb_iter-1] ;
1233 r->elts[nb_elts++] = &new_clast_term(line[i],
1234 &new_clast_name(name)->expr)->expr;
1237 constant = nb_elts == 0;
1238 /* ...the constant. */
1239 if (!cloog_int_is_zero(line[len-1]))
1240 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1242 /* our initial computation may have been an overestimate */
1243 r->n = nb_elts;
1245 if (constant) {
1246 d->empty = !constant_modulo_guard_is_satisfied(d->lower, d->bound,
1247 line[len - 1]);
1248 free_clast_reduction(r);
1249 } else
1250 insert_computed_modulo_guard(r, d->lower, line[level], d->bound,
1251 d->next);
1254 cloog_vec_free(line_vector);
1256 return -1;
1261 * insert_modulo_guard:
1262 * This function inserts a modulo guard corresponding to an equality
1263 * or a pair of inequalities.
1264 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
1266 * See insert_equation.
1267 * - matrix is the polyhedron containing all the constraints,
1268 * - upper and lower are the line numbers of the constraint in matrix
1269 * we want to print; in particular, if we want to print an equality,
1270 * then lower == -1 and upper is the row of the equality; if we want
1271 * to print an inequality, then upper is the row of the upper bound
1272 * and lower in the row of the lower bound
1273 * - level is the column number of the element in matrix we want to use,
1274 * - the infos structure gives the user some options about code printing,
1275 * the number of parameters in matrix (nb_par), and the arrays of iterator
1276 * names and parameters (iters and params).
1278 static int insert_modulo_guard(CloogConstraint *upper,
1279 CloogConstraint *lower, int level,
1280 struct clast_stmt ***next, CloogInfos *infos)
1282 int nb_par;
1283 CloogConstraintSet *set;
1284 struct clast_modulo_guard_data data = { lower, level, next, infos, 0 };
1286 cloog_int_init(data.val);
1287 cloog_constraint_coefficient_get(upper, level-1, &data.val);
1288 if (cloog_int_is_one(data.val) || cloog_int_is_neg_one(data.val)) {
1289 cloog_int_clear(data.val);
1290 return 1;
1293 nb_par = infos->names->nb_parameters;
1295 cloog_int_init(data.bound);
1296 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1297 if (cloog_constraint_is_valid(lower)) {
1298 cloog_constraint_constant_get(upper, &data.val);
1299 cloog_constraint_constant_get(lower, &data.bound);
1300 cloog_int_add(data.bound, data.val, data.bound);
1301 cloog_constraint_coefficient_get(lower, level-1, &data.val);
1302 cloog_int_sub_ui(data.val, data.val, 1);
1303 if (cloog_int_eq(data.val, data.bound)) {
1304 cloog_int_clear(data.val);
1305 cloog_int_clear(data.bound);
1306 return 1;
1310 set = cloog_constraint_set_for_reduction(upper, lower);
1311 set = cloog_constraint_set_reduce(set, level, infos->equal, nb_par, &data.bound);
1312 cloog_constraint_set_foreach_constraint(set,
1313 insert_modulo_guard_constraint, &data);
1315 cloog_constraint_set_free(set);
1316 cloog_int_clear(data.val);
1317 cloog_int_clear(data.bound);
1319 return !data.empty;
1324 * We found an equality or a pair of inequalities identifying
1325 * a loop with a single iteration, but the user wants us to generate
1326 * a loop anyway, so we do it here.
1328 static int insert_equation_as_loop(CloogConstraint *upper,
1329 CloogConstraint *lower, int level, struct clast_stmt ***next,
1330 CloogInfos *infos)
1332 const char *iterator = cloog_names_name_at_level(infos->names, level);
1333 struct clast_expr *e1, *e2;
1334 struct clast_for *f;
1336 e2 = clast_bound_from_constraint(upper, level, infos->names);
1337 if (!cloog_constraint_is_valid(lower))
1338 e1 = clast_expr_copy(e2);
1339 else
1340 e1 = clast_bound_from_constraint(lower, level, infos->names);
1341 f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1342 **next = &f->stmt;
1343 *next = &f->body;
1345 cloog_constraint_release(lower);
1346 cloog_constraint_release(upper);
1347 return 1;
1352 * insert_equation function:
1353 * This function inserts an equality
1354 * constraint according to an element in the clast.
1355 * Returns 1 if the calling function should recurse into inner loops.
1357 * An equality can be preceded by a 'modulo guard'.
1358 * For instance, consider the constraint i -2*j = 0 and the
1359 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1360 * - matrix is the polyhedron containing all the constraints,
1361 * - num is the line number of the constraint in matrix we want to print,
1362 * - level is the column number of the element in matrix we want to use,
1363 * - the infos structure gives the user some options about code printing,
1364 * the number of parameters in matrix (nb_par), and the arrays of iterator
1365 * names and parameters (iters and params).
1367 * - November 13th 2001: first version.
1368 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1369 * modulo is 0, compare vivien or vivien2 with a previous
1370 * version for an idea).
1371 * - June 29th 2003: non-unit strides support.
1372 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1373 * it was previously included in a stride calculation.
1375 static int insert_equation(CloogConstraint *upper, CloogConstraint *lower,
1376 int level, struct clast_stmt ***next, CloogInfos *infos)
1378 struct clast_expr *e;
1379 struct clast_assignment *ass;
1381 if (!infos->options->otl)
1382 return insert_equation_as_loop(upper, lower, level, next, infos);
1384 if (!insert_modulo_guard(upper, lower, level, next, infos)) {
1385 cloog_constraint_release(lower);
1386 cloog_constraint_release(upper);
1388 return 0;
1391 if (cloog_constraint_is_valid(lower) ||
1392 !clast_equal_add(infos->equal, NULL, level, upper, infos))
1393 { /* Finally, the equality. */
1395 /* If we have to make a block by dimension, we start the block. Function
1396 * pprint knows if there is an equality, if this is the case, it checks
1397 * for the same following condition to close the brace.
1399 if (infos->options->block) {
1400 struct clast_block *b = new_clast_block();
1401 **next = &b->stmt;
1402 *next = &b->body;
1405 e = clast_bound_from_constraint(upper, level, infos->names);
1406 ass = new_clast_assignment(cloog_names_name_at_level(infos->names, level), e);
1408 **next = &ass->stmt;
1409 *next = &(**next)->next;
1412 cloog_constraint_release(lower);
1413 cloog_constraint_release(upper);
1415 return 1;
1420 * Insert a loop that is executed exactly once as an assignment.
1421 * In particular, the loop
1423 * for (i = e; i <= e; ++i) {
1424 * S;
1427 * is generated as
1429 * i = e;
1430 * S;
1433 static void insert_otl_for(CloogConstraintSet *constraints, int level,
1434 struct clast_expr *e, struct clast_stmt ***next, CloogInfos *infos)
1436 const char *iterator;
1438 iterator = cloog_names_name_at_level(infos->names, level);
1440 if (!clast_equal_add(infos->equal, constraints, level,
1441 cloog_constraint_invalid(), infos)) {
1442 struct clast_assignment *ass;
1443 if (infos->options->block) {
1444 struct clast_block *b = new_clast_block();
1445 **next = &b->stmt;
1446 *next = &b->body;
1448 ass = new_clast_assignment(iterator, e);
1449 **next = &ass->stmt;
1450 *next = &(**next)->next;
1451 } else {
1452 free_clast_expr(e);
1458 * insert_for function:
1459 * This function inserts a for loop in the clast.
1460 * Returns 1 if the calling function should recurse into inner loops.
1462 * A loop header according to an element is the conjunction of a minimum and a
1463 * maximum on a given element (they give the loop bounds).
1464 * For instance, considering these constraints and the element j:
1465 * i + j -9*M >= 0
1466 * -j +5*M >= 0
1467 * j -4*M >= 0
1468 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1469 * If the given element is involved in modulo guards defined by
1470 * existentially quantified variables, then these guards should be
1471 * inserted inside the for loop. However, the constraints involved
1472 * in this guard should not be used in determining the lower and upper
1473 * bound of the loop. We therefore insert the guards first (which
1474 * removes the corresponding constraints from the constraint set)
1475 * and then reattach the guard inside the loop.
1476 * - constraints contains all constraints,
1477 * - level is the column number of the element in matrix we want to use,
1478 * - the infos structure gives the user some options about code printing,
1479 * the number of parameters in matrix (nb_par), and the arrays of iterator
1480 * names and parameters (iters and params).
1482 static int insert_for(CloogConstraintSet *constraints, int level,
1483 struct clast_stmt ***next, CloogInfos *infos)
1485 const char *iterator;
1486 struct clast_expr *e1;
1487 struct clast_expr *e2;
1489 e1 = clast_minmax(constraints, level, 1, 0, infos);
1490 e2 = clast_minmax(constraints, level, 0, 0, infos);
1492 if (clast_expr_is_bigger_constant(e1, e2)) {
1493 free_clast_expr(e1);
1494 free_clast_expr(e2);
1495 return 0;
1498 /* If min and max are not equal there is a 'for' else, there is a '='.
1499 * In the special case e1 = e2 = NULL, this is an infinite loop
1500 * so this is not a '='.
1502 if (e1 && e2 && infos->options->otl && clast_expr_equal(e1, e2)) {
1503 free_clast_expr(e2);
1504 insert_otl_for(constraints, level, e1, next, infos);
1505 } else {
1506 struct clast_for *f;
1507 iterator = cloog_names_name_at_level(infos->names, level);
1508 f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1509 **next = &f->stmt;
1510 *next = &f->body;
1513 insert_extra_modulo_guards(constraints, 0, next, infos);
1515 return 1;
1520 * insert_block function:
1521 * This function inserts a statement block.
1522 * - block is the statement block,
1523 * - level is the number of loops enclosing the statement,
1524 * - the infos structure gives the user some options about code printing,
1525 * the number of parameters in domain (nb_par), and the arrays of iterator
1526 * names and parameters (iters and params).
1528 * - September 21th 2003: first version (pick from pprint function).
1530 static void insert_block(CloogBlock *block, int level,
1531 struct clast_stmt ***next, CloogInfos *infos)
1533 CloogStatement * statement ;
1534 struct clast_stmt *subs;
1536 if (!block)
1537 return;
1539 for (statement = block->statement; statement; statement = statement->next) {
1540 CloogStatement *s_next = statement->next;
1542 subs = clast_equal(level,infos);
1544 statement->next = NULL;
1545 **next = &new_clast_user_stmt(statement, subs)->stmt;
1546 statement->next = s_next;
1547 *next = &(**next)->next;
1553 * insert_loop function:
1554 * This function converts the content of a CloogLoop structure (loop) into a
1555 * clast_stmt (inserted at **next).
1556 * The iterator (level) of
1557 * the current loop is given by 'level': this is the column number of the
1558 * domain corresponding to the current loop iterator. The data of a loop are
1559 * written in this order:
1560 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1561 * depend on the iterator (when the entry in the column 'level' is 0).
1562 * 2. The iteration domain of the iterator, given by the constraints in the
1563 * domain depending on the iterator, i.e.:
1564 * * an equality if the iterator has only one value (possibly preceded by
1565 * a guard verifying if this value is integral), *OR*
1566 * * a loop from the minimum possible value of the iterator to the maximum
1567 * possible value.
1568 * 3. The included statement block.
1569 * 4. The inner loops (recursive call).
1570 * 5. The following loops (recursive call).
1571 * - level is the recursion level or the iteration level that we are printing,
1572 * - the infos structure gives the user some options about code printing,
1573 * the number of parameters in domain (nb_par), and the arrays of iterator
1574 * names and parameters (iters and params).
1576 * - November 2nd 2001: first version.
1577 * - March 6th 2003: infinite domain support.
1578 * - April 19th 2003: (debug) NULL loop support.
1579 * - June 29th 2003: non-unit strides support.
1580 * - April 28th 2005: (debug) level is level+equality when print statement!
1581 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1582 * added to avoid iteration duplication (see DaeGon Kim
1583 * bug in cloog_program_generate). Try vasilache.cloog
1584 * with and without the call to cloog_polylib_matrix_normalize,
1585 * using -f 8 -l 9 options for an idea.
1586 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1587 * - October 16th 2005: (debug) scalar value is saved for next loops.
1589 static void insert_loop(CloogLoop * loop, int level,
1590 struct clast_stmt ***next, CloogInfos *infos)
1592 int equality = 0;
1593 CloogConstraintSet *constraints, *temp;
1594 struct clast_stmt **top = *next;
1595 CloogConstraint *i, *j;
1596 int empty_loop = 0;
1598 /* It can happen that loop be NULL when an input polyhedron is empty. */
1599 if (loop == NULL)
1600 return;
1602 /* The constraints do not always have a shape that allows us to generate code from it,
1603 * thus we normalize it, we also simplify it with the equalities.
1605 temp = cloog_domain_constraints(loop->domain);
1606 cloog_constraint_set_normalize(temp,level);
1607 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1608 infos->names->nb_parameters);
1609 cloog_constraint_set_free(temp);
1610 if (level) {
1611 cloog_int_set(infos->stride[level-1], loop->stride);
1612 cloog_int_set(infos->offset[level-1], loop->offset);
1615 /* First of all we have to print the guard. */
1616 insert_guard(constraints,level, next, infos);
1618 if (level && cloog_constraint_set_contains_level(constraints, level,
1619 infos->names->nb_parameters)) {
1620 /* We scan all the constraints to know in which case we are :
1621 * [[if] equation] or [for].
1623 if (cloog_constraint_is_valid(i =
1624 cloog_constraint_set_defining_equality(constraints, level))) {
1625 empty_loop = !insert_equation(i, cloog_constraint_invalid(),
1626 level, next, infos);
1627 equality = 1 ;
1628 } else if (cloog_constraint_is_valid(i =
1629 cloog_constraint_set_defining_inequalities(constraints,
1630 level, &j, infos->names->nb_parameters))) {
1631 empty_loop = !insert_equation(i, j, level, next, infos);
1632 } else
1633 empty_loop = !insert_for(constraints, level, next, infos);
1636 if (!empty_loop) {
1637 /* Finally, if there is an included statement block, print it. */
1638 insert_block(loop->block, level+equality, next, infos);
1640 /* Go to the next level. */
1641 if (loop->inner != NULL)
1642 insert_loop(loop->inner, level+1, next, infos);
1645 if (level)
1646 cloog_equal_del(infos->equal,level);
1647 cloog_constraint_set_free(constraints);
1649 /* Go to the next loop on the same level. */
1650 while (*top)
1651 top = &(*top)->next;
1652 if (loop->next != NULL)
1653 insert_loop(loop->next, level, &top,infos);
1657 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1658 CloogOptions *options)
1660 CloogInfos *infos = ALLOC(CloogInfos);
1661 int i, nb_levels;
1662 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1663 struct clast_stmt **next = &root->next;
1665 infos->state = options->state;
1666 infos->names = program->names;
1667 infos->options = options;
1668 infos->scaldims = program->scaldims;
1669 infos->nb_scattdims = program->nb_scattdims;
1671 /* Allocation for the array of strides, there is a +1 since the statement can
1672 * be included inside an external loop without iteration domain.
1674 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1675 infos->stride = ALLOCN(cloog_int_t, nb_levels);
1676 infos->offset = ALLOCN(cloog_int_t, nb_levels);
1677 for (i = 0; i < nb_levels; ++i) {
1678 cloog_int_init(infos->stride[i]);
1679 cloog_int_init(infos->offset[i]);
1682 infos->equal = cloog_equal_alloc(nb_levels,
1683 nb_levels, program->names->nb_parameters);
1685 insert_loop(program->loop, 0, &next, infos);
1687 cloog_equal_free(infos->equal);
1689 for (i = 0; i < nb_levels; ++i) {
1690 cloog_int_clear(infos->stride[i]);
1691 cloog_int_clear(infos->offset[i]);
1693 free(infos->stride);
1694 free(infos->offset);
1695 free(infos);
1697 return root;