1 /* Translation of CLAST (CLooG AST) to Gimple.
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop@amd.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
26 #include <isl/union_map.h>
28 #include <isl/constraint.h>
31 #include <cloog/cloog.h>
32 #include <cloog/isl/domain.h>
36 #include "coretypes.h"
37 #include "diagnostic-core.h"
40 #include "gimple-iterator.h"
41 #include "gimplify-me.h"
42 #include "gimple-ssa.h"
43 #include "tree-ssa-loop-manip.h"
44 #include "tree-ssa-loop.h"
45 #include "tree-into-ssa.h"
46 #include "tree-pass.h"
48 #include "tree-chrec.h"
49 #include "tree-data-ref.h"
50 #include "tree-scalar-evolution.h"
54 #include "cloog/cloog.h"
55 #include "graphite-poly.h"
56 #include "graphite-clast-to-gimple.h"
57 #include "graphite-htab.h"
59 typedef const struct clast_expr
*clast_name_p
;
61 #ifndef CLOOG_LANGUAGE_C
62 #define CLOOG_LANGUAGE_C LANGUAGE_C
66 /* Converts a GMP constant VAL to a tree and returns it. */
69 gmp_cst_to_tree (tree type
, mpz_t val
)
71 tree t
= type
? type
: integer_type_node
;
77 di
= mpz_get_double_int (t
, tmp
, true);
80 return double_int_to_tree (t
, di
);
83 /* Sets RES to the min of V1 and V2. */
86 value_min (mpz_t res
, mpz_t v1
, mpz_t v2
)
88 if (mpz_cmp (v1
, v2
) < 0)
94 /* Sets RES to the max of V1 and V2. */
97 value_max (mpz_t res
, mpz_t v1
, mpz_t v2
)
99 if (mpz_cmp (v1
, v2
) < 0)
106 /* This flag is set when an error occurred during the translation of
108 static bool gloog_error
;
110 /* Verifies properties that GRAPHITE should maintain during translation. */
113 graphite_verify (void)
115 #ifdef ENABLE_CHECKING
116 verify_loop_structure ();
117 verify_loop_closed_ssa (true);
121 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
122 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
123 upper bounds that can be inferred from the polyhedral representation. */
125 typedef struct clast_name_index
{
128 mpz_t bound_one
, bound_two
;
130 /* If free_name is set, the content of name was allocated by us and needs
133 } *clast_name_index_p
;
135 /* Helper for hashing clast_name_index. */
137 struct clast_index_hasher
139 typedef clast_name_index value_type
;
140 typedef clast_name_index compare_type
;
141 static inline hashval_t
hash (const value_type
*);
142 static inline bool equal (const value_type
*, const compare_type
*);
143 static inline void remove (value_type
*);
146 /* Computes a hash function for database element E. */
149 clast_index_hasher::hash (const value_type
*e
)
153 int length
= strlen (e
->name
);
156 for (i
= 0; i
< length
; ++i
)
157 hash
= hash
| (e
->name
[i
] << (i
% 4));
162 /* Compares database elements ELT1 and ELT2. */
165 clast_index_hasher::equal (const value_type
*elt1
, const compare_type
*elt2
)
167 return strcmp (elt1
->name
, elt2
->name
) == 0;
170 /* Free the memory taken by a clast_name_index struct. */
173 clast_index_hasher::remove (value_type
*c
)
177 mpz_clear (c
->bound_one
);
178 mpz_clear (c
->bound_two
);
182 typedef hash_table
<clast_index_hasher
> clast_index_htab_type
;
184 /* Returns a pointer to a new element of type clast_name_index_p built
185 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
187 static inline clast_name_index_p
188 new_clast_name_index (const char *name
, int index
, int level
,
189 mpz_t bound_one
, mpz_t bound_two
)
191 clast_name_index_p res
= XNEW (struct clast_name_index
);
192 char *new_name
= XNEWVEC (char, strlen (name
) + 1);
193 strcpy (new_name
, name
);
195 res
->name
= new_name
;
196 res
->free_name
= new_name
;
199 mpz_init (res
->bound_one
);
200 mpz_init (res
->bound_two
);
201 mpz_set (res
->bound_one
, bound_one
);
202 mpz_set (res
->bound_two
, bound_two
);
206 /* For a given clast NAME, returns -1 if NAME is not in the
207 INDEX_TABLE, otherwise returns the loop level for the induction
208 variable NAME, or if it is a parameter, the parameter number in the
209 vector of parameters. */
212 clast_name_to_level (clast_name_p name
, clast_index_htab_type index_table
)
214 struct clast_name_index tmp
;
215 clast_name_index
**slot
;
217 gcc_assert (name
->type
== clast_expr_name
);
218 tmp
.name
= ((const struct clast_name
*) name
)->name
;
219 tmp
.free_name
= NULL
;
221 slot
= index_table
.find_slot (&tmp
, NO_INSERT
);
224 return ((struct clast_name_index
*) *slot
)->level
;
229 /* For a given clast NAME, returns -1 if it does not correspond to any
230 parameter, or otherwise, returns the index in the PARAMS or
231 SCATTERING_DIMENSIONS vector. */
234 clast_name_to_index (struct clast_name
*name
, clast_index_htab_type index_table
)
236 struct clast_name_index tmp
;
237 clast_name_index
**slot
;
239 tmp
.name
= ((const struct clast_name
*) name
)->name
;
240 tmp
.free_name
= NULL
;
242 slot
= index_table
.find_slot (&tmp
, NO_INSERT
);
245 return (*slot
)->index
;
250 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
251 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
252 found in the INDEX_TABLE, false otherwise. */
255 clast_name_to_lb_ub (struct clast_name
*name
, clast_index_htab_type index_table
,
256 mpz_t bound_one
, mpz_t bound_two
)
258 struct clast_name_index tmp
;
259 clast_name_index
**slot
;
261 tmp
.name
= name
->name
;
262 tmp
.free_name
= NULL
;
264 slot
= index_table
.find_slot (&tmp
, NO_INSERT
);
268 mpz_set (bound_one
, ((struct clast_name_index
*) *slot
)->bound_one
);
269 mpz_set (bound_two
, ((struct clast_name_index
*) *slot
)->bound_two
);
276 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
279 save_clast_name_index (clast_index_htab_type index_table
, const char *name
,
280 int index
, int level
, mpz_t bound_one
, mpz_t bound_two
)
282 struct clast_name_index tmp
;
283 clast_name_index
**slot
;
286 tmp
.free_name
= NULL
;
287 slot
= index_table
.find_slot (&tmp
, INSERT
);
293 *slot
= new_clast_name_index (name
, index
, level
, bound_one
, bound_two
);
298 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
299 induction variable in NEWIVS.
301 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
302 parameter in PARAMS. */
304 typedef struct ivs_params
{
305 vec
<tree
> params
, *newivs
;
306 clast_index_htab_type newivs_index
, params_index
;
310 /* Returns the tree variable from the name NAME that was given in
311 Cloog representation. */
314 clast_name_to_gcc (struct clast_name
*name
, ivs_params_p ip
)
318 if (ip
->params
.exists () && ip
->params_index
.is_created ())
320 index
= clast_name_to_index (name
, ip
->params_index
);
323 return ip
->params
[index
];
326 gcc_assert (ip
->newivs
&& ip
->newivs_index
.is_created ());
327 index
= clast_name_to_index (name
, ip
->newivs_index
);
328 gcc_assert (index
>= 0);
330 return (*ip
->newivs
)[index
];
333 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
336 max_precision_type (tree type1
, tree type2
)
338 enum machine_mode mode
;
339 int p1
, p2
, precision
;
342 if (POINTER_TYPE_P (type1
))
345 if (POINTER_TYPE_P (type2
))
348 if (TYPE_UNSIGNED (type1
)
349 && TYPE_UNSIGNED (type2
))
350 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
352 p1
= TYPE_PRECISION (type1
);
353 p2
= TYPE_PRECISION (type2
);
356 precision
= TYPE_UNSIGNED (type1
) ? p1
* 2 : p1
;
358 precision
= TYPE_UNSIGNED (type2
) ? p2
* 2 : p2
;
360 if (precision
> BITS_PER_WORD
)
363 return integer_type_node
;
366 mode
= smallest_mode_for_size (precision
, MODE_INT
);
367 precision
= GET_MODE_PRECISION (mode
);
368 type
= build_nonstandard_integer_type (precision
, false);
373 return integer_type_node
;
380 clast_to_gcc_expression (tree
, struct clast_expr
*, ivs_params_p
);
382 /* Converts a Cloog reduction expression R with reduction operation OP
383 to a GCC expression tree of type TYPE. */
386 clast_to_gcc_expression_red (tree type
, enum tree_code op
,
387 struct clast_reduction
*r
, ivs_params_p ip
)
390 tree res
= clast_to_gcc_expression (type
, r
->elts
[0], ip
);
391 tree operand_type
= (op
== POINTER_PLUS_EXPR
) ? sizetype
: type
;
393 for (i
= 1; i
< r
->n
; i
++)
395 tree t
= clast_to_gcc_expression (operand_type
, r
->elts
[i
], ip
);
396 res
= fold_build2 (op
, type
, res
, t
);
402 /* Converts a Cloog AST expression E back to a GCC expression tree of
406 clast_to_gcc_expression (tree type
, struct clast_expr
*e
, ivs_params_p ip
)
410 case clast_expr_name
:
412 return clast_name_to_gcc ((struct clast_name
*) e
, ip
);
414 case clast_expr_term
:
416 struct clast_term
*t
= (struct clast_term
*) e
;
420 if (mpz_cmp_si (t
->val
, 1) == 0)
422 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
424 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
425 name
= convert_to_ptrofftype (name
);
427 name
= fold_convert (type
, name
);
431 else if (mpz_cmp_si (t
->val
, -1) == 0)
433 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
435 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
436 name
= convert_to_ptrofftype (name
);
438 name
= fold_convert (type
, name
);
440 return fold_build1 (NEGATE_EXPR
, type
, name
);
444 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
445 tree cst
= gmp_cst_to_tree (type
, t
->val
);
447 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
448 name
= convert_to_ptrofftype (name
);
450 name
= fold_convert (type
, name
);
452 if (!POINTER_TYPE_P (type
))
453 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
460 return gmp_cst_to_tree (type
, t
->val
);
465 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
470 return clast_to_gcc_expression_red
471 (type
, POINTER_TYPE_P (type
) ? POINTER_PLUS_EXPR
: PLUS_EXPR
,
475 return clast_to_gcc_expression_red (type
, MIN_EXPR
, r
, ip
);
478 return clast_to_gcc_expression_red (type
, MAX_EXPR
, r
, ip
);
488 struct clast_binary
*b
= (struct clast_binary
*) e
;
489 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
490 tree tl
= clast_to_gcc_expression (type
, lhs
, ip
);
491 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
496 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
499 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
502 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
505 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
519 /* Return a type that could represent the values between BOUND_ONE and
523 type_for_interval (mpz_t bound_one
, mpz_t bound_two
)
527 enum machine_mode mode
;
529 int precision
= MAX (mpz_sizeinbase (bound_one
, 2),
530 mpz_sizeinbase (bound_two
, 2));
532 if (precision
> BITS_PER_WORD
)
535 return integer_type_node
;
538 if (mpz_cmp (bound_one
, bound_two
) <= 0)
539 unsigned_p
= (mpz_sgn (bound_one
) >= 0);
541 unsigned_p
= (mpz_sgn (bound_two
) >= 0);
543 mode
= smallest_mode_for_size (precision
, MODE_INT
);
544 wider_precision
= GET_MODE_PRECISION (mode
);
546 /* As we want to generate signed types as much as possible, try to
547 fit the interval [bound_one, bound_two] in a signed type. For example,
548 supposing that we have the interval [0, 100], instead of
549 generating unsigned char, we want to generate a signed char. */
550 if (unsigned_p
&& precision
< wider_precision
)
553 type
= build_nonstandard_integer_type (wider_precision
, unsigned_p
);
558 return integer_type_node
;
564 /* Return a type that could represent the integer value VAL, or
565 otherwise return NULL_TREE. */
568 type_for_value (mpz_t val
)
570 return type_for_interval (val
, val
);
574 type_for_clast_expr (struct clast_expr
*, ivs_params_p
, mpz_t
, mpz_t
);
576 /* Return the type for the clast_term T. Initializes BOUND_ONE and
577 BOUND_TWO to the bounds of the term. */
580 type_for_clast_term (struct clast_term
*t
, ivs_params_p ip
, mpz_t bound_one
,
584 gcc_assert (t
->expr
.type
== clast_expr_term
);
588 mpz_set (bound_one
, t
->val
);
589 mpz_set (bound_two
, t
->val
);
590 return type_for_value (t
->val
);
593 type
= type_for_clast_expr (t
->var
, ip
, bound_one
, bound_two
);
595 mpz_mul (bound_one
, bound_one
, t
->val
);
596 mpz_mul (bound_two
, bound_two
, t
->val
);
598 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
601 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
602 and BOUND_TWO to the bounds of the reduction expression. */
605 type_for_clast_red (struct clast_reduction
*r
, ivs_params_p ip
,
606 mpz_t bound_one
, mpz_t bound_two
)
609 tree type
= type_for_clast_expr (r
->elts
[0], ip
, bound_one
, bound_two
);
610 mpz_t b1
, b2
, m1
, m2
;
620 for (i
= 1; i
< r
->n
; i
++)
622 tree t
= type_for_clast_expr (r
->elts
[i
], ip
, b1
, b2
);
623 type
= max_precision_type (type
, t
);
628 value_min (m1
, bound_one
, bound_two
);
629 value_min (m2
, b1
, b2
);
630 mpz_add (bound_one
, m1
, m2
);
632 value_max (m1
, bound_one
, bound_two
);
633 value_max (m2
, b1
, b2
);
634 mpz_add (bound_two
, m1
, m2
);
638 value_min (bound_one
, bound_one
, bound_two
);
639 value_min (bound_two
, b1
, b2
);
643 value_max (bound_one
, bound_one
, bound_two
);
644 value_max (bound_two
, b1
, b2
);
658 /* Return a type that can represent the result of the reduction. */
659 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
662 /* Return the type for the clast_binary B used in STMT. */
665 type_for_clast_bin (struct clast_binary
*b
, ivs_params_p ip
, mpz_t bound_one
,
669 tree l
= type_for_clast_expr ((struct clast_expr
*) b
->LHS
, ip
,
670 bound_one
, bound_two
);
671 tree r
= type_for_value (b
->RHS
);
672 tree type
= max_precision_type (l
, r
);
677 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
678 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
682 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
683 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
685 mpz_add (bound_one
, bound_one
, one
);
686 mpz_add (bound_two
, bound_two
, one
);
691 mpz_div (bound_one
, bound_one
, b
->RHS
);
692 mpz_div (bound_two
, bound_two
, b
->RHS
);
696 mpz_mod (bound_one
, bound_one
, b
->RHS
);
697 mpz_mod (bound_two
, bound_two
, b
->RHS
);
704 /* Return a type that can represent the result of the reduction. */
705 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
708 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
709 BOUND_TWO to the bounds of the term. */
712 type_for_clast_name (struct clast_name
*name
, ivs_params_p ip
, mpz_t bound_one
,
717 if (ip
->params
.exists () && ip
->params_index
.is_created ())
718 found
= clast_name_to_lb_ub (name
, ip
->params_index
, bound_one
, bound_two
);
722 gcc_assert (ip
->newivs
&& ip
->newivs_index
.is_created ());
723 found
= clast_name_to_lb_ub (name
, ip
->newivs_index
, bound_one
,
728 return TREE_TYPE (clast_name_to_gcc (name
, ip
));
731 /* Returns the type for the CLAST expression E when used in statement
735 type_for_clast_expr (struct clast_expr
*e
, ivs_params_p ip
, mpz_t bound_one
,
740 case clast_expr_term
:
741 return type_for_clast_term ((struct clast_term
*) e
, ip
,
742 bound_one
, bound_two
);
745 return type_for_clast_red ((struct clast_reduction
*) e
, ip
,
746 bound_one
, bound_two
);
749 return type_for_clast_bin ((struct clast_binary
*) e
, ip
,
750 bound_one
, bound_two
);
752 case clast_expr_name
:
753 return type_for_clast_name ((struct clast_name
*) e
, ip
,
754 bound_one
, bound_two
);
763 /* Returns true if the clast expression E is a constant with VALUE. */
766 clast_expr_const_value_p (struct clast_expr
*e
, int value
)
768 struct clast_term
*t
;
769 if (e
->type
!= clast_expr_term
)
771 t
= (struct clast_term
*)e
;
774 return 0 == mpz_cmp_si (t
->val
, value
);
777 /* Translates a clast equation CLEQ to a tree. */
780 graphite_translate_clast_equation (struct clast_equation
*cleq
,
784 tree type
, lhs
, rhs
, ltype
, rtype
;
785 mpz_t bound_one
, bound_two
;
786 struct clast_expr
*clhs
, *crhs
;
792 else if (cleq
->sign
> 0)
797 /* Special cases to reduce range of arguments to hopefully
798 don't need types with larger precision than the input. */
799 if (crhs
->type
== clast_expr_red
802 struct clast_reduction
*r
= (struct clast_reduction
*) crhs
;
803 /* X >= A+1 --> X > A and
804 X <= A-1 --> X < A */
806 && r
->type
== clast_red_sum
807 && clast_expr_const_value_p (r
->elts
[1], comp
== GE_EXPR
? 1 : -1))
810 comp
= comp
== GE_EXPR
? GT_EXPR
: LT_EXPR
;
814 mpz_init (bound_one
);
815 mpz_init (bound_two
);
817 ltype
= type_for_clast_expr (clhs
, ip
, bound_one
, bound_two
);
818 rtype
= type_for_clast_expr (crhs
, ip
, bound_one
, bound_two
);
820 mpz_clear (bound_one
);
821 mpz_clear (bound_two
);
822 type
= max_precision_type (ltype
, rtype
);
824 lhs
= clast_to_gcc_expression (type
, clhs
, ip
);
825 rhs
= clast_to_gcc_expression (type
, crhs
, ip
);
827 return fold_build2 (comp
, boolean_type_node
, lhs
, rhs
);
830 /* Creates the test for the condition in STMT. */
833 graphite_create_guard_cond_expr (struct clast_guard
*stmt
,
839 for (i
= 0; i
< stmt
->n
; i
++)
841 tree eq
= graphite_translate_clast_equation (&stmt
->eq
[i
], ip
);
844 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
852 /* Creates a new if region corresponding to Cloog's guard. */
855 graphite_create_new_guard (edge entry_edge
, struct clast_guard
*stmt
,
858 tree cond_expr
= graphite_create_guard_cond_expr (stmt
, ip
);
859 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
863 /* Compute the lower bound LOW and upper bound UP for the parameter
864 PARAM in scop SCOP based on the constraints in the context. */
867 compute_bounds_for_param (scop_p scop
, int param
, mpz_t low
, mpz_t up
)
870 isl_aff
*aff
= isl_aff_zero_on_domain
871 (isl_local_space_from_space (isl_set_get_space (scop
->context
)));
873 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, param
, 1);
876 isl_set_min (scop
->context
, aff
, &v
);
877 isl_int_get_gmp (v
, low
);
878 isl_set_max (scop
->context
, aff
, &v
);
879 isl_int_get_gmp (v
, up
);
884 /* Compute the lower bound LOW and upper bound UP for the induction
885 variable of loop LOOP.
887 FIXME: This one is not entirely correct, as min/max expressions in the
888 calculation can yield to incorrect results. To be completely
889 correct, we need to evaluate each subexpression generated by
890 CLooG. CLooG does not yet support this, so this is as good as
894 compute_bounds_for_loop (struct clast_for
*loop
, mpz_t low
, mpz_t up
)
898 isl_local_space
*local_space
;
900 enum isl_lp_result lp_result
;
902 domain
= isl_set_copy (isl_set_from_cloog_domain (loop
->domain
));
903 local_space
= isl_local_space_from_space (isl_set_get_space (domain
));
904 dimension
= isl_aff_zero_on_domain (local_space
);
905 dimension
= isl_aff_add_coefficient_si (dimension
, isl_dim_in
,
906 isl_set_dim (domain
, isl_dim_set
) - 1,
909 isl_int_init (isl_value
);
911 lp_result
= isl_set_min (domain
, dimension
, &isl_value
);
912 assert (lp_result
== isl_lp_ok
);
913 isl_int_get_gmp (isl_value
, low
);
915 lp_result
= isl_set_max (domain
, dimension
, &isl_value
);
916 assert (lp_result
== isl_lp_ok
);
917 isl_int_get_gmp (isl_value
, up
);
919 isl_int_clear (isl_value
);
920 isl_set_free (domain
);
921 isl_aff_free (dimension
);
924 /* Returns the type for the induction variable for the loop translated
928 type_for_clast_for (struct clast_for
*stmt_for
, ivs_params_p ip
)
930 mpz_t bound_one
, bound_two
;
931 tree lb_type
, ub_type
;
933 mpz_init (bound_one
);
934 mpz_init (bound_two
);
936 lb_type
= type_for_clast_expr (stmt_for
->LB
, ip
, bound_one
, bound_two
);
937 ub_type
= type_for_clast_expr (stmt_for
->UB
, ip
, bound_one
, bound_two
);
939 mpz_clear (bound_one
);
940 mpz_clear (bound_two
);
942 return max_precision_type (lb_type
, ub_type
);
945 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
946 induction variable for the new LOOP. New LOOP is attached to CFG
947 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
948 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
949 CLooG's scattering name to the induction variable created for the
950 loop of STMT. The new induction variable is inserted in the NEWIVS
951 vector and is of type TYPE. */
954 graphite_create_new_loop (edge entry_edge
, struct clast_for
*stmt
,
955 loop_p outer
, tree type
, tree lb
, tree ub
,
956 int level
, ivs_params_p ip
)
960 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
961 tree ivvar
= create_tmp_var (type
, "graphite_IV");
962 tree iv
, iv_after_increment
;
963 loop_p loop
= create_empty_loop_on_edge
964 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
965 outer
? outer
: entry_edge
->src
->loop_father
);
969 compute_bounds_for_loop (stmt
, low
, up
);
970 save_clast_name_index (ip
->newivs_index
, stmt
->iterator
,
971 (*ip
->newivs
).length (), level
, low
, up
);
974 (*ip
->newivs
).safe_push (iv
);
978 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
979 induction variables of the loops around GBB in SESE. */
982 build_iv_mapping (vec
<tree
> iv_map
, struct clast_user_stmt
*user_stmt
,
985 struct clast_stmt
*t
;
987 CloogStatement
*cs
= user_stmt
->statement
;
988 poly_bb_p pbb
= (poly_bb_p
) cs
->usr
;
989 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
990 mpz_t bound_one
, bound_two
;
992 mpz_init (bound_one
);
993 mpz_init (bound_two
);
995 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, depth
++)
997 struct clast_expr
*expr
= (struct clast_expr
*)
998 ((struct clast_assignment
*)t
)->RHS
;
999 tree type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1000 tree new_name
= clast_to_gcc_expression (type
, expr
, ip
);
1001 loop_p old_loop
= gbb_loop_at_index (gbb
, ip
->region
, depth
);
1003 iv_map
[old_loop
->num
] = new_name
;
1006 mpz_clear (bound_one
);
1007 mpz_clear (bound_two
);
1010 /* Construct bb_pbb_def with BB and PBB. */
1013 new_bb_pbb_def (basic_block bb
, poly_bb_p pbb
)
1015 bb_pbb_def
*bb_pbb_p
;
1017 bb_pbb_p
= XNEW (bb_pbb_def
);
1019 bb_pbb_p
->pbb
= pbb
;
1024 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1027 mark_bb_with_pbb (poly_bb_p pbb
, basic_block bb
,
1028 bb_pbb_htab_type bb_pbb_mapping
)
1034 x
= bb_pbb_mapping
.find_slot (&tmp
, INSERT
);
1037 *x
= new_bb_pbb_def (bb
, pbb
);
1040 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1043 find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping
, basic_block bb
)
1049 slot
= bb_pbb_mapping
.find_slot (&tmp
, NO_INSERT
);
1052 return ((bb_pbb_def
*) *slot
)->pbb
;
1057 /* Return the scop of the loop and initialize PBBS the set of
1058 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1059 by the CLAST code generator between a generated basic_block and its
1060 related poly_bb_p. */
1063 get_loop_body_pbbs (loop_p loop
, bb_pbb_htab_type bb_pbb_mapping
,
1064 vec
<poly_bb_p
> *pbbs
)
1067 basic_block
*bbs
= get_loop_body_in_dom_order (loop
);
1070 for (i
= 0; i
< loop
->num_nodes
; i
++)
1072 poly_bb_p pbb
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[i
]);
1077 scop
= PBB_SCOP (pbb
);
1078 (*pbbs
).safe_push (pbb
);
1085 /* Translates a clast user statement STMT to gimple.
1087 - NEXT_E is the edge where new generated code should be attached.
1088 - CONTEXT_LOOP is the loop in which the generated code will be placed
1089 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1092 translate_clast_user (struct clast_user_stmt
*stmt
, edge next_e
,
1093 bb_pbb_htab_type bb_pbb_mapping
, ivs_params_p ip
)
1097 poly_bb_p pbb
= (poly_bb_p
) stmt
->statement
->usr
;
1098 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1101 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR
)
1104 nb_loops
= number_of_loops (cfun
);
1105 iv_map
.create (nb_loops
);
1106 for (i
= 0; i
< nb_loops
; i
++)
1107 iv_map
.quick_push (NULL_TREE
);
1109 build_iv_mapping (iv_map
, stmt
, ip
);
1110 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), ip
->region
,
1111 next_e
, iv_map
, &gloog_error
);
1114 new_bb
= next_e
->src
;
1115 mark_bb_with_pbb (pbb
, new_bb
, bb_pbb_mapping
);
1116 mark_virtual_operands_for_renaming (cfun
);
1117 update_ssa (TODO_update_ssa
);
1122 /* Creates a new if region protecting the loop to be executed, if the execution
1123 count is zero (lb > ub). */
1126 graphite_create_new_loop_guard (edge entry_edge
, struct clast_for
*stmt
,
1127 tree
*type
, tree
*lb
, tree
*ub
,
1133 *type
= type_for_clast_for (stmt
, ip
);
1134 *lb
= clast_to_gcc_expression (*type
, stmt
->LB
, ip
);
1135 *ub
= clast_to_gcc_expression (*type
, stmt
->UB
, ip
);
1137 /* When ub is simply a constant or a parameter, use lb <= ub. */
1138 if (TREE_CODE (*ub
) == INTEGER_CST
|| TREE_CODE (*ub
) == SSA_NAME
)
1139 cond_expr
= fold_build2 (LE_EXPR
, boolean_type_node
, *lb
, *ub
);
1142 tree one
= (POINTER_TYPE_P (*type
)
1143 ? convert_to_ptrofftype (integer_one_node
)
1144 : fold_convert (*type
, integer_one_node
));
1145 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1146 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1147 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1148 even if we do not want this. However lb < ub + 1 is false, as
1150 tree ub_one
= fold_build2 (POINTER_TYPE_P (*type
) ? POINTER_PLUS_EXPR
1151 : PLUS_EXPR
, *type
, *ub
, one
);
1153 cond_expr
= fold_build2 (LT_EXPR
, boolean_type_node
, *lb
, ub_one
);
1156 exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
1162 translate_clast (loop_p
, struct clast_stmt
*, edge
, bb_pbb_htab_type
,
1165 /* Create the loop for a clast for statement.
1167 - NEXT_E is the edge where new generated code should be attached.
1168 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1171 translate_clast_for_loop (loop_p context_loop
, struct clast_for
*stmt
,
1172 edge next_e
, bb_pbb_htab_type bb_pbb_mapping
,
1173 int level
, tree type
, tree lb
, tree ub
,
1176 struct loop
*loop
= graphite_create_new_loop (next_e
, stmt
, context_loop
,
1177 type
, lb
, ub
, level
, ip
);
1178 edge last_e
= single_exit (loop
);
1179 edge to_body
= single_succ_edge (loop
->header
);
1180 basic_block after
= to_body
->dest
;
1182 /* Create a basic block for loop close phi nodes. */
1183 last_e
= single_succ_edge (split_edge (last_e
));
1185 /* Translate the body of the loop. */
1186 next_e
= translate_clast (loop
, stmt
->body
, to_body
, bb_pbb_mapping
,
1188 redirect_edge_succ_nodup (next_e
, after
);
1189 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
1191 isl_set
*domain
= isl_set_from_cloog_domain (stmt
->domain
);
1192 int scheduling_dim
= isl_set_n_dim (domain
);
1194 if (flag_loop_parallelize_all
1195 && loop_is_parallel_p (loop
, bb_pbb_mapping
, scheduling_dim
))
1196 loop
->can_be_parallel
= true;
1201 /* Translates a clast for statement STMT to gimple. First a guard is created
1202 protecting the loop, if it is executed zero times. In this guard we create
1203 the real loop structure.
1205 - NEXT_E is the edge where new generated code should be attached.
1206 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1209 translate_clast_for (loop_p context_loop
, struct clast_for
*stmt
, edge next_e
,
1210 bb_pbb_htab_type bb_pbb_mapping
, int level
,
1214 edge last_e
= graphite_create_new_loop_guard (next_e
, stmt
, &type
,
1216 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1218 translate_clast_for_loop (context_loop
, stmt
, true_e
, bb_pbb_mapping
, level
,
1223 /* Translates a clast assignment STMT to gimple.
1225 - NEXT_E is the edge where new generated code should be attached.
1226 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1229 translate_clast_assignment (struct clast_assignment
*stmt
, edge next_e
,
1230 int level
, ivs_params_p ip
)
1233 mpz_t bound_one
, bound_two
;
1234 tree type
, new_name
, var
;
1235 edge res
= single_succ_edge (split_edge (next_e
));
1236 struct clast_expr
*expr
= (struct clast_expr
*) stmt
->RHS
;
1238 mpz_init (bound_one
);
1239 mpz_init (bound_two
);
1240 type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1241 var
= create_tmp_var (type
, "graphite_var");
1242 new_name
= force_gimple_operand (clast_to_gcc_expression (type
, expr
, ip
),
1246 gsi_insert_seq_on_edge (next_e
, stmts
);
1247 gsi_commit_edge_inserts ();
1250 save_clast_name_index (ip
->newivs_index
, stmt
->LHS
,
1251 (*ip
->newivs
).length (), level
,
1252 bound_one
, bound_two
);
1253 (*ip
->newivs
).safe_push (new_name
);
1255 mpz_clear (bound_one
);
1256 mpz_clear (bound_two
);
1261 /* Translates a clast guard statement STMT to gimple.
1263 - NEXT_E is the edge where new generated code should be attached.
1264 - CONTEXT_LOOP is the loop in which the generated code will be placed
1265 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1268 translate_clast_guard (loop_p context_loop
, struct clast_guard
*stmt
,
1269 edge next_e
, bb_pbb_htab_type bb_pbb_mapping
, int level
,
1272 edge last_e
= graphite_create_new_guard (next_e
, stmt
, ip
);
1273 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1275 translate_clast (context_loop
, stmt
->then
, true_e
, bb_pbb_mapping
, level
, ip
);
1279 /* Translates a CLAST statement STMT to GCC representation in the
1282 - NEXT_E is the edge where new generated code should be attached.
1283 - CONTEXT_LOOP is the loop in which the generated code will be placed
1284 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1287 translate_clast (loop_p context_loop
, struct clast_stmt
*stmt
, edge next_e
,
1288 bb_pbb_htab_type bb_pbb_mapping
, int level
, ivs_params_p ip
)
1293 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
1296 else if (CLAST_STMT_IS_A (stmt
, stmt_user
))
1297 next_e
= translate_clast_user ((struct clast_user_stmt
*) stmt
,
1298 next_e
, bb_pbb_mapping
, ip
);
1300 else if (CLAST_STMT_IS_A (stmt
, stmt_for
))
1301 next_e
= translate_clast_for (context_loop
, (struct clast_for
*) stmt
,
1302 next_e
, bb_pbb_mapping
, level
, ip
);
1304 else if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
1305 next_e
= translate_clast_guard (context_loop
, (struct clast_guard
*) stmt
,
1306 next_e
, bb_pbb_mapping
, level
, ip
);
1308 else if (CLAST_STMT_IS_A (stmt
, stmt_block
))
1309 next_e
= translate_clast (context_loop
, ((struct clast_block
*) stmt
)->body
,
1310 next_e
, bb_pbb_mapping
, level
, ip
);
1312 else if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
1313 next_e
= translate_clast_assignment ((struct clast_assignment
*) stmt
,
1318 recompute_all_dominators ();
1321 return translate_clast (context_loop
, stmt
->next
, next_e
, bb_pbb_mapping
,
1325 /* Add parameter and iterator names to the CloogUnionDomain. */
1327 static CloogUnionDomain
*
1328 add_names_to_union_domain (scop_p scop
, CloogUnionDomain
*union_domain
,
1329 int nb_scattering_dims
,
1330 clast_index_htab_type params_index
)
1332 sese region
= SCOP_REGION (scop
);
1334 int nb_iterators
= scop_max_loop_depth (scop
);
1335 int nb_parameters
= SESE_PARAMS (region
).length ();
1336 mpz_t bound_one
, bound_two
;
1338 mpz_init (bound_one
);
1339 mpz_init (bound_two
);
1341 for (i
= 0; i
< nb_parameters
; i
++)
1343 tree param
= SESE_PARAMS (region
)[i
];
1344 const char *name
= get_name (param
);
1351 len
= strlen (name
);
1353 parameter
= XNEWVEC (char, len
+ 1);
1354 snprintf (parameter
, len
, "%s_%d", name
, SSA_NAME_VERSION (param
));
1355 save_clast_name_index (params_index
, parameter
, i
, i
, bound_one
,
1357 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_PARAM
, i
,
1359 compute_bounds_for_param (scop
, i
, bound_one
, bound_two
);
1363 mpz_clear (bound_one
);
1364 mpz_clear (bound_two
);
1366 for (i
= 0; i
< nb_iterators
; i
++)
1370 iterator
= XNEWVEC (char, len
);
1371 snprintf (iterator
, len
, "git_%d", i
);
1372 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_ITER
, i
,
1377 for (i
= 0; i
< nb_scattering_dims
; i
++)
1381 scattering
= XNEWVEC (char, len
);
1382 snprintf (scattering
, len
, "scat_%d", i
);
1383 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_SCAT
, i
,
1388 return union_domain
;
1391 /* Initialize a CLooG input file. */
1394 init_cloog_input_file (int scop_number
)
1396 FILE *graphite_out_file
;
1397 int len
= strlen (dump_base_name
);
1398 char *dumpname
= XNEWVEC (char, len
+ 25);
1399 char *s_scop_number
= XNEWVEC (char, 15);
1401 memcpy (dumpname
, dump_base_name
, len
+ 1);
1402 strip_off_ending (dumpname
, len
);
1403 sprintf (s_scop_number
, ".%d", scop_number
);
1404 strcat (dumpname
, s_scop_number
);
1405 strcat (dumpname
, ".cloog");
1406 graphite_out_file
= fopen (dumpname
, "w+b");
1408 if (graphite_out_file
== 0)
1409 fatal_error ("can%'t open %s for writing: %m", dumpname
);
1413 return graphite_out_file
;
1416 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1419 isl_map
*extend_scattering (isl_map
*scattering
, int new_dims
)
1423 isl_basic_map
*change_scattering
;
1424 isl_map
*change_scattering_map
;
1426 old_dims
= isl_map_dim (scattering
, isl_dim_out
);
1428 space
= isl_space_alloc (isl_map_get_ctx (scattering
), 0, old_dims
, new_dims
);
1429 change_scattering
= isl_basic_map_universe (isl_space_copy (space
));
1431 for (i
= 0; i
< old_dims
; i
++)
1434 c
= isl_equality_alloc
1435 (isl_local_space_from_space (isl_space_copy (space
)));
1436 isl_constraint_set_coefficient_si (c
, isl_dim_in
, i
, 1);
1437 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, -1);
1438 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1441 for (i
= old_dims
; i
< new_dims
; i
++)
1444 c
= isl_equality_alloc
1445 (isl_local_space_from_space (isl_space_copy (space
)));
1446 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
1447 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1450 change_scattering_map
= isl_map_from_basic_map (change_scattering
);
1451 change_scattering_map
= isl_map_align_params (change_scattering_map
, space
);
1452 return isl_map_apply_range (scattering
, change_scattering_map
);
1455 /* Build cloog union domain for SCoP. */
1457 static CloogUnionDomain
*
1458 build_cloog_union_domain (scop_p scop
, int nb_scattering_dims
)
1462 CloogUnionDomain
*union_domain
=
1463 cloog_union_domain_alloc (scop_nb_params (scop
));
1465 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1467 CloogDomain
*domain
;
1468 CloogScattering
*scattering
;
1470 /* Dead code elimination: when the domain of a PBB is empty,
1471 don't generate code for the PBB. */
1472 if (isl_set_is_empty (pbb
->domain
))
1475 domain
= cloog_domain_from_isl_set (isl_set_copy (pbb
->domain
));
1476 scattering
= cloog_scattering_from_isl_map
1477 (extend_scattering (isl_map_copy (pbb
->transformed
),
1478 nb_scattering_dims
));
1480 union_domain
= cloog_union_domain_add_domain (union_domain
, "", domain
,
1484 return union_domain
;
1487 /* Return the options that will be used in GLOOG. */
1489 static CloogOptions
*
1490 set_cloog_options (void)
1492 CloogOptions
*options
= cloog_options_malloc (cloog_state
);
1494 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1495 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1496 we pass an incomplete program to cloog. */
1497 options
->language
= CLOOG_LANGUAGE_C
;
1499 /* Enable complex equality spreading: removes dummy statements
1500 (assignments) in the generated code which repeats the
1501 substitution equations for statements. This is useless for
1505 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1508 /* Allow cloog to build strides with a stride width different to one.
1509 This example has stride = 4:
1511 for (i = 0; i < 20; i += 4)
1513 options
->strides
= 1;
1515 /* We want the clast to provide the iteration domains of the executed loops.
1516 This allows us to derive minimal/maximal values for the induction
1518 options
->save_domains
= 1;
1520 /* Disable optimizations and make cloog generate source code closer to the
1521 input. This is useful for debugging, but later we want the optimized
1524 XXX: We can not disable optimizations, as loop blocking is not working
1529 options
->l
= INT_MAX
;
1535 /* Prints STMT to STDERR. */
1538 print_clast_stmt (FILE *file
, struct clast_stmt
*stmt
)
1540 CloogOptions
*options
= set_cloog_options ();
1542 clast_pprint (file
, stmt
, 0, options
);
1543 cloog_options_free (options
);
1546 /* Prints STMT to STDERR. */
1549 debug_clast_stmt (struct clast_stmt
*stmt
)
1551 print_clast_stmt (stderr
, stmt
);
1554 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1557 int get_max_scattering_dimensions (scop_p scop
)
1561 int scattering_dims
= 0;
1563 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1565 int pbb_scatt_dims
= isl_map_dim (pbb
->transformed
, isl_dim_out
);
1566 if (pbb_scatt_dims
> scattering_dims
)
1567 scattering_dims
= pbb_scatt_dims
;
1570 return scattering_dims
;
1574 generate_cloog_input (scop_p scop
, clast_index_htab_type params_index
)
1576 CloogUnionDomain
*union_domain
;
1577 CloogInput
*cloog_input
;
1578 CloogDomain
*context
;
1579 int nb_scattering_dims
= get_max_scattering_dimensions (scop
);
1581 union_domain
= build_cloog_union_domain (scop
, nb_scattering_dims
);
1582 union_domain
= add_names_to_union_domain (scop
, union_domain
,
1585 context
= cloog_domain_from_isl_set (isl_set_copy (scop
->context
));
1587 cloog_input
= cloog_input_alloc (context
, union_domain
);
1592 /* Translate SCOP to a CLooG program and clast. These two
1593 representations should be freed together: a clast cannot be used
1594 without a program. */
1596 static struct clast_stmt
*
1597 scop_to_clast (scop_p scop
, clast_index_htab_type params_index
)
1599 CloogInput
*cloog_input
;
1600 struct clast_stmt
*clast
;
1601 CloogOptions
*options
= set_cloog_options ();
1603 cloog_input
= generate_cloog_input (scop
, params_index
);
1605 /* Dump a .cloog input file, if requested. This feature is only
1606 enabled in the Graphite branch. */
1609 static size_t file_scop_number
= 0;
1610 FILE *cloog_file
= init_cloog_input_file (file_scop_number
);
1611 cloog_input_dump_cloog (cloog_file
, cloog_input
, options
);
1614 clast
= cloog_clast_create_from_input (cloog_input
, options
);
1616 cloog_options_free (options
);
1620 /* Prints to FILE the code generated by CLooG for SCOP. */
1623 print_generated_program (FILE *file
, scop_p scop
)
1625 CloogOptions
*options
= set_cloog_options ();
1626 clast_index_htab_type params_index
;
1627 struct clast_stmt
*clast
;
1629 params_index
.create (10);
1631 clast
= scop_to_clast (scop
, params_index
);
1633 fprintf (file
, " (clast: \n");
1634 clast_pprint (file
, clast
, 0, options
);
1635 fprintf (file
, " )\n");
1637 cloog_options_free (options
);
1638 cloog_clast_free (clast
);
1641 /* Prints to STDERR the code generated by CLooG for SCOP. */
1644 debug_generated_program (scop_p scop
)
1646 print_generated_program (stderr
, scop
);
1649 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1650 the given SCOP. Return true if code generation succeeded.
1651 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1655 gloog (scop_p scop
, bb_pbb_htab_type bb_pbb_mapping
)
1657 stack_vec
<tree
, 10> newivs
;
1658 loop_p context_loop
;
1659 sese region
= SCOP_REGION (scop
);
1660 ifsese if_region
= NULL
;
1661 clast_index_htab_type newivs_index
, params_index
;
1662 struct clast_stmt
*clast
;
1663 struct ivs_params ip
;
1665 timevar_push (TV_GRAPHITE_CODE_GEN
);
1666 gloog_error
= false;
1668 params_index
.create (10);
1670 clast
= scop_to_clast (scop
, params_index
);
1672 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1674 fprintf (dump_file
, "\nCLAST generated by CLooG: \n");
1675 print_clast_stmt (dump_file
, clast
);
1676 fprintf (dump_file
, "\n");
1679 recompute_all_dominators ();
1682 if_region
= move_sese_in_condition (region
);
1683 sese_insert_phis_for_liveouts (region
,
1684 if_region
->region
->exit
->src
,
1685 if_region
->false_region
->exit
,
1686 if_region
->true_region
->exit
);
1687 recompute_all_dominators ();
1690 context_loop
= SESE_ENTRY (region
)->src
->loop_father
;
1691 newivs_index
.create (10);
1693 ip
.newivs
= &newivs
;
1694 ip
.newivs_index
= newivs_index
;
1695 ip
.params
= SESE_PARAMS (region
);
1696 ip
.params_index
= params_index
;
1699 translate_clast (context_loop
, clast
, if_region
->true_region
->entry
,
1700 bb_pbb_mapping
, 0, &ip
);
1703 recompute_all_dominators ();
1707 set_ifsese_condition (if_region
, integer_zero_node
);
1709 free (if_region
->true_region
);
1710 free (if_region
->region
);
1713 newivs_index
.dispose ();
1714 params_index
.dispose ();
1715 cloog_clast_free (clast
);
1716 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1718 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1721 int num_no_dependency
= 0;
1723 FOR_EACH_LOOP (loop
, 0)
1724 if (loop
->can_be_parallel
)
1725 num_no_dependency
++;
1727 fprintf (dump_file
, "\n%d loops carried no dependency.\n",
1731 return !gloog_error
;