allow building without isl
[cloog/uuh.git] / source / clast.c
blob22741a4af07e85db4444a99fec7ad8c14f3a2237
1 #include <stdlib.h>
2 #include <string.h>
3 #include <assert.h>
4 #include "../include/cloog/cloog.h"
6 #define ALLOC(type) (type*)malloc(sizeof(type))
7 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
9 /**
10 * CloogInfos structure:
11 * this structure contains all the informations necessary for pretty printing,
12 * they come from the original CloogProgram structure (language, names), from
13 * genereral options (options) or are built only for pretty printing (stride).
14 * This structure is mainly there to reduce the number of function parameters,
15 * since most pprint.c functions need most of its field.
17 struct clooginfos {
18 CloogState *state; /**< State. */
19 cloog_int_t *stride; /**< The stride for each iterator. */
20 cloog_int_t *offset; /**< The offset for each iterator. */
21 int nb_scattdims ; /**< Scattering dimension number. */
22 int * scaldims ; /**< Boolean array saying whether a given
23 * scattering dimension is scalar or not.
25 CloogNames * names ; /**< Names of iterators and parameters. */
26 CloogOptions * options ; /**< Options on CLooG's behaviour. */
27 CloogEqualities *equal; /**< Matrix of equalities. */
28 } ;
30 typedef struct clooginfos CloogInfos ;
32 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2);
33 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2);
34 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2);
35 static int clast_reduction_cmp(struct clast_reduction *r1,
36 struct clast_reduction *r2);
38 static int clast_equal_add(CloogEqualities *equal,
39 CloogConstraintSet *constraints,
40 int level, CloogConstraint *constraint,
41 CloogInfos *infos);
43 static struct clast_stmt *clast_equal(int level, CloogInfos *infos);
44 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
45 int level, int max, int guard,
46 CloogInfos *infos);
47 static void insert_guard(CloogConstraintSet *constraints, int level,
48 struct clast_stmt ***next, CloogInfos *infos);
49 static int insert_modulo_guard(CloogConstraint *upper,
50 CloogConstraint *lower, int level,
51 struct clast_stmt ***next, CloogInfos *infos);
52 static int insert_equation(CloogConstraint *upper, CloogConstraint *lower,
53 int level, struct clast_stmt ***next, CloogInfos *infos);
54 static int insert_for(CloogConstraintSet *constraints, int level,
55 struct clast_stmt ***next, CloogInfos *infos);
56 static void insert_block(CloogBlock *block, int level,
57 struct clast_stmt ***next, CloogInfos *infos);
58 static void insert_loop(CloogLoop * loop, int level,
59 struct clast_stmt ***next, CloogInfos *infos);
62 struct clast_name *new_clast_name(const char *name)
64 struct clast_name *n = malloc(sizeof(struct clast_name));
65 n->expr.type = clast_expr_name;
66 n->name = name;
67 return n;
70 struct clast_term *new_clast_term(cloog_int_t c, struct clast_expr *v)
72 struct clast_term *t = malloc(sizeof(struct clast_term));
73 t->expr.type = clast_expr_term;
74 cloog_int_init(t->val);
75 cloog_int_set(t->val, c);
76 t->var = v;
77 return t;
80 struct clast_binary *new_clast_binary(enum clast_bin_type t,
81 struct clast_expr *lhs, cloog_int_t rhs)
83 struct clast_binary *b = malloc(sizeof(struct clast_binary));
84 b->expr.type = clast_expr_bin;
85 b->type = t;
86 b->LHS = lhs;
87 cloog_int_init(b->RHS);
88 cloog_int_set(b->RHS, rhs);
89 return b;
92 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
94 int i;
95 struct clast_reduction *r;
96 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
97 r->expr.type = clast_expr_red;
98 r->type = t;
99 r->n = n;
100 for (i = 0; i < n; ++i)
101 r->elts[i] = NULL;
102 return r;
105 static void free_clast_root(struct clast_stmt *s);
107 const struct clast_stmt_op stmt_root = { free_clast_root };
109 static void free_clast_root(struct clast_stmt *s)
111 struct clast_root *r = (struct clast_root *)s;
112 assert(CLAST_STMT_IS_A(s, stmt_root));
113 cloog_names_free(r->names);
114 free(r);
117 struct clast_root *new_clast_root(CloogNames *names)
119 struct clast_root *r = malloc(sizeof(struct clast_root));
120 r->stmt.op = &stmt_root;
121 r->stmt.next = NULL;
122 r->names = cloog_names_copy(names);
123 return r;
126 static void free_clast_assignment(struct clast_stmt *s);
128 const struct clast_stmt_op stmt_ass = { free_clast_assignment };
130 static void free_clast_assignment(struct clast_stmt *s)
132 struct clast_assignment *a = (struct clast_assignment *)s;
133 assert(CLAST_STMT_IS_A(s, stmt_ass));
134 free_clast_expr(a->RHS);
135 free(a);
138 struct clast_assignment *new_clast_assignment(const char *lhs,
139 struct clast_expr *rhs)
141 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
142 a->stmt.op = &stmt_ass;
143 a->stmt.next = NULL;
144 a->LHS = lhs;
145 a->RHS = rhs;
146 return a;
149 static void free_clast_user_stmt(struct clast_stmt *s);
151 const struct clast_stmt_op stmt_user = { free_clast_user_stmt };
153 static void free_clast_user_stmt(struct clast_stmt *s)
155 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
156 assert(CLAST_STMT_IS_A(s, stmt_user));
157 cloog_statement_free(u->statement);
158 cloog_clast_free(u->substitutions);
159 free(u);
162 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
163 struct clast_stmt *subs)
165 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
166 u->stmt.op = &stmt_user;
167 u->stmt.next = NULL;
168 u->statement = cloog_statement_copy(stmt);
169 u->substitutions = subs;
170 return u;
173 static void free_clast_block(struct clast_stmt *b);
175 const struct clast_stmt_op stmt_block = { free_clast_block };
177 static void free_clast_block(struct clast_stmt *s)
179 struct clast_block *b = (struct clast_block *)s;
180 assert(CLAST_STMT_IS_A(s, stmt_block));
181 cloog_clast_free(b->body);
182 free(b);
185 struct clast_block *new_clast_block()
187 struct clast_block *b = malloc(sizeof(struct clast_block));
188 b->stmt.op = &stmt_block;
189 b->stmt.next = NULL;
190 b->body = NULL;
191 return b;
194 static void free_clast_for(struct clast_stmt *s);
196 const struct clast_stmt_op stmt_for = { free_clast_for };
198 static void free_clast_for(struct clast_stmt *s)
200 struct clast_for *f = (struct clast_for *)s;
201 assert(CLAST_STMT_IS_A(s, stmt_for));
202 free_clast_expr(f->LB);
203 free_clast_expr(f->UB);
204 cloog_int_clear(f->stride);
205 cloog_clast_free(f->body);
206 free(f);
209 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
210 struct clast_expr *UB, cloog_int_t stride)
212 struct clast_for *f = malloc(sizeof(struct clast_for));
213 f->stmt.op = &stmt_for;
214 f->stmt.next = NULL;
215 f->iterator = it;
216 f->LB = LB;
217 f->UB = UB;
218 f->body = NULL;
219 cloog_int_init(f->stride);
220 cloog_int_set(f->stride, stride);
221 return f;
224 static void free_clast_guard(struct clast_stmt *s);
226 const struct clast_stmt_op stmt_guard = { free_clast_guard };
228 static void free_clast_guard(struct clast_stmt *s)
230 int i;
231 struct clast_guard *g = (struct clast_guard *)s;
232 assert(CLAST_STMT_IS_A(s, stmt_guard));
233 cloog_clast_free(g->then);
234 for (i = 0; i < g->n; ++i) {
235 free_clast_expr(g->eq[i].LHS);
236 free_clast_expr(g->eq[i].RHS);
238 free(g);
241 struct clast_guard *new_clast_guard(int n)
243 int i;
244 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
245 (n-1) * sizeof(struct clast_equation));
246 g->stmt.op = &stmt_guard;
247 g->stmt.next = NULL;
248 g->then = NULL;
249 g->n = n;
250 for (i = 0; i < n; ++i) {
251 g->eq[i].LHS = NULL;
252 g->eq[i].RHS = NULL;
254 return g;
257 void free_clast_name(struct clast_name *n)
259 free(n);
262 void free_clast_term(struct clast_term *t)
264 cloog_int_clear(t->val);
265 free_clast_expr(t->var);
266 free(t);
269 void free_clast_binary(struct clast_binary *b)
271 cloog_int_clear(b->RHS);
272 free_clast_expr(b->LHS);
273 free(b);
276 void free_clast_reduction(struct clast_reduction *r)
278 int i;
279 for (i = 0; i < r->n; ++i)
280 free_clast_expr(r->elts[i]);
281 free(r);
284 void free_clast_expr(struct clast_expr *e)
286 if (!e)
287 return;
288 switch (e->type) {
289 case clast_expr_name:
290 free_clast_name((struct clast_name*) e);
291 break;
292 case clast_expr_term:
293 free_clast_term((struct clast_term*) e);
294 break;
295 case clast_expr_red:
296 free_clast_reduction((struct clast_reduction*) e);
297 break;
298 case clast_expr_bin:
299 free_clast_binary((struct clast_binary*) e);
300 break;
301 default:
302 assert(0);
306 void free_clast_stmt(struct clast_stmt *s)
308 assert(s->op);
309 assert(s->op->free);
310 s->op->free(s);
313 void cloog_clast_free(struct clast_stmt *s)
315 struct clast_stmt *next;
316 while (s) {
317 next = s->next;
318 free_clast_stmt(s);
319 s = next;
323 static int clast_name_cmp(struct clast_name *n1, struct clast_name *n2)
325 return n1->name == n2->name ? 0 : strcmp(n1->name, n2->name);
328 static int clast_term_cmp(struct clast_term *t1, struct clast_term *t2)
330 int c;
331 if (!t1->var && t2->var)
332 return -1;
333 if (t1->var && !t2->var)
334 return 1;
335 c = clast_expr_cmp(t1->var, t2->var);
336 if (c)
337 return c;
338 return cloog_int_cmp(t1->val, t2->val);
341 static int clast_binary_cmp(struct clast_binary *b1, struct clast_binary *b2)
343 int c;
345 if (b1->type != b2->type)
346 return b1->type - b2->type;
347 if ((c = cloog_int_cmp(b1->RHS, b2->RHS)))
348 return c;
349 return clast_expr_cmp(b1->LHS, b2->LHS);
352 static int clast_reduction_cmp(struct clast_reduction *r1, struct clast_reduction *r2)
354 int i;
355 int c;
357 if (r1->n == 1 && r2->n == 1)
358 return clast_expr_cmp(r1->elts[0], r2->elts[0]);
359 if (r1->type != r2->type)
360 return r1->type - r2->type;
361 if (r1->n != r2->n)
362 return r1->n - r2->n;
363 for (i = 0; i < r1->n; ++i)
364 if ((c = clast_expr_cmp(r1->elts[i], r2->elts[i])))
365 return c;
366 return 0;
369 static int clast_expr_cmp(struct clast_expr *e1, struct clast_expr *e2)
371 if (!e1 && !e2)
372 return 0;
373 if (!e1)
374 return -1;
375 if (!e2)
376 return 1;
377 if (e1->type != e2->type)
378 return e1->type - e2->type;
379 switch (e1->type) {
380 case clast_expr_name:
381 return clast_name_cmp((struct clast_name*) e1,
382 (struct clast_name*) e2);
383 case clast_expr_term:
384 return clast_term_cmp((struct clast_term*) e1,
385 (struct clast_term*) e2);
386 case clast_expr_bin:
387 return clast_binary_cmp((struct clast_binary*) e1,
388 (struct clast_binary*) e2);
389 case clast_expr_red:
390 return clast_reduction_cmp((struct clast_reduction*) e1,
391 (struct clast_reduction*) e2);
392 default:
393 assert(0);
397 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
399 return clast_expr_cmp(e1, e2) == 0;
403 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
405 int clast_expr_is_bigger_constant(struct clast_expr *e1, struct clast_expr *e2)
407 struct clast_term *t1, *t2;
408 struct clast_reduction *r;
410 if (!e1 || !e2)
411 return 0;
412 if (e1->type == clast_expr_red) {
413 r = (struct clast_reduction *)e1;
414 return r->n == 1 && clast_expr_is_bigger_constant(r->elts[0], e2);
416 if (e2->type == clast_expr_red) {
417 r = (struct clast_reduction *)e2;
418 return r->n == 1 && clast_expr_is_bigger_constant(e1, r->elts[0]);
420 if (e1->type != clast_expr_term || e2->type != clast_expr_term)
421 return 0;
422 t1 = (struct clast_term *)e1;
423 t2 = (struct clast_term *)e2;
424 if (t1->var || t2->var)
425 return 0;
426 return cloog_int_gt(t1->val, t2->val);
429 static int qsort_expr_cmp(const void *p1, const void *p2)
431 return clast_expr_cmp(*(struct clast_expr **)p1, *(struct clast_expr **)p2);
434 static void clast_reduction_sort(struct clast_reduction *r)
436 qsort(&r->elts[0], r->n, sizeof(struct clast_expr *), qsort_expr_cmp);
439 static int qsort_eq_cmp(const void *p1, const void *p2)
441 struct clast_equation *eq1 = (struct clast_equation *)p1;
442 struct clast_equation *eq2 = (struct clast_equation *)p2;
443 int cmp;
445 cmp = clast_expr_cmp(eq1->LHS, eq2->LHS);
446 if (cmp)
447 return cmp;
449 cmp = clast_expr_cmp(eq1->RHS, eq2->RHS);
450 if (cmp)
451 return cmp;
453 return eq1->sign - eq2->sign;
457 * Sort equations in a clast_guard.
459 static void clast_guard_sort(struct clast_guard *g)
461 qsort(&g->eq[0], g->n, sizeof(struct clast_equation), qsort_eq_cmp);
465 /******************************************************************************
466 * Equalities spreading functions *
467 ******************************************************************************/
471 * clast_equal_allow function:
472 * This function checks whether the options allow us to spread the equality or
473 * not. It returns 1 if so, 0 otherwise.
474 * - equal is the matrix of equalities,
475 * - level is the column number in equal of the element which is 'equal to',
476 * - line is the line number in equal of the constraint we want to study,
477 * - the infos structure gives the user all options on code printing and more.
479 * - October 27th 2005: first version (extracted from old pprint_equal_add).
481 static int clast_equal_allow(CloogEqualities *equal, int level, int line,
482 CloogInfos *infos)
484 if (level < infos->options->fsp)
485 return 0 ;
487 if ((cloog_equal_type(equal, level) == EQTYPE_EXAFFINE) &&
488 !infos->options->esp)
489 return 0 ;
491 return 1 ;
496 * clast_equal_add function:
497 * This function updates the row (level-1) of the equality matrix (equal) with
498 * the row that corresponds to the row (line) of the matrix (matrix). It returns
499 * 1 if the row can be updated, 0 otherwise.
500 * - equal is the matrix of equalities,
501 * - matrix is the matrix of constraints,
502 * - level is the column number in matrix of the element which is 'equal to',
503 * - line is the line number in matrix of the constraint we want to study,
504 * - the infos structure gives the user all options on code printing and more.
506 static int clast_equal_add(CloogEqualities *equal,
507 CloogConstraintSet *constraints,
508 int level, CloogConstraint *constraint,
509 CloogInfos *infos)
511 cloog_equal_add(equal, constraints, level, constraint,
512 infos->names->nb_parameters);
514 return clast_equal_allow(equal, level, level-1, infos);
520 * clast_equal function:
521 * This function prints the substitution data of a statement into a clast_stmt.
522 * Using this function instead of pprint_equal is useful for generating
523 * a compilable pseudo-code by using preprocessor macro for each statement.
524 * By opposition to pprint_equal, the result is less human-readable. For
525 * instance this function will print (i,i+3,k,3) where pprint_equal would
526 * return (j=i+3,l=3).
527 * - level is the number of loops enclosing the statement,
528 * - the infos structure gives the user all options on code printing and more.
530 * - March 12th 2004: first version.
531 * - November 21th 2005: (debug) now works well with GMP version.
533 static struct clast_stmt *clast_equal(int level, CloogInfos *infos)
535 int i ;
536 struct clast_expr *e;
537 struct clast_stmt *a = NULL;
538 struct clast_stmt **next = &a;
539 CloogEqualities *equal = infos->equal;
540 CloogConstraint *equal_constraint;
542 for (i=infos->names->nb_scattering;i<level-1;i++)
543 { if (cloog_equal_type(equal, i+1)) {
544 equal_constraint = cloog_equal_constraint(equal, i);
545 e = clast_bound_from_constraint(equal_constraint, i+1, infos->names);
546 cloog_constraint_release(equal_constraint);
547 } else {
548 e = &new_clast_term(infos->state->one, &new_clast_name(
549 cloog_names_name_at_level(infos->names, i+1))->expr)->expr;
551 *next = &new_clast_assignment(NULL, e)->stmt;
552 next = &(*next)->next;
555 return a;
560 * clast_bound_from_constraint function:
561 * This function returns a clast_expr containing the printing of the
562 * 'right part' of a constraint according to an element.
563 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
564 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
565 * function should return 'ceild(3*i+M,2)'.
566 * - matrix is the polyhedron containing all the constraints,
567 * - line_num is the line number in domain of the constraint we want to print,
568 * - level is the column number in domain of the element we want to use,
569 * - names structure gives the user some options about code printing,
570 * the number of parameters in domain (nb_par), and the arrays of iterator
571 * names and parameters (iters and params).
573 * - November 2nd 2001: first version.
574 * - June 27th 2003: 64 bits version ready.
576 struct clast_expr *clast_bound_from_constraint(CloogConstraint *constraint,
577 int level, CloogNames *names)
579 int i, sign, nb_elts=0, len;
580 cloog_int_t *line, numerator, denominator, temp, division;
581 struct clast_expr *e = NULL;
582 struct cloog_vec *line_vector;
584 len = cloog_constraint_total_dimension(constraint) + 2;
585 line_vector = cloog_vec_alloc(len);
586 line = line_vector->p;
587 cloog_constraint_copy_coefficients(constraint, line+1);
588 cloog_int_init(temp);
589 cloog_int_init(numerator);
590 cloog_int_init(denominator);
592 if (!cloog_int_is_zero(line[level])) {
593 struct clast_reduction *r;
594 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
595 sign = -cloog_int_sgn(line[level]);
597 for (i = 1, nb_elts = 0; i <= len - 1; ++i)
598 if (i != level && !cloog_int_is_zero(line[i]))
599 nb_elts++;
600 r = new_clast_reduction(clast_red_sum, nb_elts);
601 nb_elts = 0;
603 /* First, we have to print the iterators and the parameters. */
604 for (i = 1; i <= len - 2; i++) {
605 struct clast_expr *v;
607 if (i == level || cloog_int_is_zero(line[i]))
608 continue;
610 v = cloog_constraint_variable_expr(constraint, i, names);
612 if (sign == -1)
613 cloog_int_neg(temp,line[i]);
614 else
615 cloog_int_set(temp,line[i]);
617 r->elts[nb_elts++] = &new_clast_term(temp, v)->expr;
620 if (sign == -1) {
621 cloog_int_neg(numerator, line[len - 1]);
622 cloog_int_set(denominator, line[level]);
624 else {
625 cloog_int_set(numerator, line[len - 1]);
626 cloog_int_neg(denominator, line[level]);
629 /* Finally, the constant, and the final printing. */
630 if (nb_elts) {
631 if (!cloog_int_is_zero(numerator))
632 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
634 if (!cloog_int_is_one(line[level]) && !cloog_int_is_neg_one(line[level]))
635 { if (!cloog_constraint_is_equality(constraint))
636 { if (cloog_int_is_pos(line[level]))
637 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
638 else
639 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
640 } else
641 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
643 else
644 e = &r->expr;
645 } else {
646 free_clast_reduction(r);
647 if (cloog_int_is_zero(numerator))
648 e = &new_clast_term(numerator, NULL)->expr;
649 else
650 { if (!cloog_int_is_one(denominator))
651 { if (!cloog_constraint_is_equality(constraint)) { /* useful? */
652 if (cloog_int_is_divisible_by(numerator, denominator)) {
653 cloog_int_divexact(temp, numerator, denominator);
654 e = &new_clast_term(temp, NULL)->expr;
656 else {
657 cloog_int_init(division);
658 cloog_int_tdiv_q(division, numerator, denominator);
659 if (cloog_int_is_neg(numerator)) {
660 if (cloog_int_is_pos(line[level])) {
661 /* nb<0 need max */
662 e = &new_clast_term(division, NULL)->expr;
663 } else {
664 /* nb<0 need min */
665 cloog_int_sub_ui(temp, division, 1);
666 e = &new_clast_term(temp, NULL)->expr;
669 else
670 { if (cloog_int_is_pos(line[level]))
671 { /* nb>0 need max */
672 cloog_int_add_ui(temp, division, 1);
673 e = &new_clast_term(temp, NULL)->expr;
675 else
676 /* nb>0 need min */
677 e = &new_clast_term(division, NULL)->expr;
679 cloog_int_clear(division);
682 else
683 e = &new_clast_binary(clast_bin_div,
684 &new_clast_term(numerator, NULL)->expr,
685 denominator)->expr;
687 else
688 e = &new_clast_term(numerator, NULL)->expr;
693 cloog_vec_free(line_vector);
695 cloog_int_clear(temp);
696 cloog_int_clear(numerator);
697 cloog_int_clear(denominator);
699 return e;
704 * clast_minmax function:
705 * This function returns a clast_expr containing the printing of a minimum or a
706 * maximum of the 'right parts' of all constraints according to an element.
707 * For instance consider the constraints:
708 * -3*i +2*j -M >= 0
709 * 2*i +j >= 0
710 * -i -j +2*M >= 0
711 * if we are looking for the minimum for the element j, the function should
712 * return 'max(ceild(3*i+M,2),-2*i)'.
713 * - constraints is the constraints,
714 * - level is the column number in domain of the element we want to use,
715 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
716 * - guard is set to 0 if there is no guard, and set to the level of the element
717 * with a guard otherwise (then the function gives the max or the min only
718 * for the constraint where the guarded coefficient is 0),
719 * - the infos structure gives the user some options about code printing,
720 * the number of parameters in domain (nb_par), and the arrays of iterator
721 * names and parameters (iters and params).
723 * - November 2nd 2001: first version.
725 static struct clast_expr *clast_minmax(CloogConstraintSet *constraints,
726 int level, int max, int guard,
727 CloogInfos *infos)
728 { int n;
729 struct clast_reduction *r;
730 CloogConstraint *constraint;
732 n = 0;
733 for (constraint = cloog_constraint_first(constraints);
734 cloog_constraint_is_valid(constraint);
735 constraint = cloog_constraint_next(constraint))
736 if (((max && cloog_constraint_is_lower_bound(constraint, level-1)) ||
737 (!max && cloog_constraint_is_upper_bound(constraint, level-1))) &&
738 (!guard || !cloog_constraint_involves(constraint, guard-1)) &&
739 (!cloog_constraint_is_equality(constraint)))
740 n++;
741 if (!n)
742 return NULL;
743 r = new_clast_reduction(max ? clast_red_max : clast_red_min, n);
745 n = 0;
746 for (constraint = cloog_constraint_first(constraints);
747 cloog_constraint_is_valid(constraint);
748 constraint = cloog_constraint_next(constraint))
749 if (((max && cloog_constraint_is_lower_bound(constraint, level-1)) ||
750 (!max && cloog_constraint_is_upper_bound(constraint, level-1))) &&
751 (!guard || !cloog_constraint_involves(constraint, guard-1)) &&
752 (!cloog_constraint_is_equality(constraint))) {
753 r->elts[n] = clast_bound_from_constraint(constraint, level,
754 infos->names);
755 if (max && !cloog_int_is_one(infos->stride[level - 1]) &&
756 !cloog_int_is_zero(infos->stride[level - 1])) {
757 struct clast_term *t;
758 assert(r->elts[n]->type == clast_expr_term);
759 t = (struct clast_term *)r->elts[n];
760 assert(!t->var);
761 cloog_int_sub(t->val, t->val, infos->offset[level - 1]);
762 cloog_int_cdiv_q(t->val, t->val, infos->stride[level - 1]);
763 cloog_int_mul(t->val, t->val, infos->stride[level - 1]);
764 cloog_int_add(t->val, t->val, infos->offset[level - 1]);
766 n++;
769 clast_reduction_sort(r);
770 return &r->expr;
775 * Insert modulo guards defined by existentially quantified dimensions,
776 * not involving the given level.
778 * This function is called from within insert_guard or insert_for.
779 * Any constraint used in constructing * a modulo guard is removed
780 * from the constraint set to avoid insert_guard or insert_for
781 * adding a duplicate (pair of) constraint(s).
783 static void insert_extra_modulo_guards(CloogConstraintSet *constraints,
784 int level, struct clast_stmt ***next, CloogInfos *infos)
786 int i;
787 int nb_iter;
788 int total_dim;
789 CloogConstraint *upper, *lower;
791 total_dim = cloog_constraint_set_total_dimension(constraints);
792 nb_iter = cloog_constraint_set_n_iterators(constraints,
793 infos->names->nb_parameters);
795 for (i = total_dim - infos->names->nb_parameters; i >= nb_iter + 1; i--) {
796 if (cloog_constraint_is_valid(upper =
797 cloog_constraint_set_defining_equality(constraints, i))) {
798 if (!level || (nb_iter < level) ||
799 !cloog_constraint_involves(upper, level-1)) {
800 insert_modulo_guard(upper,
801 cloog_constraint_invalid(), i, next, infos);
802 cloog_constraint_clear(upper);
804 cloog_constraint_release(upper);
805 } else if (cloog_constraint_is_valid(upper =
806 cloog_constraint_set_defining_inequalities(constraints,
807 i, &lower, infos->names->nb_parameters))) {
808 if (!level || (nb_iter < level) ||
809 !cloog_constraint_involves(upper, level-1)) {
810 insert_modulo_guard(upper, lower, i, next, infos);
811 cloog_constraint_clear(upper);
812 cloog_constraint_clear(lower);
814 cloog_constraint_release(upper);
815 cloog_constraint_release(lower);
822 * insert_guard function:
823 * This function inserts a guard in the clast.
824 * A guard on an element (level) is :
825 * -> the conjunction of all the existing constraints where the coefficient of
826 * this element is 0 if the element is an iterator,
827 * -> the conjunction of all the existing constraints if the element isn't an
828 * iterator.
829 * For instance, considering these constraints and the element j:
830 * -3*i +2*j -M >= 0
831 * 2*i +M >= 0
832 * this function should return 'if (2*i+M>=0) {'.
833 * - matrix is the polyhedron containing all the constraints,
834 * - level is the column number of the element in matrix we want to use,
835 * - the infos structure gives the user some options about code printing,
836 * the number of parameters in matrix (nb_par), and the arrays of iterator
837 * names and parameters (iters and params).
839 * - November 3rd 2001: first version.
840 * - November 14th 2001: a lot of 'purifications'.
841 * - July 31th 2002: (debug) some guard parts are no more redundants.
842 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
843 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
844 * (the need came from loop_simplify that may result in
845 * domain unions, now it should be fixed directly in
846 * cloog_loop_simplify).
848 static void insert_guard(CloogConstraintSet *constraints, int level,
849 struct clast_stmt ***next, CloogInfos *infos)
851 int i, guarded, minmax=-1, nb_and = 0, nb_iter ;
852 int total_dim;
853 CloogConstraintSet *copy;
854 CloogConstraint *j, *l;
855 struct clast_guard *g;
857 if (constraints == NULL)
858 return;
860 copy = cloog_constraint_set_copy(constraints);
862 insert_extra_modulo_guards(copy, level, next, infos);
864 total_dim = cloog_constraint_set_total_dimension(constraints);
865 g = new_clast_guard(2 * total_dim);
867 /* Well, it looks complicated because I wanted to have a particular, more
868 * readable, ordering, obviously this function may be far much simpler !
870 nb_iter = cloog_constraint_set_n_iterators(constraints,
871 infos->names->nb_parameters);
873 nb_and = 0 ;
874 /* We search for guard parts. */
875 for (i = 1; i <= total_dim; i++)
876 for (j = cloog_constraint_first(copy); cloog_constraint_is_valid(j);
877 j = cloog_constraint_next(j))
878 if (cloog_constraint_involves(j, i-1) &&
879 (!level || (nb_iter < level) ||
880 !cloog_constraint_involves(j, level-1))) {
881 struct clast_expr *v;
882 struct clast_term *t;
884 v = cloog_constraint_variable_expr(j, i, infos->names);
885 g->eq[nb_and].LHS = &(t = new_clast_term(infos->state->one, v))->expr;
886 if (!level || cloog_constraint_is_equality(j)) {
887 /* put the "denominator" in the LHS */
888 cloog_constraint_coefficient_get(j, i-1, &t->val);
889 cloog_constraint_coefficient_set(j, i-1, infos->state->one);
890 if (cloog_int_is_neg(t->val)) {
891 cloog_int_neg(t->val, t->val);
892 cloog_constraint_coefficient_set(j, i-1, infos->state->negone);
894 if (level || cloog_constraint_is_equality(j))
895 g->eq[nb_and].sign = 0;
896 else if (cloog_constraint_is_lower_bound(j, i-1))
897 g->eq[nb_and].sign = 1;
898 else
899 g->eq[nb_and].sign = -1;
900 g->eq[nb_and].RHS = clast_bound_from_constraint(j, i, infos->names);
901 } else {
902 if (cloog_constraint_is_lower_bound(j, i-1)) {
903 minmax = 1;
904 g->eq[nb_and].sign = 1;
905 } else {
906 minmax = 0;
907 g->eq[nb_and].sign = -1;
910 guarded = (nb_iter >= level) ? level : 0 ;
911 g->eq[nb_and].RHS = clast_minmax(copy,i,minmax,guarded,infos) ;
913 nb_and ++ ;
915 /* 'elimination' of the current constraint, this avoid to use one
916 * constraint more than once. The current line is always eliminated,
917 * and the next lines if they are in a min or a max.
919 cloog_constraint_clear(j);
921 if (minmax == -1)
922 continue;
923 l = cloog_constraint_copy(j);
924 for (l = cloog_constraint_next(l); cloog_constraint_is_valid(l);
925 l = cloog_constraint_next(l))
926 if (((minmax == 1) && cloog_constraint_is_lower_bound(l, i-1)) ||
927 ((minmax == 0) && cloog_constraint_is_upper_bound(l, i-1)))
928 cloog_constraint_clear(l);
930 cloog_constraint_set_free(copy);
932 g->n = nb_and;
933 if (nb_and) {
934 clast_guard_sort(g);
935 **next = &g->stmt;
936 *next = &g->then;
937 } else
938 free_clast_stmt(&g->stmt);
940 return;
944 * Check if the constant "cst" satisfies the modulo guard that
945 * would be introduced by insert_computed_modulo_guard.
946 * The constant is assumed to have been reduced prior to calling
947 * this function.
949 static int constant_modulo_guard_is_satisfied(CloogConstraint *lower,
950 cloog_int_t bound, cloog_int_t cst)
952 if (cloog_constraint_is_valid(lower))
953 return cloog_int_le(cst, bound);
954 else
955 return cloog_int_is_zero(cst);
959 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
960 * depending on whether lower represents a valid constraint.
962 static void insert_computed_modulo_guard(struct clast_reduction *r,
963 CloogConstraint *lower, cloog_int_t mod, cloog_int_t bound,
964 struct clast_stmt ***next)
966 struct clast_expr *e;
967 struct clast_guard *g;
969 e = &new_clast_binary(clast_bin_mod, &r->expr, mod)->expr;
970 g = new_clast_guard(1);
971 if (!cloog_constraint_is_valid(lower)) {
972 g->eq[0].LHS = e;
973 cloog_int_set_si(bound, 0);
974 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
975 g->eq[0].sign = 0;
976 } else {
977 g->eq[0].LHS = e;
978 g->eq[0].RHS = &new_clast_term(bound, NULL)->expr;
979 g->eq[0].sign = -1;
982 **next = &g->stmt;
983 *next = &g->then;
987 * insert_modulo_guard:
988 * This function inserts a modulo guard corresponding to an equality
989 * or a pair of inequalities.
990 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
992 * See insert_equation.
993 * - matrix is the polyhedron containing all the constraints,
994 * - upper and lower are the line numbers of the constraint in matrix
995 * we want to print; in particular, if we want to print an equality,
996 * then lower == -1 and upper is the row of the equality; if we want
997 * to print an inequality, then upper is the row of the upper bound
998 * and lower in the row of the lower bound
999 * - level is the column number of the element in matrix we want to use,
1000 * - the infos structure gives the user some options about code printing,
1001 * the number of parameters in matrix (nb_par), and the arrays of iterator
1002 * names and parameters (iters and params).
1004 static int insert_modulo_guard(CloogConstraint *upper,
1005 CloogConstraint *lower, int level,
1006 struct clast_stmt ***next, CloogInfos *infos)
1008 int i, nb_elts = 0, len, len2, nb_iter, nb_par;
1009 int constant, empty = 0;
1010 struct cloog_vec *line_vector;
1011 cloog_int_t *line, val, bound;
1012 CloogConstraintSet *set;
1014 cloog_int_init(val);
1015 cloog_constraint_coefficient_get(upper, level-1, &val);
1016 if (cloog_int_is_one(val) || cloog_int_is_neg_one(val)) {
1017 cloog_int_clear(val);
1018 return 1;
1021 len = cloog_constraint_total_dimension(upper) + 2;
1022 len2 = cloog_equal_total_dimension(infos->equal) + 2;
1023 nb_par = infos->names->nb_parameters;
1024 nb_iter = len - 2 - nb_par;
1026 cloog_int_init(bound);
1027 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1028 if (cloog_constraint_is_valid(lower)) {
1029 cloog_constraint_constant_get(upper, &val);
1030 cloog_constraint_constant_get(lower, &bound);
1031 cloog_int_add(bound, val, bound);
1032 cloog_constraint_coefficient_get(lower, level-1, &val);
1033 cloog_int_sub_ui(val, val, 1);
1034 if (cloog_int_eq(val, bound)) {
1035 cloog_int_clear(val);
1036 cloog_int_clear(bound);
1037 return 1;
1041 set = cloog_constraint_set_for_reduction(upper, lower);
1042 set = cloog_constraint_set_reduce(set, level, infos->equal, nb_par, &bound);
1043 upper = cloog_constraint_first(set);
1044 if (!cloog_constraint_is_valid(upper)) {
1045 cloog_int_clear(val);
1046 cloog_int_clear(bound);
1047 cloog_constraint_set_free(set);
1048 return 1;
1051 line_vector = cloog_vec_alloc(len);
1052 line = line_vector->p;
1053 cloog_constraint_copy_coefficients(upper, line+1);
1054 if (cloog_int_is_pos(line[level]))
1055 cloog_seq_neg(line+1, line+1, len-1);
1056 cloog_int_neg(line[level], line[level]);
1057 assert(cloog_int_is_pos(line[level]));
1059 nb_elts = 0;
1060 for (i = 1; i <= len-1; ++i) {
1061 if (i == level)
1062 continue;
1063 cloog_int_fdiv_r(line[i], line[i], line[level]);
1064 if (cloog_int_is_zero(line[i]))
1065 continue;
1066 if (i == len-1)
1067 continue;
1069 nb_elts++;
1072 if (nb_elts || !cloog_int_is_zero(line[len-1])) {
1073 struct clast_reduction *r;
1074 const char *name;
1076 r = new_clast_reduction(clast_red_sum, nb_elts+1);
1077 nb_elts = 0;
1079 /* First, the modulo guard : the iterators... */
1080 for (i=1;i<=nb_iter;i++) {
1081 if (i == level || cloog_int_is_zero(line[i]))
1082 continue;
1083 if (cloog_int_is_divisible_by(infos->stride[i-1], line[level])) {
1084 cloog_int_addmul(line[len-1], line[i], infos->offset[i-1]);
1085 cloog_int_fdiv_r(line[len-1], line[len-1], line[level]);
1086 continue;
1089 name = cloog_names_name_at_level(infos->names, i);
1091 r->elts[nb_elts++] = &new_clast_term(line[i],
1092 &new_clast_name(name)->expr)->expr;
1095 /* ...the parameters... */
1096 for (i=nb_iter+1;i<=len-2;i++) {
1097 if (cloog_int_is_zero(line[i]))
1098 continue;
1100 name = infos->names->parameters[i-nb_iter-1] ;
1101 r->elts[nb_elts++] = &new_clast_term(line[i],
1102 &new_clast_name(name)->expr)->expr;
1105 constant = nb_elts == 0;
1106 /* ...the constant. */
1107 if (!cloog_int_is_zero(line[len-1]))
1108 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1110 /* our initial computation may have been an overestimate */
1111 r->n = nb_elts;
1113 if (constant) {
1114 empty = !constant_modulo_guard_is_satisfied(lower, bound, line[len-1]);
1115 free_clast_reduction(r);
1116 } else
1117 insert_computed_modulo_guard(r, lower, line[level], bound, next);
1120 cloog_constraint_release(upper);
1121 cloog_constraint_set_free(set);
1122 cloog_vec_free(line_vector);
1123 cloog_int_clear(val);
1124 cloog_int_clear(bound);
1126 return !empty;
1131 * insert_equation function:
1132 * This function inserts an equality
1133 * constraint according to an element in the clast.
1134 * Returns 1 if the calling function should recurse into inner loops.
1136 * An equality can be preceded by a 'modulo guard'.
1137 * For instance, consider the constraint i -2*j = 0 and the
1138 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1139 * - matrix is the polyhedron containing all the constraints,
1140 * - num is the line number of the constraint in matrix we want to print,
1141 * - level is the column number of the element in matrix we want to use,
1142 * - the infos structure gives the user some options about code printing,
1143 * the number of parameters in matrix (nb_par), and the arrays of iterator
1144 * names and parameters (iters and params).
1146 * - November 13th 2001: first version.
1147 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1148 * modulo is 0, compare vivien or vivien2 with a previous
1149 * version for an idea).
1150 * - June 29th 2003: non-unit strides support.
1151 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1152 * it was previously included in a stride calculation.
1154 static int insert_equation(CloogConstraint *upper, CloogConstraint *lower,
1155 int level, struct clast_stmt ***next, CloogInfos *infos)
1157 struct clast_expr *e;
1158 struct clast_assignment *ass;
1160 if (!insert_modulo_guard(upper, lower, level, next, infos)) {
1161 cloog_constraint_release(lower);
1162 cloog_constraint_release(upper);
1164 return 0;
1167 if (cloog_constraint_is_valid(lower) ||
1168 !clast_equal_add(infos->equal, NULL, level, upper, infos))
1169 { /* Finally, the equality. */
1171 /* If we have to make a block by dimension, we start the block. Function
1172 * pprint knows if there is an equality, if this is the case, it checks
1173 * for the same following condition to close the brace.
1175 if (infos->options->block) {
1176 struct clast_block *b = new_clast_block();
1177 **next = &b->stmt;
1178 *next = &b->body;
1181 e = clast_bound_from_constraint(upper, level, infos->names);
1182 ass = new_clast_assignment(cloog_names_name_at_level(infos->names, level), e);
1184 **next = &ass->stmt;
1185 *next = &(**next)->next;
1188 cloog_constraint_release(lower);
1189 cloog_constraint_release(upper);
1191 return 1;
1196 * insert_for function:
1197 * This function inserts a for loop in the clast.
1198 * Returns 1 if the calling function should recurse into inner loops.
1200 * A loop header according to an element is the conjunction of a minimum and a
1201 * maximum on a given element (they give the loop bounds).
1202 * For instance, considering these constraints and the element j:
1203 * i + j -9*M >= 0
1204 * -j +5*M >= 0
1205 * j -4*M >= 0
1206 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1207 * If the given element is involved in modulo guards defined by
1208 * existentially quantified variables, then these guards should be
1209 * inserted inside the for loop. However, the constraints involved
1210 * in this guard should not be used in determining the lower and upper
1211 * bound of the loop. We therefore insert the guards first (which
1212 * removes the corresponding constraints from the constraint set)
1213 * and then reattach the guard inside the loop.
1214 * - constraints contains all constraints,
1215 * - level is the column number of the element in matrix we want to use,
1216 * - the infos structure gives the user some options about code printing,
1217 * the number of parameters in matrix (nb_par), and the arrays of iterator
1218 * names and parameters (iters and params).
1220 static int insert_for(CloogConstraintSet *constraints, int level,
1221 struct clast_stmt ***next, CloogInfos *infos)
1223 const char *iterator;
1224 struct clast_expr *e1;
1225 struct clast_expr *e2;
1226 struct clast_assignment *ass;
1227 struct clast_stmt **old_next = *next;
1228 struct clast_stmt *guard;
1230 insert_extra_modulo_guards(constraints, 0, next, infos);
1231 guard = *old_next;
1233 iterator = cloog_names_name_at_level(infos->names, level);
1235 e1 = clast_minmax(constraints, level, 1, 0, infos);
1236 e2 = clast_minmax(constraints, level, 0, 0, infos);
1238 if (clast_expr_is_bigger_constant(e1, e2)) {
1239 free_clast_expr(e1);
1240 free_clast_expr(e2);
1241 return 0;
1244 /* If min and max are not equal there is a 'for' else, there is a '='.
1245 * In the special case e1 = e2 = NULL, this is an infinite loop
1246 * so this is not a '='.
1248 if (!clast_expr_equal(e1, e2) || !infos->options->otl || (!e1 && !e2)) {
1249 struct clast_for *f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1250 *old_next = &f->stmt;
1251 if (guard)
1252 f->body = guard;
1253 else
1254 *next = &f->body;
1256 else if (!clast_equal_add(infos->equal, constraints, level,
1257 cloog_constraint_invalid(), infos)) {
1258 if (infos->options->block) {
1259 struct clast_block *b = new_clast_block();
1260 *old_next = &b->stmt;
1261 if (guard)
1262 b->body = guard;
1263 else
1264 *next = &b->body;
1266 ass = new_clast_assignment(iterator, e1);
1267 free_clast_expr(e2);
1268 *old_next = &ass->stmt;
1269 if (guard)
1270 ass->stmt.next = guard;
1271 else
1272 *next = &(**next)->next;
1273 } else {
1274 free_clast_expr(e1);
1275 free_clast_expr(e2);
1278 return 1;
1283 * insert_block function:
1284 * This function inserts a statement block.
1285 * - block is the statement block,
1286 * - level is the number of loops enclosing the statement,
1287 * - the infos structure gives the user some options about code printing,
1288 * the number of parameters in domain (nb_par), and the arrays of iterator
1289 * names and parameters (iters and params).
1291 * - September 21th 2003: first version (pick from pprint function).
1293 static void insert_block(CloogBlock *block, int level,
1294 struct clast_stmt ***next, CloogInfos *infos)
1296 CloogStatement * statement ;
1297 struct clast_stmt *subs;
1299 if (!block)
1300 return;
1302 for (statement = block->statement; statement; statement = statement->next) {
1303 CloogStatement *s_next = statement->next;
1305 subs = clast_equal(level,infos);
1307 statement->next = NULL;
1308 **next = &new_clast_user_stmt(statement, subs)->stmt;
1309 statement->next = s_next;
1310 *next = &(**next)->next;
1316 * insert_loop function:
1317 * This function converts the content of a CloogLoop structure (loop) into a
1318 * clast_stmt (inserted at **next).
1319 * The iterator (level) of
1320 * the current loop is given by 'level': this is the column number of the
1321 * domain corresponding to the current loop iterator. The data of a loop are
1322 * written in this order:
1323 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1324 * depend on the iterator (when the entry in the column 'level' is 0).
1325 * 2. The iteration domain of the iterator, given by the constraints in the
1326 * domain depending on the iterator, i.e.:
1327 * * an equality if the iterator has only one value (possibly preceded by
1328 * a guard verifying if this value is integral), *OR*
1329 * * a loop from the minimum possible value of the iterator to the maximum
1330 * possible value.
1331 * 3. The included statement block.
1332 * 4. The inner loops (recursive call).
1333 * 5. The following loops (recursive call).
1334 * - level is the recursion level or the iteration level that we are printing,
1335 * - the infos structure gives the user some options about code printing,
1336 * the number of parameters in domain (nb_par), and the arrays of iterator
1337 * names and parameters (iters and params).
1339 * - November 2nd 2001: first version.
1340 * - March 6th 2003: infinite domain support.
1341 * - April 19th 2003: (debug) NULL loop support.
1342 * - June 29th 2003: non-unit strides support.
1343 * - April 28th 2005: (debug) level is level+equality when print statement!
1344 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1345 * added to avoid iteration duplication (see DaeGon Kim
1346 * bug in cloog_program_generate). Try vasilache.cloog
1347 * with and without the call to cloog_polylib_matrix_normalize,
1348 * using -f 8 -l 9 options for an idea.
1349 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1350 * - October 16th 2005: (debug) scalar value is saved for next loops.
1352 static void insert_loop(CloogLoop * loop, int level,
1353 struct clast_stmt ***next, CloogInfos *infos)
1355 int equality = 0;
1356 CloogConstraintSet *constraints, *temp;
1357 struct clast_stmt **top = *next;
1358 CloogConstraint *i, *j;
1359 int empty_loop = 0;
1361 /* It can happen that loop be NULL when an input polyhedron is empty. */
1362 if (loop == NULL)
1363 return;
1365 /* The constraints do not always have a shape that allows us to generate code from it,
1366 * thus we normalize it, we also simplify it with the equalities.
1368 temp = cloog_domain_constraints(loop->domain);
1369 cloog_constraint_set_normalize(temp,level);
1370 constraints = cloog_constraint_set_simplify(temp,infos->equal,level,
1371 infos->names->nb_parameters);
1372 cloog_constraint_set_free(temp);
1373 if (level) {
1374 cloog_int_set(infos->stride[level-1], loop->stride);
1375 cloog_int_set(infos->offset[level-1], loop->offset);
1378 /* First of all we have to print the guard. */
1379 insert_guard(constraints,level, next, infos);
1381 if (level && cloog_constraint_set_contains_level(constraints, level,
1382 infos->names->nb_parameters)) {
1383 /* We scan all the constraints to know in which case we are :
1384 * [[if] equation] or [for].
1386 if (cloog_constraint_is_valid(i =
1387 cloog_constraint_set_defining_equality(constraints, level))) {
1388 empty_loop = !insert_equation(i, cloog_constraint_invalid(),
1389 level, next, infos);
1390 equality = 1 ;
1391 } else if (cloog_constraint_is_valid(i =
1392 cloog_constraint_set_defining_inequalities(constraints,
1393 level, &j, infos->names->nb_parameters))) {
1394 empty_loop = !insert_equation(i, j, level, next, infos);
1395 } else
1396 empty_loop = !insert_for(constraints, level, next, infos);
1399 if (!empty_loop) {
1400 /* Finally, if there is an included statement block, print it. */
1401 insert_block(loop->block, level+equality, next, infos);
1403 /* Go to the next level. */
1404 if (loop->inner != NULL)
1405 insert_loop(loop->inner, level+1, next, infos);
1408 if (level)
1409 cloog_equal_del(infos->equal,level);
1410 cloog_constraint_set_free(constraints);
1412 /* Go to the next loop on the same level. */
1413 while (*top)
1414 top = &(*top)->next;
1415 if (loop->next != NULL)
1416 insert_loop(loop->next, level, &top,infos);
1420 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1421 CloogOptions *options)
1423 CloogInfos *infos = ALLOC(CloogInfos);
1424 int i, nb_levels;
1425 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1426 struct clast_stmt **next = &root->next;
1428 infos->state = options->state;
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 infos->offset = ALLOCN(cloog_int_t, nb_levels);
1440 for (i = 0; i < nb_levels; ++i) {
1441 cloog_int_init(infos->stride[i]);
1442 cloog_int_init(infos->offset[i]);
1445 infos->equal = cloog_equal_alloc(nb_levels,
1446 nb_levels, program->names->nb_parameters);
1448 insert_loop(program->loop, 0, &next, infos);
1450 cloog_equal_free(infos->equal);
1452 for (i = 0; i < nb_levels; ++i) {
1453 cloog_int_clear(infos->stride[i]);
1454 cloog_int_clear(infos->offset[i]);
1456 free(infos->stride);
1457 free(infos->offset);
1458 free(infos);
1460 return root;