remove cpp option (defaulting to true)
[cloog/uuh.git] / source / clast.c
blob2ee9603ddeadd530055e60ddaf019df8e78ee8c4
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 cloog_int_t *stride; /**< The stride for each iterator. */
19 int nb_scattdims ; /**< Scattering dimension number. */
20 int * scaldims ; /**< Boolean array saying whether a given
21 * scattering dimension is scalar or not.
23 CloogNames * names ; /**< Names of iterators and parameters. */
24 CloogOptions * options ; /**< Options on CLooG's behaviour. */
25 CloogEqualities *equal; /**< Matrix of equalities. */
26 } ;
28 typedef struct clooginfos CloogInfos ;
30 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2);
31 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2);
32 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2);
33 static int clast_reduction_cmp(struct clast_reduction *r1,
34 struct clast_reduction *r2);
36 static int clast_equal_add(CloogEqualities *equal,
37 CloogConstraintSet *constraints,
38 int level, CloogConstraint constraint,
39 CloogInfos *infos);
41 static struct clast_stmt *clast_equal(int level, CloogInfos *infos);
42 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
43 int level, int max, int guard,
44 CloogInfos *infos);
45 static void insert_guard(CloogConstraintSet *constraints, int level,
46 struct clast_stmt ***next, CloogInfos *infos);
47 static void insert_modulo_guard(CloogConstraint upper,
48 CloogConstraint lower, int level,
49 struct clast_stmt ***next, CloogInfos *infos);
50 static void insert_equation(CloogConstraint upper, CloogConstraint lower,
51 int level, struct clast_stmt ***next, CloogInfos *infos);
52 static void insert_for(CloogConstraintSet *constraints, int level,
53 struct clast_stmt ***next, CloogInfos *infos);
54 static void insert_block(CloogBlock *block, int level,
55 struct clast_stmt ***next, CloogInfos *infos);
56 static void insert_loop(CloogLoop * loop, int level, int scalar,
57 struct clast_stmt ***next, CloogInfos *infos);
60 struct clast_name *new_clast_name(const char *name)
62 struct clast_name *n = malloc(sizeof(struct clast_name));
63 n->expr.type = expr_name;
64 n->name = name;
65 return n;
68 struct clast_term *new_clast_term(cloog_int_t c, struct clast_expr *v)
70 struct clast_term *t = malloc(sizeof(struct clast_term));
71 t->expr.type = expr_term;
72 cloog_int_init(t->val);
73 cloog_int_set(t->val, c);
74 t->var = v;
75 return t;
78 struct clast_binary *new_clast_binary(enum clast_bin_type t,
79 struct clast_expr *lhs, cloog_int_t rhs)
81 struct clast_binary *b = malloc(sizeof(struct clast_binary));
82 b->expr.type = expr_bin;
83 b->type = t;
84 b->LHS = lhs;
85 cloog_int_init(b->RHS);
86 cloog_int_set(b->RHS, rhs);
87 return b;
90 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
92 int i;
93 struct clast_reduction *r;
94 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
95 r->expr.type = expr_red;
96 r->type = t;
97 r->n = n;
98 for (i = 0; i < n; ++i)
99 r->elts[i] = NULL;
100 return r;
103 static void free_clast_root(struct clast_stmt *s);
105 struct clast_stmt_op stmt_root = { free_clast_root };
107 static void free_clast_root(struct clast_stmt *s)
109 struct clast_root *r = (struct clast_root *)s;
110 assert(CLAST_STMT_IS_A(s, stmt_root));
111 cloog_names_free(r->names);
112 free(r);
115 struct clast_root *new_clast_root(CloogNames *names)
117 struct clast_root *r = malloc(sizeof(struct clast_root));
118 r->stmt.op = &stmt_root;
119 r->stmt.next = NULL;
120 r->names = cloog_names_copy(names);
121 return r;
124 static void free_clast_assignment(struct clast_stmt *s);
126 struct clast_stmt_op stmt_ass = { free_clast_assignment };
128 static void free_clast_assignment(struct clast_stmt *s)
130 struct clast_assignment *a = (struct clast_assignment *)s;
131 assert(CLAST_STMT_IS_A(s, stmt_ass));
132 free_clast_expr(a->RHS);
133 free(a);
136 struct clast_assignment *new_clast_assignment(const char *lhs,
137 struct clast_expr *rhs)
139 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
140 a->stmt.op = &stmt_ass;
141 a->stmt.next = NULL;
142 a->LHS = lhs;
143 a->RHS = rhs;
144 return a;
147 static void free_clast_user_stmt(struct clast_stmt *s);
149 struct clast_stmt_op stmt_user = { free_clast_user_stmt };
151 static void free_clast_user_stmt(struct clast_stmt *s)
153 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
154 assert(CLAST_STMT_IS_A(s, stmt_user));
155 cloog_clast_free(u->substitutions);
156 free(u);
159 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
160 struct clast_stmt *subs)
162 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
163 u->stmt.op = &stmt_user;
164 u->stmt.next = NULL;
165 u->statement = stmt;
166 u->substitutions = subs;
167 return u;
170 static void free_clast_block(struct clast_stmt *b);
172 struct clast_stmt_op stmt_block = { free_clast_block };
174 static void free_clast_block(struct clast_stmt *s)
176 struct clast_block *b = (struct clast_block *)s;
177 assert(CLAST_STMT_IS_A(s, stmt_block));
178 cloog_clast_free(b->body);
179 free(b);
182 struct clast_block *new_clast_block()
184 struct clast_block *b = malloc(sizeof(struct clast_block));
185 b->stmt.op = &stmt_block;
186 b->stmt.next = NULL;
187 b->body = NULL;
188 return b;
191 static void free_clast_for(struct clast_stmt *s);
193 struct clast_stmt_op stmt_for = { free_clast_for };
195 static void free_clast_for(struct clast_stmt *s)
197 struct clast_for *f = (struct clast_for *)s;
198 assert(CLAST_STMT_IS_A(s, stmt_for));
199 free_clast_expr(f->LB);
200 free_clast_expr(f->UB);
201 cloog_int_clear(f->stride);
202 cloog_clast_free(f->body);
203 free(f);
206 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
207 struct clast_expr *UB, cloog_int_t stride)
209 struct clast_for *f = malloc(sizeof(struct clast_for));
210 f->stmt.op = &stmt_for;
211 f->stmt.next = NULL;
212 f->iterator = it;
213 f->LB = LB;
214 f->UB = UB;
215 f->body = NULL;
216 cloog_int_init(f->stride);
217 cloog_int_set(f->stride, stride);
218 return f;
221 static void free_clast_guard(struct clast_stmt *s);
223 struct clast_stmt_op stmt_guard = { free_clast_guard };
225 static void free_clast_guard(struct clast_stmt *s)
227 int i;
228 struct clast_guard *g = (struct clast_guard *)s;
229 assert(CLAST_STMT_IS_A(s, stmt_guard));
230 cloog_clast_free(g->then);
231 for (i = 0; i < g->n; ++i) {
232 free_clast_expr(g->eq[i].LHS);
233 free_clast_expr(g->eq[i].RHS);
235 free(g);
238 struct clast_guard *new_clast_guard(int n)
240 int i;
241 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
242 (n-1) * sizeof(struct clast_equation));
243 g->stmt.op = &stmt_guard;
244 g->stmt.next = NULL;
245 g->then = NULL;
246 g->n = n;
247 for (i = 0; i < n; ++i) {
248 g->eq[i].LHS = NULL;
249 g->eq[i].RHS = NULL;
251 return g;
254 void free_clast_name(struct clast_name *n)
256 free(n);
259 void free_clast_term(struct clast_term *t)
261 cloog_int_clear(t->val);
262 free_clast_expr(t->var);
263 free(t);
266 void free_clast_binary(struct clast_binary *b)
268 cloog_int_clear(b->RHS);
269 free_clast_expr(b->LHS);
270 free(b);
273 void free_clast_reduction(struct clast_reduction *r)
275 int i;
276 for (i = 0; i < r->n; ++i)
277 free_clast_expr(r->elts[i]);
278 free(r);
281 void free_clast_expr(struct clast_expr *e)
283 if (!e)
284 return;
285 switch (e->type) {
286 case expr_name:
287 free_clast_name((struct clast_name*) e);
288 break;
289 case expr_term:
290 free_clast_term((struct clast_term*) e);
291 break;
292 case expr_red:
293 free_clast_reduction((struct clast_reduction*) e);
294 break;
295 case expr_bin:
296 free_clast_binary((struct clast_binary*) e);
297 break;
298 default:
299 assert(0);
303 void free_clast_stmt(struct clast_stmt *s)
305 assert(s->op);
306 assert(s->op->free);
307 s->op->free(s);
310 void cloog_clast_free(struct clast_stmt *s)
312 struct clast_stmt *next;
313 while (s) {
314 next = s->next;
315 free_clast_stmt(s);
316 s = next;
320 static int clast_name_cmp(struct clast_name *n1, struct clast_name *n2)
322 return n1->name == n2->name ? 0 : strcmp(n1->name, n2->name);
325 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
327 int c;
328 if (!t1->var && t2->var)
329 return -1;
330 if (t1->var && !t2->var)
331 return 1;
332 c = clast_expr_cmp(t1->var, t2->var);
333 if (c)
334 return c;
335 return cloog_int_cmp(t1->val, t2->val);
338 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
340 int c;
342 if (b1->type != b2->type)
343 return b1->type - b2->type;
344 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
345 return c;
346 return clast_expr_cmp(b1->LHS, b2->LHS);
349 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
351 int i;
352 int c;
354 if (r1->type == clast_red_max && r2->type == clast_red_min &&
355 r1->n == 1 && r2->n == 1)
356 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
357 if (r1->type != r2->type)
358 return r1->type - r2->type;
359 if (r1->n != r2->n)
360 return r1->n - r2->n;
361 for (i = 0; i < r1->n; ++i)
362 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
363 return c;
364 return 0;
367 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
369 if (!e1 && !e2)
370 return 0;
371 if (!e1)
372 return -1;
373 if (!e2)
374 return 1;
375 if (e1->type != e2->type)
376 return e1->type - e2->type;
377 switch (e1->type) {
378 case expr_name:
379 return clast_name_cmp((struct clast_name*) e1,
380 (struct clast_name*) e2);
381 case expr_term:
382 return clast_term_cmp((struct clast_term*) e1,
383 (struct clast_term*) e2);
384 case expr_bin:
385 return clast_binary_cmp((struct clast_binary*) e1,
386 (struct clast_binary*) e2);
387 case expr_red:
388 return clast_reduction_cmp((struct clast_reduction*) e1,
389 (struct clast_reduction*) e2);
390 default:
391 assert(0);
395 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
397 return clast_expr_cmp(e1, e2) == 0;
400 static int qsort_expr_cmp(const void *p1, const void *p2)
402 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
405 static void clast_reduction_sort(struct clast_reduction *r)
407 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
410 static int qsort_eq_cmp(const void *p1, const void *p2)
412 struct clast_equation *eq1 = (struct clast_equation *)p1;
413 struct clast_equation *eq2 = (struct clast_equation *)p2;
414 int cmp;
416 cmp = clast_expr_cmp(eq1->LHS, eq2->LHS);
417 if (cmp)
418 return cmp;
420 cmp = clast_expr_cmp(eq1->RHS, eq2->RHS);
421 if (cmp)
422 return cmp;
424 return eq1->sign - eq2->sign;
428 * Sort equations in a clast_guard.
430 static void clast_guard_sort(struct clast_guard *g)
432 qsort(&g->eq[0], g->n, sizeof(struct clast_equation), qsort_eq_cmp);
436 /******************************************************************************
437 * Equalities spreading functions *
438 ******************************************************************************/
442 * clast_equal_allow function:
443 * This function checks whether the options allow us to spread the equality or
444 * not. It returns 1 if so, 0 otherwise.
445 * - equal is the matrix of equalities,
446 * - level is the column number in equal of the element which is 'equal to',
447 * - line is the line number in equal of the constraint we want to study,
448 * - the infos structure gives the user all options on code printing and more.
450 * - October 27th 2005: first version (extracted from old pprint_equal_add).
452 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
453 CloogInfos *infos)
455 if (level < infos->options->fsp)
456 return 0 ;
458 if ((cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
459 !infos->options->esp)
460 return 0 ;
462 return 1 ;
467 * clast_equal_add function:
468 * This function updates the row (level-1) of the equality matrix (equal) with
469 * the row that corresponds to the row (line) of the matrix (matrix). It returns
470 * 1 if the row can be updated, 0 otherwise.
471 * - equal is the matrix of equalities,
472 * - matrix is the matrix of constraints,
473 * - level is the column number in matrix of the element which is 'equal to',
474 * - line is the line number in matrix of the constraint we want to study,
475 * - the infos structure gives the user all options on code printing and more.
477 static int clast_equal_add(CloogEqualities *equal,
478 CloogConstraintSet *constraints,
479 int level, CloogConstraint constraint,
480 CloogInfos *infos)
482 cloog_equal_add(equal, constraints, level, constraint,
483 infos->names->nb_parameters);
485 return clast_equal_allow(equal, level, level-1, infos);
491 * clast_equal function:
492 * This function prints the substitution data of a statement into a clast_stmt.
493 * Using this function instead of pprint_equal is useful for generating
494 * a compilable pseudo-code by using preprocessor macro for each statement.
495 * By opposition to pprint_equal, the result is less human-readable. For
496 * instance this function will print (i,i+3,k,3) where pprint_equal would
497 * return (j=i+3,l=3).
498 * - level is the number of loops enclosing the statement,
499 * - the infos structure gives the user all options on code printing and more.
501 * - March 12th 2004: first version.
502 * - November 21th 2005: (debug) now works well with GMP version.
504 static struct clast_stmt *clast_equal(int level, CloogInfos *infos)
506 int i ;
507 cloog_int_t one;
508 struct clast_expr *e;
509 struct clast_stmt *a = NULL;
510 struct clast_stmt **next = &a;
511 CloogEqualities *equal = infos->equal;
512 CloogConstraint equal_constraint;
514 cloog_int_init(one);
516 for (i=infos->names->nb_scattering;i<level-1;i++)
517 { if (cloog_equal_type(equal, i+1)) {
518 equal_constraint = cloog_equal_constraint(equal, i);
519 e = clast_bound_from_constraint(equal_constraint, i+1, infos->names);
520 cloog_constraint_release(equal_constraint);
521 } else {
522 cloog_int_set_si(one, 1);
523 e = &new_clast_term(one, &new_clast_name(
524 cloog_names_name_at_level(infos->names, i+1))->expr)->expr;
526 *next = &new_clast_assignment(NULL, e)->stmt;
527 next = &(*next)->next;
529 cloog_int_clear(one);
531 return a;
536 * clast_bound_from_constraint function:
537 * This function returns a clast_expr containing the printing of the
538 * 'right part' of a constraint according to an element.
539 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
540 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
541 * function should return 'ceild(3*i+M,2)'.
542 * - matrix is the polyhedron containing all the constraints,
543 * - line_num is the line number in domain of the constraint we want to print,
544 * - level is the column number in domain of the element we want to use,
545 * - names structure gives the user some options about code printing,
546 * the number of parameters in domain (nb_par), and the arrays of iterator
547 * names and parameters (iters and params).
549 * - November 2nd 2001: first version.
550 * - June 27th 2003: 64 bits version ready.
552 struct clast_expr *clast_bound_from_constraint(CloogConstraint constraint,
553 int level, CloogNames *names)
555 int i, sign, nb_elts=0, len;
556 cloog_int_t *line, numerator, denominator, temp, division;
557 struct clast_expr *e = NULL;
558 struct cloog_vec *line_vector;
560 len = cloog_constraint_total_dimension(constraint) + 2;
561 line_vector = cloog_vec_alloc(len);
562 line = line_vector->p;
563 cloog_constraint_copy_coefficients(constraint, line+1);
564 cloog_int_init(temp);
565 cloog_int_init(numerator);
566 cloog_int_init(denominator);
568 if (!cloog_int_is_zero(line[level])) {
569 struct clast_reduction *r;
570 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
571 sign = -cloog_int_sgn(line[level]);
573 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
574 if (i != level && !cloog_int_is_zero(line[i]))
575 nb_elts++;
576 r = new_clast_reduction(clast_red_sum, nb_elts);
577 nb_elts = 0;
579 /* First, we have to print the iterators and the parameters. */
580 for (i = 1; i <= len - 2; i++) {
581 struct clast_expr *v;
583 if (i == level || cloog_int_is_zero(line[i]))
584 continue;
586 v = cloog_constraint_variable_expr(constraint, i, names);
588 if (sign == -1)
589 cloog_int_neg(temp,line[i]);
590 else
591 cloog_int_set(temp,line[i]);
593 r->elts[nb_elts++] = &new_clast_term(temp, v)->expr;
596 if (sign == -1) {
597 cloog_int_neg(numerator, line[len - 1]);
598 cloog_int_set(denominator, line[level]);
600 else {
601 cloog_int_set(numerator, line[len - 1]);
602 cloog_int_neg(denominator, line[level]);
605 /* Finally, the constant, and the final printing. */
606 if (nb_elts) {
607 if (!cloog_int_is_zero(numerator))
608 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
610 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
611 { if (!cloog_constraint_is_equality(constraint))
612 { if (cloog_int_is_pos(line[level]))
613 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
614 else
615 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
616 } else
617 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
619 else
620 e = &r->expr;
621 } else {
622 free_clast_reduction(r);
623 if (cloog_int_is_zero(numerator))
624 e = &new_clast_term(numerator, NULL)->expr;
625 else
626 { if (!cloog_int_is_one(denominator))
627 { if (!cloog_constraint_is_equality(constraint)) { /* useful? */
628 if (cloog_int_is_divisible_by(numerator, denominator)) {
629 cloog_int_divexact(temp, numerator, denominator);
630 e = &new_clast_term(temp, NULL)->expr;
632 else {
633 cloog_int_init(division);
634 cloog_int_tdiv_q(division, numerator, denominator);
635 if (cloog_int_is_neg(numerator)) {
636 if (cloog_int_is_pos(line[level])) {
637 /* nb<0 need max */
638 e = &new_clast_term(division, NULL)->expr;
639 } else {
640 /* nb<0 need min */
641 cloog_int_sub_ui(temp, division, 1);
642 e = &new_clast_term(temp, NULL)->expr;
645 else
646 { if (cloog_int_is_pos(line[level]))
647 { /* nb>0 need max */
648 cloog_int_add_ui(temp, division, 1);
649 e = &new_clast_term(temp, NULL)->expr;
651 else
652 /* nb>0 need min */
653 e = &new_clast_term(division, NULL)->expr;
655 cloog_int_clear(division);
658 else
659 e = &new_clast_binary(clast_bin_div,
660 &new_clast_term(numerator, NULL)->expr,
661 denominator)->expr;
663 else
664 e = &new_clast_term(numerator, NULL)->expr;
669 cloog_vec_free(line_vector);
671 cloog_int_clear(temp);
672 cloog_int_clear(numerator);
673 cloog_int_clear(denominator);
675 return e;
680 * clast_minmax function:
681 * This function returns a clast_expr containing the printing of a minimum or a
682 * maximum of the 'right parts' of all constraints according to an element.
683 * For instance consider the constraints:
684 * -3*i +2*j -M >= 0
685 * 2*i +j >= 0
686 * -i -j +2*M >= 0
687 * if we are looking for the minimum for the element j, the function should
688 * return 'max(ceild(3*i+M,2),-2*i)'.
689 * - constraints is the constraints,
690 * - level is the column number in domain of the element we want to use,
691 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
692 * - guard is set to 0 if there is no guard, and set to the level of the element
693 * with a guard otherwise (then the function gives the max or the min only
694 * for the constraint where the guarded coefficient is 0),
695 * - the infos structure gives the user some options about code printing,
696 * the number of parameters in domain (nb_par), and the arrays of iterator
697 * names and parameters (iters and params).
699 * - November 2nd 2001: first version.
701 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
702 int level, int max, int guard,
703 CloogInfos *infos)
704 { int n;
705 struct clast_reduction *r;
706 CloogConstraint constraint;
708 n = 0;
709 for (constraint = cloog_constraint_first(constraints);
710 cloog_constraint_is_valid(constraint);
711 constraint = cloog_constraint_next(constraint))
712 if (((max && cloog_constraint_is_lower_bound(constraint, level-1)) ||
713 (!max && cloog_constraint_is_upper_bound(constraint, level-1))) &&
714 (!guard || !cloog_constraint_involves(constraint, guard-1)) &&
715 (!cloog_constraint_is_equality(constraint)))
716 n++;
717 if (!n)
718 return NULL;
719 r = new_clast_reduction(max ? clast_red_max : clast_red_min, n);
721 n = 0;
722 for (constraint = cloog_constraint_first(constraints);
723 cloog_constraint_is_valid(constraint);
724 constraint = cloog_constraint_next(constraint))
725 if (((max && cloog_constraint_is_lower_bound(constraint, level-1)) ||
726 (!max && cloog_constraint_is_upper_bound(constraint, level-1))) &&
727 (!guard || !cloog_constraint_involves(constraint, guard-1)) &&
728 (!cloog_constraint_is_equality(constraint)))
729 r->elts[n++] = clast_bound_from_constraint(constraint, level,
730 infos->names);
732 clast_reduction_sort(r);
733 return &r->expr;
738 * Insert modulo guards defined by existentially quantified dimensions.
740 * This function is called from within insert_guard and receives
741 * a copy of the constraints. Any constraint used in constructing
742 * a modulo guard is removed from this copy to avoid insert_guard
743 * adding a duplicate (pair of) constraint(s).
745 static void insert_extra_modulo_guards(CloogConstraintSet *constraints,
746 struct clast_stmt ***next, CloogInfos *infos)
748 int i;
749 int nb_iter;
750 int total_dim;
751 CloogConstraint upper, lower;
753 total_dim = cloog_constraint_set_total_dimension(constraints);
754 nb_iter = cloog_constraint_set_n_iterators(constraints,
755 infos->names->nb_parameters);
757 for (i = total_dim - infos->names->nb_parameters; i >= nb_iter + 1; i--) {
758 if (cloog_constraint_is_valid(upper =
759 cloog_constraint_set_defining_equality(constraints, i))) {
760 insert_modulo_guard(upper, cloog_constraint_invalid(), i, next, infos);
761 cloog_constraint_clear(upper);
762 cloog_constraint_release(upper);
763 } else if (cloog_constraint_is_valid(upper =
764 cloog_constraint_set_defining_inequalities(constraints,
765 i, &lower, infos->names->nb_parameters))) {
766 insert_modulo_guard(upper, lower, i, next, infos);
767 cloog_constraint_clear(upper);
768 cloog_constraint_clear(lower);
769 cloog_constraint_release(upper);
770 cloog_constraint_release(lower);
777 * insert_guard function:
778 * This function inserts a guard in the clast.
779 * A guard on an element (level) is :
780 * -> the conjunction of all the existing constraints where the coefficient of
781 * this element is 0 if the element is an iterator,
782 * -> the conjunction of all the existing constraints if the element isn't an
783 * iterator.
784 * For instance, considering these constraints and the element j:
785 * -3*i +2*j -M >= 0
786 * 2*i +M >= 0
787 * this function should return 'if (2*i+M>=0) {'.
788 * - matrix is the polyhedron containing all the constraints,
789 * - level is the column number of the element in matrix we want to use,
790 * - the infos structure gives the user some options about code printing,
791 * the number of parameters in matrix (nb_par), and the arrays of iterator
792 * names and parameters (iters and params).
794 * - November 3rd 2001: first version.
795 * - November 14th 2001: a lot of 'purifications'.
796 * - July 31th 2002: (debug) some guard parts are no more redundants.
797 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
798 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
799 * (the need came from loop_simplify that may result in
800 * domain unions, now it should be fixed directly in
801 * cloog_loop_simplify).
803 static void insert_guard(CloogConstraintSet *constraints, int level,
804 struct clast_stmt ***next, CloogInfos *infos)
806 int i, guarded, minmax=-1, nb_and = 0, nb_iter ;
807 int total_dim;
808 CloogConstraintSet *copy;
809 CloogConstraint j, l;
810 struct clast_guard *g;
811 cloog_int_t one;
813 if (constraints == NULL)
814 return;
816 copy = cloog_constraint_set_copy(constraints);
818 insert_extra_modulo_guards(copy, next, infos);
820 cloog_int_init(one);
821 cloog_int_set_si(one, 1);
823 total_dim = cloog_constraint_set_total_dimension(constraints);
824 g = new_clast_guard(2 * total_dim);
826 /* Well, it looks complicated because I wanted to have a particular, more
827 * readable, ordering, obviously this function may be far much simpler !
829 nb_iter = cloog_constraint_set_n_iterators(constraints,
830 infos->names->nb_parameters);
832 nb_and = 0 ;
833 /* We search for guard parts. */
834 for (i = 1; i <= total_dim; i++)
835 for (j = cloog_constraint_first(copy); cloog_constraint_is_valid(j);
836 j = cloog_constraint_next(j))
837 if (cloog_constraint_involves(j, i-1) &&
838 (!level || (nb_iter < level) ||
839 !cloog_constraint_involves(j, level-1))) {
840 struct clast_expr *v;
841 struct clast_term *t;
843 v = cloog_constraint_variable_expr(j, i, infos->names);
844 g->eq[nb_and].LHS = &(t = new_clast_term(one, v))->expr;
845 if (!level || cloog_constraint_is_equality(j)) {
846 /* put the "denominator" in the LHS */
847 cloog_constraint_coefficient_get(j, i-1, &t->val);
848 cloog_constraint_coefficient_set(j, i-1, one);
849 if (cloog_int_is_neg(t->val)) {
850 cloog_int_neg(t->val, t->val);
851 cloog_int_neg(one, one);
852 cloog_constraint_coefficient_set(j, i-1, one);
853 cloog_int_neg(one, one);
855 if (level || cloog_constraint_is_equality(j))
856 g->eq[nb_and].sign = 0;
857 else if (cloog_constraint_is_lower_bound(j, i-1))
858 g->eq[nb_and].sign = 1;
859 else
860 g->eq[nb_and].sign = -1;
861 g->eq[nb_and].RHS = clast_bound_from_constraint(j, i, infos->names);
862 } else {
863 if (cloog_constraint_is_lower_bound(j, i-1)) {
864 minmax = 1;
865 g->eq[nb_and].sign = 1;
866 } else {
867 minmax = 0;
868 g->eq[nb_and].sign = -1;
871 guarded = (nb_iter >= level) ? level : 0 ;
872 g->eq[nb_and].RHS = clast_minmax(copy,i,minmax,guarded,infos) ;
874 nb_and ++ ;
876 /* 'elimination' of the current constraint, this avoid to use one
877 * constraint more than once. The current line is always eliminated,
878 * and the next lines if they are in a min or a max.
880 cloog_constraint_clear(j);
882 if (minmax == -1)
883 continue;
884 l = cloog_constraint_copy(j);
885 for (l = cloog_constraint_next(l); cloog_constraint_is_valid(l);
886 l = cloog_constraint_next(l))
887 if (((minmax == 1) && cloog_constraint_is_lower_bound(l, i-1)) ||
888 ((minmax == 0) && cloog_constraint_is_upper_bound(l, i-1)))
889 cloog_constraint_clear(l);
891 cloog_constraint_set_free(copy);
893 g->n = nb_and;
894 if (nb_and) {
895 clast_guard_sort(g);
896 **next = &g->stmt;
897 *next = &g->then;
898 } else
899 free_clast_stmt(&g->stmt);
901 cloog_int_clear(one);
902 return;
906 /* Computes x, y and g such that g = gcd(a,b) and a*x+b*y = g */
907 static void Euclid(cloog_int_t a, cloog_int_t b,
908 cloog_int_t *x, cloog_int_t *y, cloog_int_t *g)
910 cloog_int_t c, d, e, f, tmp;
912 cloog_int_init(c);
913 cloog_int_init(d);
914 cloog_int_init(e);
915 cloog_int_init(f);
916 cloog_int_init(tmp);
917 cloog_int_abs(c, a);
918 cloog_int_abs(d, b);
919 cloog_int_set_si(e, 1);
920 cloog_int_set_si(f, 0);
921 while (cloog_int_is_pos(d)) {
922 cloog_int_tdiv_q(tmp, c, d);
923 cloog_int_mul(tmp, tmp, f);
924 cloog_int_sub(e, e, tmp);
925 cloog_int_tdiv_q(tmp, c, d);
926 cloog_int_mul(tmp, tmp, d);
927 cloog_int_sub(c, c, tmp);
928 cloog_int_swap(c, d);
929 cloog_int_swap(e, f);
931 cloog_int_set(*g, c);
932 if (cloog_int_is_zero(a))
933 cloog_int_set_si(*x, 0);
934 else if (cloog_int_is_pos(a))
935 cloog_int_set(*x, e);
936 else cloog_int_neg(*x, e);
937 if (cloog_int_is_zero(b))
938 cloog_int_set_si(*y, 0);
939 else {
940 cloog_int_mul(tmp, a, *x);
941 cloog_int_sub(tmp, c, tmp);
942 cloog_int_divexact(*y, tmp, b);
944 cloog_int_clear(c);
945 cloog_int_clear(d);
946 cloog_int_clear(e);
947 cloog_int_clear(f);
948 cloog_int_clear(tmp);
953 * insert_modulo_guard:
954 * This function inserts a modulo guard corresponding to an equality
955 * or a pair of inequalities.
956 * See insert_equation.
957 * - matrix is the polyhedron containing all the constraints,
958 * - upper and lower are the line numbers of the constraint in matrix
959 * we want to print; in particular, if we want to print an equality,
960 * then lower == -1 and upper is the row of the equality; if we want
961 * to print an inequality, then upper is the row of the upper bound
962 * and lower in the row of the lower bound
963 * - level is the column number of the element in matrix we want to use,
964 * - the infos structure gives the user some options about code printing,
965 * the number of parameters in matrix (nb_par), and the arrays of iterator
966 * names and parameters (iters and params).
968 static void insert_modulo_guard(CloogConstraint upper,
969 CloogConstraint lower, int level,
970 struct clast_stmt ***next, CloogInfos *infos)
972 int i, j, k, nb_elts = 0, len, len2, nb_iter, in_stride = 0, nb_par;
973 struct cloog_vec *line_vector, *line_vector2;
974 cloog_int_t *line, *line2, val, val2, x, y, g;
976 cloog_int_init(val);
977 cloog_constraint_coefficient_get(upper, level-1, &val);
978 if (cloog_int_is_one(val) || cloog_int_is_neg_one(val)) {
979 cloog_int_clear(val);
980 return;
983 len = cloog_constraint_total_dimension(upper) + 2;
984 len2 = cloog_equal_total_dimension(infos->equal) + 2;
985 nb_par = infos->names->nb_parameters;
986 nb_iter = len - 2 - nb_par;
988 cloog_int_init(val2);
989 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
990 if (cloog_constraint_is_valid(lower)) {
991 cloog_constraint_constant_get(upper, &val);
992 cloog_constraint_constant_get(lower, &val2);
993 cloog_int_add(val, val, val2);
994 cloog_int_add_ui(val, val, 1);
995 cloog_constraint_coefficient_get(lower, level-1, &val2);
996 if (cloog_int_eq(val, val2)) {
997 cloog_int_clear(val);
998 cloog_int_clear(val2);
999 return;
1003 cloog_int_init(x);
1004 cloog_int_init(y);
1005 cloog_int_init(g);
1007 line_vector = cloog_vec_alloc(len);
1008 line_vector2 = cloog_vec_alloc(len2);
1009 line = line_vector->p;
1010 line2 = line_vector2->p;
1011 cloog_constraint_copy_coefficients(upper, line+1);
1012 if (cloog_int_is_pos(line[level]))
1013 cloog_seq_neg(line+1, line+1, len-1);
1014 cloog_int_neg(line[level], line[level]);
1015 assert(cloog_int_is_pos(line[level]));
1017 nb_elts = 0;
1018 for (i = nb_iter; i >= 1; --i) {
1019 if (i == level)
1020 continue;
1021 cloog_int_fdiv_r(line[i], line[i], line[level]);
1022 if (cloog_int_is_zero(line[i]))
1023 continue;
1025 /* Look for an earlier variable that is also a multiple of line[level]
1026 * and check whether we can use the corresponding affine expression
1027 * to "reduce" the modulo guard, where reduction means that we eliminate
1028 * a variable, possibly at the expense of introducing other variables
1029 * with smaller index.
1031 for (j = level-1; j >= 0; --j) {
1032 CloogConstraint equal_constraint;
1033 if (cloog_equal_type(infos->equal, j+1) != EQTYPE_EXAFFINE)
1034 continue;
1035 equal_constraint = cloog_equal_constraint(infos->equal, j);
1036 cloog_constraint_coefficient_get(equal_constraint, j, &val);
1037 if (!cloog_int_is_divisible_by(val, line[level])) {
1038 cloog_constraint_release(equal_constraint);
1039 continue;
1041 cloog_constraint_coefficient_get(equal_constraint, i-1, &val);
1042 if (cloog_int_is_divisible_by(val, line[level])) {
1043 cloog_constraint_release(equal_constraint);
1044 continue;
1046 for (k = j; k > i; --k) {
1047 cloog_constraint_coefficient_get(equal_constraint, k-1, &val);
1048 if (cloog_int_is_zero(val))
1049 continue;
1050 if (!cloog_int_is_divisible_by(val, line[level]))
1051 break;
1053 if (k > i) {
1054 cloog_constraint_release(equal_constraint);
1055 continue;
1057 cloog_constraint_coefficient_get(equal_constraint, i-1, &val);
1058 Euclid(val, line[level], &x, &y, &g);
1059 if (!cloog_int_is_divisible_by(val, line[i])) {
1060 cloog_constraint_release(equal_constraint);
1061 continue;
1063 cloog_int_divexact(val, line[i], g);
1064 cloog_int_neg(val, val);
1065 cloog_int_mul(val, val, x);
1066 cloog_int_set_si(y, 1);
1067 /* Add (infos->equal->p[j][i])^{-1} * line[i] times the equality */
1068 cloog_constraint_copy_coefficients(equal_constraint, line2+1);
1069 cloog_seq_combine(line+1, y, line+1, val, line2+1, i);
1070 cloog_seq_combine(line+len-nb_par-1, y, line+len-nb_par-1,
1071 val, line2+len2-nb_par-1, nb_par+1);
1072 cloog_constraint_release(equal_constraint);
1073 break;
1075 if (j >= 0) {
1076 cloog_int_fdiv_r(line[i], line[i], line[level]);
1077 assert(cloog_int_is_zero(line[i]));
1078 continue;
1081 /* We need to know if an element of the equality has not to be printed
1082 * because of a stride that guarantees that this element can be divided by
1083 * the current coefficient. Because when there is a constant element, it
1084 * is included in the stride calculation (more exactly in the strided
1085 * iterator new lower bound: the 'offset') and we have not to print it.
1087 if (!cloog_constraint_is_valid(lower) &&
1088 cloog_int_is_divisible_by(infos->stride[i-1], line[level])) {
1089 in_stride = 1;
1090 continue;
1093 nb_elts++;
1095 for (i = nb_iter+1; i <= len-1; ++i) {
1096 cloog_int_fdiv_r(line[i], line[i], line[level]);
1097 if (cloog_int_is_zero(line[i]))
1098 continue;
1099 if (i <= len-2)
1100 nb_elts++;
1103 if (nb_elts || (!cloog_int_is_zero(line[len-1]) && (!in_stride))) {
1104 struct clast_reduction *r;
1105 struct clast_expr *e;
1106 struct clast_guard *g;
1107 const char *name;
1109 r = new_clast_reduction(clast_red_sum, nb_elts+1);
1110 nb_elts = 0;
1112 /* First, the modulo guard : the iterators... */
1113 for (i=1;i<=nb_iter;i++) {
1114 if (i == level || cloog_int_is_zero(line[i]))
1115 continue;
1116 if (cloog_int_is_divisible_by(infos->stride[i-1], line[level]))
1117 continue;
1119 name = cloog_names_name_at_level(infos->names, i);
1121 r->elts[nb_elts++] = &new_clast_term(line[i],
1122 &new_clast_name(name)->expr)->expr;
1125 /* ...the parameters... */
1126 for (i=nb_iter+1;i<=len-2;i++) {
1127 if (cloog_int_is_zero(line[i]))
1128 continue;
1130 name = infos->names->parameters[i-nb_iter-1] ;
1131 r->elts[nb_elts++] = &new_clast_term(line[i],
1132 &new_clast_name(name)->expr)->expr;
1135 /* ...the constant. */
1136 if (!cloog_int_is_zero(line[len-1]))
1137 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1139 /* our initial computation may have been an overestimate */
1140 r->n = nb_elts;
1142 e = &new_clast_binary(clast_bin_mod, &r->expr, line[level])->expr;
1143 g = new_clast_guard(1);
1144 if (!cloog_constraint_is_valid(lower)) {
1145 g->eq[0].LHS = e;
1146 cloog_int_set_si(val, 0);
1147 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1148 g->eq[0].sign = 0;
1149 } else {
1150 g->eq[0].LHS = e;
1151 cloog_constraint_constant_get(upper, &val);
1152 cloog_constraint_constant_get(lower, &val2);
1153 cloog_int_add(val, val, val2);
1154 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1155 g->eq[0].sign = -1;
1158 **next = &g->stmt;
1159 *next = &g->then;
1162 cloog_vec_free(line_vector);
1163 cloog_vec_free(line_vector2);
1165 cloog_int_clear(val);
1166 cloog_int_clear(val2);
1167 cloog_int_clear(x);
1168 cloog_int_clear(y);
1169 cloog_int_clear(g);
1174 * insert_equation function:
1175 * This function inserts an equality
1176 * constraint according to an element in the clast.
1177 * An equality can be preceded by a 'modulo guard'.
1178 * For instance, consider the constraint i -2*j = 0 and the
1179 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1180 * - matrix is the polyhedron containing all the constraints,
1181 * - num is the line number of the constraint in matrix we want to print,
1182 * - level is the column number of the element in matrix we want to use,
1183 * - the infos structure gives the user some options about code printing,
1184 * the number of parameters in matrix (nb_par), and the arrays of iterator
1185 * names and parameters (iters and params).
1187 * - November 13th 2001: first version.
1188 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1189 * modulo is 0, compare vivien or vivien2 with a previous
1190 * version for an idea).
1191 * - June 29th 2003: non-unit strides support.
1192 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1193 * it was previously included in a stride calculation.
1195 static void insert_equation(CloogConstraint upper, CloogConstraint lower,
1196 int level, struct clast_stmt ***next, CloogInfos *infos)
1198 struct clast_expr *e;
1199 struct clast_assignment *ass;
1201 insert_modulo_guard(upper, lower, level, next, infos);
1203 if (cloog_constraint_is_valid(lower) ||
1204 !clast_equal_add(infos->equal, NULL, level, upper, infos))
1205 { /* Finally, the equality. */
1207 /* If we have to make a block by dimension, we start the block. Function
1208 * pprint knows if there is an equality, if this is the case, it checks
1209 * for the same following condition to close the brace.
1211 if (infos->options->block) {
1212 struct clast_block *b = new_clast_block();
1213 **next = &b->stmt;
1214 *next = &b->body;
1217 e = clast_bound_from_constraint(upper, level, infos->names);
1218 ass = new_clast_assignment(cloog_names_name_at_level(infos->names, level), e);
1220 **next = &ass->stmt;
1221 *next = &(**next)->next;
1224 cloog_constraint_release(lower);
1225 cloog_constraint_release(upper);
1227 return;
1232 * insert_for function:
1233 * This function inserts a for loop in the clast.
1234 * A loop header according to an element is the conjonction of a minimum and a
1235 * maximum on the element (they give the loop bounds).
1236 * For instance, considering these constraints and the element j:
1237 * i + j -9*M >= 0
1238 * -j +5*M >= 0
1239 * j -4*M >= 0
1240 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1241 * - matrix is the polyhedron containing all the constraints,
1242 * - level is the column number of the element in matrix we want to use,
1243 * - the infos structure gives the user some options about code printing,
1244 * the number of parameters in matrix (nb_par), and the arrays of iterator
1245 * names and parameters (iters and params).
1247 * - July 2nd 2002: first version (pick from pprint function).
1248 * - March 6th 2003: infinite domain support.
1249 * - June 29th 2003: non-unit strides support.
1251 static void insert_for(CloogConstraintSet *constraints, int level,
1252 struct clast_stmt ***next, CloogInfos *infos)
1254 const char *iterator;
1255 struct clast_expr *e1;
1256 struct clast_expr *e2;
1257 struct clast_assignment *ass;
1259 iterator = cloog_names_name_at_level(infos->names, level);
1261 e1 = clast_minmax(constraints, level, 1, 0, infos);
1262 e2 = clast_minmax(constraints, level, 0, 0, infos);
1264 /* If min and max are not equal there is a 'for' else, there is a '='.
1265 * In the special case e1 = e2 = NULL, this is an infinite loop
1266 * so this is not a '='.
1268 if (!clast_expr_equal(e1, e2) || !infos->options->otl || (!e1 && !e2)) {
1269 struct clast_for *f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1270 **next = &f->stmt;
1271 *next = &f->body;
1273 else if (!clast_equal_add(infos->equal, constraints, level,
1274 cloog_constraint_invalid(), infos)) {
1275 if (infos->options->block) {
1276 struct clast_block *b = new_clast_block();
1277 **next = &b->stmt;
1278 *next = &b->body;
1280 ass = new_clast_assignment(iterator, e1);
1281 free_clast_expr(e2);
1282 **next = &ass->stmt;
1283 *next = &(**next)->next;
1284 } else {
1285 free_clast_expr(e1);
1286 free_clast_expr(e2);
1289 return;
1294 * insert_block function:
1295 * This function inserts a statement block.
1296 * - block is the statement block,
1297 * - level is the number of loops enclosing the statement,
1298 * - the infos structure gives the user some options about code printing,
1299 * the number of parameters in domain (nb_par), and the arrays of iterator
1300 * names and parameters (iters and params).
1302 * - September 21th 2003: first version (pick from pprint function).
1304 static void insert_block(CloogBlock *block, int level,
1305 struct clast_stmt ***next, CloogInfos *infos)
1307 CloogStatement * statement ;
1308 struct clast_stmt *subs;
1310 if (!block)
1311 return;
1313 for (statement = block->statement; statement; statement = statement->next) {
1314 subs = clast_equal(level,infos);
1316 **next = &new_clast_user_stmt(statement, subs)->stmt;
1317 *next = &(**next)->next;
1323 * insert_loop function:
1324 * This function converts the content of a CloogLoop structure (loop) into a
1325 * clast_stmt (inserted at **next).
1326 * The iterator (level) of
1327 * the current loop is given by 'level': this is the column number of the
1328 * domain corresponding to the current loop iterator. The data of a loop are
1329 * written in this order:
1330 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1331 * depend on the iterator (when the entry in the column 'level' is 0).
1332 * 2. The iteration domain of the iterator, given by the constraints in the
1333 * domain depending on the iterator, i.e.:
1334 * * an equality if the iterator has only one value (possibly preceded by
1335 * a guard verifying if this value is integral), *OR*
1336 * * a loop from the minimum possible value of the iterator to the maximum
1337 * possible value.
1338 * 3. The included statement block.
1339 * 4. The inner loops (recursive call).
1340 * 5. The following loops (recursive call).
1341 * - level is the recursion level or the iteration level that we are printing,
1342 * - the infos structure gives the user some options about code printing,
1343 * the number of parameters in domain (nb_par), and the arrays of iterator
1344 * names and parameters (iters and params).
1346 * - November 2nd 2001: first version.
1347 * - March 6th 2003: infinite domain support.
1348 * - April 19th 2003: (debug) NULL loop support.
1349 * - June 29th 2003: non-unit strides support.
1350 * - April 28th 2005: (debug) level is level+equality when print statement!
1351 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1352 * added to avoid iteration duplication (see DaeGon Kim
1353 * bug in cloog_program_generate). Try vasilache.cloog
1354 * with and without the call to cloog_matrix_normalize,
1355 * using -f 8 -l 9 options for an idea.
1356 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1357 * - October 16th 2005: (debug) scalar value is saved for next loops.
1359 static void insert_loop(CloogLoop * loop, int level, int scalar,
1360 struct clast_stmt ***next, CloogInfos *infos)
1362 int equality=0, scalar_level;
1363 CloogConstraintSet *constraints, *temp;
1364 struct clast_stmt **top = *next;
1365 CloogConstraint i, j;
1367 /* It can happen that loop be NULL when an input polyhedron is empty. */
1368 if (loop == NULL)
1369 return;
1371 /* The constraints do not always have a shape that allows us to generate code from it,
1372 * thus we normalize it, we also simplify it with the equalities.
1374 temp = cloog_domain_constraints(loop->domain);
1375 cloog_constraint_set_normalize(temp,level);
1376 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1377 infos->names->nb_parameters);
1378 cloog_constraint_set_free(temp);
1379 if (level)
1380 cloog_int_set(infos->stride[level-1], loop->stride);
1382 /* First of all we have to print the guard. */
1383 insert_guard(constraints,level, next, infos);
1385 if (level && cloog_constraint_set_contains_level(constraints, level,
1386 infos->names->nb_parameters)) {
1387 /* We scan all the constraints to know in which case we are :
1388 * [[if] equation] or [for].
1390 if (cloog_constraint_is_valid(i =
1391 cloog_constraint_set_defining_equality(constraints, level))) {
1392 insert_equation(i, cloog_constraint_invalid(), level, next, infos);
1393 equality = 1 ;
1394 } else if (cloog_constraint_is_valid(i =
1395 cloog_constraint_set_defining_inequalities(constraints,
1396 level, &j, infos->names->nb_parameters))) {
1397 insert_equation(i, j, level, next, infos);
1398 } else
1399 insert_for(constraints, level, next, infos);
1402 /* Finally, if there is an included statement block, print it. */
1403 insert_block(loop->block, level+equality, next, infos);
1405 /* Go to the next level. */
1406 if (loop->inner != NULL)
1407 insert_loop(loop->inner, level+1,scalar, next, infos);
1409 if (level)
1410 cloog_equal_del(infos->equal,level);
1411 cloog_constraint_set_free(constraints);
1413 /* Go to the next loop on the same level. */
1414 while (*top)
1415 top = &(*top)->next;
1416 if (loop->next != NULL)
1417 insert_loop(loop->next, level,scalar_level, &top,infos);
1421 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1422 CloogOptions *options)
1424 CloogInfos *infos = ALLOC(CloogInfos);
1425 int i, nb_levels;
1426 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1427 struct clast_stmt **next = &root->next;
1429 infos->names = program->names;
1430 infos->options = options;
1431 infos->scaldims = program->scaldims;
1432 infos->nb_scattdims = program->nb_scattdims;
1434 /* Allocation for the array of strides, there is a +1 since the statement can
1435 * be included inside an external loop without iteration domain.
1437 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1438 infos->stride = ALLOCN(cloog_int_t, nb_levels);
1439 for (i = 0; i < nb_levels; ++i)
1440 cloog_int_init(infos->stride[i]);
1442 infos->equal = cloog_equal_alloc(nb_levels,
1443 nb_levels, program->names->nb_parameters);
1445 insert_loop(program->loop, 0, 0, &next, infos);
1447 cloog_equal_free(infos->equal);
1449 for (i = 0; i < nb_levels; ++i)
1450 cloog_int_clear(infos->stride[i]);
1451 free(infos->stride);
1452 free(infos);
1454 return root;