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