1 /* Translation of CLAST (CLooG AST) to Gimple.
2 Copyright (C) 2009, 2010, 2011 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/>. */
23 #include "coretypes.h"
24 #include "diagnostic-core.h"
25 #include "tree-flow.h"
26 #include "tree-dump.h"
28 #include "tree-chrec.h"
29 #include "tree-data-ref.h"
30 #include "tree-scalar-evolution.h"
34 #include "cloog/cloog.h"
36 #include "graphite-cloog-util.h"
37 #include "graphite-ppl.h"
38 #include "graphite-poly.h"
39 #include "graphite-clast-to-gimple.h"
40 #include "graphite-dependences.h"
41 #include "graphite-cloog-compat.h"
43 #ifndef CLOOG_LANGUAGE_C
44 #define CLOOG_LANGUAGE_C LANGUAGE_C
47 /* This flag is set when an error occurred during the translation of
49 static bool gloog_error
;
51 /* Verifies properties that GRAPHITE should maintain during translation. */
54 graphite_verify (void)
56 #ifdef ENABLE_CHECKING
57 verify_loop_structure ();
58 verify_dominators (CDI_DOMINATORS
);
59 verify_loop_closed_ssa (true);
63 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
64 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
65 upper bounds that can be inferred from the polyhedral representation. */
67 typedef struct clast_name_index
{
70 mpz_t bound_one
, bound_two
;
72 } *clast_name_index_p
;
74 /* Returns a pointer to a new element of type clast_name_index_p built
75 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
77 static inline clast_name_index_p
78 new_clast_name_index (const char *name
, int index
, int level
,
79 mpz_t bound_one
, mpz_t bound_two
)
81 clast_name_index_p res
= XNEW (struct clast_name_index
);
86 mpz_init (res
->bound_one
);
87 mpz_init (res
->bound_two
);
88 mpz_set (res
->bound_one
, bound_one
);
89 mpz_set (res
->bound_two
, bound_two
);
93 /* Free the memory taken by a clast_name_index struct. */
96 free_clast_name_index (void *ptr
)
98 struct clast_name_index
*c
= (struct clast_name_index
*) ptr
;
99 mpz_clear (c
->bound_one
);
100 mpz_clear (c
->bound_two
);
104 /* For a given clast NAME, returns -1 if NAME is not in the
105 INDEX_TABLE, otherwise returns the loop level for the induction
106 variable NAME, or if it is a parameter, the parameter number in the
107 vector of parameters. */
110 clast_name_to_level (clast_name_p name
, htab_t index_table
)
112 struct clast_name_index tmp
;
116 gcc_assert (name
->type
== clast_expr_name
);
117 tmp
.name
= ((const struct clast_name
*) name
)->name
;
122 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
125 return ((struct clast_name_index
*) *slot
)->level
;
130 /* For a given clast NAME, returns -1 if it does not correspond to any
131 parameter, or otherwise, returns the index in the PARAMS or
132 SCATTERING_DIMENSIONS vector. */
135 clast_name_to_index (clast_name_p name
, htab_t index_table
)
137 struct clast_name_index tmp
;
141 gcc_assert (name
->type
== clast_expr_name
);
142 tmp
.name
= ((const struct clast_name
*) name
)->name
;
147 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
150 return ((struct clast_name_index
*) *slot
)->index
;
155 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
156 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
157 found in the INDEX_TABLE, false otherwise. */
160 clast_name_to_lb_ub (clast_name_p name
, htab_t index_table
, mpz_t bound_one
,
163 struct clast_name_index tmp
;
167 gcc_assert (name
->type
== clast_expr_name
);
168 tmp
.name
= ((const struct clast_name
*) name
)->name
;
173 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
177 mpz_set (bound_one
, ((struct clast_name_index
*) *slot
)->bound_one
);
178 mpz_set (bound_two
, ((struct clast_name_index
*) *slot
)->bound_two
);
185 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
188 save_clast_name_index (htab_t index_table
, const char *name
,
189 int index
, int level
, mpz_t bound_one
, mpz_t bound_two
)
191 struct clast_name_index tmp
;
195 slot
= htab_find_slot (index_table
, &tmp
, INSERT
);
201 *slot
= new_clast_name_index (name
, index
, level
, bound_one
, bound_two
);
205 /* Computes a hash function for database element ELT. */
207 static inline hashval_t
208 clast_name_index_elt_info (const void *elt
)
210 return htab_hash_pointer (((const struct clast_name_index
*) elt
)->name
);
213 /* Compares database elements E1 and E2. */
216 eq_clast_name_indexes (const void *e1
, const void *e2
)
218 const struct clast_name_index
*elt1
= (const struct clast_name_index
*) e1
;
219 const struct clast_name_index
*elt2
= (const struct clast_name_index
*) e2
;
221 return (elt1
->name
== elt2
->name
);
226 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
227 induction variable in NEWIVS.
229 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
230 parameter in PARAMS. */
232 typedef struct ivs_params
{
233 VEC (tree
, heap
) *params
, **newivs
;
234 htab_t newivs_index
, params_index
;
238 /* Returns the tree variable from the name NAME that was given in
239 Cloog representation. */
242 clast_name_to_gcc (clast_name_p name
, ivs_params_p ip
)
246 if (ip
->params
&& ip
->params_index
)
248 index
= clast_name_to_index (name
, ip
->params_index
);
251 return VEC_index (tree
, ip
->params
, index
);
254 gcc_assert (*(ip
->newivs
) && ip
->newivs_index
);
255 index
= clast_name_to_index (name
, ip
->newivs_index
);
256 gcc_assert (index
>= 0);
258 return VEC_index (tree
, *(ip
->newivs
), index
);
261 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
264 max_precision_type (tree type1
, tree type2
)
266 enum machine_mode mode
;
267 int p1
, p2
, precision
;
270 if (POINTER_TYPE_P (type1
))
273 if (POINTER_TYPE_P (type2
))
276 if (TYPE_UNSIGNED (type1
)
277 && TYPE_UNSIGNED (type2
))
278 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
280 p1
= TYPE_PRECISION (type1
);
281 p2
= TYPE_PRECISION (type2
);
284 precision
= TYPE_UNSIGNED (type1
) ? p1
* 2 : p1
;
286 precision
= TYPE_UNSIGNED (type2
) ? p2
* 2 : p2
;
288 if (precision
> BITS_PER_WORD
)
291 return integer_type_node
;
294 mode
= smallest_mode_for_size (precision
, MODE_INT
);
295 precision
= GET_MODE_PRECISION (mode
);
296 type
= build_nonstandard_integer_type (precision
, false);
301 return integer_type_node
;
308 clast_to_gcc_expression (tree
, struct clast_expr
*, ivs_params_p
);
310 /* Converts a Cloog reduction expression R with reduction operation OP
311 to a GCC expression tree of type TYPE. */
314 clast_to_gcc_expression_red (tree type
, enum tree_code op
,
315 struct clast_reduction
*r
, ivs_params_p ip
)
318 tree res
= clast_to_gcc_expression (type
, r
->elts
[0], ip
);
319 tree operand_type
= (op
== POINTER_PLUS_EXPR
) ? sizetype
: type
;
321 for (i
= 1; i
< r
->n
; i
++)
323 tree t
= clast_to_gcc_expression (operand_type
, r
->elts
[i
], ip
);
324 res
= fold_build2 (op
, type
, res
, t
);
330 /* Converts a Cloog AST expression E back to a GCC expression tree of
334 clast_to_gcc_expression (tree type
, struct clast_expr
*e
, ivs_params_p ip
)
338 case clast_expr_term
:
340 struct clast_term
*t
= (struct clast_term
*) e
;
344 if (mpz_cmp_si (t
->val
, 1) == 0)
346 tree name
= clast_name_to_gcc (t
->var
, ip
);
348 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
349 name
= convert_to_ptrofftype (name
);
351 name
= fold_convert (type
, name
);
355 else if (mpz_cmp_si (t
->val
, -1) == 0)
357 tree name
= clast_name_to_gcc (t
->var
, ip
);
359 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
360 name
= convert_to_ptrofftype (name
);
362 name
= fold_convert (type
, name
);
364 return fold_build1 (NEGATE_EXPR
, type
, name
);
368 tree name
= clast_name_to_gcc (t
->var
, ip
);
369 tree cst
= gmp_cst_to_tree (type
, t
->val
);
371 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
372 name
= convert_to_ptrofftype (name
);
374 name
= fold_convert (type
, name
);
376 if (!POINTER_TYPE_P (type
))
377 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
384 return gmp_cst_to_tree (type
, t
->val
);
389 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
394 return clast_to_gcc_expression_red
395 (type
, POINTER_TYPE_P (type
) ? POINTER_PLUS_EXPR
: PLUS_EXPR
,
399 return clast_to_gcc_expression_red (type
, MIN_EXPR
, r
, ip
);
402 return clast_to_gcc_expression_red (type
, MAX_EXPR
, r
, ip
);
412 struct clast_binary
*b
= (struct clast_binary
*) e
;
413 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
414 tree tl
= clast_to_gcc_expression (type
, lhs
, ip
);
415 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
420 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
423 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
426 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
429 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
443 /* Return a type that could represent the values between BOUND_ONE and
447 type_for_interval (mpz_t bound_one
, mpz_t bound_two
)
451 enum machine_mode mode
;
453 int precision
= MAX (mpz_sizeinbase (bound_one
, 2),
454 mpz_sizeinbase (bound_two
, 2));
456 if (precision
> BITS_PER_WORD
)
459 return integer_type_node
;
462 if (mpz_cmp (bound_one
, bound_two
) <= 0)
463 unsigned_p
= (mpz_sgn (bound_one
) >= 0);
465 unsigned_p
= (mpz_sgn (bound_two
) >= 0);
467 mode
= smallest_mode_for_size (precision
, MODE_INT
);
468 wider_precision
= GET_MODE_PRECISION (mode
);
470 /* As we want to generate signed types as much as possible, try to
471 fit the interval [bound_one, bound_two] in a signed type. For example,
472 supposing that we have the interval [0, 100], instead of
473 generating unsigned char, we want to generate a signed char. */
474 if (unsigned_p
&& precision
< wider_precision
)
477 type
= build_nonstandard_integer_type (wider_precision
, unsigned_p
);
482 return integer_type_node
;
488 /* Return a type that could represent the integer value VAL, or
489 otherwise return NULL_TREE. */
492 type_for_value (mpz_t val
)
494 return type_for_interval (val
, val
);
497 /* Return the type for the clast_term T. Initializes BOUND_ONE and
498 BOUND_TWO to the bounds of the term. */
501 type_for_clast_term (struct clast_term
*t
, ivs_params_p ip
, mpz_t bound_one
,
504 clast_name_p name
= t
->var
;
507 gcc_assert (t
->expr
.type
== clast_expr_term
);
511 mpz_set (bound_one
, t
->val
);
512 mpz_set (bound_two
, t
->val
);
513 return type_for_value (t
->val
);
516 if (ip
->params
&& ip
->params_index
)
517 found
= clast_name_to_lb_ub (name
, ip
->params_index
, bound_one
, bound_two
);
521 gcc_assert (*(ip
->newivs
) && ip
->newivs_index
);
522 found
= clast_name_to_lb_ub (name
, ip
->newivs_index
,
523 bound_one
, bound_two
);
527 mpz_mul (bound_one
, bound_one
, t
->val
);
528 mpz_mul (bound_two
, bound_two
, t
->val
);
530 return TREE_TYPE (clast_name_to_gcc (name
, ip
));
534 type_for_clast_expr (struct clast_expr
*, ivs_params_p
, mpz_t
, mpz_t
);
536 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
537 and BOUND_TWO to the bounds of the reduction expression. */
540 type_for_clast_red (struct clast_reduction
*r
, ivs_params_p ip
,
541 mpz_t bound_one
, mpz_t bound_two
)
544 tree type
= type_for_clast_expr (r
->elts
[0], ip
, bound_one
, bound_two
);
545 mpz_t b1
, b2
, m1
, m2
;
555 for (i
= 1; i
< r
->n
; i
++)
557 tree t
= type_for_clast_expr (r
->elts
[i
], ip
, b1
, b2
);
558 type
= max_precision_type (type
, t
);
563 value_min (m1
, bound_one
, bound_two
);
564 value_min (m2
, b1
, b2
);
565 mpz_add (bound_one
, m1
, m2
);
567 value_max (m1
, bound_one
, bound_two
);
568 value_max (m2
, b1
, b2
);
569 mpz_add (bound_two
, m1
, m2
);
573 value_min (bound_one
, bound_one
, bound_two
);
574 value_min (bound_two
, b1
, b2
);
578 value_max (bound_one
, bound_one
, bound_two
);
579 value_max (bound_two
, b1
, b2
);
593 /* Return a type that can represent the result of the reduction. */
594 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
597 /* Return the type for the clast_binary B used in STMT. */
600 type_for_clast_bin (struct clast_binary
*b
, ivs_params_p ip
, mpz_t bound_one
,
604 tree l
= type_for_clast_expr ((struct clast_expr
*) b
->LHS
, ip
,
605 bound_one
, bound_two
);
606 tree r
= type_for_value (b
->RHS
);
607 tree type
= max_precision_type (l
, r
);
612 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
613 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
617 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
618 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
620 mpz_add (bound_one
, bound_one
, one
);
621 mpz_add (bound_two
, bound_two
, one
);
626 mpz_div (bound_one
, bound_one
, b
->RHS
);
627 mpz_div (bound_two
, bound_two
, b
->RHS
);
631 mpz_mod (bound_one
, bound_one
, b
->RHS
);
632 mpz_mod (bound_two
, bound_two
, b
->RHS
);
639 /* Return a type that can represent the result of the reduction. */
640 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
643 /* Returns the type for the CLAST expression E when used in statement
647 type_for_clast_expr (struct clast_expr
*e
, ivs_params_p ip
, mpz_t bound_one
,
652 case clast_expr_term
:
653 return type_for_clast_term ((struct clast_term
*) e
, ip
,
654 bound_one
, bound_two
);
657 return type_for_clast_red ((struct clast_reduction
*) e
, ip
,
658 bound_one
, bound_two
);
661 return type_for_clast_bin ((struct clast_binary
*) e
, ip
,
662 bound_one
, bound_two
);
671 /* Returns the type for the equation CLEQ. */
674 type_for_clast_eq (struct clast_equation
*cleq
, ivs_params_p ip
)
676 mpz_t bound_one
, bound_two
;
679 mpz_init (bound_one
);
680 mpz_init (bound_two
);
682 l
= type_for_clast_expr (cleq
->LHS
, ip
, bound_one
, bound_two
);
683 r
= type_for_clast_expr (cleq
->RHS
, ip
, bound_one
, bound_two
);
685 mpz_clear (bound_one
);
686 mpz_clear (bound_two
);
687 return max_precision_type (l
, r
);
690 /* Translates a clast equation CLEQ to a tree. */
693 graphite_translate_clast_equation (struct clast_equation
*cleq
,
697 tree type
= type_for_clast_eq (cleq
, ip
);
698 tree lhs
= clast_to_gcc_expression (type
, cleq
->LHS
, ip
);
699 tree rhs
= clast_to_gcc_expression (type
, cleq
->RHS
, ip
);
704 else if (cleq
->sign
> 0)
710 return fold_build2 (comp
, boolean_type_node
, lhs
, rhs
);
713 /* Creates the test for the condition in STMT. */
716 graphite_create_guard_cond_expr (struct clast_guard
*stmt
,
722 for (i
= 0; i
< stmt
->n
; i
++)
724 tree eq
= graphite_translate_clast_equation (&stmt
->eq
[i
], ip
);
727 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
735 /* Creates a new if region corresponding to Cloog's guard. */
738 graphite_create_new_guard (edge entry_edge
, struct clast_guard
*stmt
,
741 tree cond_expr
= graphite_create_guard_cond_expr (stmt
, ip
);
742 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
746 /* Compute the lower bound LOW and upper bound UP for the parameter
747 PARAM in scop SCOP based on the constraints in the context. */
750 compute_bounds_for_param (scop_p scop
, int param
, mpz_t low
, mpz_t up
)
752 ppl_Linear_Expression_t le
;
754 /* Prepare the linear expression corresponding to the parameter that
755 we want to maximize/minimize. */
756 ppl_new_Linear_Expression_with_dimension (&le
, scop_nb_params (scop
));
757 ppl_set_coef (le
, param
, 1);
759 ppl_max_for_le_pointset (SCOP_CONTEXT (scop
), le
, up
);
760 ppl_min_for_le_pointset (SCOP_CONTEXT (scop
), le
, low
);
761 ppl_delete_Linear_Expression (le
);
764 /* Compute the lower bound LOW and upper bound UP for the induction
765 variable at LEVEL for the statement PBB, based on the transformed
766 scattering of PBB: T|I|G|Cst, with T the scattering transform, I
767 the iteration domain, and G the context parameters. */
770 compute_bounds_for_level (poly_bb_p pbb
, int level
, mpz_t low
, mpz_t up
)
772 ppl_Pointset_Powerset_C_Polyhedron_t ps
;
773 ppl_Linear_Expression_t le
;
775 combine_context_id_scat (&ps
, pbb
, false);
777 /* Prepare the linear expression corresponding to the level that we
778 want to maximize/minimize. */
780 ppl_dimension_type dim
= pbb_nb_scattering_transform (pbb
)
781 + pbb_dim_iter_domain (pbb
) + pbb_nb_params (pbb
);
783 ppl_new_Linear_Expression_with_dimension (&le
, dim
);
784 ppl_set_coef (le
, psct_dynamic_dim (pbb
, level
), 1);
787 ppl_max_for_le_pointset (ps
, le
, up
);
788 ppl_min_for_le_pointset (ps
, le
, low
);
789 ppl_delete_Linear_Expression (le
);
790 ppl_delete_Pointset_Powerset_C_Polyhedron (ps
);
793 /* Walks a CLAST and returns the first statement in the body of a
796 FIXME: This function should not be used to get a PBB in the STMT
797 loop in order to find out the iteration domain of the loop: the
798 counter example from Tobias is:
800 | for (i = 0; i < 100; i++)
807 This function would return S1 whose iteration domain contains only
808 one point "i = 0", whereas the iteration domain of S2 has 100 points.
810 This should be implemented using some functionality existing in
813 static struct clast_user_stmt
*
814 clast_get_body_of_loop (struct clast_stmt
*stmt
)
817 || CLAST_STMT_IS_A (stmt
, stmt_user
))
818 return (struct clast_user_stmt
*) stmt
;
820 if (CLAST_STMT_IS_A (stmt
, stmt_for
))
821 return clast_get_body_of_loop (((struct clast_for
*) stmt
)->body
);
823 if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
824 return clast_get_body_of_loop (((struct clast_guard
*) stmt
)->then
);
826 if (CLAST_STMT_IS_A (stmt
, stmt_block
))
827 return clast_get_body_of_loop (((struct clast_block
*) stmt
)->body
);
829 if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
830 return clast_get_body_of_loop (stmt
->next
);
835 /* Returns the type for the induction variable for the loop translated
839 type_for_clast_for (struct clast_for
*stmt_for
, ivs_params_p ip
)
841 mpz_t bound_one
, bound_two
;
842 tree lb_type
, ub_type
;
844 mpz_init (bound_one
);
845 mpz_init (bound_two
);
847 lb_type
= type_for_clast_expr (stmt_for
->LB
, ip
, bound_one
, bound_two
);
848 ub_type
= type_for_clast_expr (stmt_for
->UB
, ip
, bound_one
, bound_two
);
850 mpz_clear (bound_one
);
851 mpz_clear (bound_two
);
853 return max_precision_type (lb_type
, ub_type
);
856 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
857 induction variable for the new LOOP. New LOOP is attached to CFG
858 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
859 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
860 CLooG's scattering name to the induction variable created for the
861 loop of STMT. The new induction variable is inserted in the NEWIVS
862 vector and is of type TYPE. */
865 graphite_create_new_loop (edge entry_edge
, struct clast_for
*stmt
,
866 loop_p outer
, tree type
, tree lb
, tree ub
,
867 int level
, ivs_params_p ip
)
871 struct clast_user_stmt
*body
872 = clast_get_body_of_loop ((struct clast_stmt
*) stmt
);
873 poly_bb_p pbb
= (poly_bb_p
) cloog_statement_usr (body
->statement
);
875 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
876 tree ivvar
= create_tmp_var (type
, "graphite_IV");
877 tree iv
, iv_after_increment
;
878 loop_p loop
= create_empty_loop_on_edge
879 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
880 outer
? outer
: entry_edge
->src
->loop_father
);
882 add_referenced_var (ivvar
);
886 compute_bounds_for_level (pbb
, level
, low
, up
);
887 save_clast_name_index (ip
->newivs_index
, stmt
->iterator
,
888 VEC_length (tree
, *(ip
->newivs
)), level
, low
, up
);
891 VEC_safe_push (tree
, heap
, *(ip
->newivs
), iv
);
895 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
896 induction variables of the loops around GBB in SESE. */
899 build_iv_mapping (VEC (tree
, heap
) *iv_map
, struct clast_user_stmt
*user_stmt
,
902 struct clast_stmt
*t
;
904 CloogStatement
*cs
= user_stmt
->statement
;
905 poly_bb_p pbb
= (poly_bb_p
) cloog_statement_usr (cs
);
906 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
907 mpz_t bound_one
, bound_two
;
909 mpz_init (bound_one
);
910 mpz_init (bound_two
);
912 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, depth
++)
914 struct clast_expr
*expr
= (struct clast_expr
*)
915 ((struct clast_assignment
*)t
)->RHS
;
916 tree type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
917 tree new_name
= clast_to_gcc_expression (type
, expr
, ip
);
918 loop_p old_loop
= gbb_loop_at_index (gbb
, ip
->region
, depth
);
920 VEC_replace (tree
, iv_map
, old_loop
->num
, new_name
);
923 mpz_clear (bound_one
);
924 mpz_clear (bound_two
);
927 /* Construct bb_pbb_def with BB and PBB. */
930 new_bb_pbb_def (basic_block bb
, poly_bb_p pbb
)
932 bb_pbb_def
*bb_pbb_p
;
934 bb_pbb_p
= XNEW (bb_pbb_def
);
941 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
944 mark_bb_with_pbb (poly_bb_p pbb
, basic_block bb
, htab_t bb_pbb_mapping
)
950 x
= htab_find_slot (bb_pbb_mapping
, &tmp
, INSERT
);
953 *x
= new_bb_pbb_def (bb
, pbb
);
956 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
959 find_pbb_via_hash (htab_t bb_pbb_mapping
, basic_block bb
)
965 slot
= htab_find_slot (bb_pbb_mapping
, &tmp
, NO_INSERT
);
968 return ((bb_pbb_def
*) *slot
)->pbb
;
973 /* Check data dependency in LOOP at level LEVEL.
974 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
978 dependency_in_loop_p (loop_p loop
, htab_t bb_pbb_mapping
, int level
)
981 basic_block
*bbs
= get_loop_body_in_dom_order (loop
);
983 for (i
= 0; i
< loop
->num_nodes
; i
++)
985 poly_bb_p pbb1
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[i
]);
990 for (j
= 0; j
< loop
->num_nodes
; j
++)
992 poly_bb_p pbb2
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[j
]);
997 if (dependency_between_pbbs_p (pbb1
, pbb2
, level
))
1010 /* Translates a clast user statement STMT to gimple.
1012 - NEXT_E is the edge where new generated code should be attached.
1013 - CONTEXT_LOOP is the loop in which the generated code will be placed
1014 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1017 translate_clast_user (struct clast_user_stmt
*stmt
, edge next_e
,
1018 htab_t bb_pbb_mapping
, ivs_params_p ip
)
1022 poly_bb_p pbb
= (poly_bb_p
) cloog_statement_usr (stmt
->statement
);
1023 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1024 VEC (tree
, heap
) *iv_map
;
1026 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR
)
1029 nb_loops
= number_of_loops ();
1030 iv_map
= VEC_alloc (tree
, heap
, nb_loops
);
1031 for (i
= 0; i
< nb_loops
; i
++)
1032 VEC_quick_push (tree
, iv_map
, NULL_TREE
);
1034 build_iv_mapping (iv_map
, stmt
, ip
);
1035 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), ip
->region
,
1036 next_e
, iv_map
, &gloog_error
);
1037 VEC_free (tree
, heap
, iv_map
);
1039 new_bb
= next_e
->src
;
1040 mark_bb_with_pbb (pbb
, new_bb
, bb_pbb_mapping
);
1041 update_ssa (TODO_update_ssa
);
1046 /* Creates a new if region protecting the loop to be executed, if the execution
1047 count is zero (lb > ub). */
1050 graphite_create_new_loop_guard (edge entry_edge
, struct clast_for
*stmt
,
1051 tree
*type
, tree
*lb
, tree
*ub
,
1057 *type
= type_for_clast_for (stmt
, ip
);
1058 *lb
= clast_to_gcc_expression (*type
, stmt
->LB
, ip
);
1059 *ub
= clast_to_gcc_expression (*type
, stmt
->UB
, ip
);
1061 /* When ub is simply a constant or a parameter, use lb <= ub. */
1062 if (TREE_CODE (*ub
) == INTEGER_CST
|| TREE_CODE (*ub
) == SSA_NAME
)
1063 cond_expr
= fold_build2 (LE_EXPR
, boolean_type_node
, *lb
, *ub
);
1066 tree one
= (POINTER_TYPE_P (*type
)
1067 ? convert_to_ptrofftype (integer_one_node
)
1068 : fold_convert (*type
, integer_one_node
));
1069 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1070 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1071 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1072 even if we do not want this. However lb < ub + 1 is false, as
1074 tree ub_one
= fold_build2 (POINTER_TYPE_P (*type
) ? POINTER_PLUS_EXPR
1075 : PLUS_EXPR
, *type
, *ub
, one
);
1077 cond_expr
= fold_build2 (LT_EXPR
, boolean_type_node
, *lb
, ub_one
);
1080 exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
1086 translate_clast (loop_p
, struct clast_stmt
*, edge
, htab_t
, int, ivs_params_p
);
1088 /* Create the loop for a clast for statement.
1090 - NEXT_E is the edge where new generated code should be attached.
1091 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1094 translate_clast_for_loop (loop_p context_loop
, struct clast_for
*stmt
,
1095 edge next_e
, htab_t bb_pbb_mapping
, int level
,
1096 tree type
, tree lb
, tree ub
, ivs_params_p ip
)
1098 struct loop
*loop
= graphite_create_new_loop (next_e
, stmt
, context_loop
,
1099 type
, lb
, ub
, level
, ip
);
1100 edge last_e
= single_exit (loop
);
1101 edge to_body
= single_succ_edge (loop
->header
);
1102 basic_block after
= to_body
->dest
;
1104 /* Create a basic block for loop close phi nodes. */
1105 last_e
= single_succ_edge (split_edge (last_e
));
1107 /* Translate the body of the loop. */
1108 next_e
= translate_clast (loop
, stmt
->body
, to_body
, bb_pbb_mapping
,
1110 redirect_edge_succ_nodup (next_e
, after
);
1111 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
1113 if (flag_loop_parallelize_all
1114 && !dependency_in_loop_p (loop
, bb_pbb_mapping
, level
))
1115 loop
->can_be_parallel
= true;
1120 /* Translates a clast for statement STMT to gimple. First a guard is created
1121 protecting the loop, if it is executed zero times. In this guard we create
1122 the real loop structure.
1124 - NEXT_E is the edge where new generated code should be attached.
1125 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1128 translate_clast_for (loop_p context_loop
, struct clast_for
*stmt
, edge next_e
,
1129 htab_t bb_pbb_mapping
, int level
, ivs_params_p ip
)
1132 edge last_e
= graphite_create_new_loop_guard (next_e
, stmt
, &type
,
1134 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1136 translate_clast_for_loop (context_loop
, stmt
, true_e
, bb_pbb_mapping
, level
,
1141 /* Translates a clast assignment STMT to gimple.
1143 - NEXT_E is the edge where new generated code should be attached.
1144 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1147 translate_clast_assignment (struct clast_assignment
*stmt
, edge next_e
,
1148 int level
, ivs_params_p ip
)
1151 mpz_t bound_one
, bound_two
;
1152 tree type
, new_name
, var
;
1153 edge res
= single_succ_edge (split_edge (next_e
));
1154 struct clast_expr
*expr
= (struct clast_expr
*) stmt
->RHS
;
1156 mpz_init (bound_one
);
1157 mpz_init (bound_two
);
1158 type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1159 var
= create_tmp_var (type
, "graphite_var");
1160 new_name
= force_gimple_operand (clast_to_gcc_expression (type
, expr
, ip
),
1162 add_referenced_var (var
);
1165 gsi_insert_seq_on_edge (next_e
, stmts
);
1166 gsi_commit_edge_inserts ();
1169 save_clast_name_index (ip
->newivs_index
, stmt
->LHS
,
1170 VEC_length (tree
, *(ip
->newivs
)), level
,
1171 bound_one
, bound_two
);
1172 VEC_safe_push (tree
, heap
, *(ip
->newivs
), new_name
);
1174 mpz_clear (bound_one
);
1175 mpz_clear (bound_two
);
1180 /* Translates a clast guard statement STMT to gimple.
1182 - NEXT_E is the edge where new generated code should be attached.
1183 - CONTEXT_LOOP is the loop in which the generated code will be placed
1184 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1187 translate_clast_guard (loop_p context_loop
, struct clast_guard
*stmt
,
1188 edge next_e
, htab_t bb_pbb_mapping
, int level
,
1191 edge last_e
= graphite_create_new_guard (next_e
, stmt
, ip
);
1192 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1194 translate_clast (context_loop
, stmt
->then
, true_e
, bb_pbb_mapping
, level
, ip
);
1198 /* Translates a CLAST statement STMT to GCC representation in the
1201 - NEXT_E is the edge where new generated code should be attached.
1202 - CONTEXT_LOOP is the loop in which the generated code will be placed
1203 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1206 translate_clast (loop_p context_loop
, struct clast_stmt
*stmt
, edge next_e
,
1207 htab_t bb_pbb_mapping
, int level
, ivs_params_p ip
)
1212 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
1215 else if (CLAST_STMT_IS_A (stmt
, stmt_user
))
1216 next_e
= translate_clast_user ((struct clast_user_stmt
*) stmt
,
1217 next_e
, bb_pbb_mapping
, ip
);
1219 else if (CLAST_STMT_IS_A (stmt
, stmt_for
))
1220 next_e
= translate_clast_for (context_loop
, (struct clast_for
*) stmt
,
1221 next_e
, bb_pbb_mapping
, level
, ip
);
1223 else if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
1224 next_e
= translate_clast_guard (context_loop
, (struct clast_guard
*) stmt
,
1225 next_e
, bb_pbb_mapping
, level
, ip
);
1227 else if (CLAST_STMT_IS_A (stmt
, stmt_block
))
1228 next_e
= translate_clast (context_loop
, ((struct clast_block
*) stmt
)->body
,
1229 next_e
, bb_pbb_mapping
, level
, ip
);
1231 else if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
1232 next_e
= translate_clast_assignment ((struct clast_assignment
*) stmt
,
1237 recompute_all_dominators ();
1240 return translate_clast (context_loop
, stmt
->next
, next_e
, bb_pbb_mapping
,
1244 /* Free the SCATTERING domain list. */
1247 free_scattering (CloogScatteringList
*scattering
)
1251 CloogScattering
*dom
= cloog_scattering (scattering
);
1252 CloogScatteringList
*next
= cloog_next_scattering (scattering
);
1254 cloog_scattering_free (dom
);
1260 /* Initialize Cloog's parameter names from the names used in GIMPLE.
1261 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
1262 from 0 to scop_nb_loops (scop). */
1265 initialize_cloog_names (scop_p scop
, CloogProgram
*prog
)
1267 sese region
= SCOP_REGION (scop
);
1269 int nb_iterators
= scop_max_loop_depth (scop
);
1270 int nb_scattering
= cloog_program_nb_scattdims (prog
);
1271 int nb_parameters
= VEC_length (tree
, SESE_PARAMS (region
));
1272 char **iterators
= XNEWVEC (char *, nb_iterators
* 2);
1273 char **scattering
= XNEWVEC (char *, nb_scattering
);
1274 char **parameters
= XNEWVEC (char *, nb_parameters
);
1276 cloog_program_set_names (prog
, cloog_names_malloc ());
1278 for (i
= 0; i
< nb_parameters
; i
++)
1280 tree param
= VEC_index (tree
, SESE_PARAMS (region
), i
);
1281 const char *name
= get_name (param
);
1287 len
= strlen (name
);
1289 parameters
[i
] = XNEWVEC (char, len
+ 1);
1290 snprintf (parameters
[i
], len
, "%s_%d", name
, SSA_NAME_VERSION (param
));
1293 cloog_names_set_nb_parameters (cloog_program_names (prog
), nb_parameters
);
1294 cloog_names_set_parameters (cloog_program_names (prog
), parameters
);
1296 for (i
= 0; i
< nb_iterators
; i
++)
1299 iterators
[i
] = XNEWVEC (char, len
);
1300 snprintf (iterators
[i
], len
, "git_%d", i
);
1303 cloog_names_set_nb_iterators (cloog_program_names (prog
),
1305 cloog_names_set_iterators (cloog_program_names (prog
),
1308 for (i
= 0; i
< nb_scattering
; i
++)
1311 scattering
[i
] = XNEWVEC (char, len
);
1312 snprintf (scattering
[i
], len
, "scat_%d", i
);
1315 cloog_names_set_nb_scattering (cloog_program_names (prog
),
1317 cloog_names_set_scattering (cloog_program_names (prog
),
1321 /* Initialize a CLooG input file. */
1324 init_cloog_input_file (int scop_number
)
1326 FILE *graphite_out_file
;
1327 int len
= strlen (dump_base_name
);
1328 char *dumpname
= XNEWVEC (char, len
+ 25);
1329 char *s_scop_number
= XNEWVEC (char, 15);
1331 memcpy (dumpname
, dump_base_name
, len
+ 1);
1332 strip_off_ending (dumpname
, len
);
1333 sprintf (s_scop_number
, ".%d", scop_number
);
1334 strcat (dumpname
, s_scop_number
);
1335 strcat (dumpname
, ".cloog");
1336 graphite_out_file
= fopen (dumpname
, "w+b");
1338 if (graphite_out_file
== 0)
1339 fatal_error ("can%'t open %s for writing: %m", dumpname
);
1343 return graphite_out_file
;
1346 /* Build cloog program for SCoP. */
1349 build_cloog_prog (scop_p scop
, CloogProgram
*prog
,
1350 CloogOptions
*options
)
1353 int max_nb_loops
= scop_max_loop_depth (scop
);
1355 CloogLoop
*loop_list
= NULL
;
1356 CloogBlockList
*block_list
= NULL
;
1357 CloogScatteringList
*scattering
= NULL
;
1358 int nbs
= 2 * max_nb_loops
+ 1;
1361 cloog_program_set_context
1362 (prog
, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop
),
1363 scop_nb_params (scop
), cloog_state
));
1364 nbs
= unify_scattering_dimensions (scop
);
1365 scaldims
= (int *) xmalloc (nbs
* (sizeof (int)));
1366 cloog_program_set_nb_scattdims (prog
, nbs
);
1367 initialize_cloog_names (scop
, prog
);
1369 FOR_EACH_VEC_ELT (poly_bb_p
, SCOP_BBS (scop
), i
, pbb
)
1371 CloogStatement
*stmt
;
1375 /* Dead code elimination: when the domain of a PBB is empty,
1376 don't generate code for the PBB. */
1377 if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb
)))
1380 /* Build the new statement and its block. */
1381 stmt
= cloog_statement_alloc (cloog_state
, pbb_index (pbb
));
1382 dom
= new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb
),
1383 scop_nb_params (scop
),
1385 block
= cloog_block_alloc (stmt
, 0, NULL
, pbb_dim_iter_domain (pbb
));
1386 cloog_statement_set_usr (stmt
, pbb
);
1388 /* Build loop list. */
1390 CloogLoop
*new_loop_list
= cloog_loop_malloc (cloog_state
);
1391 cloog_loop_set_next (new_loop_list
, loop_list
);
1392 cloog_loop_set_domain (new_loop_list
, dom
);
1393 cloog_loop_set_block (new_loop_list
, block
);
1394 loop_list
= new_loop_list
;
1397 /* Build block list. */
1399 CloogBlockList
*new_block_list
= cloog_block_list_malloc ();
1401 cloog_block_list_set_next (new_block_list
, block_list
);
1402 cloog_block_list_set_block (new_block_list
, block
);
1403 block_list
= new_block_list
;
1406 /* Build scattering list. */
1408 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
1409 CloogScatteringList
*new_scattering
1410 = (CloogScatteringList
*) xmalloc (sizeof (CloogScatteringList
));
1411 ppl_Polyhedron_t scat
;
1412 CloogScattering
*dom
;
1414 scat
= PBB_TRANSFORMED_SCATTERING (pbb
);
1415 dom
= new_Cloog_Scattering_from_ppl_Polyhedron
1416 (scat
, scop_nb_params (scop
), pbb_nb_scattering_transform (pbb
),
1419 cloog_set_next_scattering (new_scattering
, scattering
);
1420 cloog_set_scattering (new_scattering
, dom
);
1421 scattering
= new_scattering
;
1425 cloog_program_set_loop (prog
, loop_list
);
1426 cloog_program_set_blocklist (prog
, block_list
);
1428 for (i
= 0; i
< nbs
; i
++)
1431 cloog_program_set_scaldims (prog
, scaldims
);
1433 /* Extract scalar dimensions to simplify the code generation problem. */
1434 cloog_program_extract_scalars (prog
, scattering
, options
);
1436 /* Dump a .cloog input file, if requested. This feature is only
1437 enabled in the Graphite branch. */
1440 static size_t file_scop_number
= 0;
1441 FILE *cloog_file
= init_cloog_input_file (file_scop_number
);
1443 cloog_program_dump_cloog (cloog_file
, prog
, scattering
);
1447 /* Apply scattering. */
1448 cloog_program_scatter (prog
, scattering
, options
);
1449 free_scattering (scattering
);
1451 /* Iterators corresponding to scalar dimensions have to be extracted. */
1452 cloog_names_scalarize (cloog_program_names (prog
), nbs
,
1453 cloog_program_scaldims (prog
));
1455 /* Free blocklist. */
1457 CloogBlockList
*next
= cloog_program_blocklist (prog
);
1461 CloogBlockList
*toDelete
= next
;
1462 next
= cloog_block_list_next (next
);
1463 cloog_block_list_set_next (toDelete
, NULL
);
1464 cloog_block_list_set_block (toDelete
, NULL
);
1465 cloog_block_list_free (toDelete
);
1467 cloog_program_set_blocklist (prog
, NULL
);
1471 /* Return the options that will be used in GLOOG. */
1473 static CloogOptions
*
1474 set_cloog_options (void)
1476 CloogOptions
*options
= cloog_options_malloc (cloog_state
);
1478 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1479 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1480 we pass an incomplete program to cloog. */
1481 options
->language
= CLOOG_LANGUAGE_C
;
1483 /* Enable complex equality spreading: removes dummy statements
1484 (assignments) in the generated code which repeats the
1485 substitution equations for statements. This is useless for
1490 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1493 /* Enable C pretty-printing mode: normalizes the substitution
1494 equations for statements. */
1498 /* Allow cloog to build strides with a stride width different to one.
1499 This example has stride = 4:
1501 for (i = 0; i < 20; i += 4)
1503 options
->strides
= 1;
1505 /* Disable optimizations and make cloog generate source code closer to the
1506 input. This is useful for debugging, but later we want the optimized
1509 XXX: We can not disable optimizations, as loop blocking is not working
1514 options
->l
= INT_MAX
;
1520 /* Prints STMT to STDERR. */
1523 print_clast_stmt (FILE *file
, struct clast_stmt
*stmt
)
1525 CloogOptions
*options
= set_cloog_options ();
1527 clast_pprint (file
, stmt
, 0, options
);
1528 cloog_options_free (options
);
1531 /* Prints STMT to STDERR. */
1534 debug_clast_stmt (struct clast_stmt
*stmt
)
1536 print_clast_stmt (stderr
, stmt
);
1539 /* Translate SCOP to a CLooG program and clast. These two
1540 representations should be freed together: a clast cannot be used
1541 without a program. */
1544 scop_to_clast (scop_p scop
)
1546 CloogOptions
*options
= set_cloog_options ();
1547 cloog_prog_clast pc
;
1549 /* Connect new cloog prog generation to graphite. */
1550 pc
.prog
= cloog_program_malloc ();
1551 build_cloog_prog (scop
, pc
.prog
, options
);
1552 pc
.prog
= cloog_program_generate (pc
.prog
, options
);
1553 pc
.stmt
= cloog_clast_create (pc
.prog
, options
);
1555 cloog_options_free (options
);
1559 /* Prints to FILE the code generated by CLooG for SCOP. */
1562 print_generated_program (FILE *file
, scop_p scop
)
1564 CloogOptions
*options
= set_cloog_options ();
1566 cloog_prog_clast pc
= scop_to_clast (scop
);
1568 fprintf (file
, " (prog: \n");
1569 cloog_program_print (file
, pc
.prog
);
1570 fprintf (file
, " )\n");
1572 fprintf (file
, " (clast: \n");
1573 clast_pprint (file
, pc
.stmt
, 0, options
);
1574 fprintf (file
, " )\n");
1576 cloog_options_free (options
);
1577 cloog_clast_free (pc
.stmt
);
1578 cloog_program_free (pc
.prog
);
1581 /* Prints to STDERR the code generated by CLooG for SCOP. */
1584 debug_generated_program (scop_p scop
)
1586 print_generated_program (stderr
, scop
);
1589 /* Add CLooG names to parameter index. The index is used to translate
1590 back from CLooG names to GCC trees. */
1593 create_params_index (scop_p scop
, htab_t index_table
, CloogProgram
*prog
) {
1594 CloogNames
* names
= cloog_program_names (prog
);
1595 int nb_parameters
= cloog_names_nb_parameters (names
);
1596 char **parameters
= cloog_names_parameters (names
);
1598 mpz_t bound_one
, bound_two
;
1600 mpz_init (bound_one
);
1601 mpz_init (bound_two
);
1603 for (i
= 0; i
< nb_parameters
; i
++)
1605 compute_bounds_for_param (scop
, i
, bound_one
, bound_two
);
1606 save_clast_name_index (index_table
, parameters
[i
], i
, i
,
1607 bound_one
, bound_two
);
1610 mpz_clear (bound_one
);
1611 mpz_clear (bound_two
);
1614 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1615 the given SCOP. Return true if code generation succeeded.
1616 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1620 gloog (scop_p scop
, htab_t bb_pbb_mapping
)
1622 VEC (tree
, heap
) *newivs
= VEC_alloc (tree
, heap
, 10);
1623 loop_p context_loop
;
1624 sese region
= SCOP_REGION (scop
);
1625 ifsese if_region
= NULL
;
1626 htab_t newivs_index
, params_index
;
1627 cloog_prog_clast pc
;
1628 struct ivs_params ip
;
1630 timevar_push (TV_GRAPHITE_CODE_GEN
);
1631 gloog_error
= false;
1633 pc
= scop_to_clast (scop
);
1635 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1637 fprintf (dump_file
, "\nCLAST generated by CLooG: \n");
1638 print_clast_stmt (dump_file
, pc
.stmt
);
1639 fprintf (dump_file
, "\n");
1642 recompute_all_dominators ();
1645 if_region
= move_sese_in_condition (region
);
1646 sese_insert_phis_for_liveouts (region
,
1647 if_region
->region
->exit
->src
,
1648 if_region
->false_region
->exit
,
1649 if_region
->true_region
->exit
);
1650 recompute_all_dominators ();
1653 context_loop
= SESE_ENTRY (region
)->src
->loop_father
;
1654 newivs_index
= htab_create (10, clast_name_index_elt_info
,
1655 eq_clast_name_indexes
, free_clast_name_index
);
1656 params_index
= htab_create (10, clast_name_index_elt_info
,
1657 eq_clast_name_indexes
, free_clast_name_index
);
1659 create_params_index (scop
, params_index
, pc
.prog
);
1661 ip
.newivs
= &newivs
;
1662 ip
.newivs_index
= newivs_index
;
1663 ip
.params
= SESE_PARAMS (region
);
1664 ip
.params_index
= params_index
;
1667 translate_clast (context_loop
, pc
.stmt
, if_region
->true_region
->entry
,
1668 bb_pbb_mapping
, 0, &ip
);
1671 recompute_all_dominators ();
1675 set_ifsese_condition (if_region
, integer_zero_node
);
1677 free (if_region
->true_region
);
1678 free (if_region
->region
);
1681 htab_delete (newivs_index
);
1682 htab_delete (params_index
);
1683 VEC_free (tree
, heap
, newivs
);
1684 cloog_clast_free (pc
.stmt
);
1685 cloog_program_free (pc
.prog
);
1686 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1688 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1692 int num_no_dependency
= 0;
1694 FOR_EACH_LOOP (li
, loop
, 0)
1695 if (loop
->can_be_parallel
)
1696 num_no_dependency
++;
1698 fprintf (dump_file
, "\n%d loops carried no dependency.\n",
1702 return !gloog_error
;