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"
38 #include "tree-flow.h"
39 #include "tree-pass.h"
41 #include "tree-chrec.h"
42 #include "tree-data-ref.h"
43 #include "tree-scalar-evolution.h"
47 #include "cloog/cloog.h"
48 #include "graphite-poly.h"
49 #include "graphite-clast-to-gimple.h"
50 #include "graphite-htab.h"
52 typedef const struct clast_expr
*clast_name_p
;
54 #ifndef CLOOG_LANGUAGE_C
55 #define CLOOG_LANGUAGE_C LANGUAGE_C
59 /* Converts a GMP constant VAL to a tree and returns it. */
62 gmp_cst_to_tree (tree type
, mpz_t val
)
64 tree t
= type
? type
: integer_type_node
;
70 di
= mpz_get_double_int (t
, tmp
, true);
73 return double_int_to_tree (t
, di
);
76 /* Sets RES to the min of V1 and V2. */
79 value_min (mpz_t res
, mpz_t v1
, mpz_t v2
)
81 if (mpz_cmp (v1
, v2
) < 0)
87 /* Sets RES to the max of V1 and V2. */
90 value_max (mpz_t res
, mpz_t v1
, mpz_t v2
)
92 if (mpz_cmp (v1
, v2
) < 0)
99 /* This flag is set when an error occurred during the translation of
101 static bool gloog_error
;
103 /* Verifies properties that GRAPHITE should maintain during translation. */
106 graphite_verify (void)
108 #ifdef ENABLE_CHECKING
109 verify_loop_structure ();
110 verify_loop_closed_ssa (true);
114 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
115 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
116 upper bounds that can be inferred from the polyhedral representation. */
118 typedef struct clast_name_index
{
121 mpz_t bound_one
, bound_two
;
123 /* If free_name is set, the content of name was allocated by us and needs
126 } *clast_name_index_p
;
128 /* Helper for hashing clast_name_index. */
130 struct clast_index_hasher
132 typedef clast_name_index value_type
;
133 typedef clast_name_index compare_type
;
134 static inline hashval_t
hash (const value_type
*);
135 static inline bool equal (const value_type
*, const compare_type
*);
136 static inline void remove (value_type
*);
139 /* Computes a hash function for database element E. */
142 clast_index_hasher::hash (const value_type
*e
)
146 int length
= strlen (e
->name
);
149 for (i
= 0; i
< length
; ++i
)
150 hash
= hash
| (e
->name
[i
] << (i
% 4));
155 /* Compares database elements ELT1 and ELT2. */
158 clast_index_hasher::equal (const value_type
*elt1
, const compare_type
*elt2
)
160 return strcmp (elt1
->name
, elt2
->name
) == 0;
163 /* Free the memory taken by a clast_name_index struct. */
166 clast_index_hasher::remove (value_type
*c
)
170 mpz_clear (c
->bound_one
);
171 mpz_clear (c
->bound_two
);
175 typedef hash_table
<clast_index_hasher
> clast_index_htab_type
;
177 /* Returns a pointer to a new element of type clast_name_index_p built
178 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
180 static inline clast_name_index_p
181 new_clast_name_index (const char *name
, int index
, int level
,
182 mpz_t bound_one
, mpz_t bound_two
)
184 clast_name_index_p res
= XNEW (struct clast_name_index
);
185 char *new_name
= XNEWVEC (char, strlen (name
) + 1);
186 strcpy (new_name
, name
);
188 res
->name
= new_name
;
189 res
->free_name
= new_name
;
192 mpz_init (res
->bound_one
);
193 mpz_init (res
->bound_two
);
194 mpz_set (res
->bound_one
, bound_one
);
195 mpz_set (res
->bound_two
, bound_two
);
199 /* For a given clast NAME, returns -1 if NAME is not in the
200 INDEX_TABLE, otherwise returns the loop level for the induction
201 variable NAME, or if it is a parameter, the parameter number in the
202 vector of parameters. */
205 clast_name_to_level (clast_name_p name
, clast_index_htab_type index_table
)
207 struct clast_name_index tmp
;
208 clast_name_index
**slot
;
210 gcc_assert (name
->type
== clast_expr_name
);
211 tmp
.name
= ((const struct clast_name
*) name
)->name
;
212 tmp
.free_name
= NULL
;
214 slot
= index_table
.find_slot (&tmp
, NO_INSERT
);
217 return ((struct clast_name_index
*) *slot
)->level
;
222 /* For a given clast NAME, returns -1 if it does not correspond to any
223 parameter, or otherwise, returns the index in the PARAMS or
224 SCATTERING_DIMENSIONS vector. */
227 clast_name_to_index (struct clast_name
*name
, clast_index_htab_type index_table
)
229 struct clast_name_index tmp
;
230 clast_name_index
**slot
;
232 tmp
.name
= ((const struct clast_name
*) name
)->name
;
233 tmp
.free_name
= NULL
;
235 slot
= index_table
.find_slot (&tmp
, NO_INSERT
);
238 return (*slot
)->index
;
243 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
244 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
245 found in the INDEX_TABLE, false otherwise. */
248 clast_name_to_lb_ub (struct clast_name
*name
, clast_index_htab_type index_table
,
249 mpz_t bound_one
, mpz_t bound_two
)
251 struct clast_name_index tmp
;
252 clast_name_index
**slot
;
254 tmp
.name
= name
->name
;
255 tmp
.free_name
= NULL
;
257 slot
= index_table
.find_slot (&tmp
, NO_INSERT
);
261 mpz_set (bound_one
, ((struct clast_name_index
*) *slot
)->bound_one
);
262 mpz_set (bound_two
, ((struct clast_name_index
*) *slot
)->bound_two
);
269 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
272 save_clast_name_index (clast_index_htab_type index_table
, const char *name
,
273 int index
, int level
, mpz_t bound_one
, mpz_t bound_two
)
275 struct clast_name_index tmp
;
276 clast_name_index
**slot
;
279 tmp
.free_name
= NULL
;
280 slot
= index_table
.find_slot (&tmp
, INSERT
);
286 *slot
= new_clast_name_index (name
, index
, level
, bound_one
, bound_two
);
291 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
292 induction variable in NEWIVS.
294 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
295 parameter in PARAMS. */
297 typedef struct ivs_params
{
298 vec
<tree
> params
, *newivs
;
299 clast_index_htab_type newivs_index
, params_index
;
303 /* Returns the tree variable from the name NAME that was given in
304 Cloog representation. */
307 clast_name_to_gcc (struct clast_name
*name
, ivs_params_p ip
)
311 if (ip
->params
.exists () && ip
->params_index
.is_created ())
313 index
= clast_name_to_index (name
, ip
->params_index
);
316 return ip
->params
[index
];
319 gcc_assert (ip
->newivs
&& ip
->newivs_index
.is_created ());
320 index
= clast_name_to_index (name
, ip
->newivs_index
);
321 gcc_assert (index
>= 0);
323 return (*ip
->newivs
)[index
];
326 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
329 max_precision_type (tree type1
, tree type2
)
331 enum machine_mode mode
;
332 int p1
, p2
, precision
;
335 if (POINTER_TYPE_P (type1
))
338 if (POINTER_TYPE_P (type2
))
341 if (TYPE_UNSIGNED (type1
)
342 && TYPE_UNSIGNED (type2
))
343 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
345 p1
= TYPE_PRECISION (type1
);
346 p2
= TYPE_PRECISION (type2
);
349 precision
= TYPE_UNSIGNED (type1
) ? p1
* 2 : p1
;
351 precision
= TYPE_UNSIGNED (type2
) ? p2
* 2 : p2
;
353 if (precision
> BITS_PER_WORD
)
356 return integer_type_node
;
359 mode
= smallest_mode_for_size (precision
, MODE_INT
);
360 precision
= GET_MODE_PRECISION (mode
);
361 type
= build_nonstandard_integer_type (precision
, false);
366 return integer_type_node
;
373 clast_to_gcc_expression (tree
, struct clast_expr
*, ivs_params_p
);
375 /* Converts a Cloog reduction expression R with reduction operation OP
376 to a GCC expression tree of type TYPE. */
379 clast_to_gcc_expression_red (tree type
, enum tree_code op
,
380 struct clast_reduction
*r
, ivs_params_p ip
)
383 tree res
= clast_to_gcc_expression (type
, r
->elts
[0], ip
);
384 tree operand_type
= (op
== POINTER_PLUS_EXPR
) ? sizetype
: type
;
386 for (i
= 1; i
< r
->n
; i
++)
388 tree t
= clast_to_gcc_expression (operand_type
, r
->elts
[i
], ip
);
389 res
= fold_build2 (op
, type
, res
, t
);
395 /* Converts a Cloog AST expression E back to a GCC expression tree of
399 clast_to_gcc_expression (tree type
, struct clast_expr
*e
, ivs_params_p ip
)
403 case clast_expr_name
:
405 return clast_name_to_gcc ((struct clast_name
*) e
, ip
);
407 case clast_expr_term
:
409 struct clast_term
*t
= (struct clast_term
*) e
;
413 if (mpz_cmp_si (t
->val
, 1) == 0)
415 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
417 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
418 name
= convert_to_ptrofftype (name
);
420 name
= fold_convert (type
, name
);
424 else if (mpz_cmp_si (t
->val
, -1) == 0)
426 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
428 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
429 name
= convert_to_ptrofftype (name
);
431 name
= fold_convert (type
, name
);
433 return fold_build1 (NEGATE_EXPR
, type
, name
);
437 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
438 tree cst
= gmp_cst_to_tree (type
, t
->val
);
440 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
441 name
= convert_to_ptrofftype (name
);
443 name
= fold_convert (type
, name
);
445 if (!POINTER_TYPE_P (type
))
446 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
453 return gmp_cst_to_tree (type
, t
->val
);
458 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
463 return clast_to_gcc_expression_red
464 (type
, POINTER_TYPE_P (type
) ? POINTER_PLUS_EXPR
: PLUS_EXPR
,
468 return clast_to_gcc_expression_red (type
, MIN_EXPR
, r
, ip
);
471 return clast_to_gcc_expression_red (type
, MAX_EXPR
, r
, ip
);
481 struct clast_binary
*b
= (struct clast_binary
*) e
;
482 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
483 tree tl
= clast_to_gcc_expression (type
, lhs
, ip
);
484 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
489 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
492 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
495 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
498 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
512 /* Return a type that could represent the values between BOUND_ONE and
516 type_for_interval (mpz_t bound_one
, mpz_t bound_two
)
520 enum machine_mode mode
;
522 int precision
= MAX (mpz_sizeinbase (bound_one
, 2),
523 mpz_sizeinbase (bound_two
, 2));
525 if (precision
> BITS_PER_WORD
)
528 return integer_type_node
;
531 if (mpz_cmp (bound_one
, bound_two
) <= 0)
532 unsigned_p
= (mpz_sgn (bound_one
) >= 0);
534 unsigned_p
= (mpz_sgn (bound_two
) >= 0);
536 mode
= smallest_mode_for_size (precision
, MODE_INT
);
537 wider_precision
= GET_MODE_PRECISION (mode
);
539 /* As we want to generate signed types as much as possible, try to
540 fit the interval [bound_one, bound_two] in a signed type. For example,
541 supposing that we have the interval [0, 100], instead of
542 generating unsigned char, we want to generate a signed char. */
543 if (unsigned_p
&& precision
< wider_precision
)
546 type
= build_nonstandard_integer_type (wider_precision
, unsigned_p
);
551 return integer_type_node
;
557 /* Return a type that could represent the integer value VAL, or
558 otherwise return NULL_TREE. */
561 type_for_value (mpz_t val
)
563 return type_for_interval (val
, val
);
567 type_for_clast_expr (struct clast_expr
*, ivs_params_p
, mpz_t
, mpz_t
);
569 /* Return the type for the clast_term T. Initializes BOUND_ONE and
570 BOUND_TWO to the bounds of the term. */
573 type_for_clast_term (struct clast_term
*t
, ivs_params_p ip
, mpz_t bound_one
,
577 gcc_assert (t
->expr
.type
== clast_expr_term
);
581 mpz_set (bound_one
, t
->val
);
582 mpz_set (bound_two
, t
->val
);
583 return type_for_value (t
->val
);
586 type
= type_for_clast_expr (t
->var
, ip
, bound_one
, bound_two
);
588 mpz_mul (bound_one
, bound_one
, t
->val
);
589 mpz_mul (bound_two
, bound_two
, t
->val
);
591 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
594 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
595 and BOUND_TWO to the bounds of the reduction expression. */
598 type_for_clast_red (struct clast_reduction
*r
, ivs_params_p ip
,
599 mpz_t bound_one
, mpz_t bound_two
)
602 tree type
= type_for_clast_expr (r
->elts
[0], ip
, bound_one
, bound_two
);
603 mpz_t b1
, b2
, m1
, m2
;
613 for (i
= 1; i
< r
->n
; i
++)
615 tree t
= type_for_clast_expr (r
->elts
[i
], ip
, b1
, b2
);
616 type
= max_precision_type (type
, t
);
621 value_min (m1
, bound_one
, bound_two
);
622 value_min (m2
, b1
, b2
);
623 mpz_add (bound_one
, m1
, m2
);
625 value_max (m1
, bound_one
, bound_two
);
626 value_max (m2
, b1
, b2
);
627 mpz_add (bound_two
, m1
, m2
);
631 value_min (bound_one
, bound_one
, bound_two
);
632 value_min (bound_two
, b1
, b2
);
636 value_max (bound_one
, bound_one
, bound_two
);
637 value_max (bound_two
, b1
, b2
);
651 /* Return a type that can represent the result of the reduction. */
652 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
655 /* Return the type for the clast_binary B used in STMT. */
658 type_for_clast_bin (struct clast_binary
*b
, ivs_params_p ip
, mpz_t bound_one
,
662 tree l
= type_for_clast_expr ((struct clast_expr
*) b
->LHS
, ip
,
663 bound_one
, bound_two
);
664 tree r
= type_for_value (b
->RHS
);
665 tree type
= max_precision_type (l
, r
);
670 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
671 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
675 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
676 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
678 mpz_add (bound_one
, bound_one
, one
);
679 mpz_add (bound_two
, bound_two
, one
);
684 mpz_div (bound_one
, bound_one
, b
->RHS
);
685 mpz_div (bound_two
, bound_two
, b
->RHS
);
689 mpz_mod (bound_one
, bound_one
, b
->RHS
);
690 mpz_mod (bound_two
, bound_two
, b
->RHS
);
697 /* Return a type that can represent the result of the reduction. */
698 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
701 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
702 BOUND_TWO to the bounds of the term. */
705 type_for_clast_name (struct clast_name
*name
, ivs_params_p ip
, mpz_t bound_one
,
710 if (ip
->params
.exists () && ip
->params_index
.is_created ())
711 found
= clast_name_to_lb_ub (name
, ip
->params_index
, bound_one
, bound_two
);
715 gcc_assert (ip
->newivs
&& ip
->newivs_index
.is_created ());
716 found
= clast_name_to_lb_ub (name
, ip
->newivs_index
, bound_one
,
721 return TREE_TYPE (clast_name_to_gcc (name
, ip
));
724 /* Returns the type for the CLAST expression E when used in statement
728 type_for_clast_expr (struct clast_expr
*e
, ivs_params_p ip
, mpz_t bound_one
,
733 case clast_expr_term
:
734 return type_for_clast_term ((struct clast_term
*) e
, ip
,
735 bound_one
, bound_two
);
738 return type_for_clast_red ((struct clast_reduction
*) e
, ip
,
739 bound_one
, bound_two
);
742 return type_for_clast_bin ((struct clast_binary
*) e
, ip
,
743 bound_one
, bound_two
);
745 case clast_expr_name
:
746 return type_for_clast_name ((struct clast_name
*) e
, ip
,
747 bound_one
, bound_two
);
756 /* Returns true if the clast expression E is a constant with VALUE. */
759 clast_expr_const_value_p (struct clast_expr
*e
, int value
)
761 struct clast_term
*t
;
762 if (e
->type
!= clast_expr_term
)
764 t
= (struct clast_term
*)e
;
767 return 0 == mpz_cmp_si (t
->val
, value
);
770 /* Translates a clast equation CLEQ to a tree. */
773 graphite_translate_clast_equation (struct clast_equation
*cleq
,
777 tree type
, lhs
, rhs
, ltype
, rtype
;
778 mpz_t bound_one
, bound_two
;
779 struct clast_expr
*clhs
, *crhs
;
785 else if (cleq
->sign
> 0)
790 /* Special cases to reduce range of arguments to hopefully
791 don't need types with larger precision than the input. */
792 if (crhs
->type
== clast_expr_red
795 struct clast_reduction
*r
= (struct clast_reduction
*) crhs
;
796 /* X >= A+1 --> X > A and
797 X <= A-1 --> X < A */
799 && r
->type
== clast_red_sum
800 && clast_expr_const_value_p (r
->elts
[1], comp
== GE_EXPR
? 1 : -1))
803 comp
= comp
== GE_EXPR
? GT_EXPR
: LT_EXPR
;
807 mpz_init (bound_one
);
808 mpz_init (bound_two
);
810 ltype
= type_for_clast_expr (clhs
, ip
, bound_one
, bound_two
);
811 rtype
= type_for_clast_expr (crhs
, ip
, bound_one
, bound_two
);
813 mpz_clear (bound_one
);
814 mpz_clear (bound_two
);
815 type
= max_precision_type (ltype
, rtype
);
817 lhs
= clast_to_gcc_expression (type
, clhs
, ip
);
818 rhs
= clast_to_gcc_expression (type
, crhs
, ip
);
820 return fold_build2 (comp
, boolean_type_node
, lhs
, rhs
);
823 /* Creates the test for the condition in STMT. */
826 graphite_create_guard_cond_expr (struct clast_guard
*stmt
,
832 for (i
= 0; i
< stmt
->n
; i
++)
834 tree eq
= graphite_translate_clast_equation (&stmt
->eq
[i
], ip
);
837 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
845 /* Creates a new if region corresponding to Cloog's guard. */
848 graphite_create_new_guard (edge entry_edge
, struct clast_guard
*stmt
,
851 tree cond_expr
= graphite_create_guard_cond_expr (stmt
, ip
);
852 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
856 /* Compute the lower bound LOW and upper bound UP for the parameter
857 PARAM in scop SCOP based on the constraints in the context. */
860 compute_bounds_for_param (scop_p scop
, int param
, mpz_t low
, mpz_t up
)
863 isl_aff
*aff
= isl_aff_zero_on_domain
864 (isl_local_space_from_space (isl_set_get_space (scop
->context
)));
866 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, param
, 1);
869 isl_set_min (scop
->context
, aff
, &v
);
870 isl_int_get_gmp (v
, low
);
871 isl_set_max (scop
->context
, aff
, &v
);
872 isl_int_get_gmp (v
, up
);
877 /* Compute the lower bound LOW and upper bound UP for the induction
878 variable of loop LOOP.
880 FIXME: This one is not entirely correct, as min/max expressions in the
881 calculation can yield to incorrect results. To be completely
882 correct, we need to evaluate each subexpression generated by
883 CLooG. CLooG does not yet support this, so this is as good as
887 compute_bounds_for_loop (struct clast_for
*loop
, mpz_t low
, mpz_t up
)
891 isl_local_space
*local_space
;
893 enum isl_lp_result lp_result
;
895 domain
= isl_set_copy (isl_set_from_cloog_domain (loop
->domain
));
896 local_space
= isl_local_space_from_space (isl_set_get_space (domain
));
897 dimension
= isl_aff_zero_on_domain (local_space
);
898 dimension
= isl_aff_add_coefficient_si (dimension
, isl_dim_in
,
899 isl_set_dim (domain
, isl_dim_set
) - 1,
902 isl_int_init (isl_value
);
904 lp_result
= isl_set_min (domain
, dimension
, &isl_value
);
905 assert (lp_result
== isl_lp_ok
);
906 isl_int_get_gmp (isl_value
, low
);
908 lp_result
= isl_set_max (domain
, dimension
, &isl_value
);
909 assert (lp_result
== isl_lp_ok
);
910 isl_int_get_gmp (isl_value
, up
);
912 isl_int_clear (isl_value
);
913 isl_set_free (domain
);
914 isl_aff_free (dimension
);
917 /* Returns the type for the induction variable for the loop translated
921 type_for_clast_for (struct clast_for
*stmt_for
, ivs_params_p ip
)
923 mpz_t bound_one
, bound_two
;
924 tree lb_type
, ub_type
;
926 mpz_init (bound_one
);
927 mpz_init (bound_two
);
929 lb_type
= type_for_clast_expr (stmt_for
->LB
, ip
, bound_one
, bound_two
);
930 ub_type
= type_for_clast_expr (stmt_for
->UB
, ip
, bound_one
, bound_two
);
932 mpz_clear (bound_one
);
933 mpz_clear (bound_two
);
935 return max_precision_type (lb_type
, ub_type
);
938 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
939 induction variable for the new LOOP. New LOOP is attached to CFG
940 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
941 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
942 CLooG's scattering name to the induction variable created for the
943 loop of STMT. The new induction variable is inserted in the NEWIVS
944 vector and is of type TYPE. */
947 graphite_create_new_loop (edge entry_edge
, struct clast_for
*stmt
,
948 loop_p outer
, tree type
, tree lb
, tree ub
,
949 int level
, ivs_params_p ip
)
953 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
954 tree ivvar
= create_tmp_var (type
, "graphite_IV");
955 tree iv
, iv_after_increment
;
956 loop_p loop
= create_empty_loop_on_edge
957 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
958 outer
? outer
: entry_edge
->src
->loop_father
);
962 compute_bounds_for_loop (stmt
, low
, up
);
963 save_clast_name_index (ip
->newivs_index
, stmt
->iterator
,
964 (*ip
->newivs
).length (), level
, low
, up
);
967 (*ip
->newivs
).safe_push (iv
);
971 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
972 induction variables of the loops around GBB in SESE. */
975 build_iv_mapping (vec
<tree
> iv_map
, struct clast_user_stmt
*user_stmt
,
978 struct clast_stmt
*t
;
980 CloogStatement
*cs
= user_stmt
->statement
;
981 poly_bb_p pbb
= (poly_bb_p
) cs
->usr
;
982 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
983 mpz_t bound_one
, bound_two
;
985 mpz_init (bound_one
);
986 mpz_init (bound_two
);
988 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, depth
++)
990 struct clast_expr
*expr
= (struct clast_expr
*)
991 ((struct clast_assignment
*)t
)->RHS
;
992 tree type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
993 tree new_name
= clast_to_gcc_expression (type
, expr
, ip
);
994 loop_p old_loop
= gbb_loop_at_index (gbb
, ip
->region
, depth
);
996 iv_map
[old_loop
->num
] = new_name
;
999 mpz_clear (bound_one
);
1000 mpz_clear (bound_two
);
1003 /* Construct bb_pbb_def with BB and PBB. */
1006 new_bb_pbb_def (basic_block bb
, poly_bb_p pbb
)
1008 bb_pbb_def
*bb_pbb_p
;
1010 bb_pbb_p
= XNEW (bb_pbb_def
);
1012 bb_pbb_p
->pbb
= pbb
;
1017 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1020 mark_bb_with_pbb (poly_bb_p pbb
, basic_block bb
,
1021 bb_pbb_htab_type bb_pbb_mapping
)
1027 x
= bb_pbb_mapping
.find_slot (&tmp
, INSERT
);
1030 *x
= new_bb_pbb_def (bb
, pbb
);
1033 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
1036 find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping
, basic_block bb
)
1042 slot
= bb_pbb_mapping
.find_slot (&tmp
, NO_INSERT
);
1045 return ((bb_pbb_def
*) *slot
)->pbb
;
1050 /* Return the scop of the loop and initialize PBBS the set of
1051 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1052 by the CLAST code generator between a generated basic_block and its
1053 related poly_bb_p. */
1056 get_loop_body_pbbs (loop_p loop
, bb_pbb_htab_type bb_pbb_mapping
,
1057 vec
<poly_bb_p
> *pbbs
)
1060 basic_block
*bbs
= get_loop_body_in_dom_order (loop
);
1063 for (i
= 0; i
< loop
->num_nodes
; i
++)
1065 poly_bb_p pbb
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[i
]);
1070 scop
= PBB_SCOP (pbb
);
1071 (*pbbs
).safe_push (pbb
);
1078 /* Translates a clast user statement STMT to gimple.
1080 - NEXT_E is the edge where new generated code should be attached.
1081 - CONTEXT_LOOP is the loop in which the generated code will be placed
1082 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1085 translate_clast_user (struct clast_user_stmt
*stmt
, edge next_e
,
1086 bb_pbb_htab_type bb_pbb_mapping
, ivs_params_p ip
)
1090 poly_bb_p pbb
= (poly_bb_p
) stmt
->statement
->usr
;
1091 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1094 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR
)
1097 nb_loops
= number_of_loops (cfun
);
1098 iv_map
.create (nb_loops
);
1099 for (i
= 0; i
< nb_loops
; i
++)
1100 iv_map
.quick_push (NULL_TREE
);
1102 build_iv_mapping (iv_map
, stmt
, ip
);
1103 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), ip
->region
,
1104 next_e
, iv_map
, &gloog_error
);
1107 new_bb
= next_e
->src
;
1108 mark_bb_with_pbb (pbb
, new_bb
, bb_pbb_mapping
);
1109 mark_virtual_operands_for_renaming (cfun
);
1110 update_ssa (TODO_update_ssa
);
1115 /* Creates a new if region protecting the loop to be executed, if the execution
1116 count is zero (lb > ub). */
1119 graphite_create_new_loop_guard (edge entry_edge
, struct clast_for
*stmt
,
1120 tree
*type
, tree
*lb
, tree
*ub
,
1126 *type
= type_for_clast_for (stmt
, ip
);
1127 *lb
= clast_to_gcc_expression (*type
, stmt
->LB
, ip
);
1128 *ub
= clast_to_gcc_expression (*type
, stmt
->UB
, ip
);
1130 /* When ub is simply a constant or a parameter, use lb <= ub. */
1131 if (TREE_CODE (*ub
) == INTEGER_CST
|| TREE_CODE (*ub
) == SSA_NAME
)
1132 cond_expr
= fold_build2 (LE_EXPR
, boolean_type_node
, *lb
, *ub
);
1135 tree one
= (POINTER_TYPE_P (*type
)
1136 ? convert_to_ptrofftype (integer_one_node
)
1137 : fold_convert (*type
, integer_one_node
));
1138 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1139 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1140 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1141 even if we do not want this. However lb < ub + 1 is false, as
1143 tree ub_one
= fold_build2 (POINTER_TYPE_P (*type
) ? POINTER_PLUS_EXPR
1144 : PLUS_EXPR
, *type
, *ub
, one
);
1146 cond_expr
= fold_build2 (LT_EXPR
, boolean_type_node
, *lb
, ub_one
);
1149 exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
1155 translate_clast (loop_p
, struct clast_stmt
*, edge
, bb_pbb_htab_type
,
1158 /* Create the loop for a clast for statement.
1160 - NEXT_E is the edge where new generated code should be attached.
1161 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1164 translate_clast_for_loop (loop_p context_loop
, struct clast_for
*stmt
,
1165 edge next_e
, bb_pbb_htab_type bb_pbb_mapping
,
1166 int level
, tree type
, tree lb
, tree ub
,
1169 struct loop
*loop
= graphite_create_new_loop (next_e
, stmt
, context_loop
,
1170 type
, lb
, ub
, level
, ip
);
1171 edge last_e
= single_exit (loop
);
1172 edge to_body
= single_succ_edge (loop
->header
);
1173 basic_block after
= to_body
->dest
;
1175 /* Create a basic block for loop close phi nodes. */
1176 last_e
= single_succ_edge (split_edge (last_e
));
1178 /* Translate the body of the loop. */
1179 next_e
= translate_clast (loop
, stmt
->body
, to_body
, bb_pbb_mapping
,
1181 redirect_edge_succ_nodup (next_e
, after
);
1182 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
1184 isl_set
*domain
= isl_set_from_cloog_domain (stmt
->domain
);
1185 int scheduling_dim
= isl_set_n_dim (domain
);
1187 if (flag_loop_parallelize_all
1188 && loop_is_parallel_p (loop
, bb_pbb_mapping
, scheduling_dim
))
1189 loop
->can_be_parallel
= true;
1194 /* Translates a clast for statement STMT to gimple. First a guard is created
1195 protecting the loop, if it is executed zero times. In this guard we create
1196 the real loop structure.
1198 - NEXT_E is the edge where new generated code should be attached.
1199 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1202 translate_clast_for (loop_p context_loop
, struct clast_for
*stmt
, edge next_e
,
1203 bb_pbb_htab_type bb_pbb_mapping
, int level
,
1207 edge last_e
= graphite_create_new_loop_guard (next_e
, stmt
, &type
,
1209 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1211 translate_clast_for_loop (context_loop
, stmt
, true_e
, bb_pbb_mapping
, level
,
1216 /* Translates a clast assignment STMT to gimple.
1218 - NEXT_E is the edge where new generated code should be attached.
1219 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1222 translate_clast_assignment (struct clast_assignment
*stmt
, edge next_e
,
1223 int level
, ivs_params_p ip
)
1226 mpz_t bound_one
, bound_two
;
1227 tree type
, new_name
, var
;
1228 edge res
= single_succ_edge (split_edge (next_e
));
1229 struct clast_expr
*expr
= (struct clast_expr
*) stmt
->RHS
;
1231 mpz_init (bound_one
);
1232 mpz_init (bound_two
);
1233 type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1234 var
= create_tmp_var (type
, "graphite_var");
1235 new_name
= force_gimple_operand (clast_to_gcc_expression (type
, expr
, ip
),
1239 gsi_insert_seq_on_edge (next_e
, stmts
);
1240 gsi_commit_edge_inserts ();
1243 save_clast_name_index (ip
->newivs_index
, stmt
->LHS
,
1244 (*ip
->newivs
).length (), level
,
1245 bound_one
, bound_two
);
1246 (*ip
->newivs
).safe_push (new_name
);
1248 mpz_clear (bound_one
);
1249 mpz_clear (bound_two
);
1254 /* Translates a clast guard statement STMT to gimple.
1256 - NEXT_E is the edge where new generated code should be attached.
1257 - CONTEXT_LOOP is the loop in which the generated code will be placed
1258 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1261 translate_clast_guard (loop_p context_loop
, struct clast_guard
*stmt
,
1262 edge next_e
, bb_pbb_htab_type bb_pbb_mapping
, int level
,
1265 edge last_e
= graphite_create_new_guard (next_e
, stmt
, ip
);
1266 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1268 translate_clast (context_loop
, stmt
->then
, true_e
, bb_pbb_mapping
, level
, ip
);
1272 /* Translates a CLAST statement STMT to GCC representation in the
1275 - NEXT_E is the edge where new generated code should be attached.
1276 - CONTEXT_LOOP is the loop in which the generated code will be placed
1277 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1280 translate_clast (loop_p context_loop
, struct clast_stmt
*stmt
, edge next_e
,
1281 bb_pbb_htab_type bb_pbb_mapping
, int level
, ivs_params_p ip
)
1286 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
1289 else if (CLAST_STMT_IS_A (stmt
, stmt_user
))
1290 next_e
= translate_clast_user ((struct clast_user_stmt
*) stmt
,
1291 next_e
, bb_pbb_mapping
, ip
);
1293 else if (CLAST_STMT_IS_A (stmt
, stmt_for
))
1294 next_e
= translate_clast_for (context_loop
, (struct clast_for
*) stmt
,
1295 next_e
, bb_pbb_mapping
, level
, ip
);
1297 else if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
1298 next_e
= translate_clast_guard (context_loop
, (struct clast_guard
*) stmt
,
1299 next_e
, bb_pbb_mapping
, level
, ip
);
1301 else if (CLAST_STMT_IS_A (stmt
, stmt_block
))
1302 next_e
= translate_clast (context_loop
, ((struct clast_block
*) stmt
)->body
,
1303 next_e
, bb_pbb_mapping
, level
, ip
);
1305 else if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
1306 next_e
= translate_clast_assignment ((struct clast_assignment
*) stmt
,
1311 recompute_all_dominators ();
1314 return translate_clast (context_loop
, stmt
->next
, next_e
, bb_pbb_mapping
,
1318 /* Add parameter and iterator names to the CloogUnionDomain. */
1320 static CloogUnionDomain
*
1321 add_names_to_union_domain (scop_p scop
, CloogUnionDomain
*union_domain
,
1322 int nb_scattering_dims
,
1323 clast_index_htab_type params_index
)
1325 sese region
= SCOP_REGION (scop
);
1327 int nb_iterators
= scop_max_loop_depth (scop
);
1328 int nb_parameters
= SESE_PARAMS (region
).length ();
1329 mpz_t bound_one
, bound_two
;
1331 mpz_init (bound_one
);
1332 mpz_init (bound_two
);
1334 for (i
= 0; i
< nb_parameters
; i
++)
1336 tree param
= SESE_PARAMS (region
)[i
];
1337 const char *name
= get_name (param
);
1344 len
= strlen (name
);
1346 parameter
= XNEWVEC (char, len
+ 1);
1347 snprintf (parameter
, len
, "%s_%d", name
, SSA_NAME_VERSION (param
));
1348 save_clast_name_index (params_index
, parameter
, i
, i
, bound_one
,
1350 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_PARAM
, i
,
1352 compute_bounds_for_param (scop
, i
, bound_one
, bound_two
);
1356 mpz_clear (bound_one
);
1357 mpz_clear (bound_two
);
1359 for (i
= 0; i
< nb_iterators
; i
++)
1363 iterator
= XNEWVEC (char, len
);
1364 snprintf (iterator
, len
, "git_%d", i
);
1365 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_ITER
, i
,
1370 for (i
= 0; i
< nb_scattering_dims
; i
++)
1374 scattering
= XNEWVEC (char, len
);
1375 snprintf (scattering
, len
, "scat_%d", i
);
1376 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_SCAT
, i
,
1381 return union_domain
;
1384 /* Initialize a CLooG input file. */
1387 init_cloog_input_file (int scop_number
)
1389 FILE *graphite_out_file
;
1390 int len
= strlen (dump_base_name
);
1391 char *dumpname
= XNEWVEC (char, len
+ 25);
1392 char *s_scop_number
= XNEWVEC (char, 15);
1394 memcpy (dumpname
, dump_base_name
, len
+ 1);
1395 strip_off_ending (dumpname
, len
);
1396 sprintf (s_scop_number
, ".%d", scop_number
);
1397 strcat (dumpname
, s_scop_number
);
1398 strcat (dumpname
, ".cloog");
1399 graphite_out_file
= fopen (dumpname
, "w+b");
1401 if (graphite_out_file
== 0)
1402 fatal_error ("can%'t open %s for writing: %m", dumpname
);
1406 return graphite_out_file
;
1409 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1412 isl_map
*extend_scattering(isl_map
*scattering
, int new_dims
)
1416 isl_basic_map
*change_scattering
;
1417 isl_map
*change_scattering_map
;
1419 old_dims
= isl_map_dim (scattering
, isl_dim_out
);
1421 space
= isl_space_alloc (isl_map_get_ctx (scattering
), 0, old_dims
, new_dims
);
1422 change_scattering
= isl_basic_map_universe (isl_space_copy (space
));
1424 for (i
= 0; i
< old_dims
; i
++)
1427 c
= isl_equality_alloc
1428 (isl_local_space_from_space (isl_space_copy (space
)));
1429 isl_constraint_set_coefficient_si (c
, isl_dim_in
, i
, 1);
1430 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, -1);
1431 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1434 for (i
= old_dims
; i
< new_dims
; i
++)
1437 c
= isl_equality_alloc
1438 (isl_local_space_from_space (isl_space_copy (space
)));
1439 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
1440 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1443 change_scattering_map
= isl_map_from_basic_map (change_scattering
);
1444 change_scattering_map
= isl_map_align_params (change_scattering_map
, space
);
1445 return isl_map_apply_range (scattering
, change_scattering_map
);
1448 /* Build cloog union domain for SCoP. */
1450 static CloogUnionDomain
*
1451 build_cloog_union_domain (scop_p scop
, int nb_scattering_dims
)
1455 CloogUnionDomain
*union_domain
=
1456 cloog_union_domain_alloc (scop_nb_params (scop
));
1458 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1460 CloogDomain
*domain
;
1461 CloogScattering
*scattering
;
1463 /* Dead code elimination: when the domain of a PBB is empty,
1464 don't generate code for the PBB. */
1465 if (isl_set_is_empty(pbb
->domain
))
1468 domain
= cloog_domain_from_isl_set(isl_set_copy(pbb
->domain
));
1469 scattering
= cloog_scattering_from_isl_map(extend_scattering(isl_map_copy(pbb
->transformed
),
1470 nb_scattering_dims
));
1472 union_domain
= cloog_union_domain_add_domain (union_domain
, "", domain
,
1476 return union_domain
;
1479 /* Return the options that will be used in GLOOG. */
1481 static CloogOptions
*
1482 set_cloog_options (void)
1484 CloogOptions
*options
= cloog_options_malloc (cloog_state
);
1486 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1487 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1488 we pass an incomplete program to cloog. */
1489 options
->language
= CLOOG_LANGUAGE_C
;
1491 /* Enable complex equality spreading: removes dummy statements
1492 (assignments) in the generated code which repeats the
1493 substitution equations for statements. This is useless for
1497 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1500 /* Allow cloog to build strides with a stride width different to one.
1501 This example has stride = 4:
1503 for (i = 0; i < 20; i += 4)
1505 options
->strides
= 1;
1507 /* We want the clast to provide the iteration domains of the executed loops.
1508 This allows us to derive minimal/maximal values for the induction
1510 options
->save_domains
= 1;
1512 /* Disable optimizations and make cloog generate source code closer to the
1513 input. This is useful for debugging, but later we want the optimized
1516 XXX: We can not disable optimizations, as loop blocking is not working
1521 options
->l
= INT_MAX
;
1527 /* Prints STMT to STDERR. */
1530 print_clast_stmt (FILE *file
, struct clast_stmt
*stmt
)
1532 CloogOptions
*options
= set_cloog_options ();
1534 clast_pprint (file
, stmt
, 0, options
);
1535 cloog_options_free (options
);
1538 /* Prints STMT to STDERR. */
1541 debug_clast_stmt (struct clast_stmt
*stmt
)
1543 print_clast_stmt (stderr
, stmt
);
1546 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1549 int get_max_scattering_dimensions (scop_p scop
)
1553 int scattering_dims
= 0;
1555 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1557 int pbb_scatt_dims
= isl_map_dim (pbb
->transformed
, isl_dim_out
);
1558 if (pbb_scatt_dims
> scattering_dims
)
1559 scattering_dims
= pbb_scatt_dims
;
1562 return scattering_dims
;
1566 generate_cloog_input (scop_p scop
, clast_index_htab_type params_index
)
1568 CloogUnionDomain
*union_domain
;
1569 CloogInput
*cloog_input
;
1570 CloogDomain
*context
;
1571 int nb_scattering_dims
= get_max_scattering_dimensions (scop
);
1573 union_domain
= build_cloog_union_domain (scop
, nb_scattering_dims
);
1574 union_domain
= add_names_to_union_domain (scop
, union_domain
,
1577 context
= cloog_domain_from_isl_set (isl_set_copy (scop
->context
));
1579 cloog_input
= cloog_input_alloc (context
, union_domain
);
1584 /* Translate SCOP to a CLooG program and clast. These two
1585 representations should be freed together: a clast cannot be used
1586 without a program. */
1588 static struct clast_stmt
*
1589 scop_to_clast (scop_p scop
, clast_index_htab_type params_index
)
1591 CloogInput
*cloog_input
;
1592 struct clast_stmt
*clast
;
1593 CloogOptions
*options
= set_cloog_options ();
1595 cloog_input
= generate_cloog_input (scop
, params_index
);
1597 /* Dump a .cloog input file, if requested. This feature is only
1598 enabled in the Graphite branch. */
1601 static size_t file_scop_number
= 0;
1602 FILE *cloog_file
= init_cloog_input_file (file_scop_number
);
1603 cloog_input_dump_cloog (cloog_file
, cloog_input
, options
);
1606 clast
= cloog_clast_create_from_input (cloog_input
, options
);
1608 cloog_options_free (options
);
1612 /* Prints to FILE the code generated by CLooG for SCOP. */
1615 print_generated_program (FILE *file
, scop_p scop
)
1617 CloogOptions
*options
= set_cloog_options ();
1618 clast_index_htab_type params_index
;
1619 struct clast_stmt
*clast
;
1621 params_index
.create (10);
1623 clast
= scop_to_clast (scop
, params_index
);
1625 fprintf (file
, " (clast: \n");
1626 clast_pprint (file
, clast
, 0, options
);
1627 fprintf (file
, " )\n");
1629 cloog_options_free (options
);
1630 cloog_clast_free (clast
);
1633 /* Prints to STDERR the code generated by CLooG for SCOP. */
1636 debug_generated_program (scop_p scop
)
1638 print_generated_program (stderr
, scop
);
1641 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1642 the given SCOP. Return true if code generation succeeded.
1643 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1647 gloog (scop_p scop
, bb_pbb_htab_type bb_pbb_mapping
)
1651 loop_p context_loop
;
1652 sese region
= SCOP_REGION (scop
);
1653 ifsese if_region
= NULL
;
1654 clast_index_htab_type newivs_index
, params_index
;
1655 struct clast_stmt
*clast
;
1656 struct ivs_params ip
;
1658 timevar_push (TV_GRAPHITE_CODE_GEN
);
1659 gloog_error
= false;
1661 params_index
.create (10);
1663 clast
= scop_to_clast (scop
, params_index
);
1665 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1667 fprintf (dump_file
, "\nCLAST generated by CLooG: \n");
1668 print_clast_stmt (dump_file
, clast
);
1669 fprintf (dump_file
, "\n");
1672 recompute_all_dominators ();
1675 if_region
= move_sese_in_condition (region
);
1676 sese_insert_phis_for_liveouts (region
,
1677 if_region
->region
->exit
->src
,
1678 if_region
->false_region
->exit
,
1679 if_region
->true_region
->exit
);
1680 recompute_all_dominators ();
1683 context_loop
= SESE_ENTRY (region
)->src
->loop_father
;
1684 newivs_index
.create (10);
1686 ip
.newivs
= &newivs
;
1687 ip
.newivs_index
= newivs_index
;
1688 ip
.params
= SESE_PARAMS (region
);
1689 ip
.params_index
= params_index
;
1692 translate_clast (context_loop
, clast
, if_region
->true_region
->entry
,
1693 bb_pbb_mapping
, 0, &ip
);
1696 recompute_all_dominators ();
1700 set_ifsese_condition (if_region
, integer_zero_node
);
1702 free (if_region
->true_region
);
1703 free (if_region
->region
);
1706 newivs_index
.dispose ();
1707 params_index
.dispose ();
1709 cloog_clast_free (clast
);
1710 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1712 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1716 int num_no_dependency
= 0;
1718 FOR_EACH_LOOP (li
, loop
, 0)
1719 if (loop
->can_be_parallel
)
1720 num_no_dependency
++;
1722 fprintf (dump_file
, "\n%d loops carried no dependency.\n",
1726 return !gloog_error
;