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>
33 #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE
34 #include <isl/deprecated/int.h>
36 #include <isl/deprecated/ilp_int.h>
41 #include "coretypes.h"
42 #include "diagnostic-core.h"
43 #include "tree-flow.h"
44 #include "tree-pass.h"
46 #include "tree-chrec.h"
47 #include "tree-data-ref.h"
48 #include "tree-scalar-evolution.h"
52 #include "cloog/cloog.h"
53 #include "graphite-poly.h"
54 #include "graphite-clast-to-gimple.h"
56 typedef const struct clast_expr
*clast_name_p
;
58 #ifndef CLOOG_LANGUAGE_C
59 #define CLOOG_LANGUAGE_C LANGUAGE_C
63 /* Converts a GMP constant VAL to a tree and returns it. */
66 gmp_cst_to_tree (tree type
, mpz_t val
)
68 tree t
= type
? type
: integer_type_node
;
74 di
= mpz_get_double_int (t
, tmp
, true);
77 return double_int_to_tree (t
, di
);
80 /* Sets RES to the min of V1 and V2. */
83 value_min (mpz_t res
, mpz_t v1
, mpz_t v2
)
85 if (mpz_cmp (v1
, v2
) < 0)
91 /* Sets RES to the max of V1 and V2. */
94 value_max (mpz_t res
, mpz_t v1
, mpz_t v2
)
96 if (mpz_cmp (v1
, v2
) < 0)
103 /* This flag is set when an error occurred during the translation of
105 static bool gloog_error
;
107 /* Verifies properties that GRAPHITE should maintain during translation. */
110 graphite_verify (void)
112 #ifdef ENABLE_CHECKING
113 verify_loop_structure ();
114 verify_loop_closed_ssa (true);
118 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
119 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
120 upper bounds that can be inferred from the polyhedral representation. */
122 typedef struct clast_name_index
{
125 mpz_t bound_one
, bound_two
;
127 /* If free_name is set, the content of name was allocated by us and needs
130 } *clast_name_index_p
;
132 /* Returns a pointer to a new element of type clast_name_index_p built
133 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
135 static inline clast_name_index_p
136 new_clast_name_index (const char *name
, int index
, int level
,
137 mpz_t bound_one
, mpz_t bound_two
)
139 clast_name_index_p res
= XNEW (struct clast_name_index
);
140 char *new_name
= XNEWVEC (char, strlen (name
) + 1);
141 strcpy (new_name
, name
);
143 res
->name
= new_name
;
144 res
->free_name
= new_name
;
147 mpz_init (res
->bound_one
);
148 mpz_init (res
->bound_two
);
149 mpz_set (res
->bound_one
, bound_one
);
150 mpz_set (res
->bound_two
, bound_two
);
154 /* Free the memory taken by a clast_name_index struct. */
157 free_clast_name_index (void *ptr
)
159 struct clast_name_index
*c
= (struct clast_name_index
*) ptr
;
162 mpz_clear (c
->bound_one
);
163 mpz_clear (c
->bound_two
);
167 /* For a given clast NAME, returns -1 if NAME is not in the
168 INDEX_TABLE, otherwise returns the loop level for the induction
169 variable NAME, or if it is a parameter, the parameter number in the
170 vector of parameters. */
173 clast_name_to_level (clast_name_p name
, htab_t index_table
)
175 struct clast_name_index tmp
;
178 gcc_assert (name
->type
== clast_expr_name
);
179 tmp
.name
= ((const struct clast_name
*) name
)->name
;
180 tmp
.free_name
= NULL
;
182 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
185 return ((struct clast_name_index
*) *slot
)->level
;
190 /* For a given clast NAME, returns -1 if it does not correspond to any
191 parameter, or otherwise, returns the index in the PARAMS or
192 SCATTERING_DIMENSIONS vector. */
195 clast_name_to_index (struct clast_name
*name
, htab_t index_table
)
197 struct clast_name_index tmp
;
200 tmp
.name
= ((const struct clast_name
*) name
)->name
;
201 tmp
.free_name
= NULL
;
203 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
206 return ((struct clast_name_index
*) *slot
)->index
;
211 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
212 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
213 found in the INDEX_TABLE, false otherwise. */
216 clast_name_to_lb_ub (struct clast_name
*name
, htab_t index_table
,
217 mpz_t bound_one
, mpz_t bound_two
)
219 struct clast_name_index tmp
;
222 tmp
.name
= name
->name
;
223 tmp
.free_name
= NULL
;
225 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
229 mpz_set (bound_one
, ((struct clast_name_index
*) *slot
)->bound_one
);
230 mpz_set (bound_two
, ((struct clast_name_index
*) *slot
)->bound_two
);
237 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
240 save_clast_name_index (htab_t index_table
, const char *name
,
241 int index
, int level
, mpz_t bound_one
, mpz_t bound_two
)
243 struct clast_name_index tmp
;
247 tmp
.free_name
= NULL
;
248 slot
= htab_find_slot (index_table
, &tmp
, INSERT
);
254 *slot
= new_clast_name_index (name
, index
, level
, bound_one
, bound_two
);
258 /* Computes a hash function for database element ELT. */
260 static inline hashval_t
261 clast_name_index_elt_info (const void *elt
)
263 const struct clast_name_index
*e
= ((const struct clast_name_index
*) elt
);
266 int length
= strlen (e
->name
);
269 for (i
= 0; i
< length
; ++i
)
270 hash
= hash
| (e
->name
[i
] << (i
% 4));
275 /* Compares database elements E1 and E2. */
278 eq_clast_name_indexes (const void *e1
, const void *e2
)
280 const struct clast_name_index
*elt1
= (const struct clast_name_index
*) e1
;
281 const struct clast_name_index
*elt2
= (const struct clast_name_index
*) e2
;
283 return strcmp (elt1
->name
, elt2
->name
) == 0;
288 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
289 induction variable in NEWIVS.
291 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
292 parameter in PARAMS. */
294 typedef struct ivs_params
{
295 vec
<tree
> params
, *newivs
;
296 htab_t newivs_index
, params_index
;
300 /* Returns the tree variable from the name NAME that was given in
301 Cloog representation. */
304 clast_name_to_gcc (struct clast_name
*name
, ivs_params_p ip
)
308 if (ip
->params
.exists () && ip
->params_index
)
310 index
= clast_name_to_index (name
, ip
->params_index
);
313 return ip
->params
[index
];
316 gcc_assert (ip
->newivs
&& ip
->newivs_index
);
317 index
= clast_name_to_index (name
, ip
->newivs_index
);
318 gcc_assert (index
>= 0);
320 return (*ip
->newivs
)[index
];
323 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
326 max_precision_type (tree type1
, tree type2
)
328 enum machine_mode mode
;
329 int p1
, p2
, precision
;
332 if (POINTER_TYPE_P (type1
))
335 if (POINTER_TYPE_P (type2
))
338 if (TYPE_UNSIGNED (type1
)
339 && TYPE_UNSIGNED (type2
))
340 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
342 p1
= TYPE_PRECISION (type1
);
343 p2
= TYPE_PRECISION (type2
);
346 precision
= TYPE_UNSIGNED (type1
) ? p1
* 2 : p1
;
348 precision
= TYPE_UNSIGNED (type2
) ? p2
* 2 : p2
;
350 if (precision
> BITS_PER_WORD
)
353 return integer_type_node
;
356 mode
= smallest_mode_for_size (precision
, MODE_INT
);
357 precision
= GET_MODE_PRECISION (mode
);
358 type
= build_nonstandard_integer_type (precision
, false);
363 return integer_type_node
;
370 clast_to_gcc_expression (tree
, struct clast_expr
*, ivs_params_p
);
372 /* Converts a Cloog reduction expression R with reduction operation OP
373 to a GCC expression tree of type TYPE. */
376 clast_to_gcc_expression_red (tree type
, enum tree_code op
,
377 struct clast_reduction
*r
, ivs_params_p ip
)
380 tree res
= clast_to_gcc_expression (type
, r
->elts
[0], ip
);
381 tree operand_type
= (op
== POINTER_PLUS_EXPR
) ? sizetype
: type
;
383 for (i
= 1; i
< r
->n
; i
++)
385 tree t
= clast_to_gcc_expression (operand_type
, r
->elts
[i
], ip
);
386 res
= fold_build2 (op
, type
, res
, t
);
392 /* Converts a Cloog AST expression E back to a GCC expression tree of
396 clast_to_gcc_expression (tree type
, struct clast_expr
*e
, ivs_params_p ip
)
400 case clast_expr_name
:
402 return clast_name_to_gcc ((struct clast_name
*) e
, ip
);
404 case clast_expr_term
:
406 struct clast_term
*t
= (struct clast_term
*) e
;
410 if (mpz_cmp_si (t
->val
, 1) == 0)
412 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
414 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
415 name
= convert_to_ptrofftype (name
);
417 name
= fold_convert (type
, name
);
421 else if (mpz_cmp_si (t
->val
, -1) == 0)
423 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
425 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
426 name
= convert_to_ptrofftype (name
);
428 name
= fold_convert (type
, name
);
430 return fold_build1 (NEGATE_EXPR
, type
, name
);
434 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
435 tree cst
= gmp_cst_to_tree (type
, t
->val
);
437 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
438 name
= convert_to_ptrofftype (name
);
440 name
= fold_convert (type
, name
);
442 if (!POINTER_TYPE_P (type
))
443 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
450 return gmp_cst_to_tree (type
, t
->val
);
455 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
460 return clast_to_gcc_expression_red
461 (type
, POINTER_TYPE_P (type
) ? POINTER_PLUS_EXPR
: PLUS_EXPR
,
465 return clast_to_gcc_expression_red (type
, MIN_EXPR
, r
, ip
);
468 return clast_to_gcc_expression_red (type
, MAX_EXPR
, r
, ip
);
478 struct clast_binary
*b
= (struct clast_binary
*) e
;
479 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
480 tree tl
= clast_to_gcc_expression (type
, lhs
, ip
);
481 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
486 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
489 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
492 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
495 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
509 /* Return a type that could represent the values between BOUND_ONE and
513 type_for_interval (mpz_t bound_one
, mpz_t bound_two
)
517 enum machine_mode mode
;
519 int precision
= MAX (mpz_sizeinbase (bound_one
, 2),
520 mpz_sizeinbase (bound_two
, 2));
522 if (precision
> BITS_PER_WORD
)
525 return integer_type_node
;
528 if (mpz_cmp (bound_one
, bound_two
) <= 0)
529 unsigned_p
= (mpz_sgn (bound_one
) >= 0);
531 unsigned_p
= (mpz_sgn (bound_two
) >= 0);
533 mode
= smallest_mode_for_size (precision
, MODE_INT
);
534 wider_precision
= GET_MODE_PRECISION (mode
);
536 /* As we want to generate signed types as much as possible, try to
537 fit the interval [bound_one, bound_two] in a signed type. For example,
538 supposing that we have the interval [0, 100], instead of
539 generating unsigned char, we want to generate a signed char. */
540 if (unsigned_p
&& precision
< wider_precision
)
543 type
= build_nonstandard_integer_type (wider_precision
, unsigned_p
);
548 return integer_type_node
;
554 /* Return a type that could represent the integer value VAL, or
555 otherwise return NULL_TREE. */
558 type_for_value (mpz_t val
)
560 return type_for_interval (val
, val
);
564 type_for_clast_expr (struct clast_expr
*, ivs_params_p
, mpz_t
, mpz_t
);
566 /* Return the type for the clast_term T. Initializes BOUND_ONE and
567 BOUND_TWO to the bounds of the term. */
570 type_for_clast_term (struct clast_term
*t
, ivs_params_p ip
, mpz_t bound_one
,
574 gcc_assert (t
->expr
.type
== clast_expr_term
);
578 mpz_set (bound_one
, t
->val
);
579 mpz_set (bound_two
, t
->val
);
580 return type_for_value (t
->val
);
583 type
= type_for_clast_expr (t
->var
, ip
, bound_one
, bound_two
);
585 mpz_mul (bound_one
, bound_one
, t
->val
);
586 mpz_mul (bound_two
, bound_two
, t
->val
);
588 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
591 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
592 and BOUND_TWO to the bounds of the reduction expression. */
595 type_for_clast_red (struct clast_reduction
*r
, ivs_params_p ip
,
596 mpz_t bound_one
, mpz_t bound_two
)
599 tree type
= type_for_clast_expr (r
->elts
[0], ip
, bound_one
, bound_two
);
600 mpz_t b1
, b2
, m1
, m2
;
610 for (i
= 1; i
< r
->n
; i
++)
612 tree t
= type_for_clast_expr (r
->elts
[i
], ip
, b1
, b2
);
613 type
= max_precision_type (type
, t
);
618 value_min (m1
, bound_one
, bound_two
);
619 value_min (m2
, b1
, b2
);
620 mpz_add (bound_one
, m1
, m2
);
622 value_max (m1
, bound_one
, bound_two
);
623 value_max (m2
, b1
, b2
);
624 mpz_add (bound_two
, m1
, m2
);
628 value_min (bound_one
, bound_one
, bound_two
);
629 value_min (bound_two
, b1
, b2
);
633 value_max (bound_one
, bound_one
, bound_two
);
634 value_max (bound_two
, b1
, b2
);
648 /* Return a type that can represent the result of the reduction. */
649 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
652 /* Return the type for the clast_binary B used in STMT. */
655 type_for_clast_bin (struct clast_binary
*b
, ivs_params_p ip
, mpz_t bound_one
,
659 tree l
= type_for_clast_expr ((struct clast_expr
*) b
->LHS
, ip
,
660 bound_one
, bound_two
);
661 tree r
= type_for_value (b
->RHS
);
662 tree type
= max_precision_type (l
, r
);
667 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
668 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
672 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
673 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
675 mpz_add (bound_one
, bound_one
, one
);
676 mpz_add (bound_two
, bound_two
, one
);
681 mpz_div (bound_one
, bound_one
, b
->RHS
);
682 mpz_div (bound_two
, bound_two
, b
->RHS
);
686 mpz_mod (bound_one
, bound_one
, b
->RHS
);
687 mpz_mod (bound_two
, bound_two
, b
->RHS
);
694 /* Return a type that can represent the result of the reduction. */
695 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
698 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
699 BOUND_TWO to the bounds of the term. */
702 type_for_clast_name (struct clast_name
*name
, ivs_params_p ip
, mpz_t bound_one
,
707 if (ip
->params
.exists () && ip
->params_index
)
708 found
= clast_name_to_lb_ub (name
, ip
->params_index
, bound_one
, bound_two
);
712 gcc_assert (ip
->newivs
&& ip
->newivs_index
);
713 found
= clast_name_to_lb_ub (name
, ip
->newivs_index
, bound_one
,
718 return TREE_TYPE (clast_name_to_gcc (name
, ip
));
721 /* Returns the type for the CLAST expression E when used in statement
725 type_for_clast_expr (struct clast_expr
*e
, ivs_params_p ip
, mpz_t bound_one
,
730 case clast_expr_term
:
731 return type_for_clast_term ((struct clast_term
*) e
, ip
,
732 bound_one
, bound_two
);
735 return type_for_clast_red ((struct clast_reduction
*) e
, ip
,
736 bound_one
, bound_two
);
739 return type_for_clast_bin ((struct clast_binary
*) e
, ip
,
740 bound_one
, bound_two
);
742 case clast_expr_name
:
743 return type_for_clast_name ((struct clast_name
*) e
, ip
,
744 bound_one
, bound_two
);
753 /* Returns true if the clast expression E is a constant with VALUE. */
756 clast_expr_const_value_p (struct clast_expr
*e
, int value
)
758 struct clast_term
*t
;
759 if (e
->type
!= clast_expr_term
)
761 t
= (struct clast_term
*)e
;
764 return 0 == mpz_cmp_si (t
->val
, value
);
767 /* Translates a clast equation CLEQ to a tree. */
770 graphite_translate_clast_equation (struct clast_equation
*cleq
,
774 tree type
, lhs
, rhs
, ltype
, rtype
;
775 mpz_t bound_one
, bound_two
;
776 struct clast_expr
*clhs
, *crhs
;
782 else if (cleq
->sign
> 0)
787 /* Special cases to reduce range of arguments to hopefully
788 don't need types with larger precision than the input. */
789 if (crhs
->type
== clast_expr_red
792 struct clast_reduction
*r
= (struct clast_reduction
*) crhs
;
793 /* X >= A+1 --> X > A and
794 X <= A-1 --> X < A */
796 && r
->type
== clast_red_sum
797 && clast_expr_const_value_p (r
->elts
[1], comp
== GE_EXPR
? 1 : -1))
800 comp
= comp
== GE_EXPR
? GT_EXPR
: LT_EXPR
;
804 mpz_init (bound_one
);
805 mpz_init (bound_two
);
807 ltype
= type_for_clast_expr (clhs
, ip
, bound_one
, bound_two
);
808 rtype
= type_for_clast_expr (crhs
, ip
, bound_one
, bound_two
);
810 mpz_clear (bound_one
);
811 mpz_clear (bound_two
);
812 type
= max_precision_type (ltype
, rtype
);
814 lhs
= clast_to_gcc_expression (type
, clhs
, ip
);
815 rhs
= clast_to_gcc_expression (type
, crhs
, ip
);
817 return fold_build2 (comp
, boolean_type_node
, lhs
, rhs
);
820 /* Creates the test for the condition in STMT. */
823 graphite_create_guard_cond_expr (struct clast_guard
*stmt
,
829 for (i
= 0; i
< stmt
->n
; i
++)
831 tree eq
= graphite_translate_clast_equation (&stmt
->eq
[i
], ip
);
834 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
842 /* Creates a new if region corresponding to Cloog's guard. */
845 graphite_create_new_guard (edge entry_edge
, struct clast_guard
*stmt
,
848 tree cond_expr
= graphite_create_guard_cond_expr (stmt
, ip
);
849 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
853 /* Compute the lower bound LOW and upper bound UP for the parameter
854 PARAM in scop SCOP based on the constraints in the context. */
857 compute_bounds_for_param (scop_p scop
, int param
, mpz_t low
, mpz_t up
)
860 isl_aff
*aff
= isl_aff_zero_on_domain
861 (isl_local_space_from_space (isl_set_get_space (scop
->context
)));
863 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, param
, 1);
866 isl_set_min (scop
->context
, aff
, &v
);
867 isl_int_get_gmp (v
, low
);
868 isl_set_max (scop
->context
, aff
, &v
);
869 isl_int_get_gmp (v
, up
);
874 /* Compute the lower bound LOW and upper bound UP for the induction
875 variable of loop LOOP.
877 FIXME: This one is not entirely correct, as min/max expressions in the
878 calculation can yield to incorrect results. To be completely
879 correct, we need to evaluate each subexpression generated by
880 CLooG. CLooG does not yet support this, so this is as good as
884 compute_bounds_for_loop (struct clast_for
*loop
, mpz_t low
, mpz_t up
)
888 isl_local_space
*local_space
;
890 enum isl_lp_result lp_result
;
892 domain
= isl_set_copy (isl_set_from_cloog_domain (loop
->domain
));
893 local_space
= isl_local_space_from_space (isl_set_get_space (domain
));
894 dimension
= isl_aff_zero_on_domain (local_space
);
895 dimension
= isl_aff_add_coefficient_si (dimension
, isl_dim_in
,
896 isl_set_dim (domain
, isl_dim_set
) - 1,
899 isl_int_init (isl_value
);
901 lp_result
= isl_set_min (domain
, dimension
, &isl_value
);
902 assert (lp_result
== isl_lp_ok
);
903 isl_int_get_gmp (isl_value
, low
);
905 lp_result
= isl_set_max (domain
, dimension
, &isl_value
);
906 assert (lp_result
== isl_lp_ok
);
907 isl_int_get_gmp (isl_value
, up
);
909 isl_int_clear (isl_value
);
910 isl_set_free (domain
);
911 isl_aff_free (dimension
);
914 /* Returns the type for the induction variable for the loop translated
918 type_for_clast_for (struct clast_for
*stmt_for
, ivs_params_p ip
)
920 mpz_t bound_one
, bound_two
;
921 tree lb_type
, ub_type
;
923 mpz_init (bound_one
);
924 mpz_init (bound_two
);
926 lb_type
= type_for_clast_expr (stmt_for
->LB
, ip
, bound_one
, bound_two
);
927 ub_type
= type_for_clast_expr (stmt_for
->UB
, ip
, bound_one
, bound_two
);
929 mpz_clear (bound_one
);
930 mpz_clear (bound_two
);
932 return max_precision_type (lb_type
, ub_type
);
935 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
936 induction variable for the new LOOP. New LOOP is attached to CFG
937 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
938 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
939 CLooG's scattering name to the induction variable created for the
940 loop of STMT. The new induction variable is inserted in the NEWIVS
941 vector and is of type TYPE. */
944 graphite_create_new_loop (edge entry_edge
, struct clast_for
*stmt
,
945 loop_p outer
, tree type
, tree lb
, tree ub
,
946 int level
, ivs_params_p ip
)
950 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
951 tree ivvar
= create_tmp_var (type
, "graphite_IV");
952 tree iv
, iv_after_increment
;
953 loop_p loop
= create_empty_loop_on_edge
954 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
955 outer
? outer
: entry_edge
->src
->loop_father
);
959 compute_bounds_for_loop (stmt
, low
, up
);
960 save_clast_name_index (ip
->newivs_index
, stmt
->iterator
,
961 (*ip
->newivs
).length (), level
, low
, up
);
964 (*ip
->newivs
).safe_push (iv
);
968 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
969 induction variables of the loops around GBB in SESE. */
972 build_iv_mapping (vec
<tree
> iv_map
, struct clast_user_stmt
*user_stmt
,
975 struct clast_stmt
*t
;
977 CloogStatement
*cs
= user_stmt
->statement
;
978 poly_bb_p pbb
= (poly_bb_p
) cs
->usr
;
979 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
980 mpz_t bound_one
, bound_two
;
982 mpz_init (bound_one
);
983 mpz_init (bound_two
);
985 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, depth
++)
987 struct clast_expr
*expr
= (struct clast_expr
*)
988 ((struct clast_assignment
*)t
)->RHS
;
989 tree type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
990 tree new_name
= clast_to_gcc_expression (type
, expr
, ip
);
991 loop_p old_loop
= gbb_loop_at_index (gbb
, ip
->region
, depth
);
993 iv_map
[old_loop
->num
] = new_name
;
996 mpz_clear (bound_one
);
997 mpz_clear (bound_two
);
1000 /* Construct bb_pbb_def with BB and PBB. */
1003 new_bb_pbb_def (basic_block bb
, poly_bb_p pbb
)
1005 bb_pbb_def
*bb_pbb_p
;
1007 bb_pbb_p
= XNEW (bb_pbb_def
);
1009 bb_pbb_p
->pbb
= pbb
;
1014 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1017 mark_bb_with_pbb (poly_bb_p pbb
, basic_block bb
, htab_t bb_pbb_mapping
)
1023 x
= htab_find_slot (bb_pbb_mapping
, &tmp
, INSERT
);
1026 *x
= new_bb_pbb_def (bb
, pbb
);
1029 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1032 find_pbb_via_hash (htab_t bb_pbb_mapping
, basic_block bb
)
1038 slot
= htab_find_slot (bb_pbb_mapping
, &tmp
, NO_INSERT
);
1041 return ((bb_pbb_def
*) *slot
)->pbb
;
1046 /* Return the scop of the loop and initialize PBBS the set of
1047 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1048 by the CLAST code generator between a generated basic_block and its
1049 related poly_bb_p. */
1052 get_loop_body_pbbs (loop_p loop
, htab_t bb_pbb_mapping
,
1053 vec
<poly_bb_p
> *pbbs
)
1056 basic_block
*bbs
= get_loop_body_in_dom_order (loop
);
1059 for (i
= 0; i
< loop
->num_nodes
; i
++)
1061 poly_bb_p pbb
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[i
]);
1066 scop
= PBB_SCOP (pbb
);
1067 (*pbbs
).safe_push (pbb
);
1074 /* Translates a clast user statement STMT to gimple.
1076 - NEXT_E is the edge where new generated code should be attached.
1077 - CONTEXT_LOOP is the loop in which the generated code will be placed
1078 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1081 translate_clast_user (struct clast_user_stmt
*stmt
, edge next_e
,
1082 htab_t bb_pbb_mapping
, ivs_params_p ip
)
1086 poly_bb_p pbb
= (poly_bb_p
) stmt
->statement
->usr
;
1087 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1090 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR
)
1093 nb_loops
= number_of_loops ();
1094 iv_map
.create (nb_loops
);
1095 for (i
= 0; i
< nb_loops
; i
++)
1096 iv_map
.quick_push (NULL_TREE
);
1098 build_iv_mapping (iv_map
, stmt
, ip
);
1099 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), ip
->region
,
1100 next_e
, iv_map
, &gloog_error
);
1103 new_bb
= next_e
->src
;
1104 mark_bb_with_pbb (pbb
, new_bb
, bb_pbb_mapping
);
1105 mark_virtual_operands_for_renaming (cfun
);
1106 update_ssa (TODO_update_ssa
);
1111 /* Creates a new if region protecting the loop to be executed, if the execution
1112 count is zero (lb > ub). */
1115 graphite_create_new_loop_guard (edge entry_edge
, struct clast_for
*stmt
,
1116 tree
*type
, tree
*lb
, tree
*ub
,
1122 *type
= type_for_clast_for (stmt
, ip
);
1123 *lb
= clast_to_gcc_expression (*type
, stmt
->LB
, ip
);
1124 *ub
= clast_to_gcc_expression (*type
, stmt
->UB
, ip
);
1126 /* When ub is simply a constant or a parameter, use lb <= ub. */
1127 if (TREE_CODE (*ub
) == INTEGER_CST
|| TREE_CODE (*ub
) == SSA_NAME
)
1128 cond_expr
= fold_build2 (LE_EXPR
, boolean_type_node
, *lb
, *ub
);
1131 tree one
= (POINTER_TYPE_P (*type
)
1132 ? convert_to_ptrofftype (integer_one_node
)
1133 : fold_convert (*type
, integer_one_node
));
1134 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1135 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1136 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1137 even if we do not want this. However lb < ub + 1 is false, as
1139 tree ub_one
= fold_build2 (POINTER_TYPE_P (*type
) ? POINTER_PLUS_EXPR
1140 : PLUS_EXPR
, *type
, *ub
, one
);
1142 cond_expr
= fold_build2 (LT_EXPR
, boolean_type_node
, *lb
, ub_one
);
1145 exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
1151 translate_clast (loop_p
, struct clast_stmt
*, edge
, htab_t
, int, ivs_params_p
);
1153 /* Create the loop for a clast for statement.
1155 - NEXT_E is the edge where new generated code should be attached.
1156 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1159 translate_clast_for_loop (loop_p context_loop
, struct clast_for
*stmt
,
1160 edge next_e
, htab_t bb_pbb_mapping
, int level
,
1161 tree type
, tree lb
, tree ub
, ivs_params_p ip
)
1163 struct loop
*loop
= graphite_create_new_loop (next_e
, stmt
, context_loop
,
1164 type
, lb
, ub
, level
, ip
);
1165 edge last_e
= single_exit (loop
);
1166 edge to_body
= single_succ_edge (loop
->header
);
1167 basic_block after
= to_body
->dest
;
1169 /* Create a basic block for loop close phi nodes. */
1170 last_e
= single_succ_edge (split_edge (last_e
));
1172 /* Translate the body of the loop. */
1173 next_e
= translate_clast (loop
, stmt
->body
, to_body
, bb_pbb_mapping
,
1175 redirect_edge_succ_nodup (next_e
, after
);
1176 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
1178 if (flag_loop_parallelize_all
1179 && loop_is_parallel_p (loop
, bb_pbb_mapping
, level
))
1180 loop
->can_be_parallel
= true;
1185 /* Translates a clast for statement STMT to gimple. First a guard is created
1186 protecting the loop, if it is executed zero times. In this guard we create
1187 the real loop structure.
1189 - NEXT_E is the edge where new generated code should be attached.
1190 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1193 translate_clast_for (loop_p context_loop
, struct clast_for
*stmt
, edge next_e
,
1194 htab_t bb_pbb_mapping
, int level
, ivs_params_p ip
)
1197 edge last_e
= graphite_create_new_loop_guard (next_e
, stmt
, &type
,
1199 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1201 translate_clast_for_loop (context_loop
, stmt
, true_e
, bb_pbb_mapping
, level
,
1206 /* Translates a clast assignment STMT to gimple.
1208 - NEXT_E is the edge where new generated code should be attached.
1209 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1212 translate_clast_assignment (struct clast_assignment
*stmt
, edge next_e
,
1213 int level
, ivs_params_p ip
)
1216 mpz_t bound_one
, bound_two
;
1217 tree type
, new_name
, var
;
1218 edge res
= single_succ_edge (split_edge (next_e
));
1219 struct clast_expr
*expr
= (struct clast_expr
*) stmt
->RHS
;
1221 mpz_init (bound_one
);
1222 mpz_init (bound_two
);
1223 type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1224 var
= create_tmp_var (type
, "graphite_var");
1225 new_name
= force_gimple_operand (clast_to_gcc_expression (type
, expr
, ip
),
1229 gsi_insert_seq_on_edge (next_e
, stmts
);
1230 gsi_commit_edge_inserts ();
1233 save_clast_name_index (ip
->newivs_index
, stmt
->LHS
,
1234 (*ip
->newivs
).length (), level
,
1235 bound_one
, bound_two
);
1236 (*ip
->newivs
).safe_push (new_name
);
1238 mpz_clear (bound_one
);
1239 mpz_clear (bound_two
);
1244 /* Translates a clast guard statement STMT to gimple.
1246 - NEXT_E is the edge where new generated code should be attached.
1247 - CONTEXT_LOOP is the loop in which the generated code will be placed
1248 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1251 translate_clast_guard (loop_p context_loop
, struct clast_guard
*stmt
,
1252 edge next_e
, htab_t bb_pbb_mapping
, int level
,
1255 edge last_e
= graphite_create_new_guard (next_e
, stmt
, ip
);
1256 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1258 translate_clast (context_loop
, stmt
->then
, true_e
, bb_pbb_mapping
, level
, ip
);
1262 /* Translates a CLAST statement STMT to GCC representation in the
1265 - NEXT_E is the edge where new generated code should be attached.
1266 - CONTEXT_LOOP is the loop in which the generated code will be placed
1267 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1270 translate_clast (loop_p context_loop
, struct clast_stmt
*stmt
, edge next_e
,
1271 htab_t bb_pbb_mapping
, int level
, ivs_params_p ip
)
1276 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
1279 else if (CLAST_STMT_IS_A (stmt
, stmt_user
))
1280 next_e
= translate_clast_user ((struct clast_user_stmt
*) stmt
,
1281 next_e
, bb_pbb_mapping
, ip
);
1283 else if (CLAST_STMT_IS_A (stmt
, stmt_for
))
1284 next_e
= translate_clast_for (context_loop
, (struct clast_for
*) stmt
,
1285 next_e
, bb_pbb_mapping
, level
, ip
);
1287 else if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
1288 next_e
= translate_clast_guard (context_loop
, (struct clast_guard
*) stmt
,
1289 next_e
, bb_pbb_mapping
, level
, ip
);
1291 else if (CLAST_STMT_IS_A (stmt
, stmt_block
))
1292 next_e
= translate_clast (context_loop
, ((struct clast_block
*) stmt
)->body
,
1293 next_e
, bb_pbb_mapping
, level
, ip
);
1295 else if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
1296 next_e
= translate_clast_assignment ((struct clast_assignment
*) stmt
,
1301 recompute_all_dominators ();
1304 return translate_clast (context_loop
, stmt
->next
, next_e
, bb_pbb_mapping
,
1308 /* Add parameter and iterator names to the CloogUnionDomain. */
1310 static CloogUnionDomain
*
1311 add_names_to_union_domain (scop_p scop
, CloogUnionDomain
*union_domain
,
1312 int nb_scattering_dims
, htab_t params_index
)
1314 sese region
= SCOP_REGION (scop
);
1316 int nb_iterators
= scop_max_loop_depth (scop
);
1317 int nb_parameters
= SESE_PARAMS (region
).length ();
1318 mpz_t bound_one
, bound_two
;
1320 mpz_init (bound_one
);
1321 mpz_init (bound_two
);
1323 for (i
= 0; i
< nb_parameters
; i
++)
1325 tree param
= SESE_PARAMS (region
)[i
];
1326 const char *name
= get_name (param
);
1333 len
= strlen (name
);
1335 parameter
= XNEWVEC (char, len
+ 1);
1336 snprintf (parameter
, len
, "%s_%d", name
, SSA_NAME_VERSION (param
));
1337 save_clast_name_index (params_index
, parameter
, i
, i
, bound_one
,
1339 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_PARAM
, i
,
1341 compute_bounds_for_param (scop
, i
, bound_one
, bound_two
);
1345 mpz_clear (bound_one
);
1346 mpz_clear (bound_two
);
1348 for (i
= 0; i
< nb_iterators
; i
++)
1352 iterator
= XNEWVEC (char, len
);
1353 snprintf (iterator
, len
, "git_%d", i
);
1354 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_ITER
, i
,
1359 for (i
= 0; i
< nb_scattering_dims
; i
++)
1363 scattering
= XNEWVEC (char, len
);
1364 snprintf (scattering
, len
, "scat_%d", i
);
1365 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_SCAT
, i
,
1370 return union_domain
;
1373 /* Initialize a CLooG input file. */
1376 init_cloog_input_file (int scop_number
)
1378 FILE *graphite_out_file
;
1379 int len
= strlen (dump_base_name
);
1380 char *dumpname
= XNEWVEC (char, len
+ 25);
1381 char *s_scop_number
= XNEWVEC (char, 15);
1383 memcpy (dumpname
, dump_base_name
, len
+ 1);
1384 strip_off_ending (dumpname
, len
);
1385 sprintf (s_scop_number
, ".%d", scop_number
);
1386 strcat (dumpname
, s_scop_number
);
1387 strcat (dumpname
, ".cloog");
1388 graphite_out_file
= fopen (dumpname
, "w+b");
1390 if (graphite_out_file
== 0)
1391 fatal_error ("can%'t open %s for writing: %m", dumpname
);
1395 return graphite_out_file
;
1398 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1401 isl_map
*extend_scattering(isl_map
*scattering
, int new_dims
)
1405 isl_basic_map
*change_scattering
;
1406 isl_map
*change_scattering_map
;
1408 old_dims
= isl_map_dim (scattering
, isl_dim_out
);
1410 space
= isl_space_alloc (isl_map_get_ctx (scattering
), 0, old_dims
, new_dims
);
1411 change_scattering
= isl_basic_map_universe (isl_space_copy (space
));
1413 for (i
= 0; i
< old_dims
; i
++)
1416 c
= isl_equality_alloc
1417 (isl_local_space_from_space (isl_space_copy (space
)));
1418 isl_constraint_set_coefficient_si (c
, isl_dim_in
, i
, 1);
1419 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, -1);
1420 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1423 for (i
= old_dims
; i
< new_dims
; i
++)
1426 c
= isl_equality_alloc
1427 (isl_local_space_from_space (isl_space_copy (space
)));
1428 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
1429 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1432 change_scattering_map
= isl_map_from_basic_map (change_scattering
);
1433 change_scattering_map
= isl_map_align_params (change_scattering_map
, space
);
1434 return isl_map_apply_range (scattering
, change_scattering_map
);
1437 /* Build cloog union domain for SCoP. */
1439 static CloogUnionDomain
*
1440 build_cloog_union_domain (scop_p scop
, int nb_scattering_dims
)
1444 CloogUnionDomain
*union_domain
=
1445 cloog_union_domain_alloc (scop_nb_params (scop
));
1447 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1449 CloogDomain
*domain
;
1450 CloogScattering
*scattering
;
1452 /* Dead code elimination: when the domain of a PBB is empty,
1453 don't generate code for the PBB. */
1454 if (isl_set_is_empty(pbb
->domain
))
1457 domain
= cloog_domain_from_isl_set(isl_set_copy(pbb
->domain
));
1458 scattering
= cloog_scattering_from_isl_map(extend_scattering(isl_map_copy(pbb
->transformed
),
1459 nb_scattering_dims
));
1461 union_domain
= cloog_union_domain_add_domain (union_domain
, "", domain
,
1465 return union_domain
;
1468 /* Return the options that will be used in GLOOG. */
1470 static CloogOptions
*
1471 set_cloog_options (void)
1473 CloogOptions
*options
= cloog_options_malloc (cloog_state
);
1475 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1476 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1477 we pass an incomplete program to cloog. */
1478 options
->language
= CLOOG_LANGUAGE_C
;
1480 /* Enable complex equality spreading: removes dummy statements
1481 (assignments) in the generated code which repeats the
1482 substitution equations for statements. This is useless for
1486 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1489 /* Allow cloog to build strides with a stride width different to one.
1490 This example has stride = 4:
1492 for (i = 0; i < 20; i += 4)
1494 options
->strides
= 1;
1496 /* We want the clast to provide the iteration domains of the executed loops.
1497 This allows us to derive minimal/maximal values for the induction
1499 options
->save_domains
= 1;
1501 /* Disable optimizations and make cloog generate source code closer to the
1502 input. This is useful for debugging, but later we want the optimized
1505 XXX: We can not disable optimizations, as loop blocking is not working
1510 options
->l
= INT_MAX
;
1516 /* Prints STMT to STDERR. */
1519 print_clast_stmt (FILE *file
, struct clast_stmt
*stmt
)
1521 CloogOptions
*options
= set_cloog_options ();
1523 clast_pprint (file
, stmt
, 0, options
);
1524 cloog_options_free (options
);
1527 /* Prints STMT to STDERR. */
1530 debug_clast_stmt (struct clast_stmt
*stmt
)
1532 print_clast_stmt (stderr
, stmt
);
1535 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1538 int get_max_scattering_dimensions (scop_p scop
)
1542 int scattering_dims
= 0;
1544 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1546 int pbb_scatt_dims
= isl_map_dim (pbb
->transformed
, isl_dim_out
);
1547 if (pbb_scatt_dims
> scattering_dims
)
1548 scattering_dims
= pbb_scatt_dims
;
1551 return scattering_dims
;
1555 generate_cloog_input (scop_p scop
, htab_t params_index
)
1557 CloogUnionDomain
*union_domain
;
1558 CloogInput
*cloog_input
;
1559 CloogDomain
*context
;
1560 int nb_scattering_dims
= get_max_scattering_dimensions (scop
);
1562 union_domain
= build_cloog_union_domain (scop
, nb_scattering_dims
);
1563 union_domain
= add_names_to_union_domain (scop
, union_domain
,
1566 context
= cloog_domain_from_isl_set (isl_set_copy (scop
->context
));
1568 cloog_input
= cloog_input_alloc (context
, union_domain
);
1573 /* Translate SCOP to a CLooG program and clast. These two
1574 representations should be freed together: a clast cannot be used
1575 without a program. */
1577 static struct clast_stmt
*
1578 scop_to_clast (scop_p scop
, htab_t params_index
)
1580 CloogInput
*cloog_input
;
1581 struct clast_stmt
*clast
;
1582 CloogOptions
*options
= set_cloog_options ();
1584 cloog_input
= generate_cloog_input (scop
, params_index
);
1586 /* Dump a .cloog input file, if requested. This feature is only
1587 enabled in the Graphite branch. */
1590 static size_t file_scop_number
= 0;
1591 FILE *cloog_file
= init_cloog_input_file (file_scop_number
);
1592 cloog_input_dump_cloog (cloog_file
, cloog_input
, options
);
1595 clast
= cloog_clast_create_from_input (cloog_input
, options
);
1597 cloog_options_free (options
);
1601 /* Prints to FILE the code generated by CLooG for SCOP. */
1604 print_generated_program (FILE *file
, scop_p scop
)
1606 CloogOptions
*options
= set_cloog_options ();
1607 htab_t params_index
;
1608 struct clast_stmt
*clast
;
1610 params_index
= htab_create (10, clast_name_index_elt_info
,
1611 eq_clast_name_indexes
, free_clast_name_index
);
1613 clast
= scop_to_clast (scop
, params_index
);
1615 fprintf (file
, " (clast: \n");
1616 clast_pprint (file
, clast
, 0, options
);
1617 fprintf (file
, " )\n");
1619 cloog_options_free (options
);
1620 cloog_clast_free (clast
);
1623 /* Prints to STDERR the code generated by CLooG for SCOP. */
1626 debug_generated_program (scop_p scop
)
1628 print_generated_program (stderr
, scop
);
1631 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1632 the given SCOP. Return true if code generation succeeded.
1633 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1637 gloog (scop_p scop
, htab_t bb_pbb_mapping
)
1641 loop_p context_loop
;
1642 sese region
= SCOP_REGION (scop
);
1643 ifsese if_region
= NULL
;
1644 htab_t newivs_index
, params_index
;
1645 struct clast_stmt
*clast
;
1646 struct ivs_params ip
;
1648 timevar_push (TV_GRAPHITE_CODE_GEN
);
1649 gloog_error
= false;
1651 params_index
= htab_create (10, clast_name_index_elt_info
,
1652 eq_clast_name_indexes
, free_clast_name_index
);
1654 clast
= scop_to_clast (scop
, params_index
);
1656 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1658 fprintf (dump_file
, "\nCLAST generated by CLooG: \n");
1659 print_clast_stmt (dump_file
, clast
);
1660 fprintf (dump_file
, "\n");
1663 recompute_all_dominators ();
1666 if_region
= move_sese_in_condition (region
);
1667 sese_insert_phis_for_liveouts (region
,
1668 if_region
->region
->exit
->src
,
1669 if_region
->false_region
->exit
,
1670 if_region
->true_region
->exit
);
1671 recompute_all_dominators ();
1674 context_loop
= SESE_ENTRY (region
)->src
->loop_father
;
1675 newivs_index
= htab_create (10, clast_name_index_elt_info
,
1676 eq_clast_name_indexes
, free_clast_name_index
);
1678 ip
.newivs
= &newivs
;
1679 ip
.newivs_index
= newivs_index
;
1680 ip
.params
= SESE_PARAMS (region
);
1681 ip
.params_index
= params_index
;
1684 translate_clast (context_loop
, clast
, if_region
->true_region
->entry
,
1685 bb_pbb_mapping
, 0, &ip
);
1688 recompute_all_dominators ();
1692 set_ifsese_condition (if_region
, integer_zero_node
);
1694 free (if_region
->true_region
);
1695 free (if_region
->region
);
1698 htab_delete (newivs_index
);
1699 htab_delete (params_index
);
1701 cloog_clast_free (clast
);
1702 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1704 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1708 int num_no_dependency
= 0;
1710 FOR_EACH_LOOP (li
, loop
, 0)
1711 if (loop
->can_be_parallel
)
1712 num_no_dependency
++;
1714 fprintf (dump_file
, "\n%d loops carried no dependency.\n",
1718 return !gloog_error
;