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 stride_level
; /**< Number of valid entries in stride array. */
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 struct clast_expr
*clast_expr_copy(struct clast_expr
*e
);
40 static int clast_equal_add(CloogEqualities
*equal
,
41 CloogConstraintSet
*constraints
,
42 int level
, CloogConstraint
*constraint
,
45 static struct clast_stmt
*clast_equal(int level
, CloogInfos
*infos
);
46 static struct clast_expr
*clast_minmax(CloogConstraintSet
*constraints
,
47 int level
, int max
, int guard
,
48 int lower_bound
, int no_earlier
,
50 static void insert_guard(CloogConstraintSet
*constraints
, int level
,
51 struct clast_stmt
***next
, CloogInfos
*infos
);
52 static int insert_modulo_guard(CloogConstraint
*upper
,
53 CloogConstraint
*lower
, int level
,
54 struct clast_stmt
***next
, CloogInfos
*infos
);
55 static int insert_equation(CloogDomain
*domain
, CloogConstraint
*upper
,
56 CloogConstraint
*lower
, int level
,
57 struct clast_stmt
***next
, CloogInfos
*infos
);
58 static int insert_for(CloogDomain
*domain
, CloogConstraintSet
*constraints
,
59 int level
, int otl
, struct clast_stmt
***next
,
61 static void insert_block(CloogDomain
*domain
, CloogBlock
*block
, int level
,
62 struct clast_stmt
***next
, CloogInfos
*infos
);
63 static void insert_loop(CloogLoop
* loop
, int level
,
64 struct clast_stmt
***next
, CloogInfos
*infos
);
67 struct clast_name
*new_clast_name(const char *name
)
69 struct clast_name
*n
= malloc(sizeof(struct clast_name
));
70 n
->expr
.type
= clast_expr_name
;
75 struct clast_term
*new_clast_term(cloog_int_t c
, struct clast_expr
*v
)
77 struct clast_term
*t
= malloc(sizeof(struct clast_term
));
78 t
->expr
.type
= clast_expr_term
;
79 cloog_int_init(t
->val
);
80 cloog_int_set(t
->val
, c
);
85 struct clast_binary
*new_clast_binary(enum clast_bin_type t
,
86 struct clast_expr
*lhs
, cloog_int_t rhs
)
88 struct clast_binary
*b
= malloc(sizeof(struct clast_binary
));
89 b
->expr
.type
= clast_expr_bin
;
92 cloog_int_init(b
->RHS
);
93 cloog_int_set(b
->RHS
, rhs
);
97 struct clast_reduction
*new_clast_reduction(enum clast_red_type t
, int n
)
100 struct clast_reduction
*r
;
101 r
= malloc(sizeof(struct clast_reduction
)+(n
-1)*sizeof(struct clast_expr
*));
102 r
->expr
.type
= clast_expr_red
;
105 for (i
= 0; i
< n
; ++i
)
110 static void free_clast_root(struct clast_stmt
*s
);
112 const struct clast_stmt_op stmt_root
= { free_clast_root
};
114 static void free_clast_root(struct clast_stmt
*s
)
116 struct clast_root
*r
= (struct clast_root
*)s
;
117 assert(CLAST_STMT_IS_A(s
, stmt_root
));
118 cloog_names_free(r
->names
);
122 struct clast_root
*new_clast_root(CloogNames
*names
)
124 struct clast_root
*r
= malloc(sizeof(struct clast_root
));
125 r
->stmt
.op
= &stmt_root
;
127 r
->names
= cloog_names_copy(names
);
131 static void free_clast_assignment(struct clast_stmt
*s
);
133 const struct clast_stmt_op stmt_ass
= { free_clast_assignment
};
135 static void free_clast_assignment(struct clast_stmt
*s
)
137 struct clast_assignment
*a
= (struct clast_assignment
*)s
;
138 assert(CLAST_STMT_IS_A(s
, stmt_ass
));
139 free_clast_expr(a
->RHS
);
143 struct clast_assignment
*new_clast_assignment(const char *lhs
,
144 struct clast_expr
*rhs
)
146 struct clast_assignment
*a
= malloc(sizeof(struct clast_assignment
));
147 a
->stmt
.op
= &stmt_ass
;
154 static void free_clast_user_stmt(struct clast_stmt
*s
);
156 const struct clast_stmt_op stmt_user
= { free_clast_user_stmt
};
158 static void free_clast_user_stmt(struct clast_stmt
*s
)
160 struct clast_user_stmt
*u
= (struct clast_user_stmt
*)s
;
161 assert(CLAST_STMT_IS_A(s
, stmt_user
));
162 cloog_domain_free(u
->domain
);
163 cloog_statement_free(u
->statement
);
164 cloog_clast_free(u
->substitutions
);
168 struct clast_user_stmt
*new_clast_user_stmt(CloogDomain
*domain
,
169 CloogStatement
*stmt
, struct clast_stmt
*subs
)
171 struct clast_user_stmt
*u
= malloc(sizeof(struct clast_user_stmt
));
172 u
->stmt
.op
= &stmt_user
;
174 u
->domain
= cloog_domain_copy(domain
);
175 u
->statement
= cloog_statement_copy(stmt
);
176 u
->substitutions
= subs
;
180 static void free_clast_block(struct clast_stmt
*b
);
182 const struct clast_stmt_op stmt_block
= { free_clast_block
};
184 static void free_clast_block(struct clast_stmt
*s
)
186 struct clast_block
*b
= (struct clast_block
*)s
;
187 assert(CLAST_STMT_IS_A(s
, stmt_block
));
188 cloog_clast_free(b
->body
);
192 struct clast_block
*new_clast_block()
194 struct clast_block
*b
= malloc(sizeof(struct clast_block
));
195 b
->stmt
.op
= &stmt_block
;
201 static void free_clast_for(struct clast_stmt
*s
);
203 const struct clast_stmt_op stmt_for
= { free_clast_for
};
205 static void free_clast_for(struct clast_stmt
*s
)
207 struct clast_for
*f
= (struct clast_for
*)s
;
208 assert(CLAST_STMT_IS_A(s
, stmt_for
));
209 cloog_domain_free(f
->domain
);
210 free_clast_expr(f
->LB
);
211 free_clast_expr(f
->UB
);
212 cloog_int_clear(f
->stride
);
213 cloog_clast_free(f
->body
);
214 if (f
->private_vars
) free(f
->private_vars
);
215 if (f
->reduction_vars
) free(f
->reduction_vars
);
216 if (f
->time_var_name
) free(f
->time_var_name
);
220 struct clast_for
*new_clast_for(CloogDomain
*domain
, const char *it
,
221 struct clast_expr
*LB
, struct clast_expr
*UB
,
224 struct clast_for
*f
= malloc(sizeof(struct clast_for
));
225 f
->stmt
.op
= &stmt_for
;
227 f
->domain
= cloog_domain_copy(domain
);
232 f
->parallel
= CLAST_PARALLEL_NOT
;
233 f
->private_vars
= NULL
;
234 f
->reduction_vars
= NULL
;
235 f
->time_var_name
= NULL
;
236 cloog_int_init(f
->stride
);
238 cloog_int_set(f
->stride
, stride
->stride
);
240 cloog_int_set_si(f
->stride
, 1);
244 static void free_clast_guard(struct clast_stmt
*s
);
246 const struct clast_stmt_op stmt_guard
= { free_clast_guard
};
248 static void free_clast_guard(struct clast_stmt
*s
)
251 struct clast_guard
*g
= (struct clast_guard
*)s
;
252 assert(CLAST_STMT_IS_A(s
, stmt_guard
));
253 cloog_clast_free(g
->then
);
254 for (i
= 0; i
< g
->n
; ++i
) {
255 free_clast_expr(g
->eq
[i
].LHS
);
256 free_clast_expr(g
->eq
[i
].RHS
);
261 struct clast_guard
*new_clast_guard(int n
)
264 struct clast_guard
*g
= malloc(sizeof(struct clast_guard
) +
265 (n
-1) * sizeof(struct clast_equation
));
266 g
->stmt
.op
= &stmt_guard
;
270 for (i
= 0; i
< n
; ++i
) {
277 void free_clast_name(struct clast_name
*n
)
282 void free_clast_term(struct clast_term
*t
)
284 cloog_int_clear(t
->val
);
285 free_clast_expr(t
->var
);
289 void free_clast_binary(struct clast_binary
*b
)
291 cloog_int_clear(b
->RHS
);
292 free_clast_expr(b
->LHS
);
296 void free_clast_reduction(struct clast_reduction
*r
)
299 for (i
= 0; i
< r
->n
; ++i
)
300 free_clast_expr(r
->elts
[i
]);
304 void free_clast_expr(struct clast_expr
*e
)
309 case clast_expr_name
:
310 free_clast_name((struct clast_name
*) e
);
312 case clast_expr_term
:
313 free_clast_term((struct clast_term
*) e
);
316 free_clast_reduction((struct clast_reduction
*) e
);
319 free_clast_binary((struct clast_binary
*) e
);
326 void free_clast_stmt(struct clast_stmt
*s
)
333 void cloog_clast_free(struct clast_stmt
*s
)
335 struct clast_stmt
*next
;
343 static int clast_name_cmp(struct clast_name
*n1
, struct clast_name
*n2
)
345 return n1
->name
== n2
->name
? 0 : strcmp(n1
->name
, n2
->name
);
348 static int clast_term_cmp(struct clast_term
*t1
, struct clast_term
*t2
)
351 if (!t1
->var
&& t2
->var
)
353 if (t1
->var
&& !t2
->var
)
355 c
= clast_expr_cmp(t1
->var
, t2
->var
);
358 return cloog_int_cmp(t1
->val
, t2
->val
);
361 static int clast_binary_cmp(struct clast_binary
*b1
, struct clast_binary
*b2
)
365 if (b1
->type
!= b2
->type
)
366 return b1
->type
- b2
->type
;
367 if ((c
= cloog_int_cmp(b1
->RHS
, b2
->RHS
)))
369 return clast_expr_cmp(b1
->LHS
, b2
->LHS
);
372 static int clast_reduction_cmp(struct clast_reduction
*r1
, struct clast_reduction
*r2
)
377 if (r1
->n
== 1 && r2
->n
== 1)
378 return clast_expr_cmp(r1
->elts
[0], r2
->elts
[0]);
379 if (r1
->type
!= r2
->type
)
380 return r1
->type
- r2
->type
;
382 return r1
->n
- r2
->n
;
383 for (i
= 0; i
< r1
->n
; ++i
)
384 if ((c
= clast_expr_cmp(r1
->elts
[i
], r2
->elts
[i
])))
389 static int clast_expr_cmp(struct clast_expr
*e1
, struct clast_expr
*e2
)
397 if (e1
->type
!= e2
->type
)
398 return e1
->type
- e2
->type
;
400 case clast_expr_name
:
401 return clast_name_cmp((struct clast_name
*) e1
,
402 (struct clast_name
*) e2
);
403 case clast_expr_term
:
404 return clast_term_cmp((struct clast_term
*) e1
,
405 (struct clast_term
*) e2
);
407 return clast_binary_cmp((struct clast_binary
*) e1
,
408 (struct clast_binary
*) e2
);
410 return clast_reduction_cmp((struct clast_reduction
*) e1
,
411 (struct clast_reduction
*) e2
);
417 int clast_expr_equal(struct clast_expr
*e1
, struct clast_expr
*e2
)
419 return clast_expr_cmp(e1
, e2
) == 0;
423 * Return 1 is both expressions are constant terms and e1 is bigger than e2.
425 int clast_expr_is_bigger_constant(struct clast_expr
*e1
, struct clast_expr
*e2
)
427 struct clast_term
*t1
, *t2
;
428 struct clast_reduction
*r
;
432 if (e1
->type
== clast_expr_red
) {
433 r
= (struct clast_reduction
*)e1
;
434 return r
->n
== 1 && clast_expr_is_bigger_constant(r
->elts
[0], e2
);
436 if (e2
->type
== clast_expr_red
) {
437 r
= (struct clast_reduction
*)e2
;
438 return r
->n
== 1 && clast_expr_is_bigger_constant(e1
, r
->elts
[0]);
440 if (e1
->type
!= clast_expr_term
|| e2
->type
!= clast_expr_term
)
442 t1
= (struct clast_term
*)e1
;
443 t2
= (struct clast_term
*)e2
;
444 if (t1
->var
|| t2
->var
)
446 return cloog_int_gt(t1
->val
, t2
->val
);
449 static int qsort_expr_cmp(const void *p1
, const void *p2
)
451 return clast_expr_cmp(*(struct clast_expr
**)p1
, *(struct clast_expr
**)p2
);
454 static void clast_reduction_sort(struct clast_reduction
*r
)
456 qsort(&r
->elts
[0], r
->n
, sizeof(struct clast_expr
*), qsort_expr_cmp
);
459 static int qsort_eq_cmp(const void *p1
, const void *p2
)
461 struct clast_equation
*eq1
= (struct clast_equation
*)p1
;
462 struct clast_equation
*eq2
= (struct clast_equation
*)p2
;
465 cmp
= clast_expr_cmp(eq1
->LHS
, eq2
->LHS
);
469 cmp
= clast_expr_cmp(eq1
->RHS
, eq2
->RHS
);
473 return eq1
->sign
- eq2
->sign
;
477 * Sort equations in a clast_guard.
479 static void clast_guard_sort(struct clast_guard
*g
)
481 qsort(&g
->eq
[0], g
->n
, sizeof(struct clast_equation
), qsort_eq_cmp
);
486 * Construct a (deep) copy of an expression clast.
488 static struct clast_expr
*clast_expr_copy(struct clast_expr
*e
)
493 case clast_expr_name
: {
494 struct clast_name
* n
= (struct clast_name
*) e
;
495 return &new_clast_name(n
->name
)->expr
;
497 case clast_expr_term
: {
498 struct clast_term
* t
= (struct clast_term
*) e
;
499 return &new_clast_term(t
->val
, clast_expr_copy(t
->var
))->expr
;
501 case clast_expr_red
: {
503 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
504 struct clast_reduction
*r2
= new_clast_reduction(r
->type
, r
->n
);
505 for (i
= 0; i
< r
->n
; ++i
)
506 r2
->elts
[i
] = clast_expr_copy(r
->elts
[i
]);
509 case clast_expr_bin
: {
510 struct clast_binary
*b
= (struct clast_binary
*) e
;
511 return &new_clast_binary(b
->type
, clast_expr_copy(b
->LHS
), b
->RHS
)->expr
;
519 /******************************************************************************
520 * Equalities spreading functions *
521 ******************************************************************************/
525 * clast_equal_allow function:
526 * This function checks whether the options allow us to spread the equality or
527 * not. It returns 1 if so, 0 otherwise.
528 * - equal is the matrix of equalities,
529 * - level is the column number in equal of the element which is 'equal to',
530 * - line is the line number in equal of the constraint we want to study,
531 * - the infos structure gives the user all options on code printing and more.
533 * - October 27th 2005: first version (extracted from old pprint_equal_add).
535 static int clast_equal_allow(CloogEqualities
*equal
, int level
, int line
,
538 if (level
< infos
->options
->fsp
)
541 if ((cloog_equal_type(equal
, level
) == EQTYPE_EXAFFINE
) &&
542 !infos
->options
->esp
)
550 * clast_equal_add function:
551 * This function updates the row (level-1) of the equality matrix (equal) with
552 * the row that corresponds to the row (line) of the matrix (matrix). It returns
553 * 1 if the row can be updated, 0 otherwise.
554 * - equal is the matrix of equalities,
555 * - matrix is the matrix of constraints,
556 * - level is the column number in matrix of the element which is 'equal to',
557 * - line is the line number in matrix of the constraint we want to study,
558 * - the infos structure gives the user all options on code printing and more.
560 static int clast_equal_add(CloogEqualities
*equal
,
561 CloogConstraintSet
*constraints
,
562 int level
, CloogConstraint
*constraint
,
565 cloog_equal_add(equal
, constraints
, level
, constraint
,
566 infos
->names
->nb_parameters
);
568 return clast_equal_allow(equal
, level
, level
-1, infos
);
574 * clast_equal function:
575 * This function prints the substitution data of a statement into a clast_stmt.
576 * Using this function instead of pprint_equal is useful for generating
577 * a compilable pseudo-code by using preprocessor macro for each statement.
578 * By opposition to pprint_equal, the result is less human-readable. For
579 * instance this function will print (i,i+3,k,3) where pprint_equal would
580 * return (j=i+3,l=3).
581 * - level is the number of loops enclosing the statement,
582 * - the infos structure gives the user all options on code printing and more.
584 * - March 12th 2004: first version.
585 * - November 21th 2005: (debug) now works well with GMP version.
587 static struct clast_stmt
*clast_equal(int level
, CloogInfos
*infos
)
590 struct clast_expr
*e
;
591 struct clast_stmt
*a
= NULL
;
592 struct clast_stmt
**next
= &a
;
593 CloogEqualities
*equal
= infos
->equal
;
594 CloogConstraint
*equal_constraint
;
596 for (i
=infos
->names
->nb_scattering
;i
<level
-1;i
++)
597 { if (cloog_equal_type(equal
, i
+1)) {
598 equal_constraint
= cloog_equal_constraint(equal
, i
);
599 e
= clast_bound_from_constraint(equal_constraint
, i
+1, infos
->names
);
600 cloog_constraint_release(equal_constraint
);
602 e
= &new_clast_term(infos
->state
->one
, &new_clast_name(
603 cloog_names_name_at_level(infos
->names
, i
+1))->expr
)->expr
;
605 *next
= &new_clast_assignment(NULL
, e
)->stmt
;
606 next
= &(*next
)->next
;
614 * clast_bound_from_constraint function:
615 * This function returns a clast_expr containing the printing of the
616 * 'right part' of a constraint according to an element.
617 * For instance, for the constraint -3*i + 2*j - M >=0 and the element j,
618 * we have j >= (3*i + M)/2. As we are looking for integral solutions, this
619 * function should return 'ceild(3*i+M,2)'.
620 * - matrix is the polyhedron containing all the constraints,
621 * - line_num is the line number in domain of the constraint we want to print,
622 * - level is the column number in domain of the element we want to use,
623 * - names structure gives the user some options about code printing,
624 * the number of parameters in domain (nb_par), and the arrays of iterator
625 * names and parameters (iters and params).
627 * - November 2nd 2001: first version.
628 * - June 27th 2003: 64 bits version ready.
630 struct clast_expr
*clast_bound_from_constraint(CloogConstraint
*constraint
,
631 int level
, CloogNames
*names
)
633 int i
, sign
, nb_elts
=0, len
;
634 cloog_int_t
*line
, numerator
, denominator
, temp
, division
;
635 struct clast_expr
*e
= NULL
;
636 struct cloog_vec
*line_vector
;
638 len
= cloog_constraint_total_dimension(constraint
) + 2;
639 line_vector
= cloog_vec_alloc(len
);
640 line
= line_vector
->p
;
641 cloog_constraint_copy_coefficients(constraint
, line
+1);
642 cloog_int_init(temp
);
643 cloog_int_init(numerator
);
644 cloog_int_init(denominator
);
646 if (!cloog_int_is_zero(line
[level
])) {
647 struct clast_reduction
*r
;
648 /* Maybe we need to invert signs in such a way that the element sign is>0.*/
649 sign
= -cloog_int_sgn(line
[level
]);
651 for (i
= 1, nb_elts
= 0; i
<= len
- 1; ++i
)
652 if (i
!= level
&& !cloog_int_is_zero(line
[i
]))
654 r
= new_clast_reduction(clast_red_sum
, nb_elts
);
657 /* First, we have to print the iterators and the parameters. */
658 for (i
= 1; i
<= len
- 2; i
++) {
659 struct clast_expr
*v
;
661 if (i
== level
|| cloog_int_is_zero(line
[i
]))
664 v
= cloog_constraint_variable_expr(constraint
, i
, names
);
667 cloog_int_neg(temp
,line
[i
]);
669 cloog_int_set(temp
,line
[i
]);
671 r
->elts
[nb_elts
++] = &new_clast_term(temp
, v
)->expr
;
675 cloog_int_neg(numerator
, line
[len
- 1]);
676 cloog_int_set(denominator
, line
[level
]);
679 cloog_int_set(numerator
, line
[len
- 1]);
680 cloog_int_neg(denominator
, line
[level
]);
683 /* Finally, the constant, and the final printing. */
685 if (!cloog_int_is_zero(numerator
))
686 r
->elts
[nb_elts
++] = &new_clast_term(numerator
, NULL
)->expr
;
688 if (!cloog_int_is_one(line
[level
]) && !cloog_int_is_neg_one(line
[level
]))
689 { if (!cloog_constraint_is_equality(constraint
))
690 { if (cloog_int_is_pos(line
[level
]))
691 e
= &new_clast_binary(clast_bin_cdiv
, &r
->expr
, denominator
)->expr
;
693 e
= &new_clast_binary(clast_bin_fdiv
, &r
->expr
, denominator
)->expr
;
695 e
= &new_clast_binary(clast_bin_div
, &r
->expr
, denominator
)->expr
;
700 free_clast_reduction(r
);
701 if (cloog_int_is_zero(numerator
))
702 e
= &new_clast_term(numerator
, NULL
)->expr
;
704 { if (!cloog_int_is_one(denominator
))
705 { if (!cloog_constraint_is_equality(constraint
)) { /* useful? */
706 if (cloog_int_is_divisible_by(numerator
, denominator
)) {
707 cloog_int_divexact(temp
, numerator
, denominator
);
708 e
= &new_clast_term(temp
, NULL
)->expr
;
711 cloog_int_init(division
);
712 cloog_int_tdiv_q(division
, numerator
, denominator
);
713 if (cloog_int_is_neg(numerator
)) {
714 if (cloog_int_is_pos(line
[level
])) {
716 e
= &new_clast_term(division
, NULL
)->expr
;
719 cloog_int_sub_ui(temp
, division
, 1);
720 e
= &new_clast_term(temp
, NULL
)->expr
;
724 { if (cloog_int_is_pos(line
[level
]))
725 { /* nb>0 need max */
726 cloog_int_add_ui(temp
, division
, 1);
727 e
= &new_clast_term(temp
, NULL
)->expr
;
731 e
= &new_clast_term(division
, NULL
)->expr
;
733 cloog_int_clear(division
);
737 e
= &new_clast_binary(clast_bin_div
,
738 &new_clast_term(numerator
, NULL
)->expr
,
742 e
= &new_clast_term(numerator
, NULL
)->expr
;
747 cloog_vec_free(line_vector
);
749 cloog_int_clear(temp
);
750 cloog_int_clear(numerator
);
751 cloog_int_clear(denominator
);
757 /* Temporary structure for communication between clast_minmax and
758 * its cloog_constraint_set_foreach_constraint callback functions.
760 struct clast_minmax_data
{
768 struct clast_reduction
*r
;
772 /* Should constraint "c" be considered by clast_minmax?
774 * If d->no_earlier is set, then the constraint may not involve
775 * any earlier variables.
777 static int valid_bound(CloogConstraint
*c
, struct clast_minmax_data
*d
)
781 if (d
->max
&& !cloog_constraint_is_lower_bound(c
, d
->level
- 1))
783 if (!d
->max
&& !cloog_constraint_is_upper_bound(c
, d
->level
- 1))
785 if (cloog_constraint_is_equality(c
))
787 if (d
->guard
&& cloog_constraint_involves(c
, d
->guard
- 1))
791 for (i
= 0; i
< d
->level
- 1; ++i
)
792 if (cloog_constraint_involves(c
, i
))
799 /* Increment n for each bound that should be considered by clast_minmax.
801 static int count_bounds(CloogConstraint
*c
, void *user
)
803 struct clast_minmax_data
*d
= (struct clast_minmax_data
*) user
;
805 if (!valid_bound(c
, d
))
814 /* Update the given lower bound based on stride information,
815 * for those cases where the stride offset is represented by
817 * Note that cloog_loop_stride may have already performed a
818 * similar update of the lower bounds, but the updated lower
819 * bounds may have been eliminated because they are redundant
820 * by definition. On the other hand, performing the update
821 * on an already updated constraint is an identity operation
822 * and is therefore harmless.
824 static CloogConstraint
*update_lower_bound_c(CloogConstraint
*c
, int level
,
827 if (!stride
->constraint
)
829 return cloog_constraint_stride_lower_bound(c
, level
, stride
);
833 /* Update the given lower bound based on stride information.
834 * If the stride offset is represented by a constraint,
835 * then we have already performed the update in update_lower_bound_c.
836 * Otherwise, the original lower bound is known to be a constant.
837 * If the bound has already been updated and it just happens
838 * to be a constant, then this function performs an identity
839 * operation on the constant.
841 static void update_lower_bound(struct clast_expr
*expr
, int level
,
844 struct clast_term
*t
;
845 if (stride
->constraint
)
847 if (expr
->type
!= clast_expr_term
)
849 t
= (struct clast_term
*)expr
;
852 cloog_int_sub(t
->val
, t
->val
, stride
->offset
);
853 cloog_int_cdiv_q(t
->val
, t
->val
, stride
->stride
);
854 cloog_int_mul(t
->val
, t
->val
, stride
->stride
);
855 cloog_int_add(t
->val
, t
->val
, stride
->offset
);
859 /* Add all relevant bounds to r->elts and update lower bounds
860 * based on stride information.
862 static int collect_bounds(CloogConstraint
*c
, void *user
)
864 struct clast_minmax_data
*d
= (struct clast_minmax_data
*) user
;
866 if (!valid_bound(c
, d
))
869 c
= cloog_constraint_copy(c
);
871 if (d
->lower_bound
&& d
->infos
->stride
[d
->level
- 1])
872 c
= update_lower_bound_c(c
, d
->level
, d
->infos
->stride
[d
->level
- 1]);
874 d
->r
->elts
[d
->n
] = clast_bound_from_constraint(c
, d
->level
,
876 if (d
->lower_bound
&& d
->infos
->stride
[d
->level
- 1]) {
877 update_lower_bound(d
->r
->elts
[d
->n
], d
->level
,
878 d
->infos
->stride
[d
->level
- 1]);
881 cloog_constraint_release(c
);
890 * clast_minmax function:
891 * This function returns a clast_expr containing the printing of a minimum or a
892 * maximum of the 'right parts' of all constraints according to an element.
893 * For instance consider the constraints:
897 * if we are looking for the minimum for the element j, the function should
898 * return 'max(ceild(3*i+M,2),-2*i)'.
899 * - constraints is the constraints,
900 * - level is the column number in domain of the element we want to use,
901 * - max is a boolean set to 1 if we are looking for a maximum, 0 for a minimum,
902 * - guard is set to 0 if there is no guard, and set to the level of the element
903 * with a guard otherwise (then the function gives the max or the min only
904 * for the constraint where the guarded coefficient is 0),
905 * - lower is set to 1 if the maximum is to be used a lower bound on a loop
906 * - no_earlier is set if no constraints should be used that involve
907 * earlier dimensions,
908 * - the infos structure gives the user some options about code printing,
909 * the number of parameters in domain (nb_par), and the arrays of iterator
910 * names and parameters (iters and params).
912 * - November 2nd 2001: first version.
914 static struct clast_expr
*clast_minmax(CloogConstraintSet
*constraints
,
915 int level
, int max
, int guard
,
916 int lower_bound
, int no_earlier
,
919 struct clast_minmax_data data
= { level
, max
, guard
, lower_bound
,
924 cloog_constraint_set_foreach_constraint(constraints
, count_bounds
, &data
);
928 data
.r
= new_clast_reduction(max
? clast_red_max
: clast_red_min
, data
.n
);
931 cloog_constraint_set_foreach_constraint(constraints
, collect_bounds
, &data
);
933 clast_reduction_sort(data
.r
);
934 return &data
.r
->expr
;
939 * Insert modulo guards defined by existentially quantified dimensions,
940 * not involving the given level.
942 * This function is called from within insert_guard.
943 * Any constraint used in constructing a modulo guard is removed
944 * from the constraint set to avoid insert_guard
945 * adding a duplicate (pair of) constraint(s).
947 * Return the updated CloogConstraintSet.
949 static CloogConstraintSet
*insert_extra_modulo_guards(
950 CloogConstraintSet
*constraints
, int level
,
951 struct clast_stmt
***next
, CloogInfos
*infos
)
956 CloogConstraint
*upper
, *lower
;
958 total_dim
= cloog_constraint_set_total_dimension(constraints
);
959 nb_iter
= cloog_constraint_set_n_iterators(constraints
,
960 infos
->names
->nb_parameters
);
962 for (i
= total_dim
- infos
->names
->nb_parameters
; i
>= nb_iter
+ 1; i
--) {
963 if (cloog_constraint_is_valid(upper
=
964 cloog_constraint_set_defining_equality(constraints
, i
))) {
965 if (!level
|| (nb_iter
< level
) ||
966 !cloog_constraint_involves(upper
, level
-1)) {
967 insert_modulo_guard(upper
,
968 cloog_constraint_invalid(), i
, next
, infos
);
969 constraints
= cloog_constraint_set_drop_constraint(constraints
,
972 cloog_constraint_release(upper
);
973 } else if (cloog_constraint_is_valid(upper
=
974 cloog_constraint_set_defining_inequalities(constraints
,
975 i
, &lower
, infos
->names
->nb_parameters
))) {
976 if (!level
|| (nb_iter
< level
) ||
977 !cloog_constraint_involves(upper
, level
-1)) {
978 insert_modulo_guard(upper
, lower
, i
, next
, infos
);
979 constraints
= cloog_constraint_set_drop_constraint(constraints
,
981 constraints
= cloog_constraint_set_drop_constraint(constraints
,
984 cloog_constraint_release(upper
);
985 cloog_constraint_release(lower
);
993 /* Temporary structure for communication between insert_guard and
994 * its cloog_constraint_set_foreach_constraint callback function.
996 struct clast_guard_data
{
1002 CloogConstraintSet
*copy
;
1003 struct clast_guard
*g
;
1010 static int guard_count_bounds(CloogConstraint
*c
, void *user
)
1012 struct clast_guard_data
*d
= (struct clast_guard_data
*) user
;
1020 /* Insert a guard, if necesessary, for constraint j.
1022 * If the constraint involves any earlier dimensions, then we have
1023 * already considered it during a previous iteration over the constraints.
1025 * If we have already generated a min [max] for the current level d->i
1026 * and if the current constraint is an upper [lower] bound, then we
1027 * can skip the constraint as it will already have been used
1028 * in that previously generated min [max].
1030 static int insert_guard_constraint(CloogConstraint
*j
, void *user
)
1033 struct clast_guard_data
*d
= (struct clast_guard_data
*) user
;
1035 int individual_constraint
;
1036 struct clast_expr
*v
;
1037 struct clast_term
*t
;
1039 if (!cloog_constraint_involves(j
, d
->i
- 1))
1042 for (i
= 0; i
< d
->i
- 1; ++i
)
1043 if (cloog_constraint_involves(j
, i
))
1046 if (d
->level
&& d
->nb_iter
>= d
->level
&&
1047 cloog_constraint_involves(j
, d
->level
- 1))
1050 individual_constraint
= !d
->level
|| cloog_constraint_is_equality(j
);
1051 if (!individual_constraint
) {
1052 if (d
->max
&& cloog_constraint_is_lower_bound(j
, d
->i
- 1))
1054 if (d
->min
&& cloog_constraint_is_upper_bound(j
, d
->i
- 1))
1058 v
= cloog_constraint_variable_expr(j
, d
->i
, d
->infos
->names
);
1059 d
->g
->eq
[d
->n
].LHS
= &(t
= new_clast_term(d
->infos
->state
->one
, v
))->expr
;
1060 if (individual_constraint
) {
1061 /* put the "denominator" in the LHS */
1062 cloog_constraint_coefficient_get(j
, d
->i
- 1, &t
->val
);
1063 cloog_constraint_coefficient_set(j
, d
->i
- 1, d
->infos
->state
->one
);
1064 if (cloog_int_is_neg(t
->val
)) {
1065 cloog_int_neg(t
->val
, t
->val
);
1066 cloog_constraint_coefficient_set(j
, d
->i
- 1, d
->infos
->state
->negone
);
1068 if (d
->level
|| cloog_constraint_is_equality(j
))
1069 d
->g
->eq
[d
->n
].sign
= 0;
1070 else if (cloog_constraint_is_lower_bound(j
, d
->i
- 1))
1071 d
->g
->eq
[d
->n
].sign
= 1;
1073 d
->g
->eq
[d
->n
].sign
= -1;
1074 d
->g
->eq
[d
->n
].RHS
= clast_bound_from_constraint(j
, d
->i
, d
->infos
->names
);
1078 if (cloog_constraint_is_lower_bound(j
, d
->i
- 1)) {
1081 d
->g
->eq
[d
->n
].sign
= 1;
1085 d
->g
->eq
[d
->n
].sign
= -1;
1088 guarded
= (d
->nb_iter
>= d
->level
) ? d
->level
: 0 ;
1089 d
->g
->eq
[d
->n
].RHS
= clast_minmax(d
->copy
, d
->i
, minmax
, guarded
, 0, 1,
1099 * insert_guard function:
1100 * This function inserts a guard in the clast.
1101 * A guard on an element (level) is :
1102 * -> the conjunction of all the existing constraints where the coefficient of
1103 * this element is 0 if the element is an iterator,
1104 * -> the conjunction of all the existing constraints if the element isn't an
1106 * For instance, considering these constraints and the element j:
1109 * this function should return 'if (2*i+M>=0) {'.
1110 * - matrix is the polyhedron containing all the constraints,
1111 * - level is the column number of the element in matrix we want to use,
1112 * - the infos structure gives the user some options about code printing,
1113 * the number of parameters in matrix (nb_par), and the arrays of iterator
1114 * names and parameters (iters and params).
1116 * - November 3rd 2001: first version.
1117 * - November 14th 2001: a lot of 'purifications'.
1118 * - July 31th 2002: (debug) some guard parts are no more redundants.
1119 * - August 12th 2002: polyhedra union ('or' conditions) are now supported.
1120 * - October 27th 2005: polyhedra union ('or' conditions) are no more supported
1121 * (the need came from loop_simplify that may result in
1122 * domain unions, now it should be fixed directly in
1123 * cloog_loop_simplify).
1125 static void insert_guard(CloogConstraintSet
*constraints
, int level
,
1126 struct clast_stmt
***next
, CloogInfos
*infos
)
1129 struct clast_guard_data data
= { level
, infos
, 0 };
1134 data
.copy
= cloog_constraint_set_copy(constraints
);
1136 data
.copy
= insert_extra_modulo_guards(data
.copy
, level
, next
, infos
);
1138 cloog_constraint_set_foreach_constraint(constraints
,
1139 guard_count_bounds
, &data
);
1141 data
.g
= new_clast_guard(data
.n
);
1144 /* Well, it looks complicated because I wanted to have a particular, more
1145 * readable, ordering, obviously this function may be far much simpler !
1147 data
.nb_iter
= cloog_constraint_set_n_iterators(constraints
,
1148 infos
->names
->nb_parameters
);
1150 /* We search for guard parts. */
1151 total_dim
= cloog_constraint_set_total_dimension(constraints
);
1152 for (data
.i
= 1; data
.i
<= total_dim
; data
.i
++) {
1155 cloog_constraint_set_foreach_constraint(data
.copy
,
1156 insert_guard_constraint
, &data
);
1159 cloog_constraint_set_free(data
.copy
);
1163 clast_guard_sort(data
.g
);
1164 **next
= &data
.g
->stmt
;
1165 *next
= &data
.g
->then
;
1167 free_clast_stmt(&data
.g
->stmt
);
1171 * Check if the constant "cst" satisfies the modulo guard that
1172 * would be introduced by insert_computed_modulo_guard.
1173 * The constant is assumed to have been reduced prior to calling
1176 static int constant_modulo_guard_is_satisfied(CloogConstraint
*lower
,
1177 cloog_int_t bound
, cloog_int_t cst
)
1179 if (cloog_constraint_is_valid(lower
))
1180 return cloog_int_le(cst
, bound
);
1182 return cloog_int_is_zero(cst
);
1186 * Insert a modulo guard "r % mod == 0" or "r % mod <= bound",
1187 * depending on whether lower represents a valid constraint.
1189 static void insert_computed_modulo_guard(struct clast_reduction
*r
,
1190 CloogConstraint
*lower
, cloog_int_t mod
, cloog_int_t bound
,
1191 struct clast_stmt
***next
)
1193 struct clast_expr
*e
;
1194 struct clast_guard
*g
;
1196 e
= &new_clast_binary(clast_bin_mod
, &r
->expr
, mod
)->expr
;
1197 g
= new_clast_guard(1);
1198 if (!cloog_constraint_is_valid(lower
)) {
1200 cloog_int_set_si(bound
, 0);
1201 g
->eq
[0].RHS
= &new_clast_term(bound
, NULL
)->expr
;
1205 g
->eq
[0].RHS
= &new_clast_term(bound
, NULL
)->expr
;
1214 /* Try and eliminate coefficients from a modulo constraint based on
1215 * stride information of an earlier level.
1216 * The modulo of the constraint being constructed is "m".
1217 * The stride information at level "level" is given by "stride"
1218 * and indicated that the iterator i at level "level" is equal to
1219 * some expression modulo stride->stride.
1220 * If stride->stride is a multiple of "m' then i is also equal to
1221 * the expression modulo m and so we can eliminate the coefficient of i.
1223 * If stride->constraint is NULL, then i has a constant value modulo m, stored
1224 * stride->offset. We simply multiply this constant with the coefficient
1225 * of i and add the result to the constant term, reducing it modulo m.
1227 * If stride->constraint is not NULL, then it is a constraint of the form
1231 * with s equal to stride->stride, e an expression in terms of the
1232 * parameters and earlier iterators and a some arbitrary expression
1233 * in terms of existentially quantified variables.
1234 * stride->factor is a value f such that f * k = -1 mod s.
1235 * Adding stride->constraint f * c times to the current modulo constraint,
1236 * with c the coefficient of i eliminates i in favor of parameters and
1237 * earlier variables.
1239 static void eliminate_using_stride_constraint(cloog_int_t
*line
, int len
,
1240 int nb_iter
, CloogStride
*stride
, int level
, cloog_int_t m
)
1244 if (!cloog_int_is_divisible_by(stride
->stride
, m
))
1247 if (stride
->constraint
) {
1253 cloog_int_mul(t
, line
[level
], stride
->factor
);
1254 for (i
= 1; i
< level
; ++i
) {
1255 cloog_constraint_coefficient_get(stride
->constraint
,
1257 cloog_int_addmul(line
[i
], t
, v
);
1258 cloog_int_fdiv_r(line
[i
], line
[i
], m
);
1260 s_len
= cloog_constraint_total_dimension(stride
->constraint
)+2;
1261 for (i
= nb_iter
+ 1; i
<= len
- 2; ++i
) {
1262 cloog_constraint_coefficient_get(stride
->constraint
,
1263 i
- (len
- s_len
) - 1, &v
);
1264 cloog_int_addmul(line
[i
], t
, v
);
1265 cloog_int_fdiv_r(line
[i
], line
[i
], m
);
1267 cloog_constraint_constant_get(stride
->constraint
, &v
);
1268 cloog_int_addmul(line
[len
- 1], t
, v
);
1269 cloog_int_fdiv_r(line
[len
- 1], line
[len
- 1], m
);
1273 cloog_int_addmul(line
[len
- 1], line
[level
], stride
->offset
);
1274 cloog_int_fdiv_r(line
[len
- 1], line
[len
- 1], m
);
1277 cloog_int_set_si(line
[level
], 0);
1281 /* Temporary structure for communication between insert_modulo_guard and
1282 * its cloog_constraint_set_foreach_constraint callback function.
1284 struct clast_modulo_guard_data
{
1285 CloogConstraint
*lower
;
1287 struct clast_stmt
***next
;
1290 cloog_int_t val
, bound
;
1294 /* Insert a modulo guard for constraint c.
1295 * The constraint may be either an equality or an inequality.
1296 * Since this function returns -1, it is only called on a single constraint.
1297 * In case of an inequality, the constraint is usually an upper bound
1298 * on d->level. However, if this variable is an existentially
1299 * quantified variable, the upper bound constraint may get removed
1300 * as trivially holding and then this function is called with
1301 * a lower bound instead. In this case, we need to adjust the constraint
1302 * based on the sum of the constant terms of the lower and upper bound
1303 * stored in d->bound.
1305 static int insert_modulo_guard_constraint(CloogConstraint
*c
, void *user
)
1307 struct clast_modulo_guard_data
*d
= (struct clast_modulo_guard_data
*) user
;
1308 int level
= d
->level
;
1309 CloogInfos
*infos
= d
->infos
;
1310 int i
, nb_elts
= 0, len
, nb_iter
, nb_par
;
1312 struct cloog_vec
*line_vector
;
1315 len
= cloog_constraint_total_dimension(c
) + 2;
1316 nb_par
= infos
->names
->nb_parameters
;
1317 nb_iter
= len
- 2 - nb_par
;
1319 line_vector
= cloog_vec_alloc(len
);
1320 line
= line_vector
->p
;
1321 cloog_constraint_copy_coefficients(c
, line
+ 1);
1323 if (cloog_int_is_pos(line
[level
])) {
1324 cloog_seq_neg(line
+ 1, line
+ 1, len
- 1);
1325 if (!cloog_constraint_is_equality(c
))
1326 cloog_int_add(line
[len
- 1], line
[len
- 1], d
->bound
);
1328 cloog_int_neg(line
[level
], line
[level
]);
1329 assert(cloog_int_is_pos(line
[level
]));
1332 for (i
= 1; i
<= len
-1; ++i
) {
1335 cloog_int_fdiv_r(line
[i
], line
[i
], line
[level
]);
1336 if (cloog_int_is_zero(line
[i
]))
1344 if (nb_elts
|| !cloog_int_is_zero(line
[len
-1])) {
1345 struct clast_reduction
*r
;
1348 r
= new_clast_reduction(clast_red_sum
, nb_elts
+ 1);
1351 /* First, the modulo guard : the iterators... */
1353 if (i
> infos
->stride_level
)
1354 i
= infos
->stride_level
;
1356 eliminate_using_stride_constraint(line
, len
, nb_iter
,
1357 infos
->stride
[i
- 1], i
, line
[level
]);
1358 for (i
=1;i
<=nb_iter
;i
++) {
1359 if (i
== level
|| cloog_int_is_zero(line
[i
]))
1362 name
= cloog_names_name_at_level(infos
->names
, i
);
1364 r
->elts
[nb_elts
++] = &new_clast_term(line
[i
],
1365 &new_clast_name(name
)->expr
)->expr
;
1368 /* ...the parameters... */
1369 for (i
=nb_iter
+1;i
<=len
-2;i
++) {
1370 if (cloog_int_is_zero(line
[i
]))
1373 name
= infos
->names
->parameters
[i
-nb_iter
-1] ;
1374 r
->elts
[nb_elts
++] = &new_clast_term(line
[i
],
1375 &new_clast_name(name
)->expr
)->expr
;
1378 constant
= nb_elts
== 0;
1379 /* ...the constant. */
1380 if (!cloog_int_is_zero(line
[len
-1]))
1381 r
->elts
[nb_elts
++] = &new_clast_term(line
[len
-1], NULL
)->expr
;
1383 /* our initial computation may have been an overestimate */
1387 d
->empty
= !constant_modulo_guard_is_satisfied(d
->lower
, d
->bound
,
1389 free_clast_reduction(r
);
1391 insert_computed_modulo_guard(r
, d
->lower
, line
[level
], d
->bound
,
1395 cloog_vec_free(line_vector
);
1402 * insert_modulo_guard:
1403 * This function inserts a modulo guard corresponding to an equality
1404 * or a pair of inequalities.
1405 * Returns 0 if the modulo guard is discovered to be unsatisfiable.
1407 * See insert_equation.
1408 * - matrix is the polyhedron containing all the constraints,
1409 * - upper and lower are the line numbers of the constraint in matrix
1410 * we want to print; in particular, if we want to print an equality,
1411 * then lower == -1 and upper is the row of the equality; if we want
1412 * to print an inequality, then upper is the row of the upper bound
1413 * and lower in the row of the lower bound
1414 * - level is the column number of the element in matrix we want to use,
1415 * - the infos structure gives the user some options about code printing,
1416 * the number of parameters in matrix (nb_par), and the arrays of iterator
1417 * names and parameters (iters and params).
1419 static int insert_modulo_guard(CloogConstraint
*upper
,
1420 CloogConstraint
*lower
, int level
,
1421 struct clast_stmt
***next
, CloogInfos
*infos
)
1424 CloogConstraintSet
*set
;
1425 struct clast_modulo_guard_data data
= { lower
, level
, next
, infos
, 0 };
1427 cloog_int_init(data
.val
);
1428 cloog_constraint_coefficient_get(upper
, level
-1, &data
.val
);
1429 if (cloog_int_is_one(data
.val
) || cloog_int_is_neg_one(data
.val
)) {
1430 cloog_int_clear(data
.val
);
1434 nb_par
= infos
->names
->nb_parameters
;
1436 cloog_int_init(data
.bound
);
1437 /* Check if would be emitting the redundant constraint mod(e,m) <= m-1 */
1438 if (cloog_constraint_is_valid(lower
)) {
1439 cloog_constraint_constant_get(upper
, &data
.val
);
1440 cloog_constraint_constant_get(lower
, &data
.bound
);
1441 cloog_int_add(data
.bound
, data
.val
, data
.bound
);
1442 cloog_constraint_coefficient_get(lower
, level
-1, &data
.val
);
1443 cloog_int_sub_ui(data
.val
, data
.val
, 1);
1444 if (cloog_int_eq(data
.val
, data
.bound
)) {
1445 cloog_int_clear(data
.val
);
1446 cloog_int_clear(data
.bound
);
1451 if (cloog_constraint_needs_reduction(upper
, level
)) {
1452 set
= cloog_constraint_set_for_reduction(upper
, lower
);
1453 set
= cloog_constraint_set_reduce(set
, level
, infos
->equal
,
1454 nb_par
, &data
.bound
);
1455 cloog_constraint_set_foreach_constraint(set
,
1456 insert_modulo_guard_constraint
, &data
);
1457 cloog_constraint_set_free(set
);
1459 insert_modulo_guard_constraint(upper
, &data
);
1461 cloog_int_clear(data
.val
);
1462 cloog_int_clear(data
.bound
);
1469 * We found an equality or a pair of inequalities identifying
1470 * a loop with a single iteration, but the user wants us to generate
1471 * a loop anyway, so we do it here.
1473 static int insert_equation_as_loop(CloogDomain
*domain
, CloogConstraint
*upper
,
1474 CloogConstraint
*lower
, int level
, struct clast_stmt
***next
,
1477 const char *iterator
= cloog_names_name_at_level(infos
->names
, level
);
1478 struct clast_expr
*e1
, *e2
;
1479 struct clast_for
*f
;
1481 e2
= clast_bound_from_constraint(upper
, level
, infos
->names
);
1482 if (!cloog_constraint_is_valid(lower
))
1483 e1
= clast_expr_copy(e2
);
1485 e1
= clast_bound_from_constraint(lower
, level
, infos
->names
);
1487 f
= new_clast_for(domain
, iterator
, e1
, e2
, infos
->stride
[level
-1]);
1491 cloog_constraint_release(lower
);
1492 cloog_constraint_release(upper
);
1498 * insert_equation function:
1499 * This function inserts an equality
1500 * constraint according to an element in the clast.
1501 * Returns 1 if the calling function should recurse into inner loops.
1503 * An equality can be preceded by a 'modulo guard'.
1504 * For instance, consider the constraint i -2*j = 0 and the
1505 * element j: pprint_equality should return 'if(i%2==0) { j = i/2 ;'.
1506 * - matrix is the polyhedron containing all the constraints,
1507 * - num is the line number of the constraint in matrix we want to print,
1508 * - level is the column number of the element in matrix we want to use,
1509 * - the infos structure gives the user some options about code printing,
1510 * the number of parameters in matrix (nb_par), and the arrays of iterator
1511 * names and parameters (iters and params).
1513 * - November 13th 2001: first version.
1514 * - June 26th 2003: simplification of the modulo guards (remove parts such as
1515 * modulo is 0, compare vivien or vivien2 with a previous
1516 * version for an idea).
1517 * - June 29th 2003: non-unit strides support.
1518 * - July 14th 2003: (debug) no more print the constant in the modulo guard when
1519 * it was previously included in a stride calculation.
1521 static int insert_equation(CloogDomain
*domain
, CloogConstraint
*upper
,
1522 CloogConstraint
*lower
, int level
, struct clast_stmt
1523 ***next
, CloogInfos
*infos
)
1525 struct clast_expr
*e
;
1526 struct clast_assignment
*ass
;
1528 if (!infos
->options
->otl
)
1529 return insert_equation_as_loop(domain
, upper
, lower
, level
, next
, infos
);
1531 if (!insert_modulo_guard(upper
, lower
, level
, next
, infos
)) {
1532 cloog_constraint_release(lower
);
1533 cloog_constraint_release(upper
);
1538 if (cloog_constraint_is_valid(lower
) ||
1539 !clast_equal_add(infos
->equal
, NULL
, level
, upper
, infos
))
1540 { /* Finally, the equality. */
1542 /* If we have to make a block by dimension, we start the block. Function
1543 * pprint knows if there is an equality, if this is the case, it checks
1544 * for the same following condition to close the brace.
1546 if (infos
->options
->block
) {
1547 struct clast_block
*b
= new_clast_block();
1552 e
= clast_bound_from_constraint(upper
, level
, infos
->names
);
1553 ass
= new_clast_assignment(cloog_names_name_at_level(infos
->names
, level
), e
);
1555 **next
= &ass
->stmt
;
1556 *next
= &(**next
)->next
;
1559 cloog_constraint_release(lower
);
1560 cloog_constraint_release(upper
);
1567 * Insert a loop that is executed exactly once as an assignment.
1568 * In particular, the loop
1570 * for (i = e; i <= e; ++i) {
1580 static void insert_otl_for(CloogConstraintSet
*constraints
, int level
,
1581 struct clast_expr
*e
, struct clast_stmt
***next
, CloogInfos
*infos
)
1583 const char *iterator
;
1585 iterator
= cloog_names_name_at_level(infos
->names
, level
);
1587 if (!clast_equal_add(infos
->equal
, constraints
, level
,
1588 cloog_constraint_invalid(), infos
)) {
1589 struct clast_assignment
*ass
;
1590 if (infos
->options
->block
) {
1591 struct clast_block
*b
= new_clast_block();
1595 ass
= new_clast_assignment(iterator
, e
);
1596 **next
= &ass
->stmt
;
1597 *next
= &(**next
)->next
;
1605 * Insert a loop that is executed at most once as an assignment followed
1606 * by a guard. In particular, the loop
1608 * for (i = e1; i <= e2; ++i) {
1620 static void insert_guarded_otl_for(CloogConstraintSet
*constraints
, int level
,
1621 struct clast_expr
*e1
, struct clast_expr
*e2
,
1622 struct clast_stmt
***next
, CloogInfos
*infos
)
1624 const char *iterator
;
1625 struct clast_assignment
*ass
;
1626 struct clast_guard
*guard
;
1628 iterator
= cloog_names_name_at_level(infos
->names
, level
);
1630 if (infos
->options
->block
) {
1631 struct clast_block
*b
= new_clast_block();
1635 ass
= new_clast_assignment(iterator
, e1
);
1636 **next
= &ass
->stmt
;
1637 *next
= &(**next
)->next
;
1639 guard
= new_clast_guard(1);
1640 guard
->eq
[0].sign
= -1;
1641 guard
->eq
[0].LHS
= &new_clast_term(infos
->state
->one
,
1642 &new_clast_name(iterator
)->expr
)->expr
;
1643 guard
->eq
[0].RHS
= e2
;
1645 **next
= &guard
->stmt
;
1646 *next
= &guard
->then
;
1651 * insert_for function:
1652 * This function inserts a for loop in the clast.
1653 * Returns 1 if the calling function should recurse into inner loops.
1655 * A loop header according to an element is the conjunction of a minimum and a
1656 * maximum on a given element (they give the loop bounds).
1657 * For instance, considering these constraints and the element j:
1661 * this function should return 'for (j=max(-i+9*M,4*M),j<=5*M;j++) {'.
1662 * - constraints contains all constraints,
1663 * - level is the column number of the element in matrix we want to use,
1664 * - otl is set if the loop is executed at most once,
1665 * - the infos structure gives the user some options about code printing,
1666 * the number of parameters in matrix (nb_par), and the arrays of iterator
1667 * names and parameters (iters and params).
1669 static int insert_for(CloogDomain
*domain
, CloogConstraintSet
*constraints
,
1670 int level
, int otl
, struct clast_stmt
***next
,
1673 const char *iterator
;
1674 struct clast_expr
*e1
;
1675 struct clast_expr
*e2
;
1677 e1
= clast_minmax(constraints
, level
, 1, 0, 1, 0, infos
);
1678 e2
= clast_minmax(constraints
, level
, 0, 0, 0, 0, infos
);
1680 if (clast_expr_is_bigger_constant(e1
, e2
)) {
1681 free_clast_expr(e1
);
1682 free_clast_expr(e2
);
1686 /* If min and max are not equal there is a 'for' else, there is a '='.
1687 * In the special case e1 = e2 = NULL, this is an infinite loop
1688 * so this is not a '='.
1690 if (e1
&& e2
&& infos
->options
->otl
&& clast_expr_equal(e1
, e2
)) {
1691 free_clast_expr(e2
);
1692 insert_otl_for(constraints
, level
, e1
, next
, infos
);
1694 insert_guarded_otl_for(constraints
, level
, e1
, e2
, next
, infos
);
1696 struct clast_for
*f
;
1697 iterator
= cloog_names_name_at_level(infos
->names
, level
);
1699 f
= new_clast_for(domain
, iterator
, e1
, e2
, infos
->stride
[level
-1]);
1709 * insert_block function:
1710 * This function inserts a statement block.
1711 * - block is the statement block,
1712 * - level is the number of loops enclosing the statement,
1713 * - the infos structure gives the user some options about code printing,
1714 * the number of parameters in domain (nb_par), and the arrays of iterator
1715 * names and parameters (iters and params).
1717 * - September 21th 2003: first version (pick from pprint function).
1719 static void insert_block(CloogDomain
*domain
, CloogBlock
*block
, int level
,
1720 struct clast_stmt
***next
, CloogInfos
*infos
)
1722 CloogStatement
* statement
;
1723 struct clast_stmt
*subs
;
1728 for (statement
= block
->statement
; statement
; statement
= statement
->next
) {
1729 CloogStatement
*s_next
= statement
->next
;
1731 subs
= clast_equal(level
,infos
);
1733 statement
->next
= NULL
;
1734 **next
= &new_clast_user_stmt(domain
, statement
, subs
)->stmt
;
1735 statement
->next
= s_next
;
1736 *next
= &(**next
)->next
;
1742 * insert_loop function:
1743 * This function converts the content of a CloogLoop structure (loop) into a
1744 * clast_stmt (inserted at **next).
1745 * The iterator (level) of
1746 * the current loop is given by 'level': this is the column number of the
1747 * domain corresponding to the current loop iterator. The data of a loop are
1748 * written in this order:
1749 * 1. The guard of the loop, i.e. each constraint in the domain that does not
1750 * depend on the iterator (when the entry in the column 'level' is 0).
1751 * 2. The iteration domain of the iterator, given by the constraints in the
1752 * domain depending on the iterator, i.e.:
1753 * * an equality if the iterator has only one value (possibly preceded by
1754 * a guard verifying if this value is integral), *OR*
1755 * * a loop from the minimum possible value of the iterator to the maximum
1757 * 3. The included statement block.
1758 * 4. The inner loops (recursive call).
1759 * 5. The following loops (recursive call).
1760 * - level is the recursion level or the iteration level that we are printing,
1761 * - the infos structure gives the user some options about code printing,
1762 * the number of parameters in domain (nb_par), and the arrays of iterator
1763 * names and parameters (iters and params).
1765 * - November 2nd 2001: first version.
1766 * - March 6th 2003: infinite domain support.
1767 * - April 19th 2003: (debug) NULL loop support.
1768 * - June 29th 2003: non-unit strides support.
1769 * - April 28th 2005: (debug) level is level+equality when print statement!
1770 * - June 16th 2005: (debug) the N. Vasilache normalization step has been
1771 * added to avoid iteration duplication (see DaeGon Kim
1772 * bug in cloog_program_generate). Try vasilache.cloog
1773 * with and without the call to cloog_polylib_matrix_normalize,
1774 * using -f 8 -l 9 options for an idea.
1775 * - September 15th 2005: (debug) don't close equality braces when unnecessary.
1776 * - October 16th 2005: (debug) scalar value is saved for next loops.
1778 static void insert_loop(CloogLoop
* loop
, int level
,
1779 struct clast_stmt
***next
, CloogInfos
*infos
)
1782 CloogConstraintSet
*constraints
, *temp
;
1783 struct clast_stmt
**top
= *next
;
1784 CloogConstraint
*i
, *j
;
1787 /* It can happen that loop be NULL when an input polyhedron is empty. */
1791 /* The constraints do not always have a shape that allows us to generate code from it,
1792 * thus we normalize it, we also simplify it with the equalities.
1794 temp
= cloog_domain_constraints(loop
->domain
);
1795 cloog_constraint_set_normalize(temp
,level
);
1796 constraints
= cloog_constraint_set_simplify(temp
,infos
->equal
,level
,
1797 infos
->names
->nb_parameters
);
1798 cloog_constraint_set_free(temp
);
1800 infos
->stride
[level
- 1] = loop
->stride
;
1801 infos
->stride_level
++;
1804 /* First of all we have to print the guard. */
1805 insert_guard(constraints
,level
, next
, infos
);
1807 if (level
&& cloog_constraint_set_contains_level(constraints
, level
,
1808 infos
->names
->nb_parameters
)) {
1809 /* We scan all the constraints to know in which case we are :
1810 * [[if] equation] or [for].
1812 if (cloog_constraint_is_valid(i
=
1813 cloog_constraint_set_defining_equality(constraints
, level
))) {
1814 empty_loop
= !insert_equation(loop
->unsimplified
, i
,
1815 cloog_constraint_invalid(), level
, next
,
1818 } else if (cloog_constraint_is_valid(i
=
1819 cloog_constraint_set_defining_inequalities(constraints
,
1820 level
, &j
, infos
->names
->nb_parameters
))) {
1821 empty_loop
= !insert_equation(loop
->unsimplified
, i
, j
, level
, next
,
1824 empty_loop
= !insert_for(loop
->unsimplified
, constraints
, level
,
1825 loop
->otl
, next
, infos
);
1829 /* Finally, if there is an included statement block, print it. */
1830 insert_block(loop
->unsimplified
, loop
->block
, level
+equality
, next
, infos
);
1832 /* Go to the next level. */
1833 if (loop
->inner
!= NULL
)
1834 insert_loop(loop
->inner
, level
+1, next
, infos
);
1838 cloog_equal_del(infos
->equal
,level
);
1839 infos
->stride_level
--;
1841 cloog_constraint_set_free(constraints
);
1843 /* Go to the next loop on the same level. */
1845 top
= &(*top
)->next
;
1846 if (loop
->next
!= NULL
)
1847 insert_loop(loop
->next
, level
, &top
,infos
);
1851 struct clast_stmt
*cloog_clast_create(CloogProgram
*program
,
1852 CloogOptions
*options
)
1854 CloogInfos
*infos
= ALLOC(CloogInfos
);
1856 struct clast_stmt
*root
= &new_clast_root(program
->names
)->stmt
;
1857 struct clast_stmt
**next
= &root
->next
;
1859 infos
->state
= options
->state
;
1860 infos
->names
= program
->names
;
1861 infos
->options
= options
;
1862 infos
->scaldims
= program
->scaldims
;
1863 infos
->nb_scattdims
= program
->nb_scattdims
;
1865 /* Allocation for the array of strides, there is a +1 since the statement can
1866 * be included inside an external loop without iteration domain.
1868 nb_levels
= program
->names
->nb_scattering
+program
->names
->nb_iterators
+1;
1869 infos
->stride
= ALLOCN(CloogStride
*, nb_levels
);
1870 infos
->stride_level
= 0;
1872 infos
->equal
= cloog_equal_alloc(nb_levels
,
1873 nb_levels
, program
->names
->nb_parameters
);
1875 insert_loop(program
->loop
, 0, &next
, infos
);
1877 cloog_equal_free(infos
->equal
);
1879 free(infos
->stride
);
1886 struct clast_stmt
*cloog_clast_create_from_input(CloogInput
*input
,
1887 CloogOptions
*options
)
1889 CloogProgram
*program
;
1890 struct clast_stmt
*root
;
1892 program
= cloog_program_alloc(input
->context
, input
->ud
, options
);
1895 program
= cloog_program_generate(program
, options
);
1897 root
= cloog_clast_create(program
, options
);
1898 cloog_program_free(program
);
1903 /* Adds to the list if not already in it */
1904 static int add_if_new(void **list
, int num
, void *new, int size
)
1908 for (i
=0; i
<num
; i
++) {
1909 if (!memcmp((*list
) + i
*size
, new, size
)) break;
1913 *list
= realloc(*list
, (num
+1)*size
);
1914 memcpy(*list
+ num
*size
, new, size
);
1922 /* Concatenates all elements of list2 that are not in list1;
1923 * Returns the new size of the list */
1924 int concat_if_new(void **list1
, int num1
, void *list2
, int num2
, int size
)
1928 for (i
=0; i
<num2
; i
++) {
1929 ret
= add_if_new(list1
, num1
, (char *)list2
+ i
*size
, size
);
1936 /* Compares list1 to list2
1937 * Returns 0 if both have the same elements; returns -1 if all elements of
1938 * list1 are strictly contained in list2; 1 otherwise
1940 int list_compare(const int *list1
, int num1
, const int *list2
, int num2
)
1944 for (i
=0; i
<num1
; i
++) {
1945 for (j
=0; j
<num2
; j
++) {
1946 if (list1
[i
] == list2
[j
]) break;
1963 * A multi-purpose function to traverse and get information on Clast
1966 * node: clast node where processing should start
1969 * A list of loops under clast_stmt 'node' filtered in two ways: (1) it contains
1970 * statements appearing in 'stmts_filter', (2) loop iterator's name is 'iter'
1971 * If iter' is set to NULL, no filtering based on iterator name is done
1973 * iter: loop iterator name
1974 * stmts_filter: list of statement numbers for filtering (1-indexed)
1975 * nstmts_filter: number of statements in stmts_filter
1977 * FilterType: match exact (i.e., loops containing only and all those statements
1978 * in stmts_filter) or subset, i.e., loops which have only those statements
1979 * that appear in stmts_filter
1981 * To disable all filtering, set 'iter' to NULL, provide all statement
1982 * numbers in 'stmts_filter' and set FilterType to subset
1986 * stmts: an array of statement numbers under node
1987 * nstmts: number of stmt numbers pointed to by stmts
1988 * loops: list of clast loops
1989 * nloops: number of clast loops in loops
1992 void clast_filter(struct clast_stmt
*node
,
1994 struct clast_for
***loops
, int *nloops
,
1995 int **stmts
, int *nstmts
)
1997 int num_next_stmts
, num_next_loops
, ret
, *stmts_next
;
1998 struct clast_for
**loops_next
;
2009 ClastFilterType filter_type
= filter
.filter_type
;
2010 const char *iter
= filter
.iter
;
2011 int nstmts_filter
= filter
.nstmts_filter
;
2012 const int *stmts_filter
= filter
.stmts_filter
;
2014 if (CLAST_STMT_IS_A(node
, stmt_root
)) {
2015 // printf("root stmt\n");
2016 struct clast_root
*root
= (struct clast_root
*) node
;
2017 clast_filter((root
->stmt
).next
, filter
, &loops_next
,
2018 &num_next_loops
, &stmts_next
, &num_next_stmts
);
2019 *nstmts
= concat_if_new((void **)stmts
, *nstmts
, stmts_next
, num_next_stmts
, sizeof(int));
2020 *nloops
= concat_if_new((void **)loops
, *nloops
, loops_next
, num_next_loops
,
2021 sizeof(struct clast_stmt
*));
2026 if (CLAST_STMT_IS_A(node
, stmt_guard
)) {
2027 // printf("guard stmt\n");
2028 struct clast_guard
*guard
= (struct clast_guard
*) node
;
2029 clast_filter(guard
->then
, filter
, &loops_next
,
2030 &num_next_loops
, &stmts_next
, &num_next_stmts
);
2031 *nstmts
= concat_if_new((void **)stmts
, *nstmts
, stmts_next
, num_next_stmts
, sizeof(int));
2032 *nloops
= concat_if_new((void **)loops
, *nloops
, loops_next
, num_next_loops
,
2033 sizeof(struct clast_stmt
*));
2036 clast_filter((guard
->stmt
).next
, filter
, &loops_next
,
2037 &num_next_loops
, &stmts_next
, &num_next_stmts
);
2038 *nstmts
= concat_if_new((void **)stmts
, *nstmts
, stmts_next
, num_next_stmts
, sizeof(int));
2039 *nloops
= concat_if_new((void **)loops
, *nloops
, loops_next
, num_next_loops
,
2040 sizeof(struct clast_stmt
*));
2045 if (CLAST_STMT_IS_A(node
, stmt_user
)) {
2046 struct clast_user_stmt
*user_stmt
= (struct clast_user_stmt
*) node
;
2047 // printf("user stmt: S%d\n", user_stmt->statement->number);
2048 ret
= add_if_new((void **)stmts
, *nstmts
, &user_stmt
->statement
->number
, sizeof(int));
2049 if (ret
) (*nstmts
)++;
2050 clast_filter((user_stmt
->stmt
).next
, filter
, &loops_next
,
2051 &num_next_loops
, &stmts_next
, &num_next_stmts
);
2052 *nstmts
= concat_if_new((void **)stmts
, *nstmts
, stmts_next
, num_next_stmts
, sizeof(int));
2053 *nloops
= concat_if_new((void **)loops
, *nloops
, loops_next
, num_next_loops
,
2054 sizeof(struct clast_stmt
*));
2058 if (CLAST_STMT_IS_A(node
, stmt_for
)) {
2059 struct clast_for
*for_stmt
= (struct clast_for
*) node
;
2060 clast_filter(for_stmt
->body
, filter
, &loops_next
,
2061 &num_next_loops
, &stmts_next
, &num_next_stmts
);
2062 *nstmts
= concat_if_new((void **)stmts
, *nstmts
, stmts_next
, num_next_stmts
, sizeof(int));
2063 *nloops
= concat_if_new((void **)loops
, *nloops
, loops_next
, num_next_loops
,
2064 sizeof(struct clast_stmt
*));
2066 if (iter
== NULL
|| !strcmp(for_stmt
->iterator
, iter
)) {
2067 if (stmts_filter
== NULL
||
2068 (filter_type
== subset
&& list_compare(stmts_next
, num_next_stmts
,
2069 stmts_filter
, nstmts_filter
) <= 0)
2070 || (filter_type
== exact
&& list_compare(stmts_next
, num_next_stmts
,
2071 stmts_filter
, nstmts_filter
) == 0 )) {
2072 ret
= add_if_new((void **)loops
, *nloops
, &for_stmt
, sizeof(struct clast_for
*));
2073 if (ret
) (*nloops
)++;
2079 clast_filter((for_stmt
->stmt
).next
, filter
, &loops_next
,
2080 &num_next_loops
, &stmts_next
, &num_next_stmts
);
2081 *nstmts
= concat_if_new((void **)stmts
, *nstmts
, stmts_next
, num_next_stmts
, sizeof(int));
2082 *nloops
= concat_if_new((void **)loops
, *nloops
, loops_next
, num_next_loops
,
2083 sizeof(struct clast_stmt
*));