1 /* Translation of CLAST (CLooG AST) to Gimple.
2 Copyright (C) 2009-2014 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>
32 #if defined(__cplusplus)
35 #include <isl/val_gmp.h>
36 #if defined(__cplusplus)
39 #include <cloog/cloog.h>
40 #include <cloog/isl/domain.h>
44 #include "coretypes.h"
45 #include "diagnostic-core.h"
53 #include "hard-reg-set.h"
56 #include "dominance.h"
58 #include "basic-block.h"
59 #include "tree-ssa-alias.h"
60 #include "internal-fn.h"
61 #include "gimple-expr.h"
64 #include "gimple-iterator.h"
65 #include "gimplify-me.h"
66 #include "gimple-ssa.h"
67 #include "tree-ssa-loop-manip.h"
68 #include "tree-ssa-loop.h"
69 #include "tree-into-ssa.h"
70 #include "tree-pass.h"
72 #include "tree-chrec.h"
73 #include "tree-data-ref.h"
74 #include "tree-scalar-evolution.h"
78 #include "cloog/cloog.h"
79 #include "graphite-poly.h"
80 #include "graphite-clast-to-gimple.h"
81 #include "graphite-htab.h"
83 typedef const struct clast_expr
*clast_name_p
;
85 #ifndef CLOOG_LANGUAGE_C
86 #define CLOOG_LANGUAGE_C LANGUAGE_C
90 /* Converts a GMP constant VAL to a tree and returns it. */
93 gmp_cst_to_tree (tree type
, mpz_t val
)
95 tree t
= type
? type
: integer_type_node
;
100 wide_int wi
= wi::from_mpz (t
, tmp
, true);
103 return wide_int_to_tree (t
, wi
);
106 /* Sets RES to the min of V1 and V2. */
109 value_min (mpz_t res
, mpz_t v1
, mpz_t v2
)
111 if (mpz_cmp (v1
, v2
) < 0)
117 /* Sets RES to the max of V1 and V2. */
120 value_max (mpz_t res
, mpz_t v1
, mpz_t v2
)
122 if (mpz_cmp (v1
, v2
) < 0)
129 /* This flag is set when an error occurred during the translation of
131 static bool graphite_regenerate_error
;
133 /* Verifies properties that GRAPHITE should maintain during translation. */
136 graphite_verify (void)
138 #ifdef ENABLE_CHECKING
139 verify_loop_structure ();
140 verify_loop_closed_ssa (true);
144 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
145 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
146 upper bounds that can be inferred from the polyhedral representation. */
148 typedef struct clast_name_index
{
151 mpz_t bound_one
, bound_two
;
153 /* If free_name is set, the content of name was allocated by us and needs
156 } *clast_name_index_p
;
158 /* Helper for hashing clast_name_index. */
160 struct clast_index_hasher
162 typedef clast_name_index value_type
;
163 typedef clast_name_index compare_type
;
164 static inline hashval_t
hash (const value_type
*);
165 static inline bool equal (const value_type
*, const compare_type
*);
166 static inline void remove (value_type
*);
169 /* Computes a hash function for database element E. */
172 clast_index_hasher::hash (const value_type
*e
)
176 int length
= strlen (e
->name
);
179 for (i
= 0; i
< length
; ++i
)
180 hash
= hash
| (e
->name
[i
] << (i
% 4));
185 /* Compares database elements ELT1 and ELT2. */
188 clast_index_hasher::equal (const value_type
*elt1
, const compare_type
*elt2
)
190 return strcmp (elt1
->name
, elt2
->name
) == 0;
193 /* Free the memory taken by a clast_name_index struct. */
196 clast_index_hasher::remove (value_type
*c
)
200 mpz_clear (c
->bound_one
);
201 mpz_clear (c
->bound_two
);
205 typedef hash_table
<clast_index_hasher
> clast_index_htab_type
;
207 /* Returns a pointer to a new element of type clast_name_index_p built
208 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
210 static inline clast_name_index_p
211 new_clast_name_index (const char *name
, int index
, int level
,
212 mpz_t bound_one
, mpz_t bound_two
)
214 clast_name_index_p res
= XNEW (struct clast_name_index
);
215 char *new_name
= XNEWVEC (char, strlen (name
) + 1);
216 strcpy (new_name
, name
);
218 res
->name
= new_name
;
219 res
->free_name
= new_name
;
222 mpz_init (res
->bound_one
);
223 mpz_init (res
->bound_two
);
224 mpz_set (res
->bound_one
, bound_one
);
225 mpz_set (res
->bound_two
, bound_two
);
229 /* For a given clast NAME, returns -1 if NAME is not in the
230 INDEX_TABLE, otherwise returns the loop level for the induction
231 variable NAME, or if it is a parameter, the parameter number in the
232 vector of parameters. */
235 clast_name_to_level (clast_name_p name
, clast_index_htab_type
*index_table
)
237 struct clast_name_index tmp
;
238 clast_name_index
**slot
;
240 gcc_assert (name
->type
== clast_expr_name
);
241 tmp
.name
= ((const struct clast_name
*) name
)->name
;
242 tmp
.free_name
= NULL
;
244 slot
= index_table
->find_slot (&tmp
, NO_INSERT
);
247 return ((struct clast_name_index
*) *slot
)->level
;
252 /* For a given clast NAME, returns -1 if it does not correspond to any
253 parameter, or otherwise, returns the index in the PARAMS or
254 SCATTERING_DIMENSIONS vector. */
257 clast_name_to_index (struct clast_name
*name
, clast_index_htab_type
*index_table
)
259 struct clast_name_index tmp
;
260 clast_name_index
**slot
;
262 tmp
.name
= ((const struct clast_name
*) name
)->name
;
263 tmp
.free_name
= NULL
;
265 slot
= index_table
->find_slot (&tmp
, NO_INSERT
);
268 return (*slot
)->index
;
273 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
274 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
275 found in the INDEX_TABLE, false otherwise. */
278 clast_name_to_lb_ub (struct clast_name
*name
,
279 clast_index_htab_type
*index_table
, mpz_t bound_one
,
282 struct clast_name_index tmp
;
283 clast_name_index
**slot
;
285 tmp
.name
= name
->name
;
286 tmp
.free_name
= NULL
;
288 slot
= index_table
->find_slot (&tmp
, NO_INSERT
);
292 mpz_set (bound_one
, ((struct clast_name_index
*) *slot
)->bound_one
);
293 mpz_set (bound_two
, ((struct clast_name_index
*) *slot
)->bound_two
);
300 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
303 save_clast_name_index (clast_index_htab_type
*index_table
, const char *name
,
304 int index
, int level
, mpz_t bound_one
, mpz_t bound_two
)
306 struct clast_name_index tmp
;
307 clast_name_index
**slot
;
310 tmp
.free_name
= NULL
;
311 slot
= index_table
->find_slot (&tmp
, INSERT
);
317 *slot
= new_clast_name_index (name
, index
, level
, bound_one
, bound_two
);
322 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
323 induction variable in NEWIVS.
325 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
326 parameter in PARAMS. */
328 typedef struct ivs_params
{
329 vec
<tree
> params
, *newivs
;
330 clast_index_htab_type
*newivs_index
, *params_index
;
334 /* Returns the tree variable from the name NAME that was given in
335 Cloog representation. */
338 clast_name_to_gcc (struct clast_name
*name
, ivs_params_p ip
)
342 if (ip
->params
.exists () && ip
->params_index
)
344 index
= clast_name_to_index (name
, ip
->params_index
);
347 return ip
->params
[index
];
350 gcc_assert (ip
->newivs
&& ip
->newivs_index
);
351 index
= clast_name_to_index (name
, ip
->newivs_index
);
352 gcc_assert (index
>= 0);
354 return (*ip
->newivs
)[index
];
357 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
360 max_precision_type (tree type1
, tree type2
)
363 int p1
, p2
, precision
;
366 if (POINTER_TYPE_P (type1
))
369 if (POINTER_TYPE_P (type2
))
372 if (TYPE_UNSIGNED (type1
)
373 && TYPE_UNSIGNED (type2
))
374 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
376 p1
= TYPE_PRECISION (type1
);
377 p2
= TYPE_PRECISION (type2
);
380 precision
= TYPE_UNSIGNED (type1
) ? p1
* 2 : p1
;
382 precision
= TYPE_UNSIGNED (type2
) ? p2
* 2 : p2
;
384 if (precision
> BITS_PER_WORD
)
386 graphite_regenerate_error
= true;
387 return integer_type_node
;
390 mode
= smallest_mode_for_size (precision
, MODE_INT
);
391 precision
= GET_MODE_PRECISION (mode
);
392 type
= build_nonstandard_integer_type (precision
, false);
396 graphite_regenerate_error
= true;
397 return integer_type_node
;
404 clast_to_gcc_expression (tree
, struct clast_expr
*, ivs_params_p
);
406 /* Converts a Cloog reduction expression R with reduction operation OP
407 to a GCC expression tree of type TYPE. */
410 clast_to_gcc_expression_red (tree type
, enum tree_code op
,
411 struct clast_reduction
*r
, ivs_params_p ip
)
414 tree res
= clast_to_gcc_expression (type
, r
->elts
[0], ip
);
415 tree operand_type
= (op
== POINTER_PLUS_EXPR
) ? sizetype
: type
;
417 for (i
= 1; i
< r
->n
; i
++)
419 tree t
= clast_to_gcc_expression (operand_type
, r
->elts
[i
], ip
);
420 res
= fold_build2 (op
, type
, res
, t
);
426 /* Converts a Cloog AST expression E back to a GCC expression tree of
430 clast_to_gcc_expression (tree type
, struct clast_expr
*e
, ivs_params_p ip
)
434 case clast_expr_name
:
436 return clast_name_to_gcc ((struct clast_name
*) e
, ip
);
438 case clast_expr_term
:
440 struct clast_term
*t
= (struct clast_term
*) e
;
444 if (mpz_cmp_si (t
->val
, 1) == 0)
446 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
448 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
449 name
= convert_to_ptrofftype (name
);
451 name
= fold_convert (type
, name
);
455 else if (mpz_cmp_si (t
->val
, -1) == 0)
457 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
459 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
460 name
= convert_to_ptrofftype (name
);
462 name
= fold_convert (type
, name
);
464 return fold_build1 (NEGATE_EXPR
, type
, name
);
468 tree name
= clast_to_gcc_expression (type
, t
->var
, ip
);
469 tree cst
= gmp_cst_to_tree (type
, t
->val
);
471 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
472 name
= convert_to_ptrofftype (name
);
474 name
= fold_convert (type
, name
);
476 if (!POINTER_TYPE_P (type
))
477 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
479 graphite_regenerate_error
= true;
484 return gmp_cst_to_tree (type
, t
->val
);
489 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
494 return clast_to_gcc_expression_red
495 (type
, POINTER_TYPE_P (type
) ? POINTER_PLUS_EXPR
: PLUS_EXPR
,
499 return clast_to_gcc_expression_red (type
, MIN_EXPR
, r
, ip
);
502 return clast_to_gcc_expression_red (type
, MAX_EXPR
, r
, ip
);
512 struct clast_binary
*b
= (struct clast_binary
*) e
;
513 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
514 tree tl
= clast_to_gcc_expression (type
, lhs
, ip
);
515 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
520 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
523 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
526 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
529 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
543 /* Return a type that could represent the values between BOUND_ONE and
547 type_for_interval (mpz_t bound_one
, mpz_t bound_two
)
553 int precision
= MAX (mpz_sizeinbase (bound_one
, 2),
554 mpz_sizeinbase (bound_two
, 2));
556 if (precision
> BITS_PER_WORD
)
558 graphite_regenerate_error
= true;
559 return integer_type_node
;
562 if (mpz_cmp (bound_one
, bound_two
) <= 0)
563 unsigned_p
= (mpz_sgn (bound_one
) >= 0);
565 unsigned_p
= (mpz_sgn (bound_two
) >= 0);
567 mode
= smallest_mode_for_size (precision
, MODE_INT
);
568 wider_precision
= GET_MODE_PRECISION (mode
);
570 /* As we want to generate signed types as much as possible, try to
571 fit the interval [bound_one, bound_two] in a signed type. For example,
572 supposing that we have the interval [0, 100], instead of
573 generating unsigned char, we want to generate a signed char. */
574 if (unsigned_p
&& precision
< wider_precision
)
577 type
= build_nonstandard_integer_type (wider_precision
, unsigned_p
);
581 graphite_regenerate_error
= true;
582 return integer_type_node
;
588 /* Return a type that could represent the integer value VAL, or
589 otherwise return NULL_TREE. */
592 type_for_value (mpz_t val
)
594 return type_for_interval (val
, val
);
598 type_for_clast_expr (struct clast_expr
*, ivs_params_p
, mpz_t
, mpz_t
);
600 /* Return the type for the clast_term T. Initializes BOUND_ONE and
601 BOUND_TWO to the bounds of the term. */
604 type_for_clast_term (struct clast_term
*t
, ivs_params_p ip
, mpz_t bound_one
,
608 gcc_assert (t
->expr
.type
== clast_expr_term
);
612 mpz_set (bound_one
, t
->val
);
613 mpz_set (bound_two
, t
->val
);
614 return type_for_value (t
->val
);
617 type
= type_for_clast_expr (t
->var
, ip
, bound_one
, bound_two
);
619 mpz_mul (bound_one
, bound_one
, t
->val
);
620 mpz_mul (bound_two
, bound_two
, t
->val
);
622 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
625 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
626 and BOUND_TWO to the bounds of the reduction expression. */
629 type_for_clast_red (struct clast_reduction
*r
, ivs_params_p ip
,
630 mpz_t bound_one
, mpz_t bound_two
)
633 tree type
= type_for_clast_expr (r
->elts
[0], ip
, bound_one
, bound_two
);
634 mpz_t b1
, b2
, m1
, m2
;
644 for (i
= 1; i
< r
->n
; i
++)
646 tree t
= type_for_clast_expr (r
->elts
[i
], ip
, b1
, b2
);
647 type
= max_precision_type (type
, t
);
652 value_min (m1
, bound_one
, bound_two
);
653 value_min (m2
, b1
, b2
);
654 mpz_add (bound_one
, m1
, m2
);
656 value_max (m1
, bound_one
, bound_two
);
657 value_max (m2
, b1
, b2
);
658 mpz_add (bound_two
, m1
, m2
);
662 value_min (bound_one
, bound_one
, bound_two
);
663 value_min (bound_two
, b1
, b2
);
667 value_max (bound_one
, bound_one
, bound_two
);
668 value_max (bound_two
, b1
, b2
);
682 /* Return a type that can represent the result of the reduction. */
683 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
686 /* Return the type for the clast_binary B used in STMT. */
689 type_for_clast_bin (struct clast_binary
*b
, ivs_params_p ip
, mpz_t bound_one
,
693 tree l
= type_for_clast_expr ((struct clast_expr
*) b
->LHS
, ip
,
694 bound_one
, bound_two
);
695 tree r
= type_for_value (b
->RHS
);
696 tree type
= max_precision_type (l
, r
);
701 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
702 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
706 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
707 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
709 mpz_add (bound_one
, bound_one
, one
);
710 mpz_add (bound_two
, bound_two
, one
);
715 mpz_div (bound_one
, bound_one
, b
->RHS
);
716 mpz_div (bound_two
, bound_two
, b
->RHS
);
720 mpz_mod (bound_one
, bound_one
, b
->RHS
);
721 mpz_mod (bound_two
, bound_two
, b
->RHS
);
728 /* Return a type that can represent the result of the reduction. */
729 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
732 /* Return the type for the clast_name NAME. Initializes BOUND_ONE and
733 BOUND_TWO to the bounds of the term. */
736 type_for_clast_name (struct clast_name
*name
, ivs_params_p ip
, mpz_t bound_one
,
741 if (ip
->params
.exists () && ip
->params_index
)
742 found
= clast_name_to_lb_ub (name
, ip
->params_index
, bound_one
, bound_two
);
746 gcc_assert (ip
->newivs
&& ip
->newivs_index
);
747 found
= clast_name_to_lb_ub (name
, ip
->newivs_index
, bound_one
,
752 return TREE_TYPE (clast_name_to_gcc (name
, ip
));
755 /* Returns the type for the CLAST expression E when used in statement
759 type_for_clast_expr (struct clast_expr
*e
, ivs_params_p ip
, mpz_t bound_one
,
764 case clast_expr_term
:
765 return type_for_clast_term ((struct clast_term
*) e
, ip
,
766 bound_one
, bound_two
);
769 return type_for_clast_red ((struct clast_reduction
*) e
, ip
,
770 bound_one
, bound_two
);
773 return type_for_clast_bin ((struct clast_binary
*) e
, ip
,
774 bound_one
, bound_two
);
776 case clast_expr_name
:
777 return type_for_clast_name ((struct clast_name
*) e
, ip
,
778 bound_one
, bound_two
);
787 /* Returns true if the clast expression E is a constant with VALUE. */
790 clast_expr_const_value_p (struct clast_expr
*e
, int value
)
792 struct clast_term
*t
;
793 if (e
->type
!= clast_expr_term
)
795 t
= (struct clast_term
*)e
;
798 return 0 == mpz_cmp_si (t
->val
, value
);
801 /* Translates a clast equation CLEQ to a tree. */
804 graphite_translate_clast_equation (struct clast_equation
*cleq
,
808 tree type
, lhs
, rhs
, ltype
, rtype
;
809 mpz_t bound_one
, bound_two
;
810 struct clast_expr
*clhs
, *crhs
;
816 else if (cleq
->sign
> 0)
821 /* Special cases to reduce range of arguments to hopefully
822 don't need types with larger precision than the input. */
823 if (crhs
->type
== clast_expr_red
826 struct clast_reduction
*r
= (struct clast_reduction
*) crhs
;
827 /* X >= A+1 --> X > A and
828 X <= A-1 --> X < A */
830 && r
->type
== clast_red_sum
831 && clast_expr_const_value_p (r
->elts
[1], comp
== GE_EXPR
? 1 : -1))
834 comp
= comp
== GE_EXPR
? GT_EXPR
: LT_EXPR
;
838 mpz_init (bound_one
);
839 mpz_init (bound_two
);
841 ltype
= type_for_clast_expr (clhs
, ip
, bound_one
, bound_two
);
842 rtype
= type_for_clast_expr (crhs
, ip
, bound_one
, bound_two
);
844 mpz_clear (bound_one
);
845 mpz_clear (bound_two
);
846 type
= max_precision_type (ltype
, rtype
);
848 lhs
= clast_to_gcc_expression (type
, clhs
, ip
);
849 rhs
= clast_to_gcc_expression (type
, crhs
, ip
);
851 return fold_build2 (comp
, boolean_type_node
, lhs
, rhs
);
854 /* Creates the test for the condition in STMT. */
857 graphite_create_guard_cond_expr (struct clast_guard
*stmt
,
863 for (i
= 0; i
< stmt
->n
; i
++)
865 tree eq
= graphite_translate_clast_equation (&stmt
->eq
[i
], ip
);
868 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
876 /* Creates a new if region corresponding to Cloog's guard. */
879 graphite_create_new_guard (edge entry_edge
, struct clast_guard
*stmt
,
882 tree cond_expr
= graphite_create_guard_cond_expr (stmt
, ip
);
883 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
887 /* Compute the lower bound LOW and upper bound UP for the parameter
888 PARAM in scop SCOP based on the constraints in the context. */
891 compute_bounds_for_param (scop_p scop
, int param
, mpz_t low
, mpz_t up
)
894 isl_aff
*aff
= isl_aff_zero_on_domain
895 (isl_local_space_from_space (isl_set_get_space (scop
->context
)));
897 aff
= isl_aff_add_coefficient_si (aff
, isl_dim_param
, param
, 1);
899 v
= isl_set_min_val (scop
->context
, aff
);
900 isl_val_get_num_gmp (v
, low
);
902 v
= isl_set_max_val (scop
->context
, aff
);
903 isl_val_get_num_gmp (v
, up
);
908 /* Compute the lower bound LOW and upper bound UP for the induction
909 variable of loop LOOP.
911 FIXME: This one is not entirely correct, as min/max expressions in the
912 calculation can yield to incorrect results. To be completely
913 correct, we need to evaluate each subexpression generated by
914 CLooG. CLooG does not yet support this, so this is as good as
918 compute_bounds_for_loop (struct clast_for
*loop
, mpz_t low
, mpz_t up
)
922 isl_local_space
*local_space
;
925 domain
= isl_set_copy (isl_set_from_cloog_domain (loop
->domain
));
926 local_space
= isl_local_space_from_space (isl_set_get_space (domain
));
927 dimension
= isl_aff_zero_on_domain (local_space
);
928 dimension
= isl_aff_add_coefficient_si (dimension
, isl_dim_in
,
929 isl_set_dim (domain
, isl_dim_set
) - 1,
932 isl_value
= isl_set_min_val (domain
, dimension
);
933 isl_val_get_num_gmp (isl_value
, low
);
934 isl_val_free (isl_value
);
935 isl_value
= isl_set_max_val (domain
, dimension
);
936 isl_val_get_num_gmp (isl_value
, up
);
937 isl_val_free (isl_value
);
938 isl_set_free (domain
);
939 isl_aff_free (dimension
);
942 /* Returns the type for the induction variable for the loop translated
946 type_for_clast_for (struct clast_for
*stmt_for
, ivs_params_p ip
)
948 mpz_t bound_one
, bound_two
;
949 tree lb_type
, ub_type
;
951 mpz_init (bound_one
);
952 mpz_init (bound_two
);
954 lb_type
= type_for_clast_expr (stmt_for
->LB
, ip
, bound_one
, bound_two
);
955 ub_type
= type_for_clast_expr (stmt_for
->UB
, ip
, bound_one
, bound_two
);
957 mpz_clear (bound_one
);
958 mpz_clear (bound_two
);
960 return max_precision_type (lb_type
, ub_type
);
963 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
964 induction variable for the new LOOP. New LOOP is attached to CFG
965 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
966 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
967 CLooG's scattering name to the induction variable created for the
968 loop of STMT. The new induction variable is inserted in the NEWIVS
969 vector and is of type TYPE. */
972 graphite_create_new_loop (edge entry_edge
, struct clast_for
*stmt
,
973 loop_p outer
, tree type
, tree lb
, tree ub
,
974 int level
, ivs_params_p ip
)
978 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
979 tree ivvar
= create_tmp_var (type
, "graphite_IV");
980 tree iv
, iv_after_increment
;
981 loop_p loop
= create_empty_loop_on_edge
982 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
983 outer
? outer
: entry_edge
->src
->loop_father
);
987 compute_bounds_for_loop (stmt
, low
, up
);
988 save_clast_name_index (ip
->newivs_index
, stmt
->iterator
,
989 (*ip
->newivs
).length (), level
, low
, up
);
992 (*ip
->newivs
).safe_push (iv
);
996 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
997 induction variables of the loops around GBB in SESE. */
1000 build_iv_mapping (vec
<tree
> iv_map
, struct clast_user_stmt
*user_stmt
,
1003 struct clast_stmt
*t
;
1005 CloogStatement
*cs
= user_stmt
->statement
;
1006 poly_bb_p pbb
= (poly_bb_p
) cs
->usr
;
1007 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1008 mpz_t bound_one
, bound_two
;
1010 mpz_init (bound_one
);
1011 mpz_init (bound_two
);
1013 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, depth
++)
1015 struct clast_expr
*expr
= (struct clast_expr
*)
1016 ((struct clast_assignment
*)t
)->RHS
;
1017 tree type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1018 tree new_name
= clast_to_gcc_expression (type
, expr
, ip
);
1019 loop_p old_loop
= gbb_loop_at_index (gbb
, ip
->region
, depth
);
1021 iv_map
[old_loop
->num
] = new_name
;
1024 mpz_clear (bound_one
);
1025 mpz_clear (bound_two
);
1028 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
1031 mark_bb_with_pbb (poly_bb_p pbb
, basic_block bb
,
1032 bb_pbb_htab_type
*bb_pbb_mapping
)
1035 poly_bb_p
&e
= bb_pbb_mapping
->get_or_insert (bb
, &existed
);
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
)
1045 poly_bb_p
*pbb
= bb_pbb_mapping
->get (bb
);
1052 /* Return the scop of the loop and initialize PBBS the set of
1053 poly_bb_p that belong to the LOOP. BB_PBB_MAPPING is a map created
1054 by the CLAST code generator between a generated basic_block and its
1055 related poly_bb_p. */
1058 get_loop_body_pbbs (loop_p loop
, bb_pbb_htab_type
*bb_pbb_mapping
,
1059 vec
<poly_bb_p
> *pbbs
)
1062 basic_block
*bbs
= get_loop_body_in_dom_order (loop
);
1065 for (i
= 0; i
< loop
->num_nodes
; i
++)
1067 poly_bb_p pbb
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[i
]);
1072 scop
= PBB_SCOP (pbb
);
1073 (*pbbs
).safe_push (pbb
);
1080 /* Translates a clast user statement STMT to gimple.
1082 - NEXT_E is the edge where new generated code should be attached.
1083 - CONTEXT_LOOP is the loop in which the generated code will be placed
1084 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1087 translate_clast_user (struct clast_user_stmt
*stmt
, edge next_e
,
1088 bb_pbb_htab_type
*bb_pbb_mapping
, ivs_params_p ip
)
1092 poly_bb_p pbb
= (poly_bb_p
) stmt
->statement
->usr
;
1093 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1096 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR_FOR_FN (cfun
))
1099 nb_loops
= number_of_loops (cfun
);
1100 iv_map
.create (nb_loops
);
1101 for (i
= 0; i
< nb_loops
; i
++)
1102 iv_map
.quick_push (NULL_TREE
);
1104 build_iv_mapping (iv_map
, stmt
, ip
);
1105 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), ip
->region
,
1107 &graphite_regenerate_error
);
1110 new_bb
= next_e
->src
;
1111 mark_bb_with_pbb (pbb
, new_bb
, bb_pbb_mapping
);
1112 mark_virtual_operands_for_renaming (cfun
);
1113 update_ssa (TODO_update_ssa
);
1118 /* Creates a new if region protecting the loop to be executed, if the execution
1119 count is zero (lb > ub). */
1122 graphite_create_new_loop_guard (edge entry_edge
, struct clast_for
*stmt
,
1123 tree
*type
, tree
*lb
, tree
*ub
,
1129 *type
= type_for_clast_for (stmt
, ip
);
1130 *lb
= clast_to_gcc_expression (*type
, stmt
->LB
, ip
);
1131 *ub
= clast_to_gcc_expression (*type
, stmt
->UB
, ip
);
1133 /* When ub is simply a constant or a parameter, use lb <= ub. */
1134 if (TREE_CODE (*ub
) == INTEGER_CST
|| TREE_CODE (*ub
) == SSA_NAME
)
1135 cond_expr
= fold_build2 (LE_EXPR
, boolean_type_node
, *lb
, *ub
);
1138 tree one
= (POINTER_TYPE_P (*type
)
1139 ? convert_to_ptrofftype (integer_one_node
)
1140 : fold_convert (*type
, integer_one_node
));
1141 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1142 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1143 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1144 even if we do not want this. However lb < ub + 1 is false, as
1146 tree ub_one
= fold_build2 (POINTER_TYPE_P (*type
) ? POINTER_PLUS_EXPR
1147 : PLUS_EXPR
, *type
, *ub
, one
);
1149 cond_expr
= fold_build2 (LT_EXPR
, boolean_type_node
, *lb
, ub_one
);
1152 exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
1158 translate_clast (loop_p
, struct clast_stmt
*, edge
, bb_pbb_htab_type
*,
1161 /* Create the loop for a clast for statement.
1163 - NEXT_E is the edge where new generated code should be attached.
1164 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1167 translate_clast_for_loop (loop_p context_loop
, struct clast_for
*stmt
,
1168 edge next_e
, bb_pbb_htab_type
*bb_pbb_mapping
,
1169 int level
, tree type
, tree lb
, tree ub
,
1172 struct loop
*loop
= graphite_create_new_loop (next_e
, stmt
, context_loop
,
1173 type
, lb
, ub
, level
, ip
);
1174 edge last_e
= single_exit (loop
);
1175 edge to_body
= single_succ_edge (loop
->header
);
1176 basic_block after
= to_body
->dest
;
1178 /* Create a basic block for loop close phi nodes. */
1179 last_e
= single_succ_edge (split_edge (last_e
));
1181 /* Translate the body of the loop. */
1182 next_e
= translate_clast (loop
, stmt
->body
, to_body
, bb_pbb_mapping
,
1184 redirect_edge_succ_nodup (next_e
, after
);
1185 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
1187 isl_set
*domain
= isl_set_from_cloog_domain (stmt
->domain
);
1188 int scheduling_dim
= isl_set_n_dim (domain
);
1190 if (flag_loop_parallelize_all
1191 && loop_is_parallel_p (loop
, bb_pbb_mapping
, scheduling_dim
))
1192 loop
->can_be_parallel
= true;
1197 /* Translates a clast for statement STMT to gimple. First a guard is created
1198 protecting the loop, if it is executed zero times. In this guard we create
1199 the real loop structure.
1201 - NEXT_E is the edge where new generated code should be attached.
1202 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1205 translate_clast_for (loop_p context_loop
, struct clast_for
*stmt
, edge next_e
,
1206 bb_pbb_htab_type
*bb_pbb_mapping
, int level
,
1210 edge last_e
= graphite_create_new_loop_guard (next_e
, stmt
, &type
,
1212 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1214 translate_clast_for_loop (context_loop
, stmt
, true_e
, bb_pbb_mapping
, level
,
1219 /* Translates a clast assignment STMT to gimple.
1221 - NEXT_E is the edge where new generated code should be attached.
1222 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1225 translate_clast_assignment (struct clast_assignment
*stmt
, edge next_e
,
1226 int level
, ivs_params_p ip
)
1229 mpz_t bound_one
, bound_two
;
1230 tree type
, new_name
, var
;
1231 edge res
= single_succ_edge (split_edge (next_e
));
1232 struct clast_expr
*expr
= (struct clast_expr
*) stmt
->RHS
;
1234 mpz_init (bound_one
);
1235 mpz_init (bound_two
);
1236 type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1237 var
= create_tmp_var (type
, "graphite_var");
1238 new_name
= force_gimple_operand (clast_to_gcc_expression (type
, expr
, ip
),
1242 gsi_insert_seq_on_edge (next_e
, stmts
);
1243 gsi_commit_edge_inserts ();
1246 save_clast_name_index (ip
->newivs_index
, stmt
->LHS
,
1247 (*ip
->newivs
).length (), level
,
1248 bound_one
, bound_two
);
1249 (*ip
->newivs
).safe_push (new_name
);
1251 mpz_clear (bound_one
);
1252 mpz_clear (bound_two
);
1257 /* Translates a clast guard statement STMT to gimple.
1259 - NEXT_E is the edge where new generated code should be attached.
1260 - CONTEXT_LOOP is the loop in which the generated code will be placed
1261 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1264 translate_clast_guard (loop_p context_loop
, struct clast_guard
*stmt
,
1265 edge next_e
, bb_pbb_htab_type
*bb_pbb_mapping
, int level
,
1268 edge last_e
= graphite_create_new_guard (next_e
, stmt
, ip
);
1269 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1271 translate_clast (context_loop
, stmt
->then
, true_e
, bb_pbb_mapping
, level
, ip
);
1275 /* Translates a CLAST statement STMT to GCC representation in the
1278 - NEXT_E is the edge where new generated code should be attached.
1279 - CONTEXT_LOOP is the loop in which the generated code will be placed
1280 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1283 translate_clast (loop_p context_loop
, struct clast_stmt
*stmt
, edge next_e
,
1284 bb_pbb_htab_type
*bb_pbb_mapping
, int level
, ivs_params_p ip
)
1289 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
1292 else if (CLAST_STMT_IS_A (stmt
, stmt_user
))
1293 next_e
= translate_clast_user ((struct clast_user_stmt
*) stmt
,
1294 next_e
, bb_pbb_mapping
, ip
);
1296 else if (CLAST_STMT_IS_A (stmt
, stmt_for
))
1297 next_e
= translate_clast_for (context_loop
, (struct clast_for
*) stmt
,
1298 next_e
, bb_pbb_mapping
, level
, ip
);
1300 else if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
1301 next_e
= translate_clast_guard (context_loop
, (struct clast_guard
*) stmt
,
1302 next_e
, bb_pbb_mapping
, level
, ip
);
1304 else if (CLAST_STMT_IS_A (stmt
, stmt_block
))
1305 next_e
= translate_clast (context_loop
, ((struct clast_block
*) stmt
)->body
,
1306 next_e
, bb_pbb_mapping
, level
, ip
);
1308 else if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
1309 next_e
= translate_clast_assignment ((struct clast_assignment
*) stmt
,
1314 recompute_all_dominators ();
1317 return translate_clast (context_loop
, stmt
->next
, next_e
, bb_pbb_mapping
,
1321 /* Add parameter and iterator names to the CloogUnionDomain. */
1323 static CloogUnionDomain
*
1324 add_names_to_union_domain (scop_p scop
, CloogUnionDomain
*union_domain
,
1325 int nb_scattering_dims
,
1326 clast_index_htab_type
*params_index
)
1328 sese region
= SCOP_REGION (scop
);
1330 int nb_iterators
= scop_max_loop_depth (scop
);
1331 int nb_parameters
= SESE_PARAMS (region
).length ();
1332 mpz_t bound_one
, bound_two
;
1334 mpz_init (bound_one
);
1335 mpz_init (bound_two
);
1337 for (i
= 0; i
< nb_parameters
; i
++)
1339 tree param
= SESE_PARAMS (region
)[i
];
1340 const char *name
= get_name (param
);
1347 len
= strlen (name
);
1349 parameter
= XNEWVEC (char, len
+ 1);
1350 snprintf (parameter
, len
, "%s_%d", name
, SSA_NAME_VERSION (param
));
1351 save_clast_name_index (params_index
, parameter
, i
, i
, bound_one
,
1353 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_PARAM
, i
,
1355 compute_bounds_for_param (scop
, i
, bound_one
, bound_two
);
1359 mpz_clear (bound_one
);
1360 mpz_clear (bound_two
);
1362 for (i
= 0; i
< nb_iterators
; i
++)
1366 iterator
= XNEWVEC (char, len
);
1367 snprintf (iterator
, len
, "git_%d", i
);
1368 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_ITER
, i
,
1373 for (i
= 0; i
< nb_scattering_dims
; i
++)
1377 scattering
= XNEWVEC (char, len
);
1378 snprintf (scattering
, len
, "scat_%d", i
);
1379 union_domain
= cloog_union_domain_set_name (union_domain
, CLOOG_SCAT
, i
,
1384 return union_domain
;
1387 /* Initialize a CLooG input file. */
1390 init_cloog_input_file (int scop_number
)
1392 FILE *graphite_out_file
;
1393 int len
= strlen (dump_base_name
);
1394 char *dumpname
= XNEWVEC (char, len
+ 25);
1395 char *s_scop_number
= XNEWVEC (char, 15);
1397 memcpy (dumpname
, dump_base_name
, len
+ 1);
1398 strip_off_ending (dumpname
, len
);
1399 sprintf (s_scop_number
, ".%d", scop_number
);
1400 strcat (dumpname
, s_scop_number
);
1401 strcat (dumpname
, ".cloog");
1402 graphite_out_file
= fopen (dumpname
, "w+b");
1404 if (graphite_out_file
== 0)
1405 fatal_error ("can%'t open %s for writing: %m", dumpname
);
1409 return graphite_out_file
;
1412 /* Extend the scattering to NEW_DIMS scattering dimensions. */
1415 isl_map
*extend_scattering (isl_map
*scattering
, int new_dims
)
1419 isl_basic_map
*change_scattering
;
1420 isl_map
*change_scattering_map
;
1422 old_dims
= isl_map_dim (scattering
, isl_dim_out
);
1424 space
= isl_space_alloc (isl_map_get_ctx (scattering
), 0, old_dims
, new_dims
);
1425 change_scattering
= isl_basic_map_universe (isl_space_copy (space
));
1427 for (i
= 0; i
< old_dims
; i
++)
1430 c
= isl_equality_alloc
1431 (isl_local_space_from_space (isl_space_copy (space
)));
1432 isl_constraint_set_coefficient_si (c
, isl_dim_in
, i
, 1);
1433 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, -1);
1434 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1437 for (i
= old_dims
; i
< new_dims
; i
++)
1440 c
= isl_equality_alloc
1441 (isl_local_space_from_space (isl_space_copy (space
)));
1442 isl_constraint_set_coefficient_si (c
, isl_dim_out
, i
, 1);
1443 change_scattering
= isl_basic_map_add_constraint (change_scattering
, c
);
1446 change_scattering_map
= isl_map_from_basic_map (change_scattering
);
1447 change_scattering_map
= isl_map_align_params (change_scattering_map
, space
);
1448 return isl_map_apply_range (scattering
, change_scattering_map
);
1451 /* Build cloog union domain for SCoP. */
1453 static CloogUnionDomain
*
1454 build_cloog_union_domain (scop_p scop
, int nb_scattering_dims
)
1458 CloogUnionDomain
*union_domain
=
1459 cloog_union_domain_alloc (scop_nb_params (scop
));
1461 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1463 CloogDomain
*domain
;
1464 CloogScattering
*scattering
;
1466 /* Dead code elimination: when the domain of a PBB is empty,
1467 don't generate code for the PBB. */
1468 if (isl_set_is_empty (pbb
->domain
))
1471 domain
= cloog_domain_from_isl_set (isl_set_copy (pbb
->domain
));
1472 scattering
= cloog_scattering_from_isl_map
1473 (extend_scattering (isl_map_copy (pbb
->transformed
),
1474 nb_scattering_dims
));
1476 union_domain
= cloog_union_domain_add_domain (union_domain
, "", domain
,
1480 return union_domain
;
1483 /* Return the options that will be used in graphite_regenerate_ast_cloog. */
1485 static CloogOptions
*
1486 set_cloog_options (void)
1488 CloogOptions
*options
= cloog_options_malloc (cloog_state
);
1490 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1491 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1492 we pass an incomplete program to cloog. */
1493 options
->language
= CLOOG_LANGUAGE_C
;
1495 /* Enable complex equality spreading: removes dummy statements
1496 (assignments) in the generated code which repeats the
1497 substitution equations for statements. This is useless for
1498 graphite_regenerate_ast_cloog. */
1501 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1504 /* Allow cloog to build strides with a stride width different to one.
1505 This example has stride = 4:
1507 for (i = 0; i < 20; i += 4)
1509 options
->strides
= 1;
1511 /* We want the clast to provide the iteration domains of the executed loops.
1512 This allows us to derive minimal/maximal values for the induction
1514 options
->save_domains
= 1;
1516 /* Do not remove scalar dimensions. CLooG by default removes scalar
1517 dimensions very early from the input schedule. However, they are
1518 necessary to correctly derive from the saved domains
1519 (options->save_domains) the relationship between the generated loops
1520 and the schedule dimensions they are generated from. */
1521 options
->noscalars
= 1;
1523 /* Disable optimizations and make cloog generate source code closer to the
1524 input. This is useful for debugging, but later we want the optimized
1527 XXX: We can not disable optimizations, as loop blocking is not working
1532 options
->l
= INT_MAX
;
1538 /* Prints STMT to STDERR. */
1541 print_clast_stmt (FILE *file
, struct clast_stmt
*stmt
)
1543 CloogOptions
*options
= set_cloog_options ();
1545 clast_pprint (file
, stmt
, 0, options
);
1546 cloog_options_free (options
);
1549 /* Prints STMT to STDERR. */
1552 debug_clast_stmt (struct clast_stmt
*stmt
)
1554 print_clast_stmt (stderr
, stmt
);
1557 /* Get the maximal number of scattering dimensions in the scop SCOP. */
1560 int get_max_scattering_dimensions (scop_p scop
)
1564 int scattering_dims
= 0;
1566 FOR_EACH_VEC_ELT (SCOP_BBS (scop
), i
, pbb
)
1568 int pbb_scatt_dims
= isl_map_dim (pbb
->transformed
, isl_dim_out
);
1569 if (pbb_scatt_dims
> scattering_dims
)
1570 scattering_dims
= pbb_scatt_dims
;
1573 return scattering_dims
;
1577 generate_cloog_input (scop_p scop
, clast_index_htab_type
*params_index
)
1579 CloogUnionDomain
*union_domain
;
1580 CloogInput
*cloog_input
;
1581 CloogDomain
*context
;
1582 int nb_scattering_dims
= get_max_scattering_dimensions (scop
);
1584 union_domain
= build_cloog_union_domain (scop
, nb_scattering_dims
);
1585 union_domain
= add_names_to_union_domain (scop
, union_domain
,
1588 context
= cloog_domain_from_isl_set (isl_set_copy (scop
->context
));
1590 cloog_input
= cloog_input_alloc (context
, union_domain
);
1595 /* Translate SCOP to a CLooG program and clast. These two
1596 representations should be freed together: a clast cannot be used
1597 without a program. */
1599 static struct clast_stmt
*
1600 scop_to_clast (scop_p scop
, clast_index_htab_type
*params_index
)
1602 CloogInput
*cloog_input
;
1603 struct clast_stmt
*clast
;
1604 CloogOptions
*options
= set_cloog_options ();
1606 cloog_input
= generate_cloog_input (scop
, params_index
);
1608 /* Dump a .cloog input file, if requested. This feature is only
1609 enabled in the Graphite branch. */
1612 static size_t file_scop_number
= 0;
1613 FILE *cloog_file
= init_cloog_input_file (file_scop_number
);
1614 cloog_input_dump_cloog (cloog_file
, cloog_input
, options
);
1617 clast
= cloog_clast_create_from_input (cloog_input
, options
);
1619 cloog_options_free (options
);
1623 /* Prints to FILE the code generated by CLooG for SCOP. */
1626 print_generated_program (FILE *file
, scop_p scop
)
1628 CloogOptions
*options
= set_cloog_options ();
1629 clast_index_htab_type
*params_index
= new clast_index_htab_type (10);
1630 struct clast_stmt
*clast
;
1632 clast
= scop_to_clast (scop
, params_index
);
1634 fprintf (file
, " (clast: \n");
1635 clast_pprint (file
, clast
, 0, options
);
1636 fprintf (file
, " )\n");
1638 cloog_options_free (options
);
1639 cloog_clast_free (clast
);
1642 /* Prints to STDERR the code generated by CLooG for SCOP. */
1645 debug_generated_program (scop_p scop
)
1647 print_generated_program (stderr
, scop
);
1650 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1651 the given SCOP. Return true if code generation succeeded.
1652 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1656 graphite_regenerate_ast_cloog (scop_p scop
, bb_pbb_htab_type
*bb_pbb_mapping
)
1658 auto_vec
<tree
, 10> newivs
;
1659 loop_p context_loop
;
1660 sese region
= SCOP_REGION (scop
);
1661 ifsese if_region
= NULL
;
1662 clast_index_htab_type
*newivs_index
, *params_index
;
1663 struct clast_stmt
*clast
;
1664 struct ivs_params ip
;
1666 timevar_push (TV_GRAPHITE_CODE_GEN
);
1667 graphite_regenerate_error
= false;
1669 params_index
= new clast_index_htab_type (10);
1671 clast
= scop_to_clast (scop
, params_index
);
1673 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1675 fprintf (dump_file
, "\nCLAST generated by CLooG: \n");
1676 print_clast_stmt (dump_file
, clast
);
1677 fprintf (dump_file
, "\n");
1680 recompute_all_dominators ();
1683 if_region
= move_sese_in_condition (region
);
1684 sese_insert_phis_for_liveouts (region
,
1685 if_region
->region
->exit
->src
,
1686 if_region
->false_region
->exit
,
1687 if_region
->true_region
->exit
);
1688 recompute_all_dominators ();
1691 context_loop
= SESE_ENTRY (region
)->src
->loop_father
;
1692 newivs_index
= new clast_index_htab_type (10);
1694 ip
.newivs
= &newivs
;
1695 ip
.newivs_index
= newivs_index
;
1696 ip
.params
= SESE_PARAMS (region
);
1697 ip
.params_index
= params_index
;
1700 translate_clast (context_loop
, clast
, if_region
->true_region
->entry
,
1701 bb_pbb_mapping
, 0, &ip
);
1704 recompute_all_dominators ();
1707 if (graphite_regenerate_error
)
1708 set_ifsese_condition (if_region
, integer_zero_node
);
1710 free (if_region
->true_region
);
1711 free (if_region
->region
);
1714 delete newivs_index
;
1715 newivs_index
= NULL
;
1716 delete params_index
;
1717 params_index
= NULL
;
1718 cloog_clast_free (clast
);
1719 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1721 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1724 int num_no_dependency
= 0;
1726 FOR_EACH_LOOP (loop
, 0)
1727 if (loop
->can_be_parallel
)
1728 num_no_dependency
++;
1730 fprintf (dump_file
, "\n%d loops carried no dependency.\n",
1734 return !graphite_regenerate_error
;