Include "cloog/cloog.h" and not a relative path.
[cloog-ppl.git] / source / ppl / clast.c
blobef1bd0ba2c8f98590a8ba6ed7bf09e6dda3fd0af
1 #include <stdlib.h>
2 #include <assert.h>
3 #include "cloog/cloog.h"
5 #define ALLOC(type) (type*)malloc(sizeof(type))
6 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
8 /**
9 * CloogInfos structure:
10 * this structure contains all the informations necessary for pretty printing,
11 * they come from the original CloogProgram structure (language, names), from
12 * genereral options (options) or are built only for pretty printing (stride).
13 * This structure is mainly there to reduce the number of function parameters,
14 * since most pprint.c functions need most of its field.
16 struct clooginfos
17 { Value * stride ; /**< The stride for each iterator. */
18 int nb_scattdims ; /**< Scattering dimension number. */
19 int * scaldims ; /**< Boolean array saying whether a given
20 * scattering dimension is scalar or not.
22 CloogNames * names ; /**< Names of iterators and parameters. */
23 CloogOptions * options ; /**< Options on CLooG's behaviour. */
24 CloogMatrix *equal; /**< Matrix of equalities. */
25 } ;
27 typedef struct clooginfos CloogInfos ;
29 struct clast_term *new_clast_term(Value c, const char *v)
31 struct clast_term *t = (struct clast_term *) malloc(sizeof(struct clast_term));
32 t->expr.type = expr_term;
33 value_init(t->val);
34 value_assign(t->val, c);
35 t->var = v;
36 return t;
39 struct clast_binary *new_clast_binary(enum clast_bin_type t,
40 struct clast_expr *lhs, Value rhs)
42 struct clast_binary *b = (struct clast_binary *) malloc(sizeof(struct clast_binary));
43 b->expr.type = expr_bin;
44 b->type = t;
45 b->LHS = lhs;
46 value_init(b->RHS);
47 value_assign(b->RHS, rhs);
48 return b;
51 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
53 int i;
54 struct clast_reduction *r;
55 r = (struct clast_reduction *) malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
56 r->expr.type = expr_red;
57 r->type = t;
58 r->n = n;
59 for (i = 0; i < n; ++i)
60 r->elts[i] = NULL;
61 return r;
64 static void free_clast_root(struct clast_stmt *s)
66 struct clast_root *r = (struct clast_root *)s;
67 assert(CLAST_STMT_IS_A(s, stmt_root));
68 cloog_names_free(r->names);
69 free(r);
72 struct clast_stmt_op stmt_root = { free_clast_root };
74 struct clast_root *new_clast_root(CloogNames *names)
76 struct clast_root *r = (struct clast_root *) malloc(sizeof(struct clast_root));
77 r->stmt.op = &stmt_root;
78 r->stmt.next = NULL;
79 r->names = cloog_names_copy(names);
80 return r;
83 static void free_clast_assignment(struct clast_stmt *s);
85 struct clast_stmt_op stmt_ass = { free_clast_assignment };
87 static void free_clast_assignment(struct clast_stmt *s)
89 struct clast_assignment *a = (struct clast_assignment *)s;
90 assert(CLAST_STMT_IS_A(s, stmt_ass));
91 free_clast_expr(a->RHS);
92 free(a);
95 struct clast_assignment *new_clast_assignment(const char *lhs,
96 struct clast_expr *rhs)
98 struct clast_assignment *a = (struct clast_assignment *) malloc(sizeof(struct clast_assignment));
99 a->stmt.op = &stmt_ass;
100 a->stmt.next = NULL;
101 a->LHS = lhs;
102 a->RHS = rhs;
103 return a;
106 static void free_clast_user_stmt(struct clast_stmt *s);
108 struct clast_stmt_op stmt_user = { free_clast_user_stmt };
110 static void free_clast_user_stmt(struct clast_stmt *s)
112 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
113 assert(CLAST_STMT_IS_A(s, stmt_user));
114 cloog_clast_free(u->substitutions);
115 free(u);
118 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
119 struct clast_stmt *subs)
121 struct clast_user_stmt *u = (struct clast_user_stmt *) malloc(sizeof(struct clast_user_stmt));
122 u->stmt.op = &stmt_user;
123 u->stmt.next = NULL;
124 u->statement = stmt;
125 u->substitutions = subs;
126 return u;
129 static void free_clast_block(struct clast_stmt *s)
131 struct clast_block *b = (struct clast_block *)s;
132 assert(CLAST_STMT_IS_A(s, stmt_block));
133 cloog_clast_free(b->body);
134 free(b);
137 struct clast_stmt_op stmt_block = { free_clast_block };
139 struct clast_block *new_clast_block (void)
141 struct clast_block *b = (struct clast_block *) malloc(sizeof(struct clast_block));
142 b->stmt.op = &stmt_block;
143 b->stmt.next = NULL;
144 b->body = NULL;
145 return b;
148 static void free_clast_for(struct clast_stmt *s)
150 struct clast_for *f = (struct clast_for *)s;
151 assert(CLAST_STMT_IS_A(s, stmt_for));
152 free_clast_expr(f->LB);
153 free_clast_expr(f->UB);
154 value_clear(f->stride);
155 cloog_clast_free(f->body);
156 free(f);
159 struct clast_stmt_op stmt_for = { free_clast_for };
161 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
162 struct clast_expr *UB, Value stride)
164 struct clast_for *f = (struct clast_for *) malloc(sizeof(struct clast_for));
165 f->stmt.op = &stmt_for;
166 f->stmt.next = NULL;
167 f->iterator = it;
168 f->LB = LB;
169 f->UB = UB;
170 f->body = NULL;
171 value_init(f->stride);
172 value_assign(f->stride, stride);
173 return f;
176 static void free_clast_guard(struct clast_stmt *s)
178 int i;
179 struct clast_guard *g = (struct clast_guard *)s;
180 assert(CLAST_STMT_IS_A(s, stmt_guard));
181 cloog_clast_free(g->then);
182 for (i = 0; i < g->n; ++i) {
183 free_clast_expr(g->eq[i].LHS);
184 free_clast_expr(g->eq[i].RHS);
186 free(g);
189 struct clast_stmt_op stmt_guard = { free_clast_guard };
191 struct clast_guard *new_clast_guard(int n)
193 int i;
194 struct clast_guard *g = (struct clast_guard *)
195 malloc(sizeof(struct clast_guard) + (n-1) * sizeof(struct clast_equation));
196 g->stmt.op = &stmt_guard;
197 g->stmt.next = NULL;
198 g->then = NULL;
199 g->n = n;
200 for (i = 0; i < n; ++i) {
201 g->eq[i].LHS = NULL;
202 g->eq[i].RHS = NULL;
204 return g;
207 void free_clast_term(struct clast_term *t)
209 value_clear(t->val);
210 free(t);
213 void free_clast_binary(struct clast_binary *b)
215 value_clear(b->RHS);
216 free_clast_expr(b->LHS);
217 free(b);
220 void free_clast_reduction(struct clast_reduction *r)
222 int i;
223 for (i = 0; i < r->n; ++i)
224 free_clast_expr(r->elts[i]);
225 free(r);
228 void free_clast_expr(struct clast_expr *e)
230 if (!e)
231 return;
232 switch (e->type) {
233 case expr_term:
234 free_clast_term((struct clast_term*) e);
235 break;
236 case expr_red:
237 free_clast_reduction((struct clast_reduction*) e);
238 break;
239 case expr_bin:
240 free_clast_binary((struct clast_binary*) e);
241 break;
242 default:
243 assert(0);
247 void free_clast_stmt(struct clast_stmt *s)
249 assert(s->op);
250 assert(s->op->free);
251 s->op->free(s);
254 void cloog_clast_free(struct clast_stmt *s)
256 struct clast_stmt *next;
257 while (s) {
258 next = s->next;
259 free_clast_stmt(s);
260 s = next;
264 static int clast_term_equal(struct clast_term *t1, struct clast_term *t2)
266 if (t1->var != t2->var)
267 return 0;
268 return value_eq(t1->val, t2->val);
271 static int clast_binary_equal(struct clast_binary *b1, struct clast_binary *b2)
273 if (b1->type != b2->type)
274 return 0;
275 if (value_ne(b1->RHS, b2->RHS))
276 return 0;
277 return clast_expr_equal(b1->LHS, b2->LHS);
280 static int clast_reduction_equal(struct clast_reduction *r1, struct clast_reduction *r2)
282 int i;
283 if (r1->type == clast_red_max && r2->type == clast_red_min &&
284 r1->n == 1 && r2->n == 1)
285 return clast_expr_equal(r1->elts[0], r2->elts[0]);
286 if (r1->type != r2->type)
287 return 0;
288 if (r1->n != r2->n)
289 return 0;
290 for (i = 0; i < r1->n; ++i)
291 if (!clast_expr_equal(r1->elts[i], r2->elts[i]))
292 return 0;
293 return 1;
296 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
298 if (!e1 && !e2)
299 return 1;
300 if (!e1 || !e2)
301 return 0;
302 if (e1->type != e2->type)
303 return 0;
304 switch (e1->type) {
305 case expr_term:
306 return clast_term_equal((struct clast_term*) e1,
307 (struct clast_term*) e2);
308 case expr_bin:
309 return clast_binary_equal((struct clast_binary*) e1,
310 (struct clast_binary*) e2);
311 case expr_red:
312 return clast_reduction_equal((struct clast_reduction*) e1,
313 (struct clast_reduction*) e2);
314 default:
315 assert(0);
320 /******************************************************************************
321 * Equalities spreading functions *
322 ******************************************************************************/
325 /* Equalities are stored inside a CloogMatrix data structure called "equal".
326 * This matrix has (nb_scattering + nb_iterators + 1) rows (i.e. total
327 * dimensions + 1, the "+ 1" is because a statement can be included inside an
328 * external loop without iteration domain), and (nb_scattering + nb_iterators +
329 * nb_parameters + 2) columns (all unknowns plus the scalar plus the equality
330 * type). The ith row corresponds to the equality "= 0" for the ith dimension
331 * iterator. The first column gives the equality type (0: no equality, then
332 * EQTYPE_* -see pprint.h-). At each recursion of pprint, if an equality for
333 * the current level is found, the corresponding row is updated. Then the
334 * equality if it exists is used to simplify expressions (e.g. if we have
335 * "i+1" while we know that "i=2", we simplify it in "3"). At the end of
336 * the pprint call, the corresponding row is reset to zero.
341 * clast_equal_type function :
342 * This function returns the type of the equality in the constraint (line) of
343 * (equal) for the element (level). An equality is 'constant' iff all other
344 * factors are null except the constant one. It is a 'pure item' iff one and
345 * only one factor is non null and is 1 or -1. Otherwise it is an 'affine
346 * expression'.
347 * For instance:
348 * i = -13 is constant, i = j, j = -M are pure items,
349 * j = 2*M, i = j+1 are affine expressions.
350 * When the equality comes from a 'one time loop', (line) is ONE_TIME_LOOP.
351 * This case require a specific treatment since we have to study all the
352 * constraints.
353 * - equal is the matrix of equalities,
354 * - level is the column number in equal of the element which is 'equal to',
355 * - line is the line number in equal of the constraint we want to study;
356 * if it is -1, all lines must be studied.
358 * - July 3rd 2002: first version, called pprint_equal_isconstant.
359 * - July 6th 2002: adaptation for the 3 types.
360 * - June 15th 2005: (debug) expr = domain->Constraint[line] was evaluated
361 * before checking if line != ONE_TIME_LOOP. Since
362 * ONE_TIME_LOOP is -1, an invalid read was possible.
363 * - October 19th 2005: Removal of the once-time-loop specific processing.
365 static int clast_equal_type(CloogMatrix *equal, int level, int line)
367 int i, one=0 ;
369 /* There is only one non null factor, and it must be +1 or -1 for
370 * iterators or parameters.
372 for (i=1;i<=equal->NbColumns-2;i++)
373 if (value_notzero_p(equal->p[line][i]) && (i != level))
374 { if ((value_notone_p(equal->p[line][i])
375 && value_notmone_p(equal->p[line][i]))
376 || (one != 0))
377 return EQTYPE_EXAFFINE ;
378 else
379 one = 1 ;
381 /* if the constant factor is non null, it must be alone. */
382 if (one != 0)
383 { if (value_notzero_p(equal->p[line][equal->NbColumns-1]))
384 return EQTYPE_EXAFFINE ;
386 else
387 return EQTYPE_CONSTANT ;
389 return EQTYPE_PUREITEM ;
394 * clast_equal_allow function:
395 * This function checks whether the options allow us to spread the equality or
396 * not. It returns 1 if so, 0 otherwise.
397 * - equal is the matrix of equalities,
398 * - level is the column number in equal of the element which is 'equal to',
399 * - line is the line number in equal of the constraint we want to study,
400 * - the infos structure gives the user all options on code printing and more.
402 * - October 27th 2005: first version (extracted from old pprint_equal_add).
404 static int clast_equal_allow(CloogMatrix *equal, int level, int line, CloogInfos *infos)
406 if ((!infos->options->csp && !infos->options->esp) ||
407 (level < infos->options->fsp))
408 return 0 ;
410 if (infos->options->csp &&
411 (clast_equal_type(equal,level,line) == EQTYPE_EXAFFINE) &&
412 !infos->options->esp)
413 return 0 ;
415 return 1 ;
420 * clast_equal_add function:
421 * This function updates the row (level-1) of the equality matrix (equal) with
422 * the row that corresponds to the row (line) of the matrix (matrix). It returns
423 * 1 if the row can be updated, 0 otherwise.
424 * - equal is the matrix of equalities,
425 * - matrix is the matrix of constraints,
426 * - level is the column number in matrix of the element which is 'equal to',
427 * - line is the line number in matrix of the constraint we want to study,
428 * - the infos structure gives the user all options on code printing and more.
430 * - July 2nd 2002: first version.
431 * - October 19th 2005: Addition of the once-time-loop specific processing.
433 static int clast_equal_add(CloogMatrix *equal, CloogMatrix *matrix, int level, int line,
434 CloogInfos *infos)
436 int i ;
437 Value numerator, denominator, division, modulo ;
439 /* If we are in the case of a loop running once, this means that the equality
440 * comes from an inequality. Here we find this inequality.
442 if (line == ONE_TIME_LOOP)
443 { for (i=0;i<matrix->NbRows;i++)
444 if ((value_notzero_p(matrix->p[i][0]))&&
445 (value_notzero_p(matrix->p[i][level])))
446 { line = i ;
448 /* Since in once-time-loops, equalities derive from inequalities, we
449 * may have to offset the values. For instance if we have 2i>=3, the
450 * equality is in fact i=2. This may happen when the level coefficient is
451 * not 1 or -1 and the scalar value is not zero. In any other case (e.g.,
452 * if the inequality is an expression including outer loop counters or
453 * parameters) the once time loop would not have been detected
454 * because of floord and ceild functions.
456 if (value_ne_si(matrix->p[i][level],1) &&
457 value_ne_si(matrix->p[i][level],-1) &&
458 value_notzero_p(matrix->p[i][matrix->NbColumns-1]))
459 { value_init_c(numerator) ;
460 value_init_c(denominator) ;
461 value_init_c(division) ;
462 value_init_c(modulo) ;
464 value_assign(denominator,matrix->p[i][level]) ;
465 value_absolute(denominator,denominator) ;
466 value_assign(numerator,matrix->p[i][matrix->NbColumns-1]) ;
467 value_modulus(modulo,numerator,denominator) ;
468 value_division(division,numerator,denominator) ;
470 /* There are 4 scenarios:
471 * di +n >= 0 --> i + (n div d) >= 0
472 * -di +n >= 0 --> -i + (n div d) >= 0
473 * di -n >= 0 --> if (n%d == 0) i + ((-n div d)+1) >= 0
474 * else i + (-n div d) >= 0
475 * -di -n >= 0 --> if (n%d == 0) -i + ((-n div d)-1) >= 0
476 * else -i + (-n div d) >= 0
477 * In the following we distinct the scalar value setting and the
478 * level coefficient.
480 if (value_pos_p(numerator) || value_zero_p(modulo))
481 value_assign (matrix->p[i][matrix->NbColumns-1], division);
482 else
483 { if (value_pos_p(matrix->p[i][level]))
484 value_increment (matrix->p[i][matrix->NbColumns-1], division);
485 else
486 value_decrement (matrix->p[i][matrix->NbColumns-1],division) ;
489 if (value_pos_p(matrix->p[i][level]))
490 value_set_si(matrix->p[i][level], 1) ;
491 else
492 value_set_si(matrix->p[i][level], -1) ;
494 value_clear_c(numerator) ;
495 value_clear_c(denominator) ;
496 value_clear_c(division) ;
497 value_clear_c(modulo) ;
500 break ;
504 /* We update the line of equal corresponding to level:
505 * - the first element gives the equality type,
507 value_set_si(equal->p[level-1][0], clast_equal_type(matrix,level,line)) ;
508 /* - the other elements corresponding to the equality itself
509 * (the iterators up to level, then the parameters and the scalar).
511 for (i=1;i<=level;i++)
512 value_assign(equal->p[level-1][i], matrix->p[line][i]) ;
513 for (i=0;i<cloog_names_nb_parameters (infos->names)+1;i++)
514 value_assign(equal->p[level-1][equal->NbColumns-i-1],
515 matrix->p[line][matrix->NbColumns-i-1]) ;
517 cloog_matrix_equality_update(equal,level,cloog_names_nb_parameters (infos->names)) ;
519 return (clast_equal_allow(equal,level,level-1,infos)) ;
524 * clast_equal_del function :
525 * This function reset the equality corresponding to the iterator (level)
526 * in the equality matrix (equal).
527 * - July 2nd 2002: first version.
529 static void clast_equal_del(CloogMatrix * equal, int level)
531 int i ;
533 for (i=0;i<equal->NbColumns;i++)
534 value_set_si(equal->p[level-1][i], 0) ;
539 * clast_bound_from_constraint function:
540 * This function returns a clast_expr containing the printing of the
541 * 'right part' of a constraint according to an element.
542 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
543 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
544 * function should return 'ceild(3*i+M,2)'.
545 * - matrix is the polyhedron containing all the constraints,
546 * - line_num is the line number in domain of the constraint we want to print,
547 * - level is the column number in domain of the element we want to use,
548 * - names structure gives the user some options about code printing,
549 * the number of parameters in domain (nb_par), and the arrays of iterator
550 * names and parameters (iters and params).
552 * - November 2nd 2001: first version.
553 * - June 27th 2003: 64 bits version ready.
555 static struct clast_expr *clast_bound_from_constraint(CloogMatrix *matrix,
556 int line_num, int level,
557 CloogNames *names)
559 int i, nb_iter, sign, nb_elts=0 ;
560 char * name;
561 Value numerator, denominator, temp, division ;
562 struct clast_expr *e = NULL;
564 value_init_c(temp) ;
565 value_init_c(numerator) ;
566 value_init_c(denominator) ;
568 if (value_notzero_p(matrix->p[line_num][level])) {
569 struct clast_reduction *r;
570 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
571 sign = value_pos_p(matrix->p[line_num][level]) ? -1 : 1 ;
573 for (i = 1, nb_elts = 0; i <= matrix->NbColumns - 1; ++i)
574 if (i != level && value_notzero_p(matrix->p[line_num][i]))
575 nb_elts++;
576 r = new_clast_reduction(clast_red_sum, nb_elts);
577 nb_elts = 0;
579 /* First, we have to print the iterators. */
580 nb_iter = matrix->NbColumns - 2 - cloog_names_nb_parameters (names);
581 for (i=1;i<=nb_iter;i++)
582 if ((i != level) && value_notzero_p(matrix->p[line_num][i])) {
583 if (i <= cloog_names_nb_scattering (names))
584 name = cloog_names_scattering_elt (names, i - 1);
585 else
586 name = cloog_names_iterator_elt (names, i - cloog_names_nb_scattering (names) - 1);
588 if (sign == -1)
589 value_oppose(temp,matrix->p[line_num][i]) ;
590 else
591 value_assign(temp,matrix->p[line_num][i]) ;
593 r->elts[nb_elts++] = &new_clast_term(temp, name)->expr;
596 /* Next, the parameters. */
597 for (i=nb_iter+1;i<=matrix->NbColumns-2;i++)
598 if ((i != level) && value_notzero_p(matrix->p[line_num][i])) {
599 name = cloog_names_parameter_elt (names, i - nb_iter - 1);
601 if (sign == -1)
602 value_oppose(temp,matrix->p[line_num][i]) ;
603 else
604 value_assign(temp,matrix->p[line_num][i]) ;
606 r->elts[nb_elts++] = &new_clast_term(temp, name)->expr;
609 if (sign == -1)
611 value_oppose(numerator,matrix->p[line_num][matrix->NbColumns - 1]) ;
612 value_assign(denominator,matrix->p[line_num][level]) ;
614 else
616 value_assign(numerator,matrix->p[line_num][matrix->NbColumns - 1]) ;
617 value_oppose(denominator,matrix->p[line_num][level]) ;
620 /* Finally, the constant, and the final printing. */
621 if (nb_elts) {
622 if (value_notzero_p(numerator))
623 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
625 if (value_notone_p(matrix->p[line_num][level])
626 && value_notmone_p(matrix->p[line_num][level]))
627 { if (value_one_p(matrix->p[line_num][0]))
628 { if (value_pos_p(matrix->p[line_num][level]))
629 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
630 else
631 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
632 } else
633 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
635 else
636 e = &r->expr;
637 } else {
638 free_clast_reduction(r);
639 if (value_zero_p(numerator))
640 e = &new_clast_term(numerator, NULL)->expr;
641 else
642 { if (value_notone_p(denominator))
643 { if (value_one_p(matrix->p[line_num][0])) /* useful? */
644 { value_modulus(temp,numerator,denominator) ;
645 if (value_zero_p(temp))
646 { value_division(temp,numerator,denominator) ;
647 e = &new_clast_term(temp, NULL)->expr;
649 else
650 { value_init_c(division) ;
651 value_division(division,numerator,denominator) ;
652 if (value_neg_p(numerator)) {
653 if (value_pos_p(matrix->p[line_num][level])) {
654 /* nb<0 need max */
655 e = &new_clast_term(division, NULL)->expr;
656 } else {
657 /* nb<0 need min */
658 value_decrement(temp,division) ;
659 e = &new_clast_term(temp, NULL)->expr;
662 else
663 { if (value_pos_p(matrix->p[line_num][level]))
664 { /* nb>0 need max */
665 value_increment(temp,division) ;
666 e = &new_clast_term(temp, NULL)->expr;
668 else
669 /* nb>0 need min */
670 e = &new_clast_term(division, NULL)->expr;
672 value_clear_c(division) ;
675 else
676 e = &new_clast_binary(clast_bin_div,
677 &new_clast_term(numerator, NULL)->expr,
678 denominator)->expr;
680 else
681 e = &new_clast_term(numerator, NULL)->expr;
686 value_clear_c(temp) ;
687 value_clear_c(numerator) ;
688 value_clear_c(denominator) ;
690 return e;
695 * clast_equal function:
696 * This function returns the content an equality matrix (equal) into a clast_stmt.
697 * - the infos structure gives the user all options on code printing and more.
699 * - July 2nd 2002: first version.
700 * - March 16th 2003: return now a string instead of printing directly and do
701 * not write 'Sx()' if there is no spreading, but only 'Sx'.
703 static struct clast_stmt * clast_equal(CloogInfos *infos)
705 int i, iterator ;
706 Value type ;
707 struct clast_expr *e;
708 struct clast_stmt *a = NULL;
709 struct clast_stmt **next = &a;
710 CloogMatrix *equal = infos->equal;
712 value_init_c(type) ;
714 /* It is not necessary to print here the scattering iterators since they
715 * never appear in the statement bodies.
717 for (i = cloog_names_nb_scattering (infos->names); i < equal->NbRows; i++)
718 { if (value_notzero_p(equal->p[i][0])&&clast_equal_allow(equal,i+1,i,infos)) {
719 iterator = i - cloog_names_nb_scattering (infos->names) ;
721 /* pprint_line needs to know that the current line is an equality, so
722 * we temporary remove the equality type and set it to zero (the equality
723 * tag in PolyLib.
725 value_assign(type,equal->p[i][0]) ;
726 value_set_si(equal->p[i][0], 0) ;
727 e = clast_bound_from_constraint(equal, i, i+1, infos->names);
728 value_assign(equal->p[i][0], type) ;
729 *next = &new_clast_assignment(cloog_names_iterators (infos->names)[iterator], e)->stmt;
730 next = &(*next)->next;
733 value_clear_c(type) ;
735 return a;
740 * clast_equal_cpp function:
741 * This function prints the substitution data of a statement into a clast_stmt.
742 * Using this function instead of pprint_equal is useful for generating
743 * a compilable pseudo-code by using preprocessor macro for each statement.
744 * By opposition to pprint_equal, the result is less human-readable. For
745 * instance this function will print (i,i+3,k,3) where pprint_equal would
746 * return (j=i+3,l=3).
747 * - level is the number of loops enclosing the statement,
748 * - the infos structure gives the user all options on code printing and more.
750 * - March 12th 2004: first version.
751 * - November 21th 2005: (debug) now works well with GMP version.
753 static struct clast_stmt * clast_equal_cpp(int level, CloogInfos *infos)
755 int i ;
756 Value type ;
757 struct clast_expr *e;
758 struct clast_stmt *a = NULL;
759 struct clast_stmt **next = &a;
760 CloogMatrix *equal = infos->equal;
762 value_init_c(type) ;
764 for (i=cloog_names_nb_scattering (infos->names);i<level-1;i++)
765 { if (value_notzero_p(equal->p[i][0]))
766 { /* pprint_line needs to know that the current line is an equality, so
767 * we temporary remove the equality type and set it to zero (the equality
768 * tag in PolyLib.
770 value_assign(type,equal->p[i][0]) ;
771 value_set_si(equal->p[i][0], 0) ;
772 e = clast_bound_from_constraint(equal, i, i+1, infos->names);
773 value_assign(equal->p[i][0], type) ;
774 } else {
775 value_set_si(type, 1);
776 e = &new_clast_term
777 (type, cloog_names_iterator_elt (infos->names, i - cloog_names_nb_scattering (infos->names)))->expr;
779 *next = &new_clast_assignment(NULL, e)->stmt;
780 next = &(*next)->next;
782 value_clear_c(type) ;
784 return a;
789 * clast_minmax function:
790 * This function returns a clast_expr containing the printing of a minimum or a
791 * maximum of the 'right parts' of all constraints according to an element.
792 * For instance consider the constraints:
793 * -3*i +2*j -M >= 0
794 * 2*i +j >= 0
795 * -i -j +2*M >= 0
796 * if we are looking for the minimum for the element j, the function should
797 * return 'max(ceild(3*i+M,2),-2*i)'.
798 * - matrix is the polyhedron containing all the constraints,
799 * - level is the column number in domain of the element we want to use,
800 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
801 * - guard is set to 0 if there is no guard, and set to the level of the element
802 * with a guard otherwise (then the function gives the max or the min only
803 * for the constraint where the guarded coefficient is 0),
804 * - the infos structure gives the user some options about code printing,
805 * the number of parameters in domain (nb_par), and the arrays of iterator
806 * names and parameters (iters and params).
808 * - November 2nd 2001: first version.
810 static struct clast_expr *clast_minmax(CloogMatrix *matrix,
811 int level, int max, int guard,
812 CloogInfos *infos)
813 { int i, n;
814 struct clast_reduction *r;
816 for (i=0, n=0;i<matrix->NbRows;i++)
817 if (((max && value_pos_p(matrix->p[i][level])) ||
818 (!max && value_neg_p(matrix->p[i][level]))) &&
819 (!guard || value_zero_p(matrix->p[i][guard])) &&
820 (value_notzero_p(matrix->p[i][0])))
821 n++;
822 if (!n)
823 return NULL;
824 r = new_clast_reduction(max ? clast_red_max : clast_red_min, n);
826 for (i=0, n=0;i<matrix->NbRows;i++)
827 if (((max && value_pos_p(matrix->p[i][level])) ||
828 (!max && value_neg_p(matrix->p[i][level]))) &&
829 (!guard || value_zero_p(matrix->p[i][guard])) &&
830 (value_notzero_p(matrix->p[i][0])))
831 r->elts[n++] = clast_bound_from_constraint(matrix,i,level,infos->names);
833 return &r->expr;
838 * insert_guard function:
839 * This function inserts a guard in the clast.
840 * A guard on an element (level) is :
841 * -> the conjunction of all the existing constraints where the coefficient of
842 * this element is 0 if the element is an iterator,
843 * -> the conjunction of all the existing constraints if the element isn't an
844 * iterator.
845 * For instance, considering these constraints and the element j:
846 * -3*i +2*j -M >= 0
847 * 2*i +M >= 0
848 * this function should return 'if (2*i+M>=0) {'.
849 * - matrix is the polyhedron containing all the constraints,
850 * - level is the column number of the element in matrix we want to use,
851 * - the infos structure gives the user some options about code printing,
852 * the number of parameters in matrix (nb_par), and the arrays of iterator
853 * names and parameters (iters and params).
855 * - November 3rd 2001: first version.
856 * - November 14th 2001: a lot of 'purifications'.
857 * - July 31th 2002: (debug) some guard parts are no more redundants.
858 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
859 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
860 * (the need came from loop_simplify that may result in
861 * domain unions, now it should be fixed directly in
862 * cloog_loop_simplify).
864 static void insert_guard(CloogMatrix *matrix, int level,
865 struct clast_stmt ***next, CloogInfos *infos)
867 int i, j, k, l, guarded, minmax=-1, nb_and = 0, nb_iter ;
868 char * name;
869 CloogMatrix * copy ;
870 struct clast_guard *g;
871 Value one;
873 if (matrix == NULL)
874 return;
876 value_init(one);
877 value_set_si(one, 1);
879 g = new_clast_guard(2 * (matrix->NbColumns-2));
881 /* Well, it looks complicated because I wanted to have a particular, more
882 * readable, ordering, obviously this function may be far much simpler !
884 copy = cloog_matrix_copy(matrix) ;
886 nb_iter = copy->NbColumns - 2 - cloog_names_nb_parameters (infos->names) ;
888 nb_and = 0 ;
889 /* We search for guard parts. */
890 for (i=1;i<=copy->NbColumns-2;i++)
891 for (j=0;j<copy->NbRows;j++)
892 if (value_notzero_p(copy->p[j][i]) &&
893 (value_zero_p(copy->p[j][level]) || (nb_iter < level))) {
894 struct clast_term *t;
895 if (i <= nb_iter)
896 { if (i <= cloog_names_nb_scattering (infos->names))
897 name = cloog_names_scattering_elt (infos->names, i - 1);
898 else
899 name = cloog_names_iterator_elt (infos->names, i - cloog_names_nb_scattering (infos->names) - 1);
901 else
902 name = cloog_names_parameter_elt (infos->names, i - nb_iter - 1);
904 g->eq[nb_and].LHS = &(t = new_clast_term(one, name))->expr;
905 if (value_zero_p(copy->p[j][0])) {
906 /* put the "denominator" in the LHS */
907 value_assign(t->val, copy->p[j][i]);
908 value_set_si(copy->p[j][i], 1);
909 g->eq[nb_and].sign = 0;
910 g->eq[nb_and].RHS = clast_bound_from_constraint(copy,j,i,infos->names);
911 value_assign(copy->p[j][i], t->val);
912 } else {
913 if (value_pos_p(copy->p[j][i])) {
914 minmax = 1;
915 g->eq[nb_and].sign = 1;
916 } else {
917 minmax = 0;
918 g->eq[nb_and].sign = -1;
921 guarded = (nb_iter >= level) ? level : 0 ;
922 g->eq[nb_and].RHS = clast_minmax(copy,i,minmax,guarded,infos) ;
924 nb_and ++ ;
926 /* 'elimination' of the current constraint, this avoid to use one
927 * constraint more than once. The current line is always eliminated,
928 * and the next lines if they are in a min or a max.
930 for (k=i;k<=copy->NbColumns-2;k++)
931 value_set_si(copy->p[j][k], 0) ;
933 if (minmax != -1)
934 for (l=j+1;l<copy->NbRows;l++)
935 if (((minmax == 1) && value_pos_p(copy->p[l][i])) ||
936 ((minmax == 0) && value_neg_p(copy->p[l][i])))
937 for (k=i;k<=copy->NbColumns-2;k++)
938 value_set_si(copy->p[l][k], 0) ;
940 cloog_matrix_free(copy) ;
942 g->n = nb_and;
943 if (nb_and) {
944 **next = &g->stmt;
945 *next = &g->then;
946 } else
947 free_clast_stmt(&g->stmt);
949 value_clear(one);
950 return;
954 /* Computes x, y and g such that g = gcd(a,b) and a*x+b*y = g */
955 static void Euclid(Value a, Value b, Value *x, Value *y, Value *g)
957 Value c, d, e, f, tmp;
959 value_init(c);
960 value_init(d);
961 value_init(e);
962 value_init(f);
963 value_init(tmp);
964 value_absolute(c, a);
965 value_absolute(d, b);
966 value_set_si(e, 1);
967 value_set_si(f, 0);
968 while(value_pos_p(d)) {
969 value_division(tmp, c, d);
970 value_multiply(tmp, tmp, f);
971 value_subtract(e, e, tmp);
972 value_division(tmp, c, d);
973 value_multiply(tmp, tmp, d);
974 value_subtract(c, c, tmp);
975 value_swap(c, d);
976 value_swap(e, f);
978 value_assign(*g, c);
979 if (value_zero_p(a))
980 value_set_si(*x, 0);
981 else if (value_pos_p(a))
982 value_assign(*x, e);
983 else value_oppose(*x, e);
984 if (value_zero_p(b))
985 value_set_si(*y, 0);
986 else {
987 value_multiply(tmp, a, *x);
988 value_subtract(tmp, c, tmp);
989 value_division(*y, tmp, b);
991 value_clear(c);
992 value_clear(d);
993 value_clear(e);
994 value_clear(f);
995 value_clear(tmp);
999 * insert_modulo_guard:
1000 * This function inserts a modulo guard corresponding to an equality.
1001 * See insert_equality.
1002 * - matrix is the polyhedron containing all the constraints,
1003 * - num is the line number of the constraint in matrix we want to print,
1004 * - level is the column number of the element in matrix we want to use,
1005 * - the infos structure gives the user some options about code printing,
1006 * the number of parameters in matrix (nb_par), and the arrays of iterator
1007 * names and parameters (iters and params).
1009 static void insert_modulo_guard(CloogMatrix *matrix, int num, int level,
1010 struct clast_stmt ***next, CloogInfos *infos)
1012 int i, j, k, nb_elts = 0, len, nb_iter, in_stride = 0, nb_par;
1013 Vector *line_vector;
1014 Value *line, val, x, y, g;
1016 if (value_one_p(matrix->p[num][level]) || value_mone_p(matrix->p[num][level]))
1017 return;
1019 value_init_c(val);
1020 value_init_c(x);
1021 value_init_c(y);
1022 value_init_c(g);
1024 len = matrix->NbColumns;
1025 nb_par = cloog_names_nb_parameters (infos->names);
1026 nb_iter = matrix->NbColumns - 2 - nb_par;
1028 line_vector = Vector_Alloc(len);
1029 line = line_vector->p;
1030 if (value_neg_p(matrix->p[num][level]))
1031 cloog_vector_copy(matrix->p[num]+1, line+1, len-1);
1032 else {
1033 value_set_si(val, -1);
1034 cloog_vector_scale(matrix->p[num]+1, line+1, val, len-1);
1036 value_oppose(line[level], line[level]);
1037 assert(value_pos_p(line[level]));
1039 nb_elts = 0;
1040 for (i = nb_iter; i >= 1; --i) {
1041 if (i == level)
1042 continue;
1043 value_pmodulus(line[i],line[i],line[level]);
1044 if (value_zero_p(line[i]))
1045 continue;
1047 /* Look for an earlier variable that is also a multiple of line[level]
1048 * and check whether we can use the corresponding affine expression
1049 * to "reduce" the modulo guard, where reduction means that we eliminate
1050 * a variable, possibly at the expense of introducing other variables
1051 * with smaller index.
1053 for (j = level-1; j >= 0; --j) {
1054 if (value_cmp_si(infos->equal->p[j][0], EQTYPE_EXAFFINE) != 0)
1055 continue;
1056 value_modulus(val, infos->equal->p[j][1+j], line[level]);
1057 if (value_notzero_p(val))
1058 continue;
1059 value_modulus(val, infos->equal->p[j][i], line[level]);
1060 if (value_zero_p(val))
1061 continue;
1062 for (k = j; k > i; --k) {
1063 if (value_zero_p(infos->equal->p[j][k]))
1064 continue;
1065 value_modulus(val, infos->equal->p[j][k], line[level]);
1066 if (value_notzero_p(val))
1067 break;
1069 if (k > i)
1070 continue;
1071 Euclid(infos->equal->p[j][i], line[level], &x, &y, &g);
1072 value_modulus(val, line[i], g);
1073 if (value_notzero_p(val))
1074 continue;
1075 value_division(val, line[i], g);
1076 value_oppose(val, val);
1077 value_multiply(val, val, x);
1078 value_set_si(y, 1);
1079 /* Add (infos->equal->p[j][i])^{-1} * line[i] times the equality */
1080 cloog_vector_combine(line+1, infos->equal->p[j]+1, line+1, y, val, i);
1081 cloog_vector_combine(line+len-nb_par-1,
1082 infos->equal->p[j]+infos->equal->NbColumns-nb_par-1,
1083 line+len-nb_par-1, y, val, nb_par+1);
1084 break;
1086 if (j >= 0) {
1087 value_pmodulus(line[i],line[i],line[level]);
1088 assert(value_zero_p(line[i]));
1089 continue;
1092 value_modulus(val,infos->stride[i-1],line[level]);
1093 /* We need to know if an element of the equality has not to be printed
1094 * because of a stride that guarantees that this element can be divided by
1095 * the current coefficient. Because when there is a constant element, it
1096 * is included in the stride calculation (more exactly in the strided
1097 * iterator new lower bound: the 'offset') and we have not to print it.
1099 if (value_zero_p(val)) {
1100 in_stride = 1;
1101 continue;
1104 nb_elts++;
1106 for (i = nb_iter+1; i <= len-1; ++i) {
1107 value_pmodulus(line[i],line[i],line[level]);
1108 if (value_zero_p(line[i]))
1109 continue;
1110 if (i <= len-2)
1111 nb_elts++;
1114 if (nb_elts || (value_notzero_p(line[len-1]) && (!in_stride))) {
1115 struct clast_reduction *r;
1116 struct clast_expr *e;
1117 struct clast_guard *g;
1118 char * name;
1120 r = new_clast_reduction(clast_red_sum, nb_elts+1);
1121 nb_elts = 0;
1123 /* First, the modulo guard : the iterators... */
1124 for (i=1;i<=nb_iter;i++) {
1125 if (i == level || value_zero_p(line[i]))
1126 continue;
1127 value_modulus(val,infos->stride[i-1],line[level]);
1128 if (value_zero_p(val))
1129 continue;
1131 if (i <= cloog_names_nb_scattering (infos->names))
1132 name = cloog_names_scattering_elt (infos->names, i - 1);
1133 else
1134 name = cloog_names_iterator_elt (infos->names, i - cloog_names_nb_scattering (infos->names) - 1);
1136 r->elts[nb_elts++] = &new_clast_term(line[i], name)->expr;
1139 /* ...the parameters... */
1140 for (i=nb_iter+1;i<=len-2;i++) {
1141 if (value_zero_p(line[i]))
1142 continue;
1144 name = cloog_names_parameter_elt (infos->names, i - nb_iter - 1);
1145 r->elts[nb_elts++] = &new_clast_term(line[i], name)->expr;
1148 /* ...the constant. */
1149 if (value_notzero_p(line[len-1]))
1150 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1152 /* our initial computation may have been an overestimate */
1153 r->n = nb_elts;
1155 e = &new_clast_binary(clast_bin_mod, &r->expr, line[level])->expr;
1156 g = new_clast_guard(1);
1157 g->eq[0].LHS = e;
1158 value_set_si(val, 0);
1159 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1160 g->eq[0].sign = 0;
1162 **next = &g->stmt;
1163 *next = &g->then;
1166 Vector_Free(line_vector);
1168 value_clear_c(val);
1169 value_clear_c(x);
1170 value_clear_c(y);
1171 value_clear_c(g);
1176 * insert_equality function:
1177 * This function inserts an equality
1178 * constraint according to an element in the clast.
1179 * An equality can be preceded by a 'modulo guard'.
1180 * For instance, consider the constraint i -2*j = 0 and the
1181 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1182 * - matrix is the polyhedron containing all the constraints,
1183 * - num is the line number of the constraint in matrix we want to print,
1184 * - level is the column number of the element in matrix we want to use,
1185 * - the infos structure gives the user some options about code printing,
1186 * the number of parameters in matrix (nb_par), and the arrays of iterator
1187 * names and parameters (iters and params).
1189 * - November 13th 2001: first version.
1190 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1191 * modulo is 0, compare vivien or vivien2 with a previous
1192 * version for an idea).
1193 * - June 29th 2003: non-unit strides support.
1194 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1195 * it was previously included in a stride calculation.
1197 static void insert_equality(CloogMatrix *matrix, int num,
1198 int level, struct clast_stmt ***next, CloogInfos *infos)
1200 struct clast_expr *e;
1201 struct clast_assignment *ass;
1203 insert_modulo_guard(matrix, num, level, next, infos);
1205 if (!clast_equal_add(infos->equal,matrix,level,num,infos))
1206 { /* Finally, the equality. */
1208 /* If we have to make a block by dimension, we start the block. Function
1209 * pprint knows if there is an equality, if this is the case, it checks
1210 * for the same following condition to close the brace.
1212 if (infos->options->block) {
1213 struct clast_block *b = new_clast_block();
1214 **next = &b->stmt;
1215 *next = &b->body;
1218 e = clast_bound_from_constraint(matrix,num,level,infos->names);
1219 if (level <= cloog_names_nb_scattering (infos->names))
1220 ass = new_clast_assignment(cloog_names_scattering_elt (infos->names, level - 1), e);
1221 else
1222 ass = new_clast_assignment
1223 (cloog_names_iterator_elt (infos->names, level - cloog_names_nb_scattering (infos->names) - 1), e);
1225 **next = &ass->stmt;
1226 *next = &(**next)->next;
1229 return;
1234 * insert_for function:
1235 * This function inserts a for loop in the clast.
1236 * A loop header according to an element is the conjonction of a minimum and a
1237 * maximum on the element (they give the loop bounds).
1238 * For instance, considering these constraints and the element j:
1239 * i + j -9*M >= 0
1240 * -j +5*M >= 0
1241 * j -4*M >= 0
1242 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1243 * - matrix is the polyhedron containing all the constraints,
1244 * - level is the column number of the element in matrix we want to use,
1245 * - the infos structure gives the user some options about code printing,
1246 * the number of parameters in matrix (nb_par), and the arrays of iterator
1247 * names and parameters (iters and params).
1249 * - July 2nd 2002: first version (pick from pprint function).
1250 * - March 6th 2003: infinite domain support.
1251 * - June 29th 2003: non-unit strides support.
1253 static void insert_for(CloogMatrix *matrix, int level,
1254 struct clast_stmt ***next, CloogInfos *infos)
1256 char * iterator ;
1257 struct clast_expr *e1;
1258 struct clast_expr *e2;
1259 struct clast_assignment *ass;
1261 if (level <= cloog_names_nb_scattering (infos->names))
1262 iterator = cloog_names_scattering_elt (infos->names, level - 1);
1263 else
1264 iterator = cloog_names_iterator_elt
1265 (infos->names, level - cloog_names_nb_scattering (infos->names) - 1);
1267 e1 = clast_minmax(matrix,level,1,0,infos) ;
1268 e2 = clast_minmax(matrix,level,0,0,infos) ;
1270 /* If min and max are not equal there is a 'for' else, there is a '='.
1271 * In the special case e1 = e2 = NULL, this is an infinite loop
1272 * so this is not a '='.
1274 if (!clast_expr_equal(e1, e2) || !infos->options->otl || (!e1 && !e2)) {
1275 struct clast_for *f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1276 **next = &f->stmt;
1277 *next = &f->body;
1279 else if (!clast_equal_add(infos->equal,matrix,level,ONE_TIME_LOOP,infos)) {
1280 if (infos->options->block) {
1281 struct clast_block *b = new_clast_block();
1282 **next = &b->stmt;
1283 *next = &b->body;
1285 ass = new_clast_assignment(iterator, e1);
1286 **next = &ass->stmt;
1287 *next = &(**next)->next;
1290 return;
1295 * insert_scalar function:
1296 * This function inserts assignments to the scalar values
1297 * that follows the level (level). It finds by scanning (loop) by inner level,
1298 * the first CloogBlock data structure (at this step, all blocks has the same
1299 * scalar vector information after (level)), and prints all the adjacent
1300 * scalar values following (level), if it is required by options in (info).
1301 * - loop is the loop structure to begin the search for a block,
1302 * - level is the current loop level,
1303 * - scalar points to the number of scalar values already visited,
1304 * - the infos structure gives the user options about code printing and more.
1306 * - September 12th 2005: first version.
1308 static void insert_scalar(CloogLoop *loop, int level, int *scalar,
1309 struct clast_stmt ***next, CloogInfos *infos)
1311 struct clast_block *b;
1312 struct clast_term *t;
1314 if ((!infos->options->csp) &&
1315 (level+(*scalar) <= infos->nb_scattdims) &&
1316 (infos->scaldims[level+(*scalar)-1]))
1318 while (cloog_loop_block (loop) == NULL)
1319 loop = cloog_loop_inner (loop) ;
1321 while ((level+(*scalar) <= infos->nb_scattdims) &&
1322 (infos->scaldims[level+(*scalar)-1])) {
1323 if (infos->options->block) {
1324 b = new_clast_block();
1325 **next = &b->stmt;
1326 *next = &b->body;
1329 t = new_clast_term (cloog_loop_block (loop)->scaldims[*scalar], NULL);
1330 **next = &new_clast_assignment(cloog_names_scalar_elt (infos->names, *scalar),
1331 &t->expr)->stmt;
1332 *next = &(**next)->next;
1333 (*scalar) ++ ;
1338 return;
1343 * insert_block function:
1344 * This function inserts a statement block.
1345 * - block is the statement block,
1346 * - level is the number of loops enclosing the statement,
1347 * - the infos structure gives the user some options about code printing,
1348 * the number of parameters in domain (nb_par), and the arrays of iterator
1349 * names and parameters (iters and params).
1351 * - September 21th 2003: first version (pick from pprint function).
1353 static void insert_block(CloogBlock *block, int level,
1354 struct clast_stmt ***next, CloogInfos *infos)
1356 CloogStatement * statement ;
1357 struct clast_stmt *subs;
1359 if (!block)
1360 return;
1362 for (statement = cloog_block_stmt (block); statement;
1363 statement = cloog_statement_next (statement)) {
1364 if (infos->options->cpp == 0)
1365 subs = clast_equal(infos);
1366 else
1367 subs = clast_equal_cpp(level,infos);
1369 **next = &new_clast_user_stmt(statement, subs)->stmt;
1370 *next = &(**next)->next;
1374 static CloogMatrix *
1375 cloog_simplify_domain_matrix_with_equalities (CloogDomain *domain, int level,
1376 CloogMatrix *equal, int nb_parameters)
1378 CloogMatrix *temp, *res;
1380 /* FIXME: the access to ->_polyhedron is a hack to avoid exporting
1381 the CloogMatrix in a .h file: the whole clast.c file should be
1382 rewritten specifically to Polylib and PPL. */
1384 temp = cloog_upol_domain2matrix (cloog_domain_upol (domain));
1385 cloog_matrix_normalize (temp, level);
1386 res = cloog_matrix_simplify (temp, equal, level, nb_parameters);
1387 cloog_matrix_free(temp);
1389 return res;
1394 * insert_loop function:
1395 * This function concerts the content of a CloogLoop structure (loop) into a
1396 * clast_stmt (inserted at **next).
1397 * The iterator (level) of
1398 * the current loop is given by 'level': this is the column number of the
1399 * domain corresponding to the current loop iterator. The data of a loop are
1400 * written in this order:
1401 * 1. The guard of the loop, i.e. each constraint in the domain that do not
1402 * depend on the iterator (when the entry in the column 'level' is 0).
1403 * 2. The iteration domain of the iterator, given by the constraints in the
1404 * domain depending on the iterator, i.e.:
1405 * * an equality if the iterator has only one value (possibly preceded by
1406 * a guard verifying if this value is integral), *OR*
1407 * * a loop from the minimum possible value of the iterator to the maximum
1408 * possible value.
1409 * 3. The included statement block.
1410 * 4. The inner loops (recursive call).
1411 * 5. The following loops (recursive call).
1412 * - level is the recursion level or the iteration level that we are printing,
1413 * - the infos structure gives the user some options about code printing,
1414 * the number of parameters in domain (nb_par), and the arrays of iterator
1415 * names and parameters (iters and params).
1417 * - November 2nd 2001: first version.
1418 * - March 6th 2003: infinite domain support.
1419 * - April 19th 2003: (debug) NULL loop support.
1420 * - June 29th 2003: non-unit strides support.
1421 * - April 28th 2005: (debug) level is level+equality when print statement!
1422 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1423 * added to avoid iteration duplication (see DaeGon Kim
1424 * bug in cloog_program_generate). Try vasilache.cloog
1425 * with and without the call to cloog_matrix_normalize,
1426 * using -f 8 -l 9 options for an idea.
1427 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1428 * - October 16th 2005: (debug) scalar value is saved for next loops.
1430 static void insert_loop(CloogLoop * loop, int level, int scalar,
1431 struct clast_stmt ***next, CloogInfos *infos)
1433 int i, equality=0, scalar_level;
1434 CloogMatrix * matrix;
1435 struct clast_stmt **top = *next;
1437 /* It can happen that loop be NULL when an input polyhedron is empty. */
1438 if (loop == NULL)
1439 return;
1441 /* The matrix has not always a shape that allows us to generate code from it,
1442 * thus we normalize it, we also simplify it with the matrix of equalities.
1444 matrix = cloog_simplify_domain_matrix_with_equalities
1445 (cloog_loop_domain (loop), level, infos->equal, cloog_names_nb_parameters (infos->names));
1446 value_assign(infos->stride[level-1], loop->stride);
1448 /* First of all we have to print the guard. */
1449 insert_guard(matrix,level, next, infos);
1451 /* Then we print scalar dimensions. */
1452 scalar_level = scalar ;
1453 insert_scalar(loop,level,&scalar, next, infos);
1455 if ((matrix->NbColumns - 2 - cloog_names_nb_parameters (infos->names) >= level)) {
1456 /* We scan all the constraints to know in which case we are :
1457 * [[if] equality] or [for].
1459 for (i=0;i<matrix->NbRows;i++)
1460 if (value_zero_p(matrix->p[i][0]) &&
1461 value_notzero_p(matrix->p[i][level]))
1462 { /* If there is an equality, we can print it directly -no ambiguity-.
1463 * PolyLib can give more than one equality, we use just the first one
1464 * (this is a PolyLib problem, but all equalities are equivalent).
1466 insert_equality(matrix,i,level, next, infos);
1467 equality = 1 ;
1468 break ;
1471 if (!equality)
1472 insert_for(matrix, level, next, infos);
1475 /* Finally, if there is an included statement block, print it. */
1476 insert_block(cloog_loop_block (loop), level+equality, next, infos);
1478 /* Go to the next level. */
1479 if (cloog_loop_inner (loop))
1480 insert_loop(cloog_loop_inner (loop), level+1,scalar, next, infos);
1482 clast_equal_del(infos->equal,level);
1483 cloog_matrix_free(matrix);
1485 /* Go to the next loop on the same level. */
1486 while (*top)
1487 top = &(*top)->next;
1488 if (cloog_loop_next (loop))
1489 insert_loop(cloog_loop_next (loop), level,scalar_level, &top,infos);
1493 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1494 CloogOptions *options)
1496 CloogInfos *infos = ALLOC(CloogInfos);
1497 int i, nb_levels;
1498 struct clast_stmt *root = &new_clast_root(cloog_program_names (program))->stmt;
1499 struct clast_stmt **next = &root->next;
1501 infos->names = cloog_program_names (program);
1502 infos->options = options;
1503 infos->scaldims = cloog_program_scaldims (program);
1504 infos->nb_scattdims = cloog_program_nb_scattdims (program);
1506 /* Allocation for the array of strides, there is a +1 since the statement can
1507 * be included inside an external loop without iteration domain.
1509 nb_levels = cloog_names_nb_scattering (cloog_program_names (program))
1510 + cloog_names_nb_iterators (cloog_program_names (program)) + 1;
1511 infos->stride = ALLOCN(Value, nb_levels);
1512 for (i = 0; i < nb_levels; ++i)
1513 value_init_c(infos->stride[i]);
1515 infos->equal =
1516 cloog_matrix_alloc (nb_levels, nb_levels + cloog_names_nb_parameters (cloog_program_names (program)) + 1);
1518 insert_loop (cloog_program_loop (program), 1, 0, &next, infos);
1520 cloog_matrix_free(infos->equal);
1522 for (i = 0; i < nb_levels; ++i)
1523 value_clear_c(infos->stride[i]);
1524 free(infos->stride);
1525 free(infos);
1527 return root;