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