Rename CloogConstraints to CloogConstraintSet
[cloog.git] / source / clast.c
blob749abd986533a18dc3b2812029e209e10ab1b9f2
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, CloogConstraintSet *constraints,
37 int level, int line, CloogInfos *infos);
39 static struct clast_stmt * clast_equal(CloogInfos *infos);
40 static struct clast_stmt * clast_equal_cpp(int level, CloogInfos *infos);
41 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
42 int level, int max, int guard,
43 CloogInfos *infos);
44 static void insert_guard(CloogConstraintSet *constraints, int level,
45 struct clast_stmt ***next, CloogInfos *infos);
46 static void insert_modulo_guard(CloogConstraintSet *constraints, int upper,
47 int lower, int level,
48 struct clast_stmt ***next, CloogInfos *infos);
49 static void insert_equation(CloogConstraintSet *constraints, int upper, int lower,
50 int level, struct clast_stmt ***next, CloogInfos *infos);
51 static void insert_for(CloogConstraintSet *constraints, int level,
52 struct clast_stmt ***next, CloogInfos *infos);
53 static void insert_scalar(CloogLoop *loop, int level, int *scalar,
54 struct clast_stmt ***next, CloogInfos *infos);
55 static void insert_block(CloogBlock *block, int level,
56 struct clast_stmt ***next, CloogInfos *infos);
57 static void insert_loop(CloogLoop * loop, int level, int scalar,
58 struct clast_stmt ***next, CloogInfos *infos);
61 struct clast_term *new_clast_term(cloog_int_t c, const char *v)
63 struct clast_term *t = malloc(sizeof(struct clast_term));
64 t->expr.type = expr_term;
65 cloog_int_init(t->val);
66 cloog_int_set(t->val, c);
67 t->var = v;
68 return t;
71 struct clast_binary *new_clast_binary(enum clast_bin_type t,
72 struct clast_expr *lhs, cloog_int_t rhs)
74 struct clast_binary *b = malloc(sizeof(struct clast_binary));
75 b->expr.type = expr_bin;
76 b->type = t;
77 b->LHS = lhs;
78 cloog_int_init(b->RHS);
79 cloog_int_set(b->RHS, rhs);
80 return b;
83 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
85 int i;
86 struct clast_reduction *r;
87 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
88 r->expr.type = expr_red;
89 r->type = t;
90 r->n = n;
91 for (i = 0; i < n; ++i)
92 r->elts[i] = NULL;
93 return r;
96 static void free_clast_root(struct clast_stmt *s);
98 struct clast_stmt_op stmt_root = { free_clast_root };
100 static void free_clast_root(struct clast_stmt *s)
102 struct clast_root *r = (struct clast_root *)s;
103 assert(CLAST_STMT_IS_A(s, stmt_root));
104 cloog_names_free(r->names);
105 free(r);
108 struct clast_root *new_clast_root(CloogNames *names)
110 struct clast_root *r = malloc(sizeof(struct clast_root));
111 r->stmt.op = &stmt_root;
112 r->stmt.next = NULL;
113 r->names = cloog_names_copy(names);
114 return r;
117 static void free_clast_assignment(struct clast_stmt *s);
119 struct clast_stmt_op stmt_ass = { free_clast_assignment };
121 static void free_clast_assignment(struct clast_stmt *s)
123 struct clast_assignment *a = (struct clast_assignment *)s;
124 assert(CLAST_STMT_IS_A(s, stmt_ass));
125 free_clast_expr(a->RHS);
126 free(a);
129 struct clast_assignment *new_clast_assignment(const char *lhs,
130 struct clast_expr *rhs)
132 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
133 a->stmt.op = &stmt_ass;
134 a->stmt.next = NULL;
135 a->LHS = lhs;
136 a->RHS = rhs;
137 return a;
140 static void free_clast_user_stmt(struct clast_stmt *s);
142 struct clast_stmt_op stmt_user = { free_clast_user_stmt };
144 static void free_clast_user_stmt(struct clast_stmt *s)
146 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
147 assert(CLAST_STMT_IS_A(s, stmt_user));
148 cloog_clast_free(u->substitutions);
149 free(u);
152 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
153 struct clast_stmt *subs)
155 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
156 u->stmt.op = &stmt_user;
157 u->stmt.next = NULL;
158 u->statement = stmt;
159 u->substitutions = subs;
160 return u;
163 static void free_clast_block(struct clast_stmt *b);
165 struct clast_stmt_op stmt_block = { free_clast_block };
167 static void free_clast_block(struct clast_stmt *s)
169 struct clast_block *b = (struct clast_block *)s;
170 assert(CLAST_STMT_IS_A(s, stmt_block));
171 cloog_clast_free(b->body);
172 free(b);
175 struct clast_block *new_clast_block()
177 struct clast_block *b = malloc(sizeof(struct clast_block));
178 b->stmt.op = &stmt_block;
179 b->stmt.next = NULL;
180 b->body = NULL;
181 return b;
184 static void free_clast_for(struct clast_stmt *s);
186 struct clast_stmt_op stmt_for = { free_clast_for };
188 static void free_clast_for(struct clast_stmt *s)
190 struct clast_for *f = (struct clast_for *)s;
191 assert(CLAST_STMT_IS_A(s, stmt_for));
192 free_clast_expr(f->LB);
193 free_clast_expr(f->UB);
194 cloog_int_clear(f->stride);
195 cloog_clast_free(f->body);
196 free(f);
199 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
200 struct clast_expr *UB, cloog_int_t stride)
202 struct clast_for *f = malloc(sizeof(struct clast_for));
203 f->stmt.op = &stmt_for;
204 f->stmt.next = NULL;
205 f->iterator = it;
206 f->LB = LB;
207 f->UB = UB;
208 f->body = NULL;
209 cloog_int_init(f->stride);
210 cloog_int_set(f->stride, stride);
211 return f;
214 static void free_clast_guard(struct clast_stmt *s);
216 struct clast_stmt_op stmt_guard = { free_clast_guard };
218 static void free_clast_guard(struct clast_stmt *s)
220 int i;
221 struct clast_guard *g = (struct clast_guard *)s;
222 assert(CLAST_STMT_IS_A(s, stmt_guard));
223 cloog_clast_free(g->then);
224 for (i = 0; i < g->n; ++i) {
225 free_clast_expr(g->eq[i].LHS);
226 free_clast_expr(g->eq[i].RHS);
228 free(g);
231 struct clast_guard *new_clast_guard(int n)
233 int i;
234 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
235 (n-1) * sizeof(struct clast_equation));
236 g->stmt.op = &stmt_guard;
237 g->stmt.next = NULL;
238 g->then = NULL;
239 g->n = n;
240 for (i = 0; i < n; ++i) {
241 g->eq[i].LHS = NULL;
242 g->eq[i].RHS = NULL;
244 return g;
247 void free_clast_term(struct clast_term *t)
249 cloog_int_clear(t->val);
250 free(t);
253 void free_clast_binary(struct clast_binary *b)
255 cloog_int_clear(b->RHS);
256 free_clast_expr(b->LHS);
257 free(b);
260 void free_clast_reduction(struct clast_reduction *r)
262 int i;
263 for (i = 0; i < r->n; ++i)
264 free_clast_expr(r->elts[i]);
265 free(r);
268 void free_clast_expr(struct clast_expr *e)
270 if (!e)
271 return;
272 switch (e->type) {
273 case expr_term:
274 free_clast_term((struct clast_term*) e);
275 break;
276 case expr_red:
277 free_clast_reduction((struct clast_reduction*) e);
278 break;
279 case expr_bin:
280 free_clast_binary((struct clast_binary*) e);
281 break;
282 default:
283 assert(0);
287 void free_clast_stmt(struct clast_stmt *s)
289 assert(s->op);
290 assert(s->op->free);
291 s->op->free(s);
294 void cloog_clast_free(struct clast_stmt *s)
296 struct clast_stmt *next;
297 while (s) {
298 next = s->next;
299 free_clast_stmt(s);
300 s = next;
304 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
306 int c;
307 if (!t1->var && t2->var)
308 return -1;
309 if (t1->var && !t2->var)
310 return 1;
311 if (t1->var != t2->var && (c = strcmp(t1->var, t2->var)))
312 return c;
313 return cloog_int_cmp(t1->val, t2->val);
316 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
318 int c;
320 if (b1->type != b2->type)
321 return b1->type - b2->type;
322 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
323 return c;
324 return clast_expr_cmp(b1->LHS, b2->LHS);
327 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
329 int i;
330 int c;
332 if (r1->type == clast_red_max && r2->type == clast_red_min &&
333 r1->n == 1 && r2->n == 1)
334 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
335 if (r1->type != r2->type)
336 return r1->type - r2->type;
337 if (r1->n != r2->n)
338 return r1->n - r2->n;
339 for (i = 0; i < r1->n; ++i)
340 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
341 return c;
342 return 0;
345 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
347 if (!e1 && !e2)
348 return 0;
349 if (!e1)
350 return -1;
351 if (!e2)
352 return 1;
353 if (e1->type != e2->type)
354 return e1->type - e2->type;
355 switch (e1->type) {
356 case expr_term:
357 return clast_term_cmp((struct clast_term*) e1,
358 (struct clast_term*) e2);
359 case expr_bin:
360 return clast_binary_cmp((struct clast_binary*) e1,
361 (struct clast_binary*) e2);
362 case expr_red:
363 return clast_reduction_cmp((struct clast_reduction*) e1,
364 (struct clast_reduction*) e2);
365 default:
366 assert(0);
370 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
372 return clast_expr_cmp(e1, e2) == 0;
375 static int qsort_expr_cmp(const void *p1, const void *p2)
377 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
380 static void clast_reduction_sort(struct clast_reduction *r)
382 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
386 /******************************************************************************
387 * Equalities spreading functions *
388 ******************************************************************************/
392 * clast_equal_allow function:
393 * This function checks whether the options allow us to spread the equality or
394 * not. It returns 1 if so, 0 otherwise.
395 * - equal is the matrix of equalities,
396 * - level is the column number in equal of the element which is 'equal to',
397 * - line is the line number in equal of the constraint we want to study,
398 * - the infos structure gives the user all options on code printing and more.
400 * - October 27th 2005: first version (extracted from old pprint_equal_add).
402 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
403 CloogInfos *infos)
405 if ((!infos->options->csp && !infos->options->esp) ||
406 (level < infos->options->fsp))
407 return 0 ;
409 if (infos->options->csp &&
410 (cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
411 !infos->options->esp)
412 return 0 ;
414 return 1 ;
419 * clast_equal_add function:
420 * This function updates the row (level-1) of the equality matrix (equal) with
421 * the row that corresponds to the row (line) of the matrix (matrix). It returns
422 * 1 if the row can be updated, 0 otherwise.
423 * - equal is the matrix of equalities,
424 * - matrix is the matrix of constraints,
425 * - level is the column number in matrix of the element which is 'equal to',
426 * - line is the line number in matrix of the constraint we want to study,
427 * - the infos structure gives the user all options on code printing and more.
429 static int clast_equal_add(CloogEqualities *equal, CloogConstraintSet *constraints,
430 int level, int line, CloogInfos *infos)
432 cloog_equal_add(equal, constraints, level, line, infos->names->nb_parameters);
434 return clast_equal_allow(equal, level, level-1, infos);
441 * clast_equal function:
442 * This function returns the content an equality matrix (equal) into a clast_stmt.
443 * - the infos structure gives the user all options on code printing and more.
445 * - July 2nd 2002: first version.
446 * - March 16th 2003: return now a string instead of printing directly and do
447 * not write 'Sx()' if there is no spreading, but only 'Sx'.
449 static struct clast_stmt * clast_equal(CloogInfos *infos)
451 int i, iterator ;
452 struct clast_expr *e;
453 struct clast_stmt *a = NULL;
454 struct clast_stmt **next = &a;
455 CloogEqualities *equal = infos->equal;
456 CloogConstraintSet *constraints = cloog_equal_constraints(equal);
458 /* It is not necessary to print here the scattering iterators since they
459 * never appear in the statement bodies.
461 for (i = infos->names->nb_scattering; i< cloog_equal_count(equal); i++) {
462 if (cloog_equal_type(equal, i+1) && clast_equal_allow(equal,i+1,i,infos)) {
463 iterator = i - infos->names->nb_scattering ;
464 e = clast_bound_from_constraint(constraints, i, i+1, infos->names);
465 *next = &new_clast_assignment(infos->names->iterators[iterator], e)->stmt;
466 next = &(*next)->next;
470 return a;
475 * clast_equal_cpp function:
476 * This function prints the substitution data of a statement into a clast_stmt.
477 * Using this function instead of pprint_equal is useful for generating
478 * a compilable pseudo-code by using preprocessor macro for each statement.
479 * By opposition to pprint_equal, the result is less human-readable. For
480 * instance this function will print (i,i+3,k,3) where pprint_equal would
481 * return (j=i+3,l=3).
482 * - level is the number of loops enclosing the statement,
483 * - the infos structure gives the user all options on code printing and more.
485 * - March 12th 2004: first version.
486 * - November 21th 2005: (debug) now works well with GMP version.
488 static struct clast_stmt * clast_equal_cpp(int level, CloogInfos *infos)
490 int i ;
491 cloog_int_t one;
492 struct clast_expr *e;
493 struct clast_stmt *a = NULL;
494 struct clast_stmt **next = &a;
495 CloogEqualities *equal = infos->equal;
496 CloogConstraintSet *constraints = cloog_equal_constraints(equal);
498 cloog_int_init(one);
500 for (i=infos->names->nb_scattering;i<level-1;i++)
501 { if (cloog_equal_type(equal, i+1)) {
502 e = clast_bound_from_constraint(constraints, i, i+1, infos->names);
503 } else {
504 cloog_int_set_si(one, 1);
505 e = &new_clast_term(one,
506 infos->names->iterators[i-infos->names->nb_scattering])->expr;
508 *next = &new_clast_assignment(NULL, e)->stmt;
509 next = &(*next)->next;
511 cloog_int_clear(one);
513 return a;
518 * clast_bound_from_constraint function:
519 * This function returns a clast_expr containing the printing of the
520 * 'right part' of a constraint according to an element.
521 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
522 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
523 * function should return 'ceild(3*i+M,2)'.
524 * - matrix is the polyhedron containing all the constraints,
525 * - line_num is the line number in domain of the constraint we want to print,
526 * - level is the column number in domain of the element we want to use,
527 * - names structure gives the user some options about code printing,
528 * the number of parameters in domain (nb_par), and the arrays of iterator
529 * names and parameters (iters and params).
531 * - November 2nd 2001: first version.
532 * - June 27th 2003: 64 bits version ready.
534 struct clast_expr *clast_bound_from_constraint(CloogConstraintSet *constraints,
535 int line_num, int level,
536 CloogNames *names)
538 int i, nb_iter, sign, nb_elts=0, len;
539 char * name;
540 cloog_int_t *line, numerator, denominator, temp, division;
541 struct clast_expr *e = NULL;
542 struct cloog_vec *line_vector;
544 len = cloog_constraint_set_total_dimension(constraints) + 2;
545 line_vector = cloog_vec_alloc(len);
546 line = line_vector->p;
547 cloog_constraint_copy(constraints, line_num, line+1);
548 cloog_int_init(temp);
549 cloog_int_init(numerator);
550 cloog_int_init(denominator);
552 if (!cloog_int_is_zero(line[level])) {
553 struct clast_reduction *r;
554 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
555 sign = -cloog_int_sgn(line[level]);
557 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
558 if (i != level && !cloog_int_is_zero(line[i]))
559 nb_elts++;
560 r = new_clast_reduction(clast_red_sum, nb_elts);
561 nb_elts = 0;
563 /* First, we have to print the iterators. */
564 nb_iter = len - 2 - names->nb_parameters;
565 for (i=1;i<=nb_iter;i++)
566 if ((i != level) && !cloog_int_is_zero(line[i])) {
567 if (i <= names->nb_scattering)
568 name = names->scattering[i-1];
569 else
570 name = names->iterators[i-names->nb_scattering-1];
572 if (sign == -1)
573 cloog_int_neg(temp,line[i]);
574 else
575 cloog_int_set(temp,line[i]);
577 r->elts[nb_elts++] = &new_clast_term(temp, name)->expr;
580 /* Next, the parameters. */
581 for (i = nb_iter + 1; i <= len - 2; i++)
582 if ((i != level) && !cloog_int_is_zero(line[i])) {
583 name = names->parameters[i-nb_iter-1];
585 if (sign == -1)
586 cloog_int_neg(temp,line[i]);
587 else
588 cloog_int_set(temp,line[i]);
590 r->elts[nb_elts++] = &new_clast_term(temp, name)->expr;
593 if (sign == -1) {
594 cloog_int_neg(numerator, line[len - 1]);
595 cloog_int_set(denominator, line[level]);
597 else {
598 cloog_int_set(numerator, line[len - 1]);
599 cloog_int_neg(denominator, line[level]);
602 /* Finally, the constant, and the final printing. */
603 if (nb_elts) {
604 if (!cloog_int_is_zero(numerator))
605 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
607 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
608 { if (!cloog_constraint_is_equality(constraints, line_num))
609 { if (cloog_int_is_pos(line[level]))
610 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
611 else
612 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
613 } else
614 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
616 else
617 e = &r->expr;
618 } else {
619 free_clast_reduction(r);
620 if (cloog_int_is_zero(numerator))
621 e = &new_clast_term(numerator, NULL)->expr;
622 else
623 { if (!cloog_int_is_one(denominator))
624 { if (!cloog_constraint_is_equality(constraints, line_num)) { /* useful? */
625 if (cloog_int_is_divisible_by(numerator, denominator)) {
626 cloog_int_divexact(temp, numerator, denominator);
627 e = &new_clast_term(temp, NULL)->expr;
629 else {
630 cloog_int_init(division);
631 cloog_int_tdiv_q(division, numerator, denominator);
632 if (cloog_int_is_neg(numerator)) {
633 if (cloog_int_is_pos(line[level])) {
634 /* nb<0 need max */
635 e = &new_clast_term(division, NULL)->expr;
636 } else {
637 /* nb<0 need min */
638 cloog_int_sub_ui(temp, division, 1);
639 e = &new_clast_term(temp, NULL)->expr;
642 else
643 { if (cloog_int_is_pos(line[level]))
644 { /* nb>0 need max */
645 cloog_int_add_ui(temp, division, 1);
646 e = &new_clast_term(temp, NULL)->expr;
648 else
649 /* nb>0 need min */
650 e = &new_clast_term(division, NULL)->expr;
652 cloog_int_clear(division);
655 else
656 e = &new_clast_binary(clast_bin_div,
657 &new_clast_term(numerator, NULL)->expr,
658 denominator)->expr;
660 else
661 e = &new_clast_term(numerator, NULL)->expr;
666 cloog_vec_free(line_vector);
668 cloog_int_clear(temp);
669 cloog_int_clear(numerator);
670 cloog_int_clear(denominator);
672 return e;
677 * clast_minmax function:
678 * This function returns a clast_expr containing the printing of a minimum or a
679 * maximum of the 'right parts' of all constraints according to an element.
680 * For instance consider the constraints:
681 * -3*i +2*j -M >= 0
682 * 2*i +j >= 0
683 * -i -j +2*M >= 0
684 * if we are looking for the minimum for the element j, the function should
685 * return 'max(ceild(3*i+M,2),-2*i)'.
686 * - constraints is the constraints,
687 * - level is the column number in domain of the element we want to use,
688 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
689 * - guard is set to 0 if there is no guard, and set to the level of the element
690 * with a guard otherwise (then the function gives the max or the min only
691 * for the constraint where the guarded coefficient is 0),
692 * - the infos structure gives the user some options about code printing,
693 * the number of parameters in domain (nb_par), and the arrays of iterator
694 * names and parameters (iters and params).
696 * - November 2nd 2001: first version.
698 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
699 int level, int max, int guard,
700 CloogInfos *infos)
701 { int i, n;
702 struct clast_reduction *r;
704 for (i = 0, n = 0; i < cloog_constraint_set_count(constraints); i++)
705 if (((max && cloog_constraint_is_lower_bound(constraints, i, level-1)) ||
706 (!max && cloog_constraint_is_upper_bound(constraints, i, level-1))) &&
707 (!guard || !cloog_constraint_involves(constraints, i, guard-1)) &&
708 (!cloog_constraint_is_equality(constraints, i)))
709 n++;
710 if (!n)
711 return NULL;
712 r = new_clast_reduction(max ? clast_red_max : clast_red_min, n);
714 for (i = 0, n = 0; i < cloog_constraint_set_count(constraints); i++)
715 if (((max && cloog_constraint_is_lower_bound(constraints, i, level-1)) ||
716 (!max && cloog_constraint_is_upper_bound(constraints, i, level-1))) &&
717 (!guard || !cloog_constraint_involves(constraints, i, guard-1)) &&
718 (!cloog_constraint_is_equality(constraints, i)))
719 r->elts[n++] = clast_bound_from_constraint(constraints, i, level,
720 infos->names);
722 clast_reduction_sort(r);
723 return &r->expr;
728 * insert_guard function:
729 * This function inserts a guard in the clast.
730 * A guard on an element (level) is :
731 * -> the conjunction of all the existing constraints where the coefficient of
732 * this element is 0 if the element is an iterator,
733 * -> the conjunction of all the existing constraints if the element isn't an
734 * iterator.
735 * For instance, considering these constraints and the element j:
736 * -3*i +2*j -M >= 0
737 * 2*i +M >= 0
738 * this function should return 'if (2*i+M>=0) {'.
739 * - matrix is the polyhedron containing all the constraints,
740 * - level is the column number of the element in matrix we want to use,
741 * - the infos structure gives the user some options about code printing,
742 * the number of parameters in matrix (nb_par), and the arrays of iterator
743 * names and parameters (iters and params).
745 * - November 3rd 2001: first version.
746 * - November 14th 2001: a lot of 'purifications'.
747 * - July 31th 2002: (debug) some guard parts are no more redundants.
748 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
749 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
750 * (the need came from loop_simplify that may result in
751 * domain unions, now it should be fixed directly in
752 * cloog_loop_simplify).
754 static void insert_guard(CloogConstraintSet *constraints, int level,
755 struct clast_stmt ***next, CloogInfos *infos)
757 int i, j, l, guarded, minmax=-1, nb_and = 0, nb_iter ;
758 int total_dim;
759 char * name;
760 CloogConstraintSet *copy;
761 struct clast_guard *g;
762 cloog_int_t one;
764 if (constraints == NULL)
765 return;
767 cloog_int_init(one);
768 cloog_int_set_si(one, 1);
770 total_dim = cloog_constraint_set_total_dimension(constraints);
771 g = new_clast_guard(2 * total_dim);
773 /* Well, it looks complicated because I wanted to have a particular, more
774 * readable, ordering, obviously this function may be far much simpler !
776 copy = cloog_constraint_set_copy(constraints);
778 nb_iter = total_dim - infos->names->nb_parameters;
780 nb_and = 0 ;
781 /* We search for guard parts. */
782 for (i = 1; i <= total_dim; i++)
783 for (j = 0; j< cloog_constraint_set_count(copy); j++)
784 if (cloog_constraint_involves(copy, j, i-1) &&
785 (!cloog_constraint_involves(copy, j, level-1) || (nb_iter < level))) {
786 struct clast_term *t;
787 if (i <= nb_iter)
788 { if (i <= infos->names->nb_scattering)
789 name = infos->names->scattering[i-1] ;
790 else
791 name = infos->names->iterators[i-infos->names->nb_scattering-1] ;
793 else
794 name = infos->names->parameters[i-(nb_iter+1)] ;
796 g->eq[nb_and].LHS = &(t = new_clast_term(one, name))->expr;
797 if (cloog_constraint_is_equality(copy, j)) {
798 /* put the "denominator" in the LHS */
799 cloog_constraint_coefficient_get(copy, j, i-1, &t->val);
800 cloog_constraint_coefficient_set(copy, j, i-1, one);
801 g->eq[nb_and].sign = 0;
802 g->eq[nb_and].RHS = clast_bound_from_constraint(copy,j,i,infos->names);
803 } else {
804 if (cloog_constraint_is_lower_bound(copy, j, i-1)) {
805 minmax = 1;
806 g->eq[nb_and].sign = 1;
807 } else {
808 minmax = 0;
809 g->eq[nb_and].sign = -1;
812 guarded = (nb_iter >= level) ? level : 0 ;
813 g->eq[nb_and].RHS = clast_minmax(copy,i,minmax,guarded,infos) ;
815 nb_and ++ ;
817 /* 'elimination' of the current constraint, this avoid to use one
818 * constraint more than once. The current line is always eliminated,
819 * and the next lines if they are in a min or a max.
821 cloog_constraint_clear(copy, j);
823 if (minmax == -1)
824 continue;
825 for (l = j + 1; l < cloog_constraint_set_count(copy); l++)
826 if (((minmax == 1) && cloog_constraint_is_lower_bound(copy, l, i-1)) ||
827 ((minmax == 0) && cloog_constraint_is_upper_bound(copy, l, i-1)))
828 cloog_constraint_clear(copy, l);
830 cloog_constraint_set_free(copy);
832 g->n = nb_and;
833 if (nb_and) {
834 **next = &g->stmt;
835 *next = &g->then;
836 } else
837 free_clast_stmt(&g->stmt);
839 cloog_int_clear(one);
840 return;
844 /* Computes x, y and g such that g = gcd(a,b) and a*x+b*y = g */
845 static void Euclid(cloog_int_t a, cloog_int_t b,
846 cloog_int_t *x, cloog_int_t *y, cloog_int_t *g)
848 cloog_int_t c, d, e, f, tmp;
850 cloog_int_init(c);
851 cloog_int_init(d);
852 cloog_int_init(e);
853 cloog_int_init(f);
854 cloog_int_init(tmp);
855 cloog_int_abs(c, a);
856 cloog_int_abs(d, b);
857 cloog_int_set_si(e, 1);
858 cloog_int_set_si(f, 0);
859 while (cloog_int_is_pos(d)) {
860 cloog_int_tdiv_q(tmp, c, d);
861 cloog_int_mul(tmp, tmp, f);
862 cloog_int_sub(e, e, tmp);
863 cloog_int_tdiv_q(tmp, c, d);
864 cloog_int_mul(tmp, tmp, d);
865 cloog_int_sub(c, c, tmp);
866 cloog_int_swap(c, d);
867 cloog_int_swap(e, f);
869 cloog_int_set(*g, c);
870 if (cloog_int_is_zero(a))
871 cloog_int_set_si(*x, 0);
872 else if (cloog_int_is_pos(a))
873 cloog_int_set(*x, e);
874 else cloog_int_neg(*x, e);
875 if (cloog_int_is_zero(b))
876 cloog_int_set_si(*y, 0);
877 else {
878 cloog_int_mul(tmp, a, *x);
879 cloog_int_sub(tmp, c, tmp);
880 cloog_int_divexact(*y, tmp, b);
882 cloog_int_clear(c);
883 cloog_int_clear(d);
884 cloog_int_clear(e);
885 cloog_int_clear(f);
886 cloog_int_clear(tmp);
891 * insert_modulo_guard:
892 * This function inserts a modulo guard corresponding to an equality
893 * or a pair of inequalities.
894 * See insert_equation.
895 * - matrix is the polyhedron containing all the constraints,
896 * - upper and lower are the line numbers of the constraint in matrix
897 * we want to print; in particular, if we want to print an equality,
898 * then lower == -1 and upper is the row of the equality; if we want
899 * to print an inequality, then upper is the row of the upper bound
900 * and lower in the row of the lower bound
901 * - level is the column number of the element in matrix we want to use,
902 * - the infos structure gives the user some options about code printing,
903 * the number of parameters in matrix (nb_par), and the arrays of iterator
904 * names and parameters (iters and params).
906 static void insert_modulo_guard(CloogConstraintSet *constraints, int upper,
907 int lower, int level,
908 struct clast_stmt ***next, CloogInfos *infos)
910 int i, j, k, nb_elts = 0, len, len2, nb_iter, in_stride = 0, nb_par;
911 struct cloog_vec *line_vector, *line_vector2;
912 cloog_int_t *line, *line2, val, val2, x, y, g;
913 CloogConstraintSet *equal_constraints = cloog_equal_constraints(infos->equal);
915 cloog_int_init(val);
916 cloog_constraint_coefficient_get(constraints, upper, level-1, &val);
917 if (cloog_int_is_one(val) || cloog_int_is_neg_one(val)) {
918 cloog_int_clear(val);
919 return;
922 len = cloog_constraint_set_total_dimension(constraints) + 2;
923 len2 = cloog_constraint_set_total_dimension(equal_constraints) + 2;
924 nb_par = infos->names->nb_parameters;
925 nb_iter = len - 2 - nb_par;
927 cloog_int_init(val2);
928 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
929 if (lower != -1) {
930 cloog_constraint_constant_get(constraints, upper, &val);
931 cloog_constraint_constant_get(constraints, lower, &val2);
932 cloog_int_add(val, val, val2);
933 cloog_int_add_ui(val, val, 1);
934 cloog_constraint_coefficient_get(constraints, lower, level-1, &val2);
935 if (cloog_int_eq(val, val2)) {
936 cloog_int_clear(val);
937 cloog_int_clear(val2);
938 return;
942 cloog_int_init(x);
943 cloog_int_init(y);
944 cloog_int_init(g);
946 line_vector = cloog_vec_alloc(len);
947 line_vector2 = cloog_vec_alloc(len2);
948 line = line_vector->p;
949 line2 = line_vector2->p;
950 cloog_constraint_copy(constraints, upper, line+1);
951 if (cloog_int_is_pos(line[level]))
952 cloog_seq_neg(line+1, line+1, len-1);
953 cloog_int_neg(line[level], line[level]);
954 assert(cloog_int_is_pos(line[level]));
956 nb_elts = 0;
957 for (i = nb_iter; i >= 1; --i) {
958 if (i == level)
959 continue;
960 cloog_int_fdiv_r(line[i], line[i], line[level]);
961 if (cloog_int_is_zero(line[i]))
962 continue;
964 /* Look for an earlier variable that is also a multiple of line[level]
965 * and check whether we can use the corresponding affine expression
966 * to "reduce" the modulo guard, where reduction means that we eliminate
967 * a variable, possibly at the expense of introducing other variables
968 * with smaller index.
970 for (j = level-1; j >= 0; --j) {
971 if (cloog_equal_type(infos->equal, j+1) != EQTYPE_EXAFFINE)
972 continue;
973 cloog_constraint_coefficient_get(equal_constraints, j, j, &val);
974 if (!cloog_int_is_divisible_by(val, line[level]))
975 continue;
976 cloog_constraint_coefficient_get(equal_constraints, j, i-1, &val);
977 if (cloog_int_is_divisible_by(val, line[level]))
978 continue;
979 for (k = j; k > i; --k) {
980 cloog_constraint_coefficient_get(equal_constraints, j, k-1, &val);
981 if (cloog_int_is_zero(val))
982 continue;
983 if (!cloog_int_is_divisible_by(val, line[level]))
984 break;
986 if (k > i)
987 continue;
988 cloog_constraint_coefficient_get(equal_constraints, j, i-1, &val);
989 Euclid(val, line[level], &x, &y, &g);
990 if (!cloog_int_is_divisible_by(val, line[i]))
991 continue;
992 cloog_int_divexact(val, line[i], g);
993 cloog_int_neg(val, val);
994 cloog_int_mul(val, val, x);
995 cloog_int_set_si(y, 1);
996 /* Add (infos->equal->p[j][i])^{-1} * line[i] times the equality */
997 cloog_constraint_copy(equal_constraints, j, line2+1);
998 cloog_seq_combine(line+1, y, line+1, val, line2+1, i);
999 cloog_seq_combine(line+len-nb_par-1, y, line+len-nb_par-1,
1000 val, line2+len2-nb_par-1, nb_par+1);
1001 break;
1003 if (j >= 0) {
1004 cloog_int_fdiv_r(line[i], line[i], line[level]);
1005 assert(cloog_int_is_zero(line[i]));
1006 continue;
1009 /* We need to know if an element of the equality has not to be printed
1010 * because of a stride that guarantees that this element can be divided by
1011 * the current coefficient. Because when there is a constant element, it
1012 * is included in the stride calculation (more exactly in the strided
1013 * iterator new lower bound: the 'offset') and we have not to print it.
1015 if (lower == -1 && cloog_int_is_divisible_by(infos->stride[i-1], line[level])) {
1016 in_stride = 1;
1017 continue;
1020 nb_elts++;
1022 for (i = nb_iter+1; i <= len-1; ++i) {
1023 cloog_int_fdiv_r(line[i], line[i], line[level]);
1024 if (cloog_int_is_zero(line[i]))
1025 continue;
1026 if (i <= len-2)
1027 nb_elts++;
1030 if (nb_elts || (!cloog_int_is_zero(line[len-1]) && (!in_stride))) {
1031 struct clast_reduction *r;
1032 struct clast_expr *e;
1033 struct clast_guard *g;
1034 char * name;
1036 r = new_clast_reduction(clast_red_sum, nb_elts+1);
1037 nb_elts = 0;
1039 /* First, the modulo guard : the iterators... */
1040 for (i=1;i<=nb_iter;i++) {
1041 if (i == level || cloog_int_is_zero(line[i]))
1042 continue;
1043 if (cloog_int_is_divisible_by(infos->stride[i-1], line[level]))
1044 continue;
1046 if (i <= infos->names->nb_scattering)
1047 name = infos->names->scattering[i-1];
1048 else
1049 name = infos->names->iterators[i-infos->names->nb_scattering-1];
1051 r->elts[nb_elts++] = &new_clast_term(line[i], name)->expr;
1054 /* ...the parameters... */
1055 for (i=nb_iter+1;i<=len-2;i++) {
1056 if (cloog_int_is_zero(line[i]))
1057 continue;
1059 name = infos->names->parameters[i-nb_iter-1] ;
1060 r->elts[nb_elts++] = &new_clast_term(line[i], name)->expr;
1063 /* ...the constant. */
1064 if (!cloog_int_is_zero(line[len-1]))
1065 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1067 /* our initial computation may have been an overestimate */
1068 r->n = nb_elts;
1070 e = &new_clast_binary(clast_bin_mod, &r->expr, line[level])->expr;
1071 g = new_clast_guard(1);
1072 if (lower == -1) {
1073 g->eq[0].LHS = e;
1074 cloog_int_set_si(val, 0);
1075 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1076 g->eq[0].sign = 0;
1077 } else {
1078 g->eq[0].LHS = e;
1079 cloog_constraint_constant_get(constraints, upper, &val);
1080 cloog_constraint_constant_get(constraints, lower, &val2);
1081 cloog_int_add(val, val, val2);
1082 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1083 g->eq[0].sign = -1;
1086 **next = &g->stmt;
1087 *next = &g->then;
1090 cloog_vec_free(line_vector);
1091 cloog_vec_free(line_vector2);
1093 cloog_int_clear(val);
1094 cloog_int_clear(val2);
1095 cloog_int_clear(x);
1096 cloog_int_clear(y);
1097 cloog_int_clear(g);
1102 * insert_equation function:
1103 * This function inserts an equality
1104 * constraint according to an element in the clast.
1105 * An equality can be preceded by a 'modulo guard'.
1106 * For instance, consider the constraint i -2*j = 0 and the
1107 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1108 * - matrix is the polyhedron containing all the constraints,
1109 * - num is the line number of the constraint in matrix we want to print,
1110 * - level is the column number of the element in matrix we want to use,
1111 * - the infos structure gives the user some options about code printing,
1112 * the number of parameters in matrix (nb_par), and the arrays of iterator
1113 * names and parameters (iters and params).
1115 * - November 13th 2001: first version.
1116 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1117 * modulo is 0, compare vivien or vivien2 with a previous
1118 * version for an idea).
1119 * - June 29th 2003: non-unit strides support.
1120 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1121 * it was previously included in a stride calculation.
1123 static void insert_equation(CloogConstraintSet *constraints, int upper, int lower,
1124 int level, struct clast_stmt ***next, CloogInfos *infos)
1126 struct clast_expr *e;
1127 struct clast_assignment *ass;
1129 insert_modulo_guard(constraints, upper, lower, level, next, infos);
1131 if (lower != -1 || !clast_equal_add(infos->equal, constraints, level, upper, infos))
1132 { /* Finally, the equality. */
1134 /* If we have to make a block by dimension, we start the block. Function
1135 * pprint knows if there is an equality, if this is the case, it checks
1136 * for the same following condition to close the brace.
1138 if (infos->options->block) {
1139 struct clast_block *b = new_clast_block();
1140 **next = &b->stmt;
1141 *next = &b->body;
1144 e = clast_bound_from_constraint(constraints, upper, level, infos->names);
1145 if (level <= infos->names->nb_scattering)
1146 ass = new_clast_assignment(infos->names->scattering[level-1], e);
1147 else
1148 ass = new_clast_assignment(
1149 infos->names->iterators[level-infos->names->nb_scattering-1], e);
1151 **next = &ass->stmt;
1152 *next = &(**next)->next;
1155 return;
1160 * insert_for function:
1161 * This function inserts a for loop in the clast.
1162 * A loop header according to an element is the conjonction of a minimum and a
1163 * maximum on the element (they give the loop bounds).
1164 * For instance, considering these constraints and the element j:
1165 * i + j -9*M >= 0
1166 * -j +5*M >= 0
1167 * j -4*M >= 0
1168 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1169 * - matrix is the polyhedron containing all the constraints,
1170 * - level is the column number of the element in matrix we want to use,
1171 * - the infos structure gives the user some options about code printing,
1172 * the number of parameters in matrix (nb_par), and the arrays of iterator
1173 * names and parameters (iters and params).
1175 * - July 2nd 2002: first version (pick from pprint function).
1176 * - March 6th 2003: infinite domain support.
1177 * - June 29th 2003: non-unit strides support.
1179 static void insert_for(CloogConstraintSet *constraints, int level,
1180 struct clast_stmt ***next, CloogInfos *infos)
1182 char * iterator ;
1183 struct clast_expr *e1;
1184 struct clast_expr *e2;
1185 struct clast_assignment *ass;
1187 if (level <= infos->names->nb_scattering)
1188 iterator = infos->names->scattering[level-1] ;
1189 else
1190 iterator = infos->names->iterators[level-infos->names->nb_scattering-1] ;
1192 e1 = clast_minmax(constraints, level, 1, 0, infos);
1193 e2 = clast_minmax(constraints, level, 0, 0, infos);
1195 /* If min and max are not equal there is a 'for' else, there is a '='.
1196 * In the special case e1 = e2 = NULL, this is an infinite loop
1197 * so this is not a '='.
1199 if (!clast_expr_equal(e1, e2) || !infos->options->otl || (!e1 && !e2)) {
1200 struct clast_for *f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1201 **next = &f->stmt;
1202 *next = &f->body;
1204 else if (!clast_equal_add(infos->equal, constraints, level, ONE_TIME_LOOP, infos)) {
1205 if (infos->options->block) {
1206 struct clast_block *b = new_clast_block();
1207 **next = &b->stmt;
1208 *next = &b->body;
1210 ass = new_clast_assignment(iterator, e1);
1211 free_clast_expr(e2);
1212 **next = &ass->stmt;
1213 *next = &(**next)->next;
1214 } else {
1215 free_clast_expr(e1);
1216 free_clast_expr(e2);
1219 return;
1224 * insert_scalar function:
1225 * This function inserts assignments to the scalar values
1226 * that follows the level (level). It finds by scanning (loop) by inner level,
1227 * the first CloogBlock data structure (at this step, all blocks has the same
1228 * scalar vector information after (level)), and prints all the adjacent
1229 * scalar values following (level), if it is required by options in (info).
1230 * - loop is the loop structure to begin the search for a block,
1231 * - level is the current loop level,
1232 * - scalar points to the number of scalar values already visited,
1233 * - the infos structure gives the user options about code printing and more.
1235 * - September 12th 2005: first version.
1237 static void insert_scalar(CloogLoop *loop, int level, int *scalar,
1238 struct clast_stmt ***next, CloogInfos *infos)
1240 struct clast_block *b;
1241 struct clast_term *t;
1243 if ((!infos->options->csp) &&
1244 (level+(*scalar) <= infos->nb_scattdims) &&
1245 (infos->scaldims[level+(*scalar)-1]))
1246 { while (loop->block == NULL)
1247 loop = loop->inner ;
1249 while ((level+(*scalar) <= infos->nb_scattdims) &&
1250 (infos->scaldims[level+(*scalar)-1])) {
1251 if (infos->options->block) {
1252 b = new_clast_block();
1253 **next = &b->stmt;
1254 *next = &b->body;
1257 t = new_clast_term(loop->block->scaldims[(*scalar)], NULL);
1258 **next = &new_clast_assignment(infos->names->scalars[(*scalar)],
1259 &t->expr)->stmt;
1260 *next = &(**next)->next;
1261 (*scalar) ++ ;
1266 return;
1271 * insert_block function:
1272 * This function inserts a statement block.
1273 * - block is the statement block,
1274 * - level is the number of loops enclosing the statement,
1275 * - the infos structure gives the user some options about code printing,
1276 * the number of parameters in domain (nb_par), and the arrays of iterator
1277 * names and parameters (iters and params).
1279 * - September 21th 2003: first version (pick from pprint function).
1281 static void insert_block(CloogBlock *block, int level,
1282 struct clast_stmt ***next, CloogInfos *infos)
1284 CloogStatement * statement ;
1285 struct clast_stmt *subs;
1287 if (!block)
1288 return;
1290 for (statement = block->statement; statement; statement = statement->next) {
1291 if (infos->options->cpp == 0)
1292 subs = clast_equal(infos);
1293 else
1294 subs = clast_equal_cpp(level,infos);
1296 **next = &new_clast_user_stmt(statement, subs)->stmt;
1297 *next = &(**next)->next;
1303 * insert_loop function:
1304 * This function converts the content of a CloogLoop structure (loop) into a
1305 * clast_stmt (inserted at **next).
1306 * The iterator (level) of
1307 * the current loop is given by 'level': this is the column number of the
1308 * domain corresponding to the current loop iterator. The data of a loop are
1309 * written in this order:
1310 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1311 * depend on the iterator (when the entry in the column 'level' is 0).
1312 * 2. The iteration domain of the iterator, given by the constraints in the
1313 * domain depending on the iterator, i.e.:
1314 * * an equality if the iterator has only one value (possibly preceded by
1315 * a guard verifying if this value is integral), *OR*
1316 * * a loop from the minimum possible value of the iterator to the maximum
1317 * possible value.
1318 * 3. The included statement block.
1319 * 4. The inner loops (recursive call).
1320 * 5. The following loops (recursive call).
1321 * - level is the recursion level or the iteration level that we are printing,
1322 * - the infos structure gives the user some options about code printing,
1323 * the number of parameters in domain (nb_par), and the arrays of iterator
1324 * names and parameters (iters and params).
1326 * - November 2nd 2001: first version.
1327 * - March 6th 2003: infinite domain support.
1328 * - April 19th 2003: (debug) NULL loop support.
1329 * - June 29th 2003: non-unit strides support.
1330 * - April 28th 2005: (debug) level is level+equality when print statement!
1331 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1332 * added to avoid iteration duplication (see DaeGon Kim
1333 * bug in cloog_program_generate). Try vasilache.cloog
1334 * with and without the call to cloog_matrix_normalize,
1335 * using -f 8 -l 9 options for an idea.
1336 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1337 * - October 16th 2005: (debug) scalar value is saved for next loops.
1339 static void insert_loop(CloogLoop * loop, int level, int scalar,
1340 struct clast_stmt ***next, CloogInfos *infos)
1342 int i, j, equality=0, scalar_level;
1343 CloogConstraintSet *constraints, *temp;
1344 struct clast_stmt **top = *next;
1346 /* It can happen that loop be NULL when an input polyhedron is empty. */
1347 if (loop == NULL)
1348 return;
1350 /* The constraints do not always have a shape that allows us to generate code from it,
1351 * thus we normalize it, we also simplify it with the equalities.
1353 temp = cloog_domain_constraints(loop->domain);
1354 cloog_constraint_set_normalize(temp,level);
1355 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1356 infos->names->nb_parameters);
1357 cloog_constraint_set_free(temp);
1358 cloog_int_set(infos->stride[level-1], loop->stride);
1360 /* First of all we have to print the guard. */
1361 insert_guard(constraints,level, next, infos);
1363 /* Then we print scalar dimensions. */
1364 scalar_level = scalar ;
1365 insert_scalar(loop,level,&scalar, next, infos);
1367 if (cloog_constraint_set_contains_level(constraints, level,
1368 infos->names->nb_parameters)) {
1369 /* We scan all the constraints to know in which case we are :
1370 * [[if] equation] or [for].
1372 if ((i = cloog_constraint_set_defining_equality(constraints, level)) != -1) {
1373 insert_equation(constraints, i, -1, level, next, infos);
1374 equality = 1 ;
1375 } else if ((i = cloog_constraint_set_defining_inequalities(constraints,
1376 level, &j, infos->names->nb_parameters)) != -1) {
1377 insert_equation(constraints, i, j, level, next, infos);
1378 } else
1379 insert_for(constraints, level, next, infos);
1382 /* Finally, if there is an included statement block, print it. */
1383 insert_block(loop->block, level+equality, next, infos);
1385 /* Go to the next level. */
1386 if (loop->inner != NULL)
1387 insert_loop(loop->inner, level+1,scalar, next, infos);
1389 cloog_equal_del(infos->equal,level);
1390 cloog_constraint_set_free(constraints);
1392 /* Go to the next loop on the same level. */
1393 while (*top)
1394 top = &(*top)->next;
1395 if (loop->next != NULL)
1396 insert_loop(loop->next, level,scalar_level, &top,infos);
1400 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1401 CloogOptions *options)
1403 CloogInfos *infos = ALLOC(CloogInfos);
1404 int i, nb_levels;
1405 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1406 struct clast_stmt **next = &root->next;
1408 infos->names = program->names;
1409 infos->options = options;
1410 infos->scaldims = program->scaldims;
1411 infos->nb_scattdims = program->nb_scattdims;
1413 /* Allocation for the array of strides, there is a +1 since the statement can
1414 * be included inside an external loop without iteration domain.
1416 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1417 infos->stride = ALLOCN(cloog_int_t, nb_levels);
1418 for (i = 0; i < nb_levels; ++i)
1419 cloog_int_init(infos->stride[i]);
1421 infos->equal = cloog_equal_alloc(nb_levels,
1422 nb_levels, program->names->nb_parameters);
1424 insert_loop(program->loop, 1, 0, &next, infos);
1426 cloog_equal_free(infos->equal);
1428 for (i = 0; i < nb_levels; ++i)
1429 cloog_int_clear(infos->stride[i]);
1430 free(infos->stride);
1431 free(infos);
1433 return root;