source/clast.c: detect pairs of inequalities that uniquely define a variable
[cloog.git] / source / clast.c
blobab0b545e4728db486b07b88889f403a2c047e7eb
1 #include <stdlib.h>
2 #include <assert.h>
3 #include "../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 static int clast_term_equal(struct clast_term *t1, struct clast_term *t2);
30 static int clast_binary_equal(struct clast_binary *b1, struct clast_binary *b2);
31 static int clast_reduction_equal(struct clast_reduction *r1,
32 struct clast_reduction *r2);
34 static int clast_equal_type(CloogMatrix *equal, int level, int line);
35 static int clast_equal_add(CloogMatrix *equal, CloogMatrix *matrix, int level,
36 int line, CloogInfos *infos);
37 static void clast_equal_del(CloogMatrix * equal, int level);
39 static struct clast_stmt * clast_equal(CloogInfos *infos);
40 static struct clast_stmt * clast_equal_cpp(int level, CloogInfos *infos);
41 static struct clast_expr *clast_minmax(CloogMatrix *matrix,
42 int level, int max, int guard,
43 CloogInfos *infos);
44 static void insert_guard(CloogMatrix *matrix, int level,
45 struct clast_stmt ***next, CloogInfos *infos);
46 static void insert_modulo_guard(CloogMatrix *matrix, int upper, int lower,
47 int level,
48 struct clast_stmt ***next, CloogInfos *infos);
49 static void insert_equation(CloogMatrix *matrix, int upper, int lower,
50 int level, struct clast_stmt ***next, CloogInfos *infos);
51 static void insert_for(CloogMatrix *matrix, int level,
52 struct clast_stmt ***next, CloogInfos *infos);
53 static void insert_scalar(CloogLoop *loop, int level, int *scalar,
54 struct clast_stmt ***next, CloogInfos *infos);
55 static void insert_block(CloogBlock *block, int level,
56 struct clast_stmt ***next, CloogInfos *infos);
57 static void insert_loop(CloogLoop * loop, int level, int scalar,
58 struct clast_stmt ***next, CloogInfos *infos);
61 struct clast_term *new_clast_term(Value c, const char *v)
63 struct clast_term *t = malloc(sizeof(struct clast_term));
64 t->expr.type = expr_term;
65 value_init(t->val);
66 value_assign(t->val, c);
67 t->var = v;
68 return t;
71 struct clast_binary *new_clast_binary(enum clast_bin_type t,
72 struct clast_expr *lhs, Value rhs)
74 struct clast_binary *b = malloc(sizeof(struct clast_binary));
75 b->expr.type = expr_bin;
76 b->type = t;
77 b->LHS = lhs;
78 value_init(b->RHS);
79 value_assign(b->RHS, rhs);
80 return b;
83 struct clast_reduction *new_clast_reduction(enum clast_red_type t, int n)
85 int i;
86 struct clast_reduction *r;
87 r = malloc(sizeof(struct clast_reduction)+(n-1)*sizeof(struct clast_expr *));
88 r->expr.type = expr_red;
89 r->type = t;
90 r->n = n;
91 for (i = 0; i < n; ++i)
92 r->elts[i] = NULL;
93 return r;
96 static void free_clast_root(struct clast_stmt *s);
98 struct clast_stmt_op stmt_root = { free_clast_root };
100 static void free_clast_root(struct clast_stmt *s)
102 struct clast_root *r = (struct clast_root *)s;
103 assert(CLAST_STMT_IS_A(s, stmt_root));
104 cloog_names_free(r->names);
105 free(r);
108 struct clast_root *new_clast_root(CloogNames *names)
110 struct clast_root *r = malloc(sizeof(struct clast_root));
111 r->stmt.op = &stmt_root;
112 r->stmt.next = NULL;
113 r->names = cloog_names_copy(names);
114 return r;
117 static void free_clast_assignment(struct clast_stmt *s);
119 struct clast_stmt_op stmt_ass = { free_clast_assignment };
121 static void free_clast_assignment(struct clast_stmt *s)
123 struct clast_assignment *a = (struct clast_assignment *)s;
124 assert(CLAST_STMT_IS_A(s, stmt_ass));
125 free_clast_expr(a->RHS);
126 free(a);
129 struct clast_assignment *new_clast_assignment(const char *lhs,
130 struct clast_expr *rhs)
132 struct clast_assignment *a = malloc(sizeof(struct clast_assignment));
133 a->stmt.op = &stmt_ass;
134 a->stmt.next = NULL;
135 a->LHS = lhs;
136 a->RHS = rhs;
137 return a;
140 static void free_clast_user_stmt(struct clast_stmt *s);
142 struct clast_stmt_op stmt_user = { free_clast_user_stmt };
144 static void free_clast_user_stmt(struct clast_stmt *s)
146 struct clast_user_stmt *u = (struct clast_user_stmt *)s;
147 assert(CLAST_STMT_IS_A(s, stmt_user));
148 cloog_clast_free(u->substitutions);
149 free(u);
152 struct clast_user_stmt *new_clast_user_stmt(CloogStatement *stmt,
153 struct clast_stmt *subs)
155 struct clast_user_stmt *u = malloc(sizeof(struct clast_user_stmt));
156 u->stmt.op = &stmt_user;
157 u->stmt.next = NULL;
158 u->statement = stmt;
159 u->substitutions = subs;
160 return u;
163 static void free_clast_block(struct clast_stmt *b);
165 struct clast_stmt_op stmt_block = { free_clast_block };
167 static void free_clast_block(struct clast_stmt *s)
169 struct clast_block *b = (struct clast_block *)s;
170 assert(CLAST_STMT_IS_A(s, stmt_block));
171 cloog_clast_free(b->body);
172 free(b);
175 struct clast_block *new_clast_block()
177 struct clast_block *b = malloc(sizeof(struct clast_block));
178 b->stmt.op = &stmt_block;
179 b->stmt.next = NULL;
180 b->body = NULL;
181 return b;
184 static void free_clast_for(struct clast_stmt *s);
186 struct clast_stmt_op stmt_for = { free_clast_for };
188 static void free_clast_for(struct clast_stmt *s)
190 struct clast_for *f = (struct clast_for *)s;
191 assert(CLAST_STMT_IS_A(s, stmt_for));
192 free_clast_expr(f->LB);
193 free_clast_expr(f->UB);
194 value_clear(f->stride);
195 cloog_clast_free(f->body);
196 free(f);
199 struct clast_for *new_clast_for(const char *it, struct clast_expr *LB,
200 struct clast_expr *UB, Value stride)
202 struct clast_for *f = malloc(sizeof(struct clast_for));
203 f->stmt.op = &stmt_for;
204 f->stmt.next = NULL;
205 f->iterator = it;
206 f->LB = LB;
207 f->UB = UB;
208 f->body = NULL;
209 value_init(f->stride);
210 value_assign(f->stride, stride);
211 return f;
214 static void free_clast_guard(struct clast_stmt *s);
216 struct clast_stmt_op stmt_guard = { free_clast_guard };
218 static void free_clast_guard(struct clast_stmt *s)
220 int i;
221 struct clast_guard *g = (struct clast_guard *)s;
222 assert(CLAST_STMT_IS_A(s, stmt_guard));
223 cloog_clast_free(g->then);
224 for (i = 0; i < g->n; ++i) {
225 free_clast_expr(g->eq[i].LHS);
226 free_clast_expr(g->eq[i].RHS);
228 free(g);
231 struct clast_guard *new_clast_guard(int n)
233 int i;
234 struct clast_guard *g = malloc(sizeof(struct clast_guard) +
235 (n-1) * sizeof(struct clast_equation));
236 g->stmt.op = &stmt_guard;
237 g->stmt.next = NULL;
238 g->then = NULL;
239 g->n = n;
240 for (i = 0; i < n; ++i) {
241 g->eq[i].LHS = NULL;
242 g->eq[i].RHS = NULL;
244 return g;
247 void free_clast_term(struct clast_term *t)
249 value_clear(t->val);
250 free(t);
253 void free_clast_binary(struct clast_binary *b)
255 value_clear(b->RHS);
256 free_clast_expr(b->LHS);
257 free(b);
260 void free_clast_reduction(struct clast_reduction *r)
262 int i;
263 for (i = 0; i < r->n; ++i)
264 free_clast_expr(r->elts[i]);
265 free(r);
268 void free_clast_expr(struct clast_expr *e)
270 if (!e)
271 return;
272 switch (e->type) {
273 case expr_term:
274 free_clast_term((struct clast_term*) e);
275 break;
276 case expr_red:
277 free_clast_reduction((struct clast_reduction*) e);
278 break;
279 case expr_bin:
280 free_clast_binary((struct clast_binary*) e);
281 break;
282 default:
283 assert(0);
287 void free_clast_stmt(struct clast_stmt *s)
289 assert(s->op);
290 assert(s->op->free);
291 s->op->free(s);
294 void cloog_clast_free(struct clast_stmt *s)
296 struct clast_stmt *next;
297 while (s) {
298 next = s->next;
299 free_clast_stmt(s);
300 s = next;
304 static int clast_term_equal(struct clast_term *t1, struct clast_term *t2)
306 if (t1->var != t2->var)
307 return 0;
308 return value_eq(t1->val, t2->val);
311 static int clast_binary_equal(struct clast_binary *b1, struct clast_binary *b2)
313 if (b1->type != b2->type)
314 return 0;
315 if (value_ne(b1->RHS, b2->RHS))
316 return 0;
317 return clast_expr_equal(b1->LHS, b2->LHS);
320 static int clast_reduction_equal(struct clast_reduction *r1, struct clast_reduction *r2)
322 int i;
323 if (r1->type == clast_red_max && r2->type == clast_red_min &&
324 r1->n == 1 && r2->n == 1)
325 return clast_expr_equal(r1->elts[0], r2->elts[0]);
326 if (r1->type != r2->type)
327 return 0;
328 if (r1->n != r2->n)
329 return 0;
330 for (i = 0; i < r1->n; ++i)
331 if (!clast_expr_equal(r1->elts[i], r2->elts[i]))
332 return 0;
333 return 1;
336 int clast_expr_equal(struct clast_expr *e1, struct clast_expr *e2)
338 if (!e1 && !e2)
339 return 1;
340 if (!e1 || !e2)
341 return 0;
342 if (e1->type != e2->type)
343 return 0;
344 switch (e1->type) {
345 case expr_term:
346 return clast_term_equal((struct clast_term*) e1,
347 (struct clast_term*) e2);
348 case expr_bin:
349 return clast_binary_equal((struct clast_binary*) e1,
350 (struct clast_binary*) e2);
351 case expr_red:
352 return clast_reduction_equal((struct clast_reduction*) e1,
353 (struct clast_reduction*) e2);
354 default:
355 assert(0);
360 /******************************************************************************
361 * Equalities spreading functions *
362 ******************************************************************************/
365 /* Equalities are stored inside a CloogMatrix data structure called "equal".
366 * This matrix has (nb_scattering + nb_iterators + 1) rows (i.e. total
367 * dimensions + 1, the "+ 1" is because a statement can be included inside an
368 * external loop without iteration domain), and (nb_scattering + nb_iterators +
369 * nb_parameters + 2) columns (all unknowns plus the scalar plus the equality
370 * type). The ith row corresponds to the equality "= 0" for the ith dimension
371 * iterator. The first column gives the equality type (0: no equality, then
372 * EQTYPE_* -see pprint.h-). At each recursion of pprint, if an equality for
373 * the current level is found, the corresponding row is updated. Then the
374 * equality if it exists is used to simplify expressions (e.g. if we have
375 * "i+1" while we know that "i=2", we simplify it in "3"). At the end of
376 * the pprint call, the corresponding row is reset to zero.
381 * clast_equal_type function :
382 * This function returns the type of the equality in the constraint (line) of
383 * (equal) for the element (level). An equality is 'constant' iff all other
384 * factors are null except the constant one. It is a 'pure item' iff one and
385 * only one factor is non null and is 1 or -1. Otherwise it is an 'affine
386 * expression'.
387 * For instance:
388 * i = -13 is constant, i = j, j = -M are pure items,
389 * j = 2*M, i = j+1 are affine expressions.
390 * When the equality comes from a 'one time loop', (line) is ONE_TIME_LOOP.
391 * This case require a specific treatment since we have to study all the
392 * constraints.
393 * - equal is the matrix of equalities,
394 * - level is the column number in equal of the element which is 'equal to',
395 * - line is the line number in equal of the constraint we want to study;
396 * if it is -1, all lines must be studied.
398 * - July 3rd 2002: first version, called pprint_equal_isconstant.
399 * - July 6th 2002: adaptation for the 3 types.
400 * - June 15th 2005: (debug) expr = domain->Constraint[line] was evaluated
401 * before checking if line != ONE_TIME_LOOP. Since
402 * ONE_TIME_LOOP is -1, an invalid read was possible.
403 * - October 19th 2005: Removal of the once-time-loop specific processing.
405 static int clast_equal_type(CloogMatrix *equal, int level, int line)
407 int i, one=0 ;
408 Value * expr ;
410 expr = equal->p[line] ;
412 /* There is only one non null factor, and it must be +1 or -1 for
413 * iterators or parameters.
415 for (i=1;i<=equal->NbColumns-2;i++)
416 if (value_notzero_p(expr[i]) && (i != level))
417 { if ((value_notone_p(expr[i]) && value_notmone_p(expr[i])) || (one != 0))
418 return EQTYPE_EXAFFINE ;
419 else
420 one = 1 ;
422 /* if the constant factor is non null, it must be alone. */
423 if (one != 0)
424 { if (value_notzero_p(expr[equal->NbColumns-1]))
425 return EQTYPE_EXAFFINE ;
427 else
428 return EQTYPE_CONSTANT ;
430 return EQTYPE_PUREITEM ;
435 * clast_equal_allow function:
436 * This function checks whether the options allow us to spread the equality or
437 * not. It returns 1 if so, 0 otherwise.
438 * - equal is the matrix of equalities,
439 * - level is the column number in equal of the element which is 'equal to',
440 * - line is the line number in equal of the constraint we want to study,
441 * - the infos structure gives the user all options on code printing and more.
443 * - October 27th 2005: first version (extracted from old pprint_equal_add).
445 static int clast_equal_allow(CloogMatrix *equal, int level, int line, CloogInfos *infos)
447 if ((!infos->options->csp && !infos->options->esp) ||
448 (level < infos->options->fsp))
449 return 0 ;
451 if (infos->options->csp &&
452 (clast_equal_type(equal,level,line) == EQTYPE_EXAFFINE) &&
453 !infos->options->esp)
454 return 0 ;
456 return 1 ;
461 * clast_equal_add function:
462 * This function updates the row (level-1) of the equality matrix (equal) with
463 * the row that corresponds to the row (line) of the matrix (matrix). It returns
464 * 1 if the row can be updated, 0 otherwise.
465 * - equal is the matrix of equalities,
466 * - matrix is the matrix of constraints,
467 * - level is the column number in matrix of the element which is 'equal to',
468 * - line is the line number in matrix of the constraint we want to study,
469 * - the infos structure gives the user all options on code printing and more.
471 * - July 2nd 2002: first version.
472 * - October 19th 2005: Addition of the once-time-loop specific processing.
474 static int clast_equal_add(CloogMatrix *equal, CloogMatrix *matrix, int level, int line,
475 CloogInfos *infos)
477 int i ;
478 Value numerator, denominator, division, modulo ;
480 /* If we are in the case of a loop running once, this means that the equality
481 * comes from an inequality. Here we find this inequality.
483 if (line == ONE_TIME_LOOP)
484 { for (i=0;i<matrix->NbRows;i++)
485 if ((value_notzero_p(matrix->p[i][0]))&&
486 (value_notzero_p(matrix->p[i][level])))
487 { line = i ;
489 /* Since in once-time-loops, equalities derive from inequalities, we
490 * may have to offset the values. For instance if we have 2i>=3, the
491 * equality is in fact i=2. This may happen when the level coefficient is
492 * not 1 or -1 and the scalar value is not zero. In any other case (e.g.,
493 * if the inequality is an expression including outer loop counters or
494 * parameters) the once time loop would not have been detected
495 * because of floord and ceild functions.
497 if (value_ne_si(matrix->p[i][level],1) &&
498 value_ne_si(matrix->p[i][level],-1) &&
499 value_notzero_p(matrix->p[i][matrix->NbColumns-1]))
500 { value_init_c(numerator) ;
501 value_init_c(denominator) ;
502 value_init_c(division) ;
503 value_init_c(modulo) ;
505 value_assign(denominator,matrix->p[i][level]) ;
506 value_absolute(denominator,denominator) ;
507 value_assign(numerator,matrix->p[i][matrix->NbColumns-1]) ;
508 value_modulus(modulo,numerator,denominator) ;
509 value_division(division,numerator,denominator) ;
511 /* There are 4 scenarios:
512 * di +n >= 0 --> i + (n div d) >= 0
513 * -di +n >= 0 --> -i + (n div d) >= 0
514 * di -n >= 0 --> if (n%d == 0) i + ((-n div d)+1) >= 0
515 * else i + (-n div d) >= 0
516 * -di -n >= 0 --> if (n%d == 0) -i + ((-n div d)-1) >= 0
517 * else -i + (-n div d) >= 0
518 * In the following we distinct the scalar value setting and the
519 * level coefficient.
521 if (value_pos_p(numerator) || value_zero_p(modulo))
522 value_assign(matrix->p[i][matrix->NbColumns-1],division) ;
523 else
524 { if (value_pos_p(matrix->p[i][level]))
525 value_increment(matrix->p[i][matrix->NbColumns-1],division) ;
526 else
527 value_decrement(matrix->p[i][matrix->NbColumns-1],division) ;
530 if (value_pos_p(matrix->p[i][level]))
531 value_set_si(matrix->p[i][level],1) ;
532 else
533 value_set_si(matrix->p[i][level],-1) ;
535 value_clear_c(numerator) ;
536 value_clear_c(denominator) ;
537 value_clear_c(division) ;
538 value_clear_c(modulo) ;
541 break ;
545 /* We update the line of equal corresponding to level:
546 * - the first element gives the equality type,
548 value_set_si(equal->p[level-1][0],clast_equal_type(matrix,level,line)) ;
549 /* - the other elements corresponding to the equality itself
550 * (the iterators up to level, then the parameters and the scalar).
552 for (i=1;i<=level;i++)
553 value_assign(equal->p[level-1][i],matrix->p[line][i]) ;
554 for (i=0;i<infos->names->nb_parameters+1;i++)
555 value_assign(equal->p[level-1][equal->NbColumns-i-1],
556 matrix->p[line][matrix->NbColumns-i-1]) ;
558 cloog_matrix_equality_update(equal,level,infos->names->nb_parameters) ;
560 return (clast_equal_allow(equal,level,level-1,infos)) ;
565 * clast_equal_del function :
566 * This function reset the equality corresponding to the iterator (level)
567 * in the equality matrix (equal).
568 * - July 2nd 2002: first version.
570 static void clast_equal_del(CloogMatrix * equal, int level)
572 int i ;
574 for (i=0;i<equal->NbColumns;i++)
575 value_set_si(equal->p[level-1][i],0) ;
582 * clast_equal function:
583 * This function returns the content an equality matrix (equal) into a clast_stmt.
584 * - the infos structure gives the user all options on code printing and more.
586 * - July 2nd 2002: first version.
587 * - March 16th 2003: return now a string instead of printing directly and do
588 * not write 'Sx()' if there is no spreading, but only 'Sx'.
590 static struct clast_stmt * clast_equal(CloogInfos *infos)
592 int i, iterator ;
593 Value type ;
594 struct clast_expr *e;
595 struct clast_stmt *a = NULL;
596 struct clast_stmt **next = &a;
597 CloogMatrix *equal = infos->equal;
599 value_init_c(type) ;
601 /* It is not necessary to print here the scattering iterators since they
602 * never appear in the statement bodies.
604 for (i=infos->names->nb_scattering;i<equal->NbRows;i++)
605 { if (value_notzero_p(equal->p[i][0])&&clast_equal_allow(equal,i+1,i,infos)) {
606 iterator = i - infos->names->nb_scattering ;
608 /* pprint_line needs to know that the current line is an equality, so
609 * we temporary remove the equality type and set it to zero (the equality
610 * tag in PolyLib.
612 value_assign(type,equal->p[i][0]) ;
613 value_set_si(equal->p[i][0],0) ;
614 e = clast_bound_from_constraint(equal, i, i+1, infos->names);
615 value_assign(equal->p[i][0],type) ;
616 *next = &new_clast_assignment(infos->names->iterators[iterator], e)->stmt;
617 next = &(*next)->next;
620 value_clear_c(type) ;
622 return a;
627 * clast_equal_cpp function:
628 * This function prints the substitution data of a statement into a clast_stmt.
629 * Using this function instead of pprint_equal is useful for generating
630 * a compilable pseudo-code by using preprocessor macro for each statement.
631 * By opposition to pprint_equal, the result is less human-readable. For
632 * instance this function will print (i,i+3,k,3) where pprint_equal would
633 * return (j=i+3,l=3).
634 * - level is the number of loops enclosing the statement,
635 * - the infos structure gives the user all options on code printing and more.
637 * - March 12th 2004: first version.
638 * - November 21th 2005: (debug) now works well with GMP version.
640 static struct clast_stmt * clast_equal_cpp(int level, CloogInfos *infos)
642 int i ;
643 Value type ;
644 struct clast_expr *e;
645 struct clast_stmt *a = NULL;
646 struct clast_stmt **next = &a;
647 CloogMatrix *equal = infos->equal;
649 value_init_c(type) ;
651 for (i=infos->names->nb_scattering;i<level-1;i++)
652 { if (value_notzero_p(equal->p[i][0]))
653 { /* pprint_line needs to know that the current line is an equality, so
654 * we temporary remove the equality type and set it to zero (the equality
655 * tag in PolyLib.
657 value_assign(type,equal->p[i][0]) ;
658 value_set_si(equal->p[i][0],0) ;
659 e = clast_bound_from_constraint(equal, i, i+1, infos->names);
660 value_assign(equal->p[i][0],type) ;
661 } else {
662 value_set_si(type, 1);
663 e = &new_clast_term(type,
664 infos->names->iterators[i-infos->names->nb_scattering])->expr;
666 *next = &new_clast_assignment(NULL, e)->stmt;
667 next = &(*next)->next;
669 value_clear_c(type) ;
671 return a;
676 * clast_bound_from_constraint function:
677 * This function returns a clast_expr containing the printing of the
678 * 'right part' of a constraint according to an element.
679 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
680 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
681 * function should return 'ceild(3*i+M,2)'.
682 * - matrix is the polyhedron containing all the constraints,
683 * - line_num is the line number in domain of the constraint we want to print,
684 * - level is the column number in domain of the element we want to use,
685 * - names structure gives the user some options about code printing,
686 * the number of parameters in domain (nb_par), and the arrays of iterator
687 * names and parameters (iters and params).
689 * - November 2nd 2001: first version.
690 * - June 27th 2003: 64 bits version ready.
692 struct clast_expr *clast_bound_from_constraint(CloogMatrix *matrix,
693 int line_num, int level,
694 CloogNames *names)
696 int i, nb_iter, sign, nb_elts=0 ;
697 char * name;
698 Value * line, numerator, denominator, temp, division ;
699 struct clast_expr *e = NULL;
701 line = matrix->p[line_num] ;
702 value_init_c(temp) ;
703 value_init_c(numerator) ;
704 value_init_c(denominator) ;
706 if (value_notzero_p(line[level])) {
707 struct clast_reduction *r;
708 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
709 sign = value_pos_p(line[level]) ? -1 : 1 ;
711 for (i = 1, nb_elts = 0; i <= matrix->NbColumns - 1; ++i)
712 if (i != level && value_notzero_p(line[i]))
713 nb_elts++;
714 r = new_clast_reduction(clast_red_sum, nb_elts);
715 nb_elts = 0;
717 /* First, we have to print the iterators. */
718 nb_iter = matrix->NbColumns - 2 - names->nb_parameters;
719 for (i=1;i<=nb_iter;i++)
720 if ((i != level) && value_notzero_p(line[i])) {
721 if (i <= names->nb_scattering)
722 name = names->scattering[i-1];
723 else
724 name = names->iterators[i-names->nb_scattering-1];
726 if (sign == -1)
727 value_oppose(temp,line[i]) ;
728 else
729 value_assign(temp,line[i]) ;
731 r->elts[nb_elts++] = &new_clast_term(temp, name)->expr;
734 /* Next, the parameters. */
735 for (i=nb_iter+1;i<=matrix->NbColumns-2;i++)
736 if ((i != level) && value_notzero_p(line[i])) {
737 name = names->parameters[i-nb_iter-1];
739 if (sign == -1)
740 value_oppose(temp,line[i]) ;
741 else
742 value_assign(temp,line[i]) ;
744 r->elts[nb_elts++] = &new_clast_term(temp, name)->expr;
747 if (sign == -1)
748 { value_oppose(numerator,line[matrix->NbColumns - 1]) ;
749 value_assign(denominator,line[level]) ;
751 else
752 { value_assign(numerator,line[matrix->NbColumns - 1]) ;
753 value_oppose(denominator,line[level]) ;
756 /* Finally, the constant, and the final printing. */
757 if (nb_elts) {
758 if (value_notzero_p(numerator))
759 r->elts[nb_elts++] = &new_clast_term(numerator, NULL)->expr;
761 if (value_notone_p(line[level]) && value_notmone_p(line[level]))
762 { if (value_one_p(line[0]))
763 { if (value_pos_p(line[level]))
764 e = &new_clast_binary(clast_bin_cdiv, &r->expr, denominator)->expr;
765 else
766 e = &new_clast_binary(clast_bin_fdiv, &r->expr, denominator)->expr;
767 } else
768 e = &new_clast_binary(clast_bin_div, &r->expr, denominator)->expr;
770 else
771 e = &r->expr;
772 } else {
773 free_clast_reduction(r);
774 if (value_zero_p(numerator))
775 e = &new_clast_term(numerator, NULL)->expr;
776 else
777 { if (value_notone_p(denominator))
778 { if (value_one_p(line[0])) /* useful? */
779 { value_modulus(temp,numerator,denominator) ;
780 if (value_zero_p(temp))
781 { value_division(temp,numerator,denominator) ;
782 e = &new_clast_term(temp, NULL)->expr;
784 else
785 { value_init_c(division) ;
786 value_division(division,numerator,denominator) ;
787 if (value_neg_p(numerator)) {
788 if (value_pos_p(line[level])) {
789 /* nb<0 need max */
790 e = &new_clast_term(division, NULL)->expr;
791 } else {
792 /* nb<0 need min */
793 value_decrement(temp,division) ;
794 e = &new_clast_term(temp, NULL)->expr;
797 else
798 { if (value_pos_p(line[level]))
799 { /* nb>0 need max */
800 value_increment(temp,division) ;
801 e = &new_clast_term(temp, NULL)->expr;
803 else
804 /* nb>0 need min */
805 e = &new_clast_term(division, NULL)->expr;
807 value_clear_c(division) ;
810 else
811 e = &new_clast_binary(clast_bin_div,
812 &new_clast_term(numerator, NULL)->expr,
813 denominator)->expr;
815 else
816 e = &new_clast_term(numerator, NULL)->expr;
821 value_clear_c(temp) ;
822 value_clear_c(numerator) ;
823 value_clear_c(denominator) ;
825 return e;
830 * clast_minmax function:
831 * This function returns a clast_expr containing the printing of a minimum or a
832 * maximum of the 'right parts' of all constraints according to an element.
833 * For instance consider the constraints:
834 * -3*i +2*j -M >= 0
835 * 2*i +j >= 0
836 * -i -j +2*M >= 0
837 * if we are looking for the minimum for the element j, the function should
838 * return 'max(ceild(3*i+M,2),-2*i)'.
839 * - matrix is the polyhedron containing all the constraints,
840 * - level is the column number in domain of the element we want to use,
841 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
842 * - guard is set to 0 if there is no guard, and set to the level of the element
843 * with a guard otherwise (then the function gives the max or the min only
844 * for the constraint where the guarded coefficient is 0),
845 * - the infos structure gives the user some options about code printing,
846 * the number of parameters in domain (nb_par), and the arrays of iterator
847 * names and parameters (iters and params).
849 * - November 2nd 2001: first version.
851 static struct clast_expr *clast_minmax(CloogMatrix *matrix,
852 int level, int max, int guard,
853 CloogInfos *infos)
854 { int i, n;
855 struct clast_reduction *r;
857 for (i=0, n=0;i<matrix->NbRows;i++)
858 if (((max && value_pos_p(matrix->p[i][level])) ||
859 (!max && value_neg_p(matrix->p[i][level]))) &&
860 (!guard || value_zero_p(matrix->p[i][guard])) &&
861 (value_notzero_p(matrix->p[i][0])))
862 n++;
863 if (!n)
864 return NULL;
865 r = new_clast_reduction(max ? clast_red_max : clast_red_min, n);
867 for (i=0, n=0;i<matrix->NbRows;i++)
868 if (((max && value_pos_p(matrix->p[i][level])) ||
869 (!max && value_neg_p(matrix->p[i][level]))) &&
870 (!guard || value_zero_p(matrix->p[i][guard])) &&
871 (value_notzero_p(matrix->p[i][0])))
872 r->elts[n++] = clast_bound_from_constraint(matrix,i,level,infos->names);
874 return &r->expr;
879 * insert_guard function:
880 * This function inserts a guard in the clast.
881 * A guard on an element (level) is :
882 * -> the conjunction of all the existing constraints where the coefficient of
883 * this element is 0 if the element is an iterator,
884 * -> the conjunction of all the existing constraints if the element isn't an
885 * iterator.
886 * For instance, considering these constraints and the element j:
887 * -3*i +2*j -M >= 0
888 * 2*i +M >= 0
889 * this function should return 'if (2*i+M>=0) {'.
890 * - matrix is the polyhedron containing all the constraints,
891 * - level is the column number of the element in matrix we want to use,
892 * - the infos structure gives the user some options about code printing,
893 * the number of parameters in matrix (nb_par), and the arrays of iterator
894 * names and parameters (iters and params).
896 * - November 3rd 2001: first version.
897 * - November 14th 2001: a lot of 'purifications'.
898 * - July 31th 2002: (debug) some guard parts are no more redundants.
899 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
900 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
901 * (the need came from loop_simplify that may result in
902 * domain unions, now it should be fixed directly in
903 * cloog_loop_simplify).
905 static void insert_guard(CloogMatrix *matrix, int level,
906 struct clast_stmt ***next, CloogInfos *infos)
908 int i, j, k, l, guarded, minmax=-1, nb_and = 0, nb_iter ;
909 char * name;
910 CloogMatrix * copy ;
911 struct clast_guard *g;
912 Value one;
914 if (matrix == NULL)
915 return;
917 value_init(one);
918 value_set_si(one, 1);
920 g = new_clast_guard(2 * (matrix->NbColumns-2));
922 /* Well, it looks complicated because I wanted to have a particular, more
923 * readable, ordering, obviously this function may be far much simpler !
925 copy = cloog_matrix_copy(matrix) ;
927 nb_iter = copy->NbColumns - 2 - infos->names->nb_parameters ;
929 nb_and = 0 ;
930 /* We search for guard parts. */
931 for (i=1;i<=copy->NbColumns-2;i++)
932 for (j=0;j<copy->NbRows;j++)
933 if (value_notzero_p(copy->p[j][i]) &&
934 (value_zero_p(copy->p[j][level]) || (nb_iter < level))) {
935 struct clast_term *t;
936 if (i <= nb_iter)
937 { if (i <= infos->names->nb_scattering)
938 name = infos->names->scattering[i-1] ;
939 else
940 name = infos->names->iterators[i-infos->names->nb_scattering-1] ;
942 else
943 name = infos->names->parameters[i-(nb_iter+1)] ;
945 g->eq[nb_and].LHS = &(t = new_clast_term(one, name))->expr;
946 if (value_zero_p(copy->p[j][0])) {
947 /* put the "denominator" in the LHS */
948 value_assign(t->val, copy->p[j][i]);
949 value_set_si(copy->p[j][i], 1);
950 g->eq[nb_and].sign = 0;
951 g->eq[nb_and].RHS = clast_bound_from_constraint(copy,j,i,infos->names);
952 value_assign(copy->p[j][i], t->val);
953 } else {
954 if (value_pos_p(copy->p[j][i])) {
955 minmax = 1;
956 g->eq[nb_and].sign = 1;
957 } else {
958 minmax = 0;
959 g->eq[nb_and].sign = -1;
962 guarded = (nb_iter >= level) ? level : 0 ;
963 g->eq[nb_and].RHS = clast_minmax(copy,i,minmax,guarded,infos) ;
965 nb_and ++ ;
967 /* 'elimination' of the current constraint, this avoid to use one
968 * constraint more than once. The current line is always eliminated,
969 * and the next lines if they are in a min or a max.
971 for (k=i;k<=copy->NbColumns-2;k++)
972 value_set_si(copy->p[j][k],0) ;
974 if (minmax != -1)
975 for (l=j+1;l<copy->NbRows;l++)
976 if (((minmax == 1) && value_pos_p(copy->p[l][i])) ||
977 ((minmax == 0) && value_neg_p(copy->p[l][i])))
978 for (k=i;k<=copy->NbColumns-2;k++)
979 value_set_si(copy->p[l][k],0) ;
981 cloog_matrix_free(copy) ;
983 g->n = nb_and;
984 if (nb_and) {
985 **next = &g->stmt;
986 *next = &g->then;
987 } else
988 free_clast_stmt(&g->stmt);
990 value_clear(one);
991 return;
995 /* Computes x, y and g such that g = gcd(a,b) and a*x+b*y = g */
996 static void Euclid(Value a, Value b, Value *x, Value *y, Value *g)
998 Value c, d, e, f, tmp;
1000 value_init(c);
1001 value_init(d);
1002 value_init(e);
1003 value_init(f);
1004 value_init(tmp);
1005 value_absolute(c, a);
1006 value_absolute(d, b);
1007 value_set_si(e, 1);
1008 value_set_si(f, 0);
1009 while(value_pos_p(d)) {
1010 value_division(tmp, c, d);
1011 value_multiply(tmp, tmp, f);
1012 value_subtract(e, e, tmp);
1013 value_division(tmp, c, d);
1014 value_multiply(tmp, tmp, d);
1015 value_subtract(c, c, tmp);
1016 value_swap(c, d);
1017 value_swap(e, f);
1019 value_assign(*g, c);
1020 if (value_zero_p(a))
1021 value_set_si(*x, 0);
1022 else if (value_pos_p(a))
1023 value_assign(*x, e);
1024 else value_oppose(*x, e);
1025 if (value_zero_p(b))
1026 value_set_si(*y, 0);
1027 else {
1028 value_multiply(tmp, a, *x);
1029 value_subtract(tmp, c, tmp);
1030 value_division(*y, tmp, b);
1032 value_clear(c);
1033 value_clear(d);
1034 value_clear(e);
1035 value_clear(f);
1036 value_clear(tmp);
1041 * insert_modulo_guard:
1042 * This function inserts a modulo guard corresponding to an equality
1043 * or a pair of inequalities.
1044 * See insert_equation.
1045 * - matrix is the polyhedron containing all the constraints,
1046 * - upper and lower are the line numbers of the constraint in matrix
1047 * we want to print; in particular, if we want to print an equality,
1048 * then lower == -1 and upper is the row of the equality; if we want
1049 * to print an inequality, then upper is the row of the upper bound
1050 * and lower in the row of the lower bound
1051 * - level is the column number of the element in matrix we want to use,
1052 * - the infos structure gives the user some options about code printing,
1053 * the number of parameters in matrix (nb_par), and the arrays of iterator
1054 * names and parameters (iters and params).
1056 static void insert_modulo_guard(CloogMatrix *matrix, int upper, int lower,
1057 int level,
1058 struct clast_stmt ***next, CloogInfos *infos)
1060 int i, j, k, nb_elts = 0, len, nb_iter, in_stride = 0, nb_par;
1061 Vector *line_vector;
1062 Value *line, val, x, y, g;
1064 if (value_one_p(matrix->p[upper][level]) ||
1065 value_mone_p(matrix->p[upper][level]))
1066 return;
1068 len = matrix->NbColumns;
1069 nb_par = infos->names->nb_parameters;
1070 nb_iter = matrix->NbColumns - 2 - nb_par;
1072 value_init_c(val);
1073 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1074 if (lower != -1) {
1075 value_addto(val, matrix->p[upper][len-1], matrix->p[lower][len-1]);
1076 value_add_int(val, val, 1);
1077 if (value_eq(val, matrix->p[lower][level])) {
1078 value_clear_c(val);
1079 return;
1083 value_init_c(x);
1084 value_init_c(y);
1085 value_init_c(g);
1087 line_vector = Vector_Alloc(len);
1088 line = line_vector->p;
1089 if (value_neg_p(matrix->p[upper][level]))
1090 Vector_Copy(matrix->p[upper]+1, line+1, len-1);
1091 else {
1092 value_set_si(val, -1);
1093 Vector_Scale(matrix->p[upper]+1, line+1, val, len-1);
1095 value_oppose(line[level], line[level]);
1096 assert(value_pos_p(line[level]));
1098 nb_elts = 0;
1099 for (i = nb_iter; i >= 1; --i) {
1100 if (i == level)
1101 continue;
1102 value_pmodulus(line[i],line[i],line[level]);
1103 if (value_zero_p(line[i]))
1104 continue;
1106 /* Look for an earlier variable that is also a multiple of line[level]
1107 * and check whether we can use the corresponding affine expression
1108 * to "reduce" the modulo guard, where reduction means that we eliminate
1109 * a variable, possibly at the expense of introducing other variables
1110 * with smaller index.
1112 for (j = level-1; j >= 0; --j) {
1113 if (value_cmp_si(infos->equal->p[j][0], EQTYPE_EXAFFINE) != 0)
1114 continue;
1115 value_modulus(val, infos->equal->p[j][1+j], line[level]);
1116 if (value_notzero_p(val))
1117 continue;
1118 value_modulus(val, infos->equal->p[j][i], line[level]);
1119 if (value_zero_p(val))
1120 continue;
1121 for (k = j; k > i; --k) {
1122 if (value_zero_p(infos->equal->p[j][k]))
1123 continue;
1124 value_modulus(val, infos->equal->p[j][k], line[level]);
1125 if (value_notzero_p(val))
1126 break;
1128 if (k > i)
1129 continue;
1130 Euclid(infos->equal->p[j][i], line[level], &x, &y, &g);
1131 value_modulus(val, line[i], g);
1132 if (value_notzero_p(val))
1133 continue;
1134 value_division(val, line[i], g);
1135 value_oppose(val, val);
1136 value_multiply(val, val, x);
1137 value_set_si(y, 1);
1138 /* Add (infos->equal->p[j][i])^{-1} * line[i] times the equality */
1139 Vector_Combine(line+1, infos->equal->p[j]+1, line+1, y, val, i);
1140 Vector_Combine(line+len-nb_par-1,
1141 infos->equal->p[j]+infos->equal->NbColumns-nb_par-1,
1142 line+len-nb_par-1, y, val, nb_par+1);
1143 break;
1145 if (j >= 0) {
1146 value_pmodulus(line[i],line[i],line[level]);
1147 assert(value_zero_p(line[i]));
1148 continue;
1151 value_modulus(val,infos->stride[i-1],line[level]);
1152 /* We need to know if an element of the equality has not to be printed
1153 * because of a stride that guarantees that this element can be divided by
1154 * the current coefficient. Because when there is a constant element, it
1155 * is included in the stride calculation (more exactly in the strided
1156 * iterator new lower bound: the 'offset') and we have not to print it.
1158 if (lower == -1 && value_zero_p(val)) {
1159 in_stride = 1;
1160 continue;
1163 nb_elts++;
1165 for (i = nb_iter+1; i <= len-1; ++i) {
1166 value_pmodulus(line[i],line[i],line[level]);
1167 if (value_zero_p(line[i]))
1168 continue;
1169 if (i <= len-2)
1170 nb_elts++;
1173 if (nb_elts || (value_notzero_p(line[len-1]) && (!in_stride))) {
1174 struct clast_reduction *r;
1175 struct clast_expr *e;
1176 struct clast_guard *g;
1177 char * name;
1179 r = new_clast_reduction(clast_red_sum, nb_elts+1);
1180 nb_elts = 0;
1182 /* First, the modulo guard : the iterators... */
1183 for (i=1;i<=nb_iter;i++) {
1184 if (i == level || value_zero_p(line[i]))
1185 continue;
1186 value_modulus(val,infos->stride[i-1],line[level]);
1187 if (value_zero_p(val))
1188 continue;
1190 if (i <= infos->names->nb_scattering)
1191 name = infos->names->scattering[i-1];
1192 else
1193 name = infos->names->iterators[i-infos->names->nb_scattering-1];
1195 r->elts[nb_elts++] = &new_clast_term(line[i], name)->expr;
1198 /* ...the parameters... */
1199 for (i=nb_iter+1;i<=len-2;i++) {
1200 if (value_zero_p(line[i]))
1201 continue;
1203 name = infos->names->parameters[i-nb_iter-1] ;
1204 r->elts[nb_elts++] = &new_clast_term(line[i], name)->expr;
1207 /* ...the constant. */
1208 if (value_notzero_p(line[len-1]))
1209 r->elts[nb_elts++] = &new_clast_term(line[len-1], NULL)->expr;
1211 /* our initial computation may have been an overestimate */
1212 r->n = nb_elts;
1214 e = &new_clast_binary(clast_bin_mod, &r->expr, line[level])->expr;
1215 g = new_clast_guard(1);
1216 if (lower == -1) {
1217 g->eq[0].LHS = e;
1218 value_set_si(val, 0);
1219 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1220 g->eq[0].sign = 0;
1221 } else {
1222 g->eq[0].LHS = e;
1223 value_addto(val, matrix->p[upper][len-1], matrix->p[lower][len-1]);
1224 g->eq[0].RHS = &new_clast_term(val, NULL)->expr;
1225 g->eq[0].sign = -1;
1228 **next = &g->stmt;
1229 *next = &g->then;
1232 Vector_Free(line_vector);
1234 value_clear_c(val);
1235 value_clear_c(x);
1236 value_clear_c(y);
1237 value_clear_c(g);
1242 * insert_equation function:
1243 * This function inserts an equality
1244 * constraint according to an element in the clast.
1245 * An equality can be preceded by a 'modulo guard'.
1246 * For instance, consider the constraint i -2*j = 0 and the
1247 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1248 * - matrix is the polyhedron containing all the constraints,
1249 * - num is the line number of the constraint in matrix we want to print,
1250 * - level is the column number of the element in matrix we want to use,
1251 * - the infos structure gives the user some options about code printing,
1252 * the number of parameters in matrix (nb_par), and the arrays of iterator
1253 * names and parameters (iters and params).
1255 * - November 13th 2001: first version.
1256 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1257 * modulo is 0, compare vivien or vivien2 with a previous
1258 * version for an idea).
1259 * - June 29th 2003: non-unit strides support.
1260 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1261 * it was previously included in a stride calculation.
1263 static void insert_equation(CloogMatrix *matrix, int upper, int lower,
1264 int level, struct clast_stmt ***next, CloogInfos *infos)
1266 struct clast_expr *e;
1267 struct clast_assignment *ass;
1269 insert_modulo_guard(matrix, upper, lower, level, next, infos);
1271 if (lower != -1 || !clast_equal_add(infos->equal, matrix, level, upper, infos))
1272 { /* Finally, the equality. */
1274 /* If we have to make a block by dimension, we start the block. Function
1275 * pprint knows if there is an equality, if this is the case, it checks
1276 * for the same following condition to close the brace.
1278 if (infos->options->block) {
1279 struct clast_block *b = new_clast_block();
1280 **next = &b->stmt;
1281 *next = &b->body;
1284 e = clast_bound_from_constraint(matrix, upper, level, infos->names);
1285 if (level <= infos->names->nb_scattering)
1286 ass = new_clast_assignment(infos->names->scattering[level-1], e);
1287 else
1288 ass = new_clast_assignment(
1289 infos->names->iterators[level-infos->names->nb_scattering-1], e);
1291 **next = &ass->stmt;
1292 *next = &(**next)->next;
1295 return;
1300 * insert_for function:
1301 * This function inserts a for loop in the clast.
1302 * A loop header according to an element is the conjonction of a minimum and a
1303 * maximum on the element (they give the loop bounds).
1304 * For instance, considering these constraints and the element j:
1305 * i + j -9*M >= 0
1306 * -j +5*M >= 0
1307 * j -4*M >= 0
1308 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1309 * - matrix is the polyhedron containing all the constraints,
1310 * - level is the column number of the element in matrix we want to use,
1311 * - the infos structure gives the user some options about code printing,
1312 * the number of parameters in matrix (nb_par), and the arrays of iterator
1313 * names and parameters (iters and params).
1315 * - July 2nd 2002: first version (pick from pprint function).
1316 * - March 6th 2003: infinite domain support.
1317 * - June 29th 2003: non-unit strides support.
1319 static void insert_for(CloogMatrix *matrix, int level,
1320 struct clast_stmt ***next, CloogInfos *infos)
1322 char * iterator ;
1323 struct clast_expr *e1;
1324 struct clast_expr *e2;
1325 struct clast_assignment *ass;
1327 if (level <= infos->names->nb_scattering)
1328 iterator = infos->names->scattering[level-1] ;
1329 else
1330 iterator = infos->names->iterators[level-infos->names->nb_scattering-1] ;
1332 e1 = clast_minmax(matrix,level,1,0,infos) ;
1333 e2 = clast_minmax(matrix,level,0,0,infos) ;
1335 /* If min and max are not equal there is a 'for' else, there is a '='.
1336 * In the special case e1 = e2 = NULL, this is an infinite loop
1337 * so this is not a '='.
1339 if (!clast_expr_equal(e1, e2) || !infos->options->otl || (!e1 && !e2)) {
1340 struct clast_for *f = new_clast_for(iterator, e1, e2, infos->stride[level-1]);
1341 **next = &f->stmt;
1342 *next = &f->body;
1344 else if (!clast_equal_add(infos->equal,matrix,level,ONE_TIME_LOOP,infos)) {
1345 if (infos->options->block) {
1346 struct clast_block *b = new_clast_block();
1347 **next = &b->stmt;
1348 *next = &b->body;
1350 ass = new_clast_assignment(iterator, e1);
1351 **next = &ass->stmt;
1352 *next = &(**next)->next;
1355 return;
1360 * insert_scalar function:
1361 * This function inserts assignments to the scalar values
1362 * that follows the level (level). It finds by scanning (loop) by inner level,
1363 * the first CloogBlock data structure (at this step, all blocks has the same
1364 * scalar vector information after (level)), and prints all the adjacent
1365 * scalar values following (level), if it is required by options in (info).
1366 * - loop is the loop structure to begin the search for a block,
1367 * - level is the current loop level,
1368 * - scalar points to the number of scalar values already visited,
1369 * - the infos structure gives the user options about code printing and more.
1371 * - September 12th 2005: first version.
1373 static void insert_scalar(CloogLoop *loop, int level, int *scalar,
1374 struct clast_stmt ***next, CloogInfos *infos)
1376 struct clast_block *b;
1377 struct clast_term *t;
1379 if ((!infos->options->csp) &&
1380 (level+(*scalar) <= infos->nb_scattdims) &&
1381 (infos->scaldims[level+(*scalar)-1]))
1382 { while (loop->block == NULL)
1383 loop = loop->inner ;
1385 while ((level+(*scalar) <= infos->nb_scattdims) &&
1386 (infos->scaldims[level+(*scalar)-1])) {
1387 if (infos->options->block) {
1388 b = new_clast_block();
1389 **next = &b->stmt;
1390 *next = &b->body;
1393 t = new_clast_term(loop->block->scaldims[(*scalar)], NULL);
1394 **next = &new_clast_assignment(infos->names->scalars[(*scalar)],
1395 &t->expr)->stmt;
1396 *next = &(**next)->next;
1397 (*scalar) ++ ;
1402 return;
1407 * insert_block function:
1408 * This function inserts a statement block.
1409 * - block is the statement block,
1410 * - level is the number of loops enclosing the statement,
1411 * - the infos structure gives the user some options about code printing,
1412 * the number of parameters in domain (nb_par), and the arrays of iterator
1413 * names and parameters (iters and params).
1415 * - September 21th 2003: first version (pick from pprint function).
1417 static void insert_block(CloogBlock *block, int level,
1418 struct clast_stmt ***next, CloogInfos *infos)
1420 CloogStatement * statement ;
1421 struct clast_stmt *subs;
1423 if (!block)
1424 return;
1426 for (statement = block->statement; statement; statement = statement->next) {
1427 if (infos->options->cpp == 0)
1428 subs = clast_equal(infos);
1429 else
1430 subs = clast_equal_cpp(level,infos);
1432 **next = &new_clast_user_stmt(statement, subs)->stmt;
1433 *next = &(**next)->next;
1438 /* Check if the variable at position level is defined by an
1439 * equality. If so, return the row number. Otherwise, return -1.
1441 static int defining_equality(CloogMatrix *matrix, int level)
1443 int i;
1445 for (i = 0; i < matrix->NbRows; i++)
1446 if (value_zero_p(matrix->p[i][0]) &&
1447 value_notzero_p(matrix->p[i][level]))
1448 return i;
1449 return -1;
1452 /* Check if two vectors are eachothers opposite.
1453 * Return 1 if they are, 0 if they are not.
1455 static int Vector_Opposite(Value *p1, Value *p2, unsigned len)
1457 int i;
1459 for (i = 0; i < len; ++i) {
1460 if (value_abs_ne(p1[i], p2[i]))
1461 return 0;
1462 if (value_zero_p(p1[i]))
1463 continue;
1464 if (value_eq(p1[i], p2[i]))
1465 return 0;
1467 return 1;
1470 /* Check if the variable (e) at position level is defined by a
1471 * pair of inequalities
1472 * <a, i> + -m e + <b, p> + k1 >= 0
1473 * <-a, i> + m e + <-b, p> + k2 >= 0
1474 * with 0 <= k1 + k2 < m
1475 * If so return the row number of the upper bound and set *lower
1476 * to the row number of the lower bound. If not, return -1.
1478 * If the variable at position level occurs in any other constraint,
1479 * then we currently return -1. The modulo guard that we would generate
1480 * would still be correct, but we would also need to generate
1481 * guards corresponding to the other constraints, and this has not
1482 * been implemented yet.
1484 static int defining_inequalities(CloogMatrix *matrix, int level, int *lower,
1485 CloogInfos *infos)
1487 int i, j, k;
1488 Value m;
1489 unsigned len = matrix->NbColumns - 2;
1490 unsigned nb_par = infos->names->nb_parameters;
1491 unsigned nb_iter = len - nb_par;
1493 for (i = 0; i < matrix->NbRows; i++) {
1494 if (value_zero_p(matrix->p[i][level]))
1495 continue;
1496 if (value_zero_p(matrix->p[i][0]))
1497 return -1;
1498 if (value_one_p(matrix->p[i][level]))
1499 return -1;
1500 if (value_mone_p(matrix->p[i][level]))
1501 return -1;
1502 if (First_Non_Zero(matrix->p[i]+level+1,
1503 (1+nb_iter)-(level+1)) != -1)
1504 return -1;
1505 for (j = i+1; j < matrix->NbRows; ++j) {
1506 if (value_zero_p(matrix->p[j][level]))
1507 continue;
1508 if (value_zero_p(matrix->p[j][0]))
1509 return -1;
1510 if (value_one_p(matrix->p[j][level]))
1511 return -1;
1512 if (value_mone_p(matrix->p[j][level]))
1513 return -1;
1514 if (First_Non_Zero(matrix->p[j]+level+1,
1515 (1+nb_iter)-(level+1)) != -1)
1516 return -1;
1518 value_init(m);
1519 value_addto(m, matrix->p[i][1+len], matrix->p[j][1+len]);
1520 if (value_neg_p(m) ||
1521 value_abs_ge(m, matrix->p[i][level])) {
1522 value_clear(m);
1523 return -1;
1525 value_clear(m);
1527 if (!Vector_Opposite(matrix->p[i]+1, matrix->p[j]+1,
1528 len))
1529 return -1;
1530 for (k = j+1; k < matrix->NbRows; ++k)
1531 if (value_notzero_p(matrix->p[k][level]))
1532 return -1;
1533 if (value_pos_p(matrix->p[i][level])) {
1534 *lower = i;
1535 return j;
1536 } else {
1537 *lower = j;
1538 return i;
1542 return -1;
1547 * insert_loop function:
1548 * This function concerts the content of a CloogLoop structure (loop) into a
1549 * clast_stmt (inserted at **next).
1550 * The iterator (level) of
1551 * the current loop is given by 'level': this is the column number of the
1552 * domain corresponding to the current loop iterator. The data of a loop are
1553 * written in this order:
1554 * 1. The guard of the loop, i.e. each constraint in the domain that do not
1555 * depend on the iterator (when the entry in the column 'level' is 0).
1556 * 2. The iteration domain of the iterator, given by the constraints in the
1557 * domain depending on the iterator, i.e.:
1558 * * an equality if the iterator has only one value (possibly preceded by
1559 * a guard verifying if this value is integral), *OR*
1560 * * a loop from the minimum possible value of the iterator to the maximum
1561 * possible value.
1562 * 3. The included statement block.
1563 * 4. The inner loops (recursive call).
1564 * 5. The following loops (recursive call).
1565 * - level is the recursion level or the iteration level that we are printing,
1566 * - the infos structure gives the user some options about code printing,
1567 * the number of parameters in domain (nb_par), and the arrays of iterator
1568 * names and parameters (iters and params).
1570 * - November 2nd 2001: first version.
1571 * - March 6th 2003: infinite domain support.
1572 * - April 19th 2003: (debug) NULL loop support.
1573 * - June 29th 2003: non-unit strides support.
1574 * - April 28th 2005: (debug) level is level+equality when print statement!
1575 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1576 * added to avoid iteration duplication (see DaeGon Kim
1577 * bug in cloog_program_generate). Try vasilache.cloog
1578 * with and without the call to cloog_matrix_normalize,
1579 * using -f 8 -l 9 options for an idea.
1580 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1581 * - October 16th 2005: (debug) scalar value is saved for next loops.
1583 static void insert_loop(CloogLoop * loop, int level, int scalar,
1584 struct clast_stmt ***next, CloogInfos *infos)
1586 int i, j, equality=0, scalar_level;
1587 CloogMatrix * matrix, * temp;
1588 struct clast_stmt **top = *next;
1590 /* It can happen that loop be NULL when an input polyhedron is empty. */
1591 if (loop == NULL)
1592 return;
1594 /* The matrix has not always a shape that allows us to generate code from it,
1595 * thus we normalize it, we also simplify it with the matrix of equalities.
1597 temp = cloog_domain_domain2matrix(loop->domain);
1598 cloog_matrix_normalize(temp,level);
1599 matrix = cloog_matrix_simplify(temp,infos->equal,level,
1600 infos->names->nb_parameters);
1601 cloog_matrix_free(temp);
1602 value_assign(infos->stride[level-1],loop->stride);
1604 /* First of all we have to print the guard. */
1605 insert_guard(matrix,level, next, infos);
1607 /* Then we print scalar dimensions. */
1608 scalar_level = scalar ;
1609 insert_scalar(loop,level,&scalar, next, infos);
1611 if ((matrix->NbColumns - 2 - infos->names->nb_parameters >= level)) {
1612 /* We scan all the constraints to know in which case we are :
1613 * [[if] equation] or [for].
1615 if ((i = defining_equality(matrix, level)) != -1) {
1616 /* If there is an equality, we can print it directly -no ambiguity-.
1617 * PolyLib can give more than one equality, we use just the first one
1618 * (this is a PolyLib problem, but all equalities are equivalent).
1620 insert_equation(matrix, i, -1, level, next, infos);
1621 equality = 1 ;
1622 } else if ((i = defining_inequalities(matrix, level, &j, infos)) != -1) {
1623 insert_equation(matrix, i, j, level, next, infos);
1624 } else
1625 insert_for(matrix, level, next, infos);
1628 /* Finally, if there is an included statement block, print it. */
1629 insert_block(loop->block, level+equality, next, infos);
1631 /* Go to the next level. */
1632 if (loop->inner != NULL)
1633 insert_loop(loop->inner, level+1,scalar, next, infos);
1635 clast_equal_del(infos->equal,level);
1636 cloog_matrix_free(matrix);
1638 /* Go to the next loop on the same level. */
1639 while (*top)
1640 top = &(*top)->next;
1641 if (loop->next != NULL)
1642 insert_loop(loop->next, level,scalar_level, &top,infos);
1646 struct clast_stmt *cloog_clast_create(CloogProgram *program,
1647 CloogOptions *options)
1649 CloogInfos *infos = ALLOC(CloogInfos);
1650 int i, nb_levels;
1651 struct clast_stmt *root = &new_clast_root(program->names)->stmt;
1652 struct clast_stmt **next = &root->next;
1654 infos->names = program->names;
1655 infos->options = options;
1656 infos->scaldims = program->scaldims;
1657 infos->nb_scattdims = program->nb_scattdims;
1659 /* Allocation for the array of strides, there is a +1 since the statement can
1660 * be included inside an external loop without iteration domain.
1662 nb_levels = program->names->nb_scattering+program->names->nb_iterators+1;
1663 infos->stride = ALLOCN(Value, nb_levels);
1664 for (i = 0; i < nb_levels; ++i)
1665 value_init_c(infos->stride[i]);
1667 infos->equal = cloog_matrix_alloc(nb_levels,
1668 nb_levels + program->names->nb_parameters + 1);
1670 insert_loop(program->loop, 1, 0, &next, infos);
1672 cloog_matrix_free(infos->equal);
1674 for (i = 0; i < nb_levels; ++i)
1675 value_clear_c(infos->stride[i]);
1676 free(infos->stride);
1677 free(infos);
1679 return root;