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. */
20 int nb_scattdims
; /**< Scattering dimension number. */
21 int * scaldims
; /**< Boolean array saying whether a given
22 * scattering dimension is scalar or not.
24 CloogNames
* names
; /**< Names of iterators and parameters. */
25 CloogOptions
* options
; /**< Options on CLooG's behaviour. */
26 CloogEqualities
*equal
; /**< Matrix of equalities. */
29 typedef struct clooginfos CloogInfos
;
31 static int clast_expr_cmp(struct clast_expr
*e1
, struct clast_expr
*e2
);
32 static int clast_term_cmp(struct clast_term
*t1
, struct clast_term
*t2
);
33 static int clast_binary_cmp(struct clast_binary
*b1
, struct clast_binary
*b2
);
34 static int clast_reduction_cmp(struct clast_reduction
*r1
,
35 struct clast_reduction
*r2
);
37 static struct clast_expr
*clast_expr_copy(struct clast_expr
*e
);
39 static int clast_equal_add(CloogEqualities
*equal
,
40 CloogConstraintSet
*constraints
,
41 int level
, CloogConstraint
*constraint
,
44 static struct clast_stmt
*clast_equal(int level
, CloogInfos
*infos
);
45 static struct clast_expr
*clast_minmax(CloogConstraintSet
*constraints
,
46 int level
, int max
, int guard
,
49 static void insert_guard(CloogConstraintSet
*constraints
, int level
,
50 struct clast_stmt
***next
, CloogInfos
*infos
);
51 static int insert_modulo_guard(CloogConstraint
*upper
,
52 CloogConstraint
*lower
, int level
,
53 struct clast_stmt
***next
, CloogInfos
*infos
);
54 static int insert_equation(CloogConstraint
*upper
, CloogConstraint
*lower
,
55 int level
, struct clast_stmt
***next
, CloogInfos
*infos
);
56 static int insert_for(CloogConstraintSet
*constraints
, int level
, int otl
,
57 struct clast_stmt
***next
, CloogInfos
*infos
);
58 static void insert_block(CloogBlock
*block
, int level
,
59 struct clast_stmt
***next
, CloogInfos
*infos
);
60 static void insert_loop(CloogLoop
* loop
, int level
,
61 struct clast_stmt
***next
, CloogInfos
*infos
);
64 struct clast_name
*new_clast_name(const char *name
)
66 struct clast_name
*n
= malloc(sizeof(struct clast_name
));
67 n
->expr
.type
= clast_expr_name
;
72 struct clast_term
*new_clast_term(cloog_int_t c
, struct clast_expr
*v
)
74 struct clast_term
*t
= malloc(sizeof(struct clast_term
));
75 t
->expr
.type
= clast_expr_term
;
76 cloog_int_init(t
->val
);
77 cloog_int_set(t
->val
, c
);
82 struct clast_binary
*new_clast_binary(enum clast_bin_type t
,
83 struct clast_expr
*lhs
, cloog_int_t rhs
)
85 struct clast_binary
*b
= malloc(sizeof(struct clast_binary
));
86 b
->expr
.type
= clast_expr_bin
;
89 cloog_int_init(b
->RHS
);
90 cloog_int_set(b
->RHS
, rhs
);
94 struct clast_reduction
*new_clast_reduction(enum clast_red_type t
, int n
)
97 struct clast_reduction
*r
;
98 r
= malloc(sizeof(struct clast_reduction
)+(n
-1)*sizeof(struct clast_expr
*));
99 r
->expr
.type
= clast_expr_red
;
102 for (i
= 0; i
< n
; ++i
)
107 static void free_clast_root(struct clast_stmt
*s
);
109 const struct clast_stmt_op stmt_root
= { free_clast_root
};
111 static void free_clast_root(struct clast_stmt
*s
)
113 struct clast_root
*r
= (struct clast_root
*)s
;
114 assert(CLAST_STMT_IS_A(s
, stmt_root
));
115 cloog_names_free(r
->names
);
119 struct clast_root
*new_clast_root(CloogNames
*names
)
121 struct clast_root
*r
= malloc(sizeof(struct clast_root
));
122 r
->stmt
.op
= &stmt_root
;
124 r
->names
= cloog_names_copy(names
);
128 static void free_clast_assignment(struct clast_stmt
*s
);
130 const struct clast_stmt_op stmt_ass
= { free_clast_assignment
};
132 static void free_clast_assignment(struct clast_stmt
*s
)
134 struct clast_assignment
*a
= (struct clast_assignment
*)s
;
135 assert(CLAST_STMT_IS_A(s
, stmt_ass
));
136 free_clast_expr(a
->RHS
);
140 struct clast_assignment
*new_clast_assignment(const char *lhs
,
141 struct clast_expr
*rhs
)
143 struct clast_assignment
*a
= malloc(sizeof(struct clast_assignment
));
144 a
->stmt
.op
= &stmt_ass
;
151 static void free_clast_user_stmt(struct clast_stmt
*s
);
153 const struct clast_stmt_op stmt_user
= { free_clast_user_stmt
};
155 static void free_clast_user_stmt(struct clast_stmt
*s
)
157 struct clast_user_stmt
*u
= (struct clast_user_stmt
*)s
;
158 assert(CLAST_STMT_IS_A(s
, stmt_user
));
159 cloog_statement_free(u
->statement
);
160 cloog_clast_free(u
->substitutions
);
164 struct clast_user_stmt
*new_clast_user_stmt(CloogStatement
*stmt
,
165 struct clast_stmt
*subs
)
167 struct clast_user_stmt
*u
= malloc(sizeof(struct clast_user_stmt
));
168 u
->stmt
.op
= &stmt_user
;
170 u
->statement
= cloog_statement_copy(stmt
);
171 u
->substitutions
= subs
;
175 static void free_clast_block(struct clast_stmt
*b
);
177 const struct clast_stmt_op stmt_block
= { free_clast_block
};
179 static void free_clast_block(struct clast_stmt
*s
)
181 struct clast_block
*b
= (struct clast_block
*)s
;
182 assert(CLAST_STMT_IS_A(s
, stmt_block
));
183 cloog_clast_free(b
->body
);
187 struct clast_block
*new_clast_block()
189 struct clast_block
*b
= malloc(sizeof(struct clast_block
));
190 b
->stmt
.op
= &stmt_block
;
196 static void free_clast_for(struct clast_stmt
*s
);
198 const struct clast_stmt_op stmt_for
= { free_clast_for
};
200 static void free_clast_for(struct clast_stmt
*s
)
202 struct clast_for
*f
= (struct clast_for
*)s
;
203 assert(CLAST_STMT_IS_A(s
, stmt_for
));
204 free_clast_expr(f
->LB
);
205 free_clast_expr(f
->UB
);
206 cloog_int_clear(f
->stride
);
207 cloog_clast_free(f
->body
);
211 struct clast_for
*new_clast_for(const char *it
, struct clast_expr
*LB
,
212 struct clast_expr
*UB
, CloogStride
*stride
)
214 struct clast_for
*f
= malloc(sizeof(struct clast_for
));
215 f
->stmt
.op
= &stmt_for
;
221 cloog_int_init(f
->stride
);
223 cloog_int_set(f
->stride
, stride
->stride
);
225 cloog_int_set_si(f
->stride
, 1);
229 static void free_clast_guard(struct clast_stmt
*s
);
231 const struct clast_stmt_op stmt_guard
= { free_clast_guard
};
233 static void free_clast_guard(struct clast_stmt
*s
)
236 struct clast_guard
*g
= (struct clast_guard
*)s
;
237 assert(CLAST_STMT_IS_A(s
, stmt_guard
));
238 cloog_clast_free(g
->then
);
239 for (i
= 0; i
< g
->n
; ++i
) {
240 free_clast_expr(g
->eq
[i
].LHS
);
241 free_clast_expr(g
->eq
[i
].RHS
);
246 struct clast_guard
*new_clast_guard(int n
)
249 struct clast_guard
*g
= malloc(sizeof(struct clast_guard
) +
250 (n
-1) * sizeof(struct clast_equation
));
251 g
->stmt
.op
= &stmt_guard
;
255 for (i
= 0; i
< n
; ++i
) {
262 void free_clast_name(struct clast_name
*n
)
267 void free_clast_term(struct clast_term
*t
)
269 cloog_int_clear(t
->val
);
270 free_clast_expr(t
->var
);
274 void free_clast_binary(struct clast_binary
*b
)
276 cloog_int_clear(b
->RHS
);
277 free_clast_expr(b
->LHS
);
281 void free_clast_reduction(struct clast_reduction
*r
)
284 for (i
= 0; i
< r
->n
; ++i
)
285 free_clast_expr(r
->elts
[i
]);
289 void free_clast_expr(struct clast_expr
*e
)
294 case clast_expr_name
:
295 free_clast_name((struct clast_name
*) e
);
297 case clast_expr_term
:
298 free_clast_term((struct clast_term
*) e
);
301 free_clast_reduction((struct clast_reduction
*) e
);
304 free_clast_binary((struct clast_binary
*) e
);
311 void free_clast_stmt(struct clast_stmt
*s
)
318 void cloog_clast_free(struct clast_stmt
*s
)
320 struct clast_stmt
*next
;
328 static int clast_name_cmp(struct clast_name
*n1
, struct clast_name
*n2
)
330 return n1
->name
== n2
->name
? 0 : strcmp(n1
->name
, n2
->name
);
333 static int clast_term_cmp(struct clast_term
*t1
, struct clast_term
*t2
)
336 if (!t1
->var
&& t2
->var
)
338 if (t1
->var
&& !t2
->var
)
340 c
= clast_expr_cmp(t1
->var
, t2
->var
);
343 return cloog_int_cmp(t1
->val
, t2
->val
);
346 static int clast_binary_cmp(struct clast_binary
*b1
, struct clast_binary
*b2
)
350 if (b1
->type
!= b2
->type
)
351 return b1
->type
- b2
->type
;
352 if ((c
= cloog_int_cmp(b1
->RHS
, b2
->RHS
)))
354 return clast_expr_cmp(b1
->LHS
, b2
->LHS
);
357 static int clast_reduction_cmp(struct clast_reduction
*r1
, struct clast_reduction
*r2
)
362 if (r1
->n
== 1 && r2
->n
== 1)
363 return clast_expr_cmp(r1
->elts
[0], r2
->elts
[0]);
364 if (r1
->type
!= r2
->type
)
365 return r1
->type
- r2
->type
;
367 return r1
->n
- r2
->n
;
368 for (i
= 0; i
< r1
->n
; ++i
)
369 if ((c
= clast_expr_cmp(r1
->elts
[i
], r2
->elts
[i
])))
374 static int clast_expr_cmp(struct clast_expr
*e1
, struct clast_expr
*e2
)
382 if (e1
->type
!= e2
->type
)
383 return e1
->type
- e2
->type
;
385 case clast_expr_name
:
386 return clast_name_cmp((struct clast_name
*) e1
,
387 (struct clast_name
*) e2
);
388 case clast_expr_term
:
389 return clast_term_cmp((struct clast_term
*) e1
,
390 (struct clast_term
*) e2
);
392 return clast_binary_cmp((struct clast_binary
*) e1
,
393 (struct clast_binary
*) e2
);
395 return clast_reduction_cmp((struct clast_reduction
*) e1
,
396 (struct clast_reduction
*) e2
);
402 int clast_expr_equal(struct clast_expr
*e1
, struct clast_expr
*e2
)
404 return clast_expr_cmp(e1
, e2
) == 0;
408 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
410 int clast_expr_is_bigger_constant(struct clast_expr
*e1
, struct clast_expr
*e2
)
412 struct clast_term
*t1
, *t2
;
413 struct clast_reduction
*r
;
417 if (e1
->type
== clast_expr_red
) {
418 r
= (struct clast_reduction
*)e1
;
419 return r
->n
== 1 && clast_expr_is_bigger_constant(r
->elts
[0], e2
);
421 if (e2
->type
== clast_expr_red
) {
422 r
= (struct clast_reduction
*)e2
;
423 return r
->n
== 1 && clast_expr_is_bigger_constant(e1
, r
->elts
[0]);
425 if (e1
->type
!= clast_expr_term
|| e2
->type
!= clast_expr_term
)
427 t1
= (struct clast_term
*)e1
;
428 t2
= (struct clast_term
*)e2
;
429 if (t1
->var
|| t2
->var
)
431 return cloog_int_gt(t1
->val
, t2
->val
);
434 static int qsort_expr_cmp(const void *p1
, const void *p2
)
436 return clast_expr_cmp(*(struct clast_expr
**)p1
, *(struct clast_expr
**)p2
);
439 static void clast_reduction_sort(struct clast_reduction
*r
)
441 qsort(&r
->elts
[0], r
->n
, sizeof(struct clast_expr
*), qsort_expr_cmp
);
444 static int qsort_eq_cmp(const void *p1
, const void *p2
)
446 struct clast_equation
*eq1
= (struct clast_equation
*)p1
;
447 struct clast_equation
*eq2
= (struct clast_equation
*)p2
;
450 cmp
= clast_expr_cmp(eq1
->LHS
, eq2
->LHS
);
454 cmp
= clast_expr_cmp(eq1
->RHS
, eq2
->RHS
);
458 return eq1
->sign
- eq2
->sign
;
462 * Sort equations in a clast_guard.
464 static void clast_guard_sort(struct clast_guard
*g
)
466 qsort(&g
->eq
[0], g
->n
, sizeof(struct clast_equation
), qsort_eq_cmp
);
471 * Construct a (deep) copy of an expression clast.
473 static struct clast_expr
*clast_expr_copy(struct clast_expr
*e
)
478 case clast_expr_name
: {
479 struct clast_name
* n
= (struct clast_name
*) e
;
480 return &new_clast_name(n
->name
)->expr
;
482 case clast_expr_term
: {
483 struct clast_term
* t
= (struct clast_term
*) e
;
484 return &new_clast_term(t
->val
, clast_expr_copy(t
->var
))->expr
;
486 case clast_expr_red
: {
488 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
489 struct clast_reduction
*r2
= new_clast_reduction(r
->type
, r
->n
);
490 for (i
= 0; i
< r
->n
; ++i
)
491 r2
->elts
[i
] = clast_expr_copy(r
->elts
[i
]);
494 case clast_expr_bin
: {
495 struct clast_binary
*b
= (struct clast_binary
*) e
;
496 return &new_clast_binary(b
->type
, clast_expr_copy(b
->LHS
), b
->RHS
)->expr
;
504 /******************************************************************************
505 * Equalities spreading functions *
506 ******************************************************************************/
510 * clast_equal_allow function:
511 * This function checks whether the options allow us to spread the equality or
512 * not. It returns 1 if so, 0 otherwise.
513 * - equal is the matrix of equalities,
514 * - level is the column number in equal of the element which is 'equal to',
515 * - line is the line number in equal of the constraint we want to study,
516 * - the infos structure gives the user all options on code printing and more.
518 * - October 27th 2005: first version (extracted from old pprint_equal_add).
520 static int clast_equal_allow(CloogEqualities
*equal
, int level
, int line
,
523 if (level
< infos
->options
->fsp
)
526 if ((cloog_equal_type(equal
, level
) == EQTYPE_EXAFFINE
) &&
527 !infos
->options
->esp
)
535 * clast_equal_add function:
536 * This function updates the row (level-1) of the equality matrix (equal) with
537 * the row that corresponds to the row (line) of the matrix (matrix). It returns
538 * 1 if the row can be updated, 0 otherwise.
539 * - equal is the matrix of equalities,
540 * - matrix is the matrix of constraints,
541 * - level is the column number in matrix of the element which is 'equal to',
542 * - line is the line number in matrix of the constraint we want to study,
543 * - the infos structure gives the user all options on code printing and more.
545 static int clast_equal_add(CloogEqualities
*equal
,
546 CloogConstraintSet
*constraints
,
547 int level
, CloogConstraint
*constraint
,
550 cloog_equal_add(equal
, constraints
, level
, constraint
,
551 infos
->names
->nb_parameters
);
553 return clast_equal_allow(equal
, level
, level
-1, infos
);
559 * clast_equal function:
560 * This function prints the substitution data of a statement into a clast_stmt.
561 * Using this function instead of pprint_equal is useful for generating
562 * a compilable pseudo-code by using preprocessor macro for each statement.
563 * By opposition to pprint_equal, the result is less human-readable. For
564 * instance this function will print (i,i+3,k,3) where pprint_equal would
565 * return (j=i+3,l=3).
566 * - level is the number of loops enclosing the statement,
567 * - the infos structure gives the user all options on code printing and more.
569 * - March 12th 2004: first version.
570 * - November 21th 2005: (debug) now works well with GMP version.
572 static struct clast_stmt
*clast_equal(int level
, CloogInfos
*infos
)
575 struct clast_expr
*e
;
576 struct clast_stmt
*a
= NULL
;
577 struct clast_stmt
**next
= &a
;
578 CloogEqualities
*equal
= infos
->equal
;
579 CloogConstraint
*equal_constraint
;
581 for (i
=infos
->names
->nb_scattering
;i
<level
-1;i
++)
582 { if (cloog_equal_type(equal
, i
+1)) {
583 equal_constraint
= cloog_equal_constraint(equal
, i
);
584 e
= clast_bound_from_constraint(equal_constraint
, i
+1, infos
->names
);
585 cloog_constraint_release(equal_constraint
);
587 e
= &new_clast_term(infos
->state
->one
, &new_clast_name(
588 cloog_names_name_at_level(infos
->names
, i
+1))->expr
)->expr
;
590 *next
= &new_clast_assignment(NULL
, e
)->stmt
;
591 next
= &(*next
)->next
;
599 * clast_bound_from_constraint function:
600 * This function returns a clast_expr containing the printing of the
601 * 'right part' of a constraint according to an element.
602 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
603 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
604 * function should return 'ceild(3*i+M,2)'.
605 * - matrix is the polyhedron containing all the constraints,
606 * - line_num is the line number in domain of the constraint we want to print,
607 * - level is the column number in domain of the element we want to use,
608 * - names structure gives the user some options about code printing,
609 * the number of parameters in domain (nb_par), and the arrays of iterator
610 * names and parameters (iters and params).
612 * - November 2nd 2001: first version.
613 * - June 27th 2003: 64 bits version ready.
615 struct clast_expr
*clast_bound_from_constraint(CloogConstraint
*constraint
,
616 int level
, CloogNames
*names
)
618 int i
, sign
, nb_elts
=0, len
;
619 cloog_int_t
*line
, numerator
, denominator
, temp
, division
;
620 struct clast_expr
*e
= NULL
;
621 struct cloog_vec
*line_vector
;
623 len
= cloog_constraint_total_dimension(constraint
) + 2;
624 line_vector
= cloog_vec_alloc(len
);
625 line
= line_vector
->p
;
626 cloog_constraint_copy_coefficients(constraint
, line
+1);
627 cloog_int_init(temp
);
628 cloog_int_init(numerator
);
629 cloog_int_init(denominator
);
631 if (!cloog_int_is_zero(line
[level
])) {
632 struct clast_reduction
*r
;
633 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
634 sign
= -cloog_int_sgn(line
[level
]);
636 for (i
= 1, nb_elts
= 0; i
<= len
- 1; ++i
)
637 if (i
!= level
&& !cloog_int_is_zero(line
[i
]))
639 r
= new_clast_reduction(clast_red_sum
, nb_elts
);
642 /* First, we have to print the iterators and the parameters. */
643 for (i
= 1; i
<= len
- 2; i
++) {
644 struct clast_expr
*v
;
646 if (i
== level
|| cloog_int_is_zero(line
[i
]))
649 v
= cloog_constraint_variable_expr(constraint
, i
, names
);
652 cloog_int_neg(temp
,line
[i
]);
654 cloog_int_set(temp
,line
[i
]);
656 r
->elts
[nb_elts
++] = &new_clast_term(temp
, v
)->expr
;
660 cloog_int_neg(numerator
, line
[len
- 1]);
661 cloog_int_set(denominator
, line
[level
]);
664 cloog_int_set(numerator
, line
[len
- 1]);
665 cloog_int_neg(denominator
, line
[level
]);
668 /* Finally, the constant, and the final printing. */
670 if (!cloog_int_is_zero(numerator
))
671 r
->elts
[nb_elts
++] = &new_clast_term(numerator
, NULL
)->expr
;
673 if (!cloog_int_is_one(line
[level
]) && !cloog_int_is_neg_one(line
[level
]))
674 { if (!cloog_constraint_is_equality(constraint
))
675 { if (cloog_int_is_pos(line
[level
]))
676 e
= &new_clast_binary(clast_bin_cdiv
, &r
->expr
, denominator
)->expr
;
678 e
= &new_clast_binary(clast_bin_fdiv
, &r
->expr
, denominator
)->expr
;
680 e
= &new_clast_binary(clast_bin_div
, &r
->expr
, denominator
)->expr
;
685 free_clast_reduction(r
);
686 if (cloog_int_is_zero(numerator
))
687 e
= &new_clast_term(numerator
, NULL
)->expr
;
689 { if (!cloog_int_is_one(denominator
))
690 { if (!cloog_constraint_is_equality(constraint
)) { /* useful? */
691 if (cloog_int_is_divisible_by(numerator
, denominator
)) {
692 cloog_int_divexact(temp
, numerator
, denominator
);
693 e
= &new_clast_term(temp
, NULL
)->expr
;
696 cloog_int_init(division
);
697 cloog_int_tdiv_q(division
, numerator
, denominator
);
698 if (cloog_int_is_neg(numerator
)) {
699 if (cloog_int_is_pos(line
[level
])) {
701 e
= &new_clast_term(division
, NULL
)->expr
;
704 cloog_int_sub_ui(temp
, division
, 1);
705 e
= &new_clast_term(temp
, NULL
)->expr
;
709 { if (cloog_int_is_pos(line
[level
]))
710 { /* nb>0 need max */
711 cloog_int_add_ui(temp
, division
, 1);
712 e
= &new_clast_term(temp
, NULL
)->expr
;
716 e
= &new_clast_term(division
, NULL
)->expr
;
718 cloog_int_clear(division
);
722 e
= &new_clast_binary(clast_bin_div
,
723 &new_clast_term(numerator
, NULL
)->expr
,
727 e
= &new_clast_term(numerator
, NULL
)->expr
;
732 cloog_vec_free(line_vector
);
734 cloog_int_clear(temp
);
735 cloog_int_clear(numerator
);
736 cloog_int_clear(denominator
);
742 /* Temporary structure for communication between clast_minmax and
743 * its cloog_constraint_set_foreach_constraint callback functions.
745 struct clast_minmax_data
{
752 struct clast_reduction
*r
;
756 /* Should constraint "c" be considered by clast_minmax?
758 static int valid_bound(CloogConstraint
*c
, struct clast_minmax_data
*d
)
760 if (d
->max
&& !cloog_constraint_is_lower_bound(c
, d
->level
- 1))
762 if (!d
->max
&& !cloog_constraint_is_upper_bound(c
, d
->level
- 1))
764 if (cloog_constraint_is_equality(c
))
766 if (d
->guard
&& cloog_constraint_involves(c
, d
->guard
- 1))
773 /* Increment n for each bound that should be considered by clast_minmax.
775 static int count_bounds(CloogConstraint
*c
, void *user
)
777 struct clast_minmax_data
*d
= (struct clast_minmax_data
*) user
;
779 if (!valid_bound(c
, d
))
788 /* Update the given lower bound based on stride information.
789 * In some backends, the lower bounds are updated from within
790 * cloog_loop_stride, but other backends leave the updating to
791 * this function. In the later case, the original lower bound
792 * is known to be a constant.
793 * If the bound turns out not to be a constant, we know we
794 * are in the former case and nothing needs to be done.
795 * If the bound has already been updated and it just happens
796 * to be a constant, then this function performs an identity
797 * operation on the constant.
799 static void update_lower_bound(struct clast_expr
*expr
, int level
,
802 struct clast_term
*t
;
803 if (expr
->type
!= clast_expr_term
)
805 t
= (struct clast_term
*)expr
;
808 cloog_int_sub(t
->val
, t
->val
, stride
->offset
);
809 cloog_int_cdiv_q(t
->val
, t
->val
, stride
->stride
);
810 cloog_int_mul(t
->val
, t
->val
, stride
->stride
);
811 cloog_int_add(t
->val
, t
->val
, stride
->offset
);
815 /* Add all relevant bounds to r->elts and update lower bounds
816 * based on stride information.
818 static int collect_bounds(CloogConstraint
*c
, void *user
)
820 struct clast_minmax_data
*d
= (struct clast_minmax_data
*) user
;
822 if (!valid_bound(c
, d
))
825 d
->r
->elts
[d
->n
] = clast_bound_from_constraint(c
, d
->level
,
827 if (d
->lower_bound
&& d
->infos
->stride
[d
->level
- 1]) {
828 update_lower_bound(d
->r
->elts
[d
->n
], d
->level
,
829 d
->infos
->stride
[d
->level
- 1]);
839 * clast_minmax function:
840 * This function returns a clast_expr containing the printing of a minimum or a
841 * maximum of the 'right parts' of all constraints according to an element.
842 * For instance consider the constraints:
846 * if we are looking for the minimum for the element j, the function should
847 * return 'max(ceild(3*i+M,2),-2*i)'.
848 * - constraints is the constraints,
849 * - level is the column number in domain of the element we want to use,
850 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
851 * - guard is set to 0 if there is no guard, and set to the level of the element
852 * with a guard otherwise (then the function gives the max or the min only
853 * for the constraint where the guarded coefficient is 0),
854 * - lower is set to 1 if the maximum is to be used a lower bound on a loop
855 * - the infos structure gives the user some options about code printing,
856 * the number of parameters in domain (nb_par), and the arrays of iterator
857 * names and parameters (iters and params).
859 * - November 2nd 2001: first version.
861 static struct clast_expr
*clast_minmax(CloogConstraintSet
*constraints
,
862 int level
, int max
, int guard
,
866 struct clast_minmax_data data
= { level
, max
, guard
, lower_bound
, infos
};
870 cloog_constraint_set_foreach_constraint(constraints
, count_bounds
, &data
);
874 data
.r
= new_clast_reduction(max
? clast_red_max
: clast_red_min
, data
.n
);
877 cloog_constraint_set_foreach_constraint(constraints
, collect_bounds
, &data
);
879 clast_reduction_sort(data
.r
);
880 return &data
.r
->expr
;
885 * Insert modulo guards defined by existentially quantified dimensions,
886 * not involving the given level.
888 * This function is called from within insert_guard or insert_for.
889 * Any constraint used in constructing * a modulo guard is removed
890 * from the constraint set to avoid insert_guard or insert_for
891 * adding a duplicate (pair of) constraint(s).
893 static void insert_extra_modulo_guards(CloogConstraintSet
*constraints
,
894 int level
, struct clast_stmt
***next
, CloogInfos
*infos
)
899 CloogConstraint
*upper
, *lower
;
901 total_dim
= cloog_constraint_set_total_dimension(constraints
);
902 nb_iter
= cloog_constraint_set_n_iterators(constraints
,
903 infos
->names
->nb_parameters
);
905 for (i
= total_dim
- infos
->names
->nb_parameters
; i
>= nb_iter
+ 1; i
--) {
906 if (cloog_constraint_is_valid(upper
=
907 cloog_constraint_set_defining_equality(constraints
, i
))) {
908 if (!level
|| (nb_iter
< level
) ||
909 !cloog_constraint_involves(upper
, level
-1)) {
910 insert_modulo_guard(upper
,
911 cloog_constraint_invalid(), i
, next
, infos
);
912 cloog_constraint_clear(upper
);
914 cloog_constraint_release(upper
);
915 } else if (cloog_constraint_is_valid(upper
=
916 cloog_constraint_set_defining_inequalities(constraints
,
917 i
, &lower
, infos
->names
->nb_parameters
))) {
918 if (!level
|| (nb_iter
< level
) ||
919 !cloog_constraint_involves(upper
, level
-1)) {
920 insert_modulo_guard(upper
, lower
, i
, next
, infos
);
921 cloog_constraint_clear(upper
);
922 cloog_constraint_clear(lower
);
924 cloog_constraint_release(upper
);
925 cloog_constraint_release(lower
);
931 static int clear_lower_bound_at_level(CloogConstraint
*c
, void *user
)
933 int level
= *(int *)user
;
935 if (cloog_constraint_is_lower_bound(c
, level
- 1))
936 cloog_constraint_clear(c
);
942 static int clear_upper_bound_at_level(CloogConstraint
*c
, void *user
)
944 int level
= *(int *)user
;
946 if (cloog_constraint_is_upper_bound(c
, level
- 1))
947 cloog_constraint_clear(c
);
953 /* Temporary structure for communication between insert_guard and
954 * its cloog_constraint_set_foreach_constraint callback function.
956 struct clast_guard_data
{
962 CloogConstraintSet
*copy
;
963 struct clast_guard
*g
;
967 static int guard_count_bounds(CloogConstraint
*c
, void *user
)
969 struct clast_guard_data
*d
= (struct clast_guard_data
*) user
;
977 /* Insert a guard, if necesessary, for constraint j.
979 static int insert_guard_constraint(CloogConstraint
*j
, void *user
)
981 struct clast_guard_data
*d
= (struct clast_guard_data
*) user
;
983 struct clast_expr
*v
;
984 struct clast_term
*t
;
986 if (!cloog_constraint_involves(j
, d
->i
- 1))
989 if (d
->level
&& d
->nb_iter
>= d
->level
&&
990 cloog_constraint_involves(j
, d
->level
- 1))
993 v
= cloog_constraint_variable_expr(j
, d
->i
, d
->infos
->names
);
994 d
->g
->eq
[d
->n
].LHS
= &(t
= new_clast_term(d
->infos
->state
->one
, v
))->expr
;
995 if (!d
->level
|| cloog_constraint_is_equality(j
)) {
996 /* put the "denominator" in the LHS */
997 cloog_constraint_coefficient_get(j
, d
->i
- 1, &t
->val
);
998 cloog_constraint_coefficient_set(j
, d
->i
- 1, d
->infos
->state
->one
);
999 if (cloog_int_is_neg(t
->val
)) {
1000 cloog_int_neg(t
->val
, t
->val
);
1001 cloog_constraint_coefficient_set(j
, d
->i
- 1, d
->infos
->state
->negone
);
1003 if (d
->level
|| cloog_constraint_is_equality(j
))
1004 d
->g
->eq
[d
->n
].sign
= 0;
1005 else if (cloog_constraint_is_lower_bound(j
, d
->i
- 1))
1006 d
->g
->eq
[d
->n
].sign
= 1;
1008 d
->g
->eq
[d
->n
].sign
= -1;
1009 d
->g
->eq
[d
->n
].RHS
= clast_bound_from_constraint(j
, d
->i
, d
->infos
->names
);
1013 if (cloog_constraint_is_lower_bound(j
, d
->i
- 1)) {
1015 d
->g
->eq
[d
->n
].sign
= 1;
1018 d
->g
->eq
[d
->n
].sign
= -1;
1021 guarded
= (d
->nb_iter
>= d
->level
) ? d
->level
: 0 ;
1022 d
->g
->eq
[d
->n
].RHS
= clast_minmax(d
->copy
, d
->i
, minmax
, guarded
, 0,
1027 /* 'elimination' of the current constraint, this avoid to use one
1028 * constraint more than once. The current line is always eliminated,
1029 * and the next lines if they are in a min or a max.
1031 cloog_constraint_clear(j
);
1036 cloog_constraint_set_foreach_constraint(d
->copy
,
1037 clear_lower_bound_at_level
, &d
->i
);
1038 else if (minmax
== 0)
1039 cloog_constraint_set_foreach_constraint(d
->copy
,
1040 clear_upper_bound_at_level
, &d
->i
);
1047 * insert_guard function:
1048 * This function inserts a guard in the clast.
1049 * A guard on an element (level) is :
1050 * -> the conjunction of all the existing constraints where the coefficient of
1051 * this element is 0 if the element is an iterator,
1052 * -> the conjunction of all the existing constraints if the element isn't an
1054 * For instance, considering these constraints and the element j:
1057 * this function should return 'if (2*i+M>=0) {'.
1058 * - matrix is the polyhedron containing all the constraints,
1059 * - level is the column number of the element in matrix we want to use,
1060 * - the infos structure gives the user some options about code printing,
1061 * the number of parameters in matrix (nb_par), and the arrays of iterator
1062 * names and parameters (iters and params).
1064 * - November 3rd 2001: first version.
1065 * - November 14th 2001: a lot of 'purifications'.
1066 * - July 31th 2002: (debug) some guard parts are no more redundants.
1067 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
1068 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
1069 * (the need came from loop_simplify that may result in
1070 * domain unions, now it should be fixed directly in
1071 * cloog_loop_simplify).
1073 static void insert_guard(CloogConstraintSet
*constraints
, int level
,
1074 struct clast_stmt
***next
, CloogInfos
*infos
)
1077 struct clast_guard_data data
= { level
, infos
, 0 };
1082 data
.copy
= cloog_constraint_set_copy(constraints
);
1084 insert_extra_modulo_guards(data
.copy
, level
, next
, infos
);
1086 cloog_constraint_set_foreach_constraint(constraints
,
1087 guard_count_bounds
, &data
);
1089 data
.g
= new_clast_guard(data
.n
);
1092 /* Well, it looks complicated because I wanted to have a particular, more
1093 * readable, ordering, obviously this function may be far much simpler !
1095 data
.nb_iter
= cloog_constraint_set_n_iterators(constraints
,
1096 infos
->names
->nb_parameters
);
1098 /* We search for guard parts. */
1099 total_dim
= cloog_constraint_set_total_dimension(constraints
);
1100 for (data
.i
= 1; data
.i
<= total_dim
; data
.i
++)
1101 cloog_constraint_set_foreach_constraint(data
.copy
,
1102 insert_guard_constraint
, &data
);
1104 cloog_constraint_set_free(data
.copy
);
1108 clast_guard_sort(data
.g
);
1109 **next
= &data
.g
->stmt
;
1110 *next
= &data
.g
->then
;
1112 free_clast_stmt(&data
.g
->stmt
);
1116 * Check if the constant "cst" satisfies the modulo guard that
1117 * would be introduced by insert_computed_modulo_guard.
1118 * The constant is assumed to have been reduced prior to calling
1121 static int constant_modulo_guard_is_satisfied(CloogConstraint
*lower
,
1122 cloog_int_t bound
, cloog_int_t cst
)
1124 if (cloog_constraint_is_valid(lower
))
1125 return cloog_int_le(cst
, bound
);
1127 return cloog_int_is_zero(cst
);
1131 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
1132 * depending on whether lower represents a valid constraint.
1134 static void insert_computed_modulo_guard(struct clast_reduction
*r
,
1135 CloogConstraint
*lower
, cloog_int_t mod
, cloog_int_t bound
,
1136 struct clast_stmt
***next
)
1138 struct clast_expr
*e
;
1139 struct clast_guard
*g
;
1141 e
= &new_clast_binary(clast_bin_mod
, &r
->expr
, mod
)->expr
;
1142 g
= new_clast_guard(1);
1143 if (!cloog_constraint_is_valid(lower
)) {
1145 cloog_int_set_si(bound
, 0);
1146 g
->eq
[0].RHS
= &new_clast_term(bound
, NULL
)->expr
;
1150 g
->eq
[0].RHS
= &new_clast_term(bound
, NULL
)->expr
;
1159 /* Temporary structure for communication between insert_modulo_guard and
1160 * its cloog_constraint_set_foreach_constraint callback function.
1162 struct clast_modulo_guard_data
{
1163 CloogConstraint
*lower
;
1165 struct clast_stmt
***next
;
1168 cloog_int_t val
, bound
;
1172 /* Insert a modulo guard for constraint c.
1174 static int insert_modulo_guard_constraint(CloogConstraint
*c
, void *user
)
1176 struct clast_modulo_guard_data
*d
= (struct clast_modulo_guard_data
*) user
;
1177 int level
= d
->level
;
1178 CloogInfos
*infos
= d
->infos
;
1179 int i
, nb_elts
= 0, len
, len2
, nb_iter
, nb_par
;
1181 struct cloog_vec
*line_vector
;
1184 len
= cloog_constraint_total_dimension(c
) + 2;
1185 len2
= cloog_equal_total_dimension(infos
->equal
) + 2;
1186 nb_par
= infos
->names
->nb_parameters
;
1187 nb_iter
= len
- 2 - nb_par
;
1189 line_vector
= cloog_vec_alloc(len
);
1190 line
= line_vector
->p
;
1191 cloog_constraint_copy_coefficients(c
, line
+ 1);
1193 if (cloog_int_is_pos(line
[level
]))
1194 cloog_seq_neg(line
+ 1, line
+ 1, len
- 1);
1195 cloog_int_neg(line
[level
], line
[level
]);
1196 assert(cloog_int_is_pos(line
[level
]));
1199 for (i
= 1; i
<= len
-1; ++i
) {
1202 cloog_int_fdiv_r(line
[i
], line
[i
], line
[level
]);
1203 if (cloog_int_is_zero(line
[i
]))
1211 if (nb_elts
|| !cloog_int_is_zero(line
[len
-1])) {
1212 struct clast_reduction
*r
;
1215 r
= new_clast_reduction(clast_red_sum
, nb_elts
+ 1);
1218 /* First, the modulo guard : the iterators... */
1219 for (i
=1;i
<=nb_iter
;i
++) {
1220 if (i
== level
|| cloog_int_is_zero(line
[i
]))
1222 if (infos
->stride
[i
- 1] &&
1223 cloog_int_is_divisible_by(infos
->stride
[i
-1]->stride
, line
[level
])) {
1224 cloog_int_addmul(line
[len
-1], line
[i
], infos
->stride
[i
-1]->offset
);
1225 cloog_int_fdiv_r(line
[len
-1], line
[len
-1], line
[level
]);
1229 name
= cloog_names_name_at_level(infos
->names
, i
);
1231 r
->elts
[nb_elts
++] = &new_clast_term(line
[i
],
1232 &new_clast_name(name
)->expr
)->expr
;
1235 /* ...the parameters... */
1236 for (i
=nb_iter
+1;i
<=len
-2;i
++) {
1237 if (cloog_int_is_zero(line
[i
]))
1240 name
= infos
->names
->parameters
[i
-nb_iter
-1] ;
1241 r
->elts
[nb_elts
++] = &new_clast_term(line
[i
],
1242 &new_clast_name(name
)->expr
)->expr
;
1245 constant
= nb_elts
== 0;
1246 /* ...the constant. */
1247 if (!cloog_int_is_zero(line
[len
-1]))
1248 r
->elts
[nb_elts
++] = &new_clast_term(line
[len
-1], NULL
)->expr
;
1250 /* our initial computation may have been an overestimate */
1254 d
->empty
= !constant_modulo_guard_is_satisfied(d
->lower
, d
->bound
,
1256 free_clast_reduction(r
);
1258 insert_computed_modulo_guard(r
, d
->lower
, line
[level
], d
->bound
,
1262 cloog_vec_free(line_vector
);
1269 * insert_modulo_guard:
1270 * This function inserts a modulo guard corresponding to an equality
1271 * or a pair of inequalities.
1272 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
1274 * See insert_equation.
1275 * - matrix is the polyhedron containing all the constraints,
1276 * - upper and lower are the line numbers of the constraint in matrix
1277 * we want to print; in particular, if we want to print an equality,
1278 * then lower == -1 and upper is the row of the equality; if we want
1279 * to print an inequality, then upper is the row of the upper bound
1280 * and lower in the row of the lower bound
1281 * - level is the column number of the element in matrix we want to use,
1282 * - the infos structure gives the user some options about code printing,
1283 * the number of parameters in matrix (nb_par), and the arrays of iterator
1284 * names and parameters (iters and params).
1286 static int insert_modulo_guard(CloogConstraint
*upper
,
1287 CloogConstraint
*lower
, int level
,
1288 struct clast_stmt
***next
, CloogInfos
*infos
)
1291 CloogConstraintSet
*set
;
1292 struct clast_modulo_guard_data data
= { lower
, level
, next
, infos
, 0 };
1294 cloog_int_init(data
.val
);
1295 cloog_constraint_coefficient_get(upper
, level
-1, &data
.val
);
1296 if (cloog_int_is_one(data
.val
) || cloog_int_is_neg_one(data
.val
)) {
1297 cloog_int_clear(data
.val
);
1301 nb_par
= infos
->names
->nb_parameters
;
1303 cloog_int_init(data
.bound
);
1304 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1305 if (cloog_constraint_is_valid(lower
)) {
1306 cloog_constraint_constant_get(upper
, &data
.val
);
1307 cloog_constraint_constant_get(lower
, &data
.bound
);
1308 cloog_int_add(data
.bound
, data
.val
, data
.bound
);
1309 cloog_constraint_coefficient_get(lower
, level
-1, &data
.val
);
1310 cloog_int_sub_ui(data
.val
, data
.val
, 1);
1311 if (cloog_int_eq(data
.val
, data
.bound
)) {
1312 cloog_int_clear(data
.val
);
1313 cloog_int_clear(data
.bound
);
1318 set
= cloog_constraint_set_for_reduction(upper
, lower
);
1319 set
= cloog_constraint_set_reduce(set
, level
, infos
->equal
, nb_par
, &data
.bound
);
1320 cloog_constraint_set_foreach_constraint(set
,
1321 insert_modulo_guard_constraint
, &data
);
1323 cloog_constraint_set_free(set
);
1324 cloog_int_clear(data
.val
);
1325 cloog_int_clear(data
.bound
);
1332 * We found an equality or a pair of inequalities identifying
1333 * a loop with a single iteration, but the user wants us to generate
1334 * a loop anyway, so we do it here.
1336 static int insert_equation_as_loop(CloogConstraint
*upper
,
1337 CloogConstraint
*lower
, int level
, struct clast_stmt
***next
,
1340 const char *iterator
= cloog_names_name_at_level(infos
->names
, level
);
1341 struct clast_expr
*e1
, *e2
;
1342 struct clast_for
*f
;
1344 e2
= clast_bound_from_constraint(upper
, level
, infos
->names
);
1345 if (!cloog_constraint_is_valid(lower
))
1346 e1
= clast_expr_copy(e2
);
1348 e1
= clast_bound_from_constraint(lower
, level
, infos
->names
);
1349 f
= new_clast_for(iterator
, e1
, e2
, infos
->stride
[level
-1]);
1353 cloog_constraint_release(lower
);
1354 cloog_constraint_release(upper
);
1360 * insert_equation function:
1361 * This function inserts an equality
1362 * constraint according to an element in the clast.
1363 * Returns 1 if the calling function should recurse into inner loops.
1365 * An equality can be preceded by a 'modulo guard'.
1366 * For instance, consider the constraint i -2*j = 0 and the
1367 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1368 * - matrix is the polyhedron containing all the constraints,
1369 * - num is the line number of the constraint in matrix we want to print,
1370 * - level is the column number of the element in matrix we want to use,
1371 * - the infos structure gives the user some options about code printing,
1372 * the number of parameters in matrix (nb_par), and the arrays of iterator
1373 * names and parameters (iters and params).
1375 * - November 13th 2001: first version.
1376 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1377 * modulo is 0, compare vivien or vivien2 with a previous
1378 * version for an idea).
1379 * - June 29th 2003: non-unit strides support.
1380 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1381 * it was previously included in a stride calculation.
1383 static int insert_equation(CloogConstraint
*upper
, CloogConstraint
*lower
,
1384 int level
, struct clast_stmt
***next
, CloogInfos
*infos
)
1386 struct clast_expr
*e
;
1387 struct clast_assignment
*ass
;
1389 if (!infos
->options
->otl
)
1390 return insert_equation_as_loop(upper
, lower
, level
, next
, infos
);
1392 if (!insert_modulo_guard(upper
, lower
, level
, next
, infos
)) {
1393 cloog_constraint_release(lower
);
1394 cloog_constraint_release(upper
);
1399 if (cloog_constraint_is_valid(lower
) ||
1400 !clast_equal_add(infos
->equal
, NULL
, level
, upper
, infos
))
1401 { /* Finally, the equality. */
1403 /* If we have to make a block by dimension, we start the block. Function
1404 * pprint knows if there is an equality, if this is the case, it checks
1405 * for the same following condition to close the brace.
1407 if (infos
->options
->block
) {
1408 struct clast_block
*b
= new_clast_block();
1413 e
= clast_bound_from_constraint(upper
, level
, infos
->names
);
1414 ass
= new_clast_assignment(cloog_names_name_at_level(infos
->names
, level
), e
);
1416 **next
= &ass
->stmt
;
1417 *next
= &(**next
)->next
;
1420 cloog_constraint_release(lower
);
1421 cloog_constraint_release(upper
);
1428 * Insert a loop that is executed exactly once as an assignment.
1429 * In particular, the loop
1431 * for (i = e; i <= e; ++i) {
1441 static void insert_otl_for(CloogConstraintSet
*constraints
, int level
,
1442 struct clast_expr
*e
, struct clast_stmt
***next
, CloogInfos
*infos
)
1444 const char *iterator
;
1446 iterator
= cloog_names_name_at_level(infos
->names
, level
);
1448 if (!clast_equal_add(infos
->equal
, constraints
, level
,
1449 cloog_constraint_invalid(), infos
)) {
1450 struct clast_assignment
*ass
;
1451 if (infos
->options
->block
) {
1452 struct clast_block
*b
= new_clast_block();
1456 ass
= new_clast_assignment(iterator
, e
);
1457 **next
= &ass
->stmt
;
1458 *next
= &(**next
)->next
;
1466 * Insert a loop that is executed at most once as an assignment followed
1467 * by a guard. In particular, the loop
1469 * for (i = e1; i <= e2; ++i) {
1481 static void insert_guarded_otl_for(CloogConstraintSet
*constraints
, int level
,
1482 struct clast_expr
*e1
, struct clast_expr
*e2
,
1483 struct clast_stmt
***next
, CloogInfos
*infos
)
1485 const char *iterator
;
1486 struct clast_assignment
*ass
;
1487 struct clast_guard
*guard
;
1489 iterator
= cloog_names_name_at_level(infos
->names
, level
);
1491 if (infos
->options
->block
) {
1492 struct clast_block
*b
= new_clast_block();
1496 ass
= new_clast_assignment(iterator
, e1
);
1497 **next
= &ass
->stmt
;
1498 *next
= &(**next
)->next
;
1500 guard
= new_clast_guard(1);
1501 guard
->eq
[0].sign
= -1;
1502 guard
->eq
[0].LHS
= &new_clast_term(infos
->state
->one
,
1503 &new_clast_name(iterator
)->expr
)->expr
;
1504 guard
->eq
[0].RHS
= e2
;
1506 **next
= &guard
->stmt
;
1507 *next
= &guard
->then
;
1512 * insert_for function:
1513 * This function inserts a for loop in the clast.
1514 * Returns 1 if the calling function should recurse into inner loops.
1516 * A loop header according to an element is the conjunction of a minimum and a
1517 * maximum on a given element (they give the loop bounds).
1518 * For instance, considering these constraints and the element j:
1522 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1523 * If the given element is involved in modulo guards defined by
1524 * existentially quantified variables, then these guards should be
1525 * inserted inside the for loop. However, the constraints involved
1526 * in this guard should not be used in determining the lower and upper
1527 * bound of the loop. We therefore insert the guards first (which
1528 * removes the corresponding constraints from the constraint set)
1529 * and then reattach the guard inside the loop.
1530 * - constraints contains all constraints,
1531 * - level is the column number of the element in matrix we want to use,
1532 * - otl is set if the loop is executed at most once,
1533 * - the infos structure gives the user some options about code printing,
1534 * the number of parameters in matrix (nb_par), and the arrays of iterator
1535 * names and parameters (iters and params).
1537 static int insert_for(CloogConstraintSet
*constraints
, int level
, int otl
,
1538 struct clast_stmt
***next
, CloogInfos
*infos
)
1540 const char *iterator
;
1541 struct clast_expr
*e1
;
1542 struct clast_expr
*e2
;
1544 e1
= clast_minmax(constraints
, level
, 1, 0, 1, infos
);
1545 e2
= clast_minmax(constraints
, level
, 0, 0, 0, infos
);
1547 if (clast_expr_is_bigger_constant(e1
, e2
)) {
1548 free_clast_expr(e1
);
1549 free_clast_expr(e2
);
1553 /* If min and max are not equal there is a 'for' else, there is a '='.
1554 * In the special case e1 = e2 = NULL, this is an infinite loop
1555 * so this is not a '='.
1557 if (e1
&& e2
&& infos
->options
->otl
&& clast_expr_equal(e1
, e2
)) {
1558 free_clast_expr(e2
);
1559 insert_otl_for(constraints
, level
, e1
, next
, infos
);
1561 insert_guarded_otl_for(constraints
, level
, e1
, e2
, next
, infos
);
1563 struct clast_for
*f
;
1564 iterator
= cloog_names_name_at_level(infos
->names
, level
);
1565 f
= new_clast_for(iterator
, e1
, e2
, infos
->stride
[level
-1]);
1570 insert_extra_modulo_guards(constraints
, 0, next
, infos
);
1577 * insert_block function:
1578 * This function inserts a statement block.
1579 * - block is the statement block,
1580 * - level is the number of loops enclosing the statement,
1581 * - the infos structure gives the user some options about code printing,
1582 * the number of parameters in domain (nb_par), and the arrays of iterator
1583 * names and parameters (iters and params).
1585 * - September 21th 2003: first version (pick from pprint function).
1587 static void insert_block(CloogBlock
*block
, int level
,
1588 struct clast_stmt
***next
, CloogInfos
*infos
)
1590 CloogStatement
* statement
;
1591 struct clast_stmt
*subs
;
1596 for (statement
= block
->statement
; statement
; statement
= statement
->next
) {
1597 CloogStatement
*s_next
= statement
->next
;
1599 subs
= clast_equal(level
,infos
);
1601 statement
->next
= NULL
;
1602 **next
= &new_clast_user_stmt(statement
, subs
)->stmt
;
1603 statement
->next
= s_next
;
1604 *next
= &(**next
)->next
;
1610 * insert_loop function:
1611 * This function converts the content of a CloogLoop structure (loop) into a
1612 * clast_stmt (inserted at **next).
1613 * The iterator (level) of
1614 * the current loop is given by 'level': this is the column number of the
1615 * domain corresponding to the current loop iterator. The data of a loop are
1616 * written in this order:
1617 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1618 * depend on the iterator (when the entry in the column 'level' is 0).
1619 * 2. The iteration domain of the iterator, given by the constraints in the
1620 * domain depending on the iterator, i.e.:
1621 * * an equality if the iterator has only one value (possibly preceded by
1622 * a guard verifying if this value is integral), *OR*
1623 * * a loop from the minimum possible value of the iterator to the maximum
1625 * 3. The included statement block.
1626 * 4. The inner loops (recursive call).
1627 * 5. The following loops (recursive call).
1628 * - level is the recursion level or the iteration level that we are printing,
1629 * - the infos structure gives the user some options about code printing,
1630 * the number of parameters in domain (nb_par), and the arrays of iterator
1631 * names and parameters (iters and params).
1633 * - November 2nd 2001: first version.
1634 * - March 6th 2003: infinite domain support.
1635 * - April 19th 2003: (debug) NULL loop support.
1636 * - June 29th 2003: non-unit strides support.
1637 * - April 28th 2005: (debug) level is level+equality when print statement!
1638 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1639 * added to avoid iteration duplication (see DaeGon Kim
1640 * bug in cloog_program_generate). Try vasilache.cloog
1641 * with and without the call to cloog_polylib_matrix_normalize,
1642 * using -f 8 -l 9 options for an idea.
1643 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1644 * - October 16th 2005: (debug) scalar value is saved for next loops.
1646 static void insert_loop(CloogLoop
* loop
, int level
,
1647 struct clast_stmt
***next
, CloogInfos
*infos
)
1650 CloogConstraintSet
*constraints
, *temp
;
1651 struct clast_stmt
**top
= *next
;
1652 CloogConstraint
*i
, *j
;
1655 /* It can happen that loop be NULL when an input polyhedron is empty. */
1659 /* The constraints do not always have a shape that allows us to generate code from it,
1660 * thus we normalize it, we also simplify it with the equalities.
1662 temp
= cloog_domain_constraints(loop
->domain
);
1663 cloog_constraint_set_normalize(temp
,level
);
1664 constraints
= cloog_constraint_set_simplify(temp
,infos
->equal
,level
,
1665 infos
->names
->nb_parameters
);
1666 cloog_constraint_set_free(temp
);
1668 infos
->stride
[level
- 1] = loop
->stride
;
1670 /* First of all we have to print the guard. */
1671 insert_guard(constraints
,level
, next
, infos
);
1673 if (level
&& cloog_constraint_set_contains_level(constraints
, level
,
1674 infos
->names
->nb_parameters
)) {
1675 /* We scan all the constraints to know in which case we are :
1676 * [[if] equation] or [for].
1678 if (cloog_constraint_is_valid(i
=
1679 cloog_constraint_set_defining_equality(constraints
, level
))) {
1680 empty_loop
= !insert_equation(i
, cloog_constraint_invalid(),
1681 level
, next
, infos
);
1683 } else if (cloog_constraint_is_valid(i
=
1684 cloog_constraint_set_defining_inequalities(constraints
,
1685 level
, &j
, infos
->names
->nb_parameters
))) {
1686 empty_loop
= !insert_equation(i
, j
, level
, next
, infos
);
1688 empty_loop
= !insert_for(constraints
, level
, loop
->otl
, next
, infos
);
1692 /* Finally, if there is an included statement block, print it. */
1693 insert_block(loop
->block
, level
+equality
, next
, infos
);
1695 /* Go to the next level. */
1696 if (loop
->inner
!= NULL
)
1697 insert_loop(loop
->inner
, level
+1, next
, infos
);
1701 cloog_equal_del(infos
->equal
,level
);
1702 cloog_constraint_set_free(constraints
);
1704 /* Go to the next loop on the same level. */
1706 top
= &(*top
)->next
;
1707 if (loop
->next
!= NULL
)
1708 insert_loop(loop
->next
, level
, &top
,infos
);
1712 struct clast_stmt
*cloog_clast_create(CloogProgram
*program
,
1713 CloogOptions
*options
)
1715 CloogInfos
*infos
= ALLOC(CloogInfos
);
1717 struct clast_stmt
*root
= &new_clast_root(program
->names
)->stmt
;
1718 struct clast_stmt
**next
= &root
->next
;
1720 infos
->state
= options
->state
;
1721 infos
->names
= program
->names
;
1722 infos
->options
= options
;
1723 infos
->scaldims
= program
->scaldims
;
1724 infos
->nb_scattdims
= program
->nb_scattdims
;
1726 /* Allocation for the array of strides, there is a +1 since the statement can
1727 * be included inside an external loop without iteration domain.
1729 nb_levels
= program
->names
->nb_scattering
+program
->names
->nb_iterators
+1;
1730 infos
->stride
= ALLOCN(CloogStride
*, nb_levels
);
1732 infos
->equal
= cloog_equal_alloc(nb_levels
,
1733 nb_levels
, program
->names
->nb_parameters
);
1735 insert_loop(program
->loop
, 0, &next
, infos
);
1737 cloog_equal_free(infos
->equal
);
1739 free(infos
->stride
);
1746 struct clast_stmt
*cloog_clast_create_from_input(CloogInput
*input
,
1747 CloogOptions
*options
)
1749 CloogProgram
*program
;
1750 struct clast_stmt
*root
;
1752 program
= cloog_program_alloc(input
->context
, input
->ud
, options
);
1755 program
= cloog_program_generate(program
, options
);
1757 root
= cloog_clast_create(program
, options
);
1758 cloog_program_free(program
);