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_loop_closed_ssa (true);
62 /* Stores the INDEX in a vector and the loop nesting LEVEL for a given
63 clast NAME. BOUND_ONE and BOUND_TWO represent the exact lower and
64 upper bounds that can be inferred from the polyhedral representation. */
66 typedef struct clast_name_index
{
69 mpz_t bound_one
, bound_two
;
71 } *clast_name_index_p
;
73 /* Returns a pointer to a new element of type clast_name_index_p built
74 from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
76 static inline clast_name_index_p
77 new_clast_name_index (const char *name
, int index
, int level
,
78 mpz_t bound_one
, mpz_t bound_two
)
80 clast_name_index_p res
= XNEW (struct clast_name_index
);
85 mpz_init (res
->bound_one
);
86 mpz_init (res
->bound_two
);
87 mpz_set (res
->bound_one
, bound_one
);
88 mpz_set (res
->bound_two
, bound_two
);
92 /* Free the memory taken by a clast_name_index struct. */
95 free_clast_name_index (void *ptr
)
97 struct clast_name_index
*c
= (struct clast_name_index
*) ptr
;
98 mpz_clear (c
->bound_one
);
99 mpz_clear (c
->bound_two
);
103 /* For a given clast NAME, returns -1 if NAME is not in the
104 INDEX_TABLE, otherwise returns the loop level for the induction
105 variable NAME, or if it is a parameter, the parameter number in the
106 vector of parameters. */
109 clast_name_to_level (clast_name_p name
, htab_t index_table
)
111 struct clast_name_index tmp
;
115 gcc_assert (name
->type
== clast_expr_name
);
116 tmp
.name
= ((const struct clast_name
*) name
)->name
;
121 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
124 return ((struct clast_name_index
*) *slot
)->level
;
129 /* For a given clast NAME, returns -1 if it does not correspond to any
130 parameter, or otherwise, returns the index in the PARAMS or
131 SCATTERING_DIMENSIONS vector. */
134 clast_name_to_index (clast_name_p name
, htab_t index_table
)
136 struct clast_name_index tmp
;
140 gcc_assert (name
->type
== clast_expr_name
);
141 tmp
.name
= ((const struct clast_name
*) name
)->name
;
146 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
149 return ((struct clast_name_index
*) *slot
)->index
;
154 /* For a given clast NAME, initializes the lower and upper bounds BOUND_ONE
155 and BOUND_TWO stored in the INDEX_TABLE. Returns true when NAME has been
156 found in the INDEX_TABLE, false otherwise. */
159 clast_name_to_lb_ub (clast_name_p name
, htab_t index_table
, mpz_t bound_one
,
162 struct clast_name_index tmp
;
166 gcc_assert (name
->type
== clast_expr_name
);
167 tmp
.name
= ((const struct clast_name
*) name
)->name
;
172 slot
= htab_find_slot (index_table
, &tmp
, NO_INSERT
);
176 mpz_set (bound_one
, ((struct clast_name_index
*) *slot
)->bound_one
);
177 mpz_set (bound_two
, ((struct clast_name_index
*) *slot
)->bound_two
);
184 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
187 save_clast_name_index (htab_t index_table
, const char *name
,
188 int index
, int level
, mpz_t bound_one
, mpz_t bound_two
)
190 struct clast_name_index tmp
;
194 slot
= htab_find_slot (index_table
, &tmp
, INSERT
);
200 *slot
= new_clast_name_index (name
, index
, level
, bound_one
, bound_two
);
204 /* Computes a hash function for database element ELT. */
206 static inline hashval_t
207 clast_name_index_elt_info (const void *elt
)
209 return htab_hash_pointer (((const struct clast_name_index
*) elt
)->name
);
212 /* Compares database elements E1 and E2. */
215 eq_clast_name_indexes (const void *e1
, const void *e2
)
217 const struct clast_name_index
*elt1
= (const struct clast_name_index
*) e1
;
218 const struct clast_name_index
*elt2
= (const struct clast_name_index
*) e2
;
220 return (elt1
->name
== elt2
->name
);
225 /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
226 induction variable in NEWIVS.
228 PARAMS_INDEX binds CLooG's parameter name to the index of the tree
229 parameter in PARAMS. */
231 typedef struct ivs_params
{
232 VEC (tree
, heap
) *params
, **newivs
;
233 htab_t newivs_index
, params_index
;
237 /* Returns the tree variable from the name NAME that was given in
238 Cloog representation. */
241 clast_name_to_gcc (clast_name_p name
, ivs_params_p ip
)
245 if (ip
->params
&& ip
->params_index
)
247 index
= clast_name_to_index (name
, ip
->params_index
);
250 return VEC_index (tree
, ip
->params
, index
);
253 gcc_assert (*(ip
->newivs
) && ip
->newivs_index
);
254 index
= clast_name_to_index (name
, ip
->newivs_index
);
255 gcc_assert (index
>= 0);
257 return VEC_index (tree
, *(ip
->newivs
), index
);
260 /* Returns the maximal precision type for expressions TYPE1 and TYPE2. */
263 max_precision_type (tree type1
, tree type2
)
265 enum machine_mode mode
;
266 int p1
, p2
, precision
;
269 if (POINTER_TYPE_P (type1
))
272 if (POINTER_TYPE_P (type2
))
275 if (TYPE_UNSIGNED (type1
)
276 && TYPE_UNSIGNED (type2
))
277 return TYPE_PRECISION (type1
) > TYPE_PRECISION (type2
) ? type1
: type2
;
279 p1
= TYPE_PRECISION (type1
);
280 p2
= TYPE_PRECISION (type2
);
283 precision
= TYPE_UNSIGNED (type1
) ? p1
* 2 : p1
;
285 precision
= TYPE_UNSIGNED (type2
) ? p2
* 2 : p2
;
287 if (precision
> BITS_PER_WORD
)
290 return integer_type_node
;
293 mode
= smallest_mode_for_size (precision
, MODE_INT
);
294 precision
= GET_MODE_PRECISION (mode
);
295 type
= build_nonstandard_integer_type (precision
, false);
300 return integer_type_node
;
307 clast_to_gcc_expression (tree
, struct clast_expr
*, ivs_params_p
);
309 /* Converts a Cloog reduction expression R with reduction operation OP
310 to a GCC expression tree of type TYPE. */
313 clast_to_gcc_expression_red (tree type
, enum tree_code op
,
314 struct clast_reduction
*r
, ivs_params_p ip
)
317 tree res
= clast_to_gcc_expression (type
, r
->elts
[0], ip
);
318 tree operand_type
= (op
== POINTER_PLUS_EXPR
) ? sizetype
: type
;
320 for (i
= 1; i
< r
->n
; i
++)
322 tree t
= clast_to_gcc_expression (operand_type
, r
->elts
[i
], ip
);
323 res
= fold_build2 (op
, type
, res
, t
);
329 /* Converts a Cloog AST expression E back to a GCC expression tree of
333 clast_to_gcc_expression (tree type
, struct clast_expr
*e
, ivs_params_p ip
)
337 case clast_expr_term
:
339 struct clast_term
*t
= (struct clast_term
*) e
;
343 if (mpz_cmp_si (t
->val
, 1) == 0)
345 tree name
= clast_name_to_gcc (t
->var
, ip
);
347 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
348 name
= convert_to_ptrofftype (name
);
350 name
= fold_convert (type
, name
);
354 else if (mpz_cmp_si (t
->val
, -1) == 0)
356 tree name
= clast_name_to_gcc (t
->var
, ip
);
358 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
359 name
= convert_to_ptrofftype (name
);
361 name
= fold_convert (type
, name
);
363 return fold_build1 (NEGATE_EXPR
, type
, name
);
367 tree name
= clast_name_to_gcc (t
->var
, ip
);
368 tree cst
= gmp_cst_to_tree (type
, t
->val
);
370 if (POINTER_TYPE_P (TREE_TYPE (name
)) != POINTER_TYPE_P (type
))
371 name
= convert_to_ptrofftype (name
);
373 name
= fold_convert (type
, name
);
375 if (!POINTER_TYPE_P (type
))
376 return fold_build2 (MULT_EXPR
, type
, cst
, name
);
383 return gmp_cst_to_tree (type
, t
->val
);
388 struct clast_reduction
*r
= (struct clast_reduction
*) e
;
393 return clast_to_gcc_expression_red
394 (type
, POINTER_TYPE_P (type
) ? POINTER_PLUS_EXPR
: PLUS_EXPR
,
398 return clast_to_gcc_expression_red (type
, MIN_EXPR
, r
, ip
);
401 return clast_to_gcc_expression_red (type
, MAX_EXPR
, r
, ip
);
411 struct clast_binary
*b
= (struct clast_binary
*) e
;
412 struct clast_expr
*lhs
= (struct clast_expr
*) b
->LHS
;
413 tree tl
= clast_to_gcc_expression (type
, lhs
, ip
);
414 tree tr
= gmp_cst_to_tree (type
, b
->RHS
);
419 return fold_build2 (FLOOR_DIV_EXPR
, type
, tl
, tr
);
422 return fold_build2 (CEIL_DIV_EXPR
, type
, tl
, tr
);
425 return fold_build2 (EXACT_DIV_EXPR
, type
, tl
, tr
);
428 return fold_build2 (TRUNC_MOD_EXPR
, type
, tl
, tr
);
442 /* Return a type that could represent the values between BOUND_ONE and
446 type_for_interval (mpz_t bound_one
, mpz_t bound_two
)
450 enum machine_mode mode
;
452 int precision
= MAX (mpz_sizeinbase (bound_one
, 2),
453 mpz_sizeinbase (bound_two
, 2));
455 if (precision
> BITS_PER_WORD
)
458 return integer_type_node
;
461 if (mpz_cmp (bound_one
, bound_two
) <= 0)
462 unsigned_p
= (mpz_sgn (bound_one
) >= 0);
464 unsigned_p
= (mpz_sgn (bound_two
) >= 0);
466 mode
= smallest_mode_for_size (precision
, MODE_INT
);
467 wider_precision
= GET_MODE_PRECISION (mode
);
469 /* As we want to generate signed types as much as possible, try to
470 fit the interval [bound_one, bound_two] in a signed type. For example,
471 supposing that we have the interval [0, 100], instead of
472 generating unsigned char, we want to generate a signed char. */
473 if (unsigned_p
&& precision
< wider_precision
)
476 type
= build_nonstandard_integer_type (wider_precision
, unsigned_p
);
481 return integer_type_node
;
487 /* Return a type that could represent the integer value VAL, or
488 otherwise return NULL_TREE. */
491 type_for_value (mpz_t val
)
493 return type_for_interval (val
, val
);
496 /* Return the type for the clast_term T. Initializes BOUND_ONE and
497 BOUND_TWO to the bounds of the term. */
500 type_for_clast_term (struct clast_term
*t
, ivs_params_p ip
, mpz_t bound_one
,
503 clast_name_p name
= t
->var
;
506 gcc_assert (t
->expr
.type
== clast_expr_term
);
510 mpz_set (bound_one
, t
->val
);
511 mpz_set (bound_two
, t
->val
);
512 return type_for_value (t
->val
);
515 if (ip
->params
&& ip
->params_index
)
516 found
= clast_name_to_lb_ub (name
, ip
->params_index
, bound_one
, bound_two
);
520 gcc_assert (*(ip
->newivs
) && ip
->newivs_index
);
521 found
= clast_name_to_lb_ub (name
, ip
->newivs_index
,
522 bound_one
, bound_two
);
526 mpz_mul (bound_one
, bound_one
, t
->val
);
527 mpz_mul (bound_two
, bound_two
, t
->val
);
529 return TREE_TYPE (clast_name_to_gcc (name
, ip
));
533 type_for_clast_expr (struct clast_expr
*, ivs_params_p
, mpz_t
, mpz_t
);
535 /* Return the type for the clast_reduction R. Initializes BOUND_ONE
536 and BOUND_TWO to the bounds of the reduction expression. */
539 type_for_clast_red (struct clast_reduction
*r
, ivs_params_p ip
,
540 mpz_t bound_one
, mpz_t bound_two
)
543 tree type
= type_for_clast_expr (r
->elts
[0], ip
, bound_one
, bound_two
);
544 mpz_t b1
, b2
, m1
, m2
;
554 for (i
= 1; i
< r
->n
; i
++)
556 tree t
= type_for_clast_expr (r
->elts
[i
], ip
, b1
, b2
);
557 type
= max_precision_type (type
, t
);
562 value_min (m1
, bound_one
, bound_two
);
563 value_min (m2
, b1
, b2
);
564 mpz_add (bound_one
, m1
, m2
);
566 value_max (m1
, bound_one
, bound_two
);
567 value_max (m2
, b1
, b2
);
568 mpz_add (bound_two
, m1
, m2
);
572 value_min (bound_one
, bound_one
, bound_two
);
573 value_min (bound_two
, b1
, b2
);
577 value_max (bound_one
, bound_one
, bound_two
);
578 value_max (bound_two
, b1
, b2
);
592 /* Return a type that can represent the result of the reduction. */
593 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
596 /* Return the type for the clast_binary B used in STMT. */
599 type_for_clast_bin (struct clast_binary
*b
, ivs_params_p ip
, mpz_t bound_one
,
603 tree l
= type_for_clast_expr ((struct clast_expr
*) b
->LHS
, ip
,
604 bound_one
, bound_two
);
605 tree r
= type_for_value (b
->RHS
);
606 tree type
= max_precision_type (l
, r
);
611 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
612 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
616 mpz_mdiv (bound_one
, bound_one
, b
->RHS
);
617 mpz_mdiv (bound_two
, bound_two
, b
->RHS
);
619 mpz_add (bound_one
, bound_one
, one
);
620 mpz_add (bound_two
, bound_two
, one
);
625 mpz_div (bound_one
, bound_one
, b
->RHS
);
626 mpz_div (bound_two
, bound_two
, b
->RHS
);
630 mpz_mod (bound_one
, bound_one
, b
->RHS
);
631 mpz_mod (bound_two
, bound_two
, b
->RHS
);
638 /* Return a type that can represent the result of the reduction. */
639 return max_precision_type (type
, type_for_interval (bound_one
, bound_two
));
642 /* Returns the type for the CLAST expression E when used in statement
646 type_for_clast_expr (struct clast_expr
*e
, ivs_params_p ip
, mpz_t bound_one
,
651 case clast_expr_term
:
652 return type_for_clast_term ((struct clast_term
*) e
, ip
,
653 bound_one
, bound_two
);
656 return type_for_clast_red ((struct clast_reduction
*) e
, ip
,
657 bound_one
, bound_two
);
660 return type_for_clast_bin ((struct clast_binary
*) e
, ip
,
661 bound_one
, bound_two
);
670 /* Returns the type for the equation CLEQ. */
673 type_for_clast_eq (struct clast_equation
*cleq
, ivs_params_p ip
)
675 mpz_t bound_one
, bound_two
;
678 mpz_init (bound_one
);
679 mpz_init (bound_two
);
681 l
= type_for_clast_expr (cleq
->LHS
, ip
, bound_one
, bound_two
);
682 r
= type_for_clast_expr (cleq
->RHS
, ip
, bound_one
, bound_two
);
684 mpz_clear (bound_one
);
685 mpz_clear (bound_two
);
686 return max_precision_type (l
, r
);
689 /* Translates a clast equation CLEQ to a tree. */
692 graphite_translate_clast_equation (struct clast_equation
*cleq
,
696 tree type
= type_for_clast_eq (cleq
, ip
);
697 tree lhs
= clast_to_gcc_expression (type
, cleq
->LHS
, ip
);
698 tree rhs
= clast_to_gcc_expression (type
, cleq
->RHS
, ip
);
703 else if (cleq
->sign
> 0)
709 return fold_build2 (comp
, boolean_type_node
, lhs
, rhs
);
712 /* Creates the test for the condition in STMT. */
715 graphite_create_guard_cond_expr (struct clast_guard
*stmt
,
721 for (i
= 0; i
< stmt
->n
; i
++)
723 tree eq
= graphite_translate_clast_equation (&stmt
->eq
[i
], ip
);
726 cond
= fold_build2 (TRUTH_AND_EXPR
, TREE_TYPE (eq
), cond
, eq
);
734 /* Creates a new if region corresponding to Cloog's guard. */
737 graphite_create_new_guard (edge entry_edge
, struct clast_guard
*stmt
,
740 tree cond_expr
= graphite_create_guard_cond_expr (stmt
, ip
);
741 edge exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
745 /* Compute the lower bound LOW and upper bound UP for the parameter
746 PARAM in scop SCOP based on the constraints in the context. */
749 compute_bounds_for_param (scop_p scop
, int param
, mpz_t low
, mpz_t up
)
751 ppl_Linear_Expression_t le
;
753 /* Prepare the linear expression corresponding to the parameter that
754 we want to maximize/minimize. */
755 ppl_new_Linear_Expression_with_dimension (&le
, scop_nb_params (scop
));
756 ppl_set_coef (le
, param
, 1);
758 ppl_max_for_le_pointset (SCOP_CONTEXT (scop
), le
, up
);
759 ppl_min_for_le_pointset (SCOP_CONTEXT (scop
), le
, low
);
760 ppl_delete_Linear_Expression (le
);
763 /* Compute the lower bound LOW and upper bound UP for the induction
764 variable at LEVEL for the statement PBB, based on the transformed
765 scattering of PBB: T|I|G|Cst, with T the scattering transform, I
766 the iteration domain, and G the context parameters. */
769 compute_bounds_for_level (poly_bb_p pbb
, int level
, mpz_t low
, mpz_t up
)
771 ppl_Pointset_Powerset_C_Polyhedron_t ps
;
772 ppl_Linear_Expression_t le
;
774 combine_context_id_scat (&ps
, pbb
, false);
776 /* Prepare the linear expression corresponding to the level that we
777 want to maximize/minimize. */
779 ppl_dimension_type dim
= pbb_nb_scattering_transform (pbb
)
780 + pbb_dim_iter_domain (pbb
) + pbb_nb_params (pbb
);
782 ppl_new_Linear_Expression_with_dimension (&le
, dim
);
783 ppl_set_coef (le
, psct_dynamic_dim (pbb
, level
), 1);
786 ppl_max_for_le_pointset (ps
, le
, up
);
787 ppl_min_for_le_pointset (ps
, le
, low
);
788 ppl_delete_Linear_Expression (le
);
789 ppl_delete_Pointset_Powerset_C_Polyhedron (ps
);
792 /* Walks a CLAST and returns the first statement in the body of a
795 FIXME: This function should not be used to get a PBB in the STMT
796 loop in order to find out the iteration domain of the loop: the
797 counter example from Tobias is:
799 | for (i = 0; i < 100; i++)
806 This function would return S1 whose iteration domain contains only
807 one point "i = 0", whereas the iteration domain of S2 has 100 points.
809 This should be implemented using some functionality existing in
812 static struct clast_user_stmt
*
813 clast_get_body_of_loop (struct clast_stmt
*stmt
)
816 || CLAST_STMT_IS_A (stmt
, stmt_user
))
817 return (struct clast_user_stmt
*) stmt
;
819 if (CLAST_STMT_IS_A (stmt
, stmt_for
))
820 return clast_get_body_of_loop (((struct clast_for
*) stmt
)->body
);
822 if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
823 return clast_get_body_of_loop (((struct clast_guard
*) stmt
)->then
);
825 if (CLAST_STMT_IS_A (stmt
, stmt_block
))
826 return clast_get_body_of_loop (((struct clast_block
*) stmt
)->body
);
828 if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
829 return clast_get_body_of_loop (stmt
->next
);
834 /* Returns the type for the induction variable for the loop translated
838 type_for_clast_for (struct clast_for
*stmt_for
, ivs_params_p ip
)
840 mpz_t bound_one
, bound_two
;
841 tree lb_type
, ub_type
;
843 mpz_init (bound_one
);
844 mpz_init (bound_two
);
846 lb_type
= type_for_clast_expr (stmt_for
->LB
, ip
, bound_one
, bound_two
);
847 ub_type
= type_for_clast_expr (stmt_for
->UB
, ip
, bound_one
, bound_two
);
849 mpz_clear (bound_one
);
850 mpz_clear (bound_two
);
852 return max_precision_type (lb_type
, ub_type
);
855 /* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
856 induction variable for the new LOOP. New LOOP is attached to CFG
857 starting at ENTRY_EDGE. LOOP is inserted into the loop tree and
858 becomes the child loop of the OUTER_LOOP. NEWIVS_INDEX binds
859 CLooG's scattering name to the induction variable created for the
860 loop of STMT. The new induction variable is inserted in the NEWIVS
861 vector and is of type TYPE. */
864 graphite_create_new_loop (edge entry_edge
, struct clast_for
*stmt
,
865 loop_p outer
, tree type
, tree lb
, tree ub
,
866 int level
, ivs_params_p ip
)
870 struct clast_user_stmt
*body
871 = clast_get_body_of_loop ((struct clast_stmt
*) stmt
);
872 poly_bb_p pbb
= (poly_bb_p
) cloog_statement_usr (body
->statement
);
874 tree stride
= gmp_cst_to_tree (type
, stmt
->stride
);
875 tree ivvar
= create_tmp_var (type
, "graphite_IV");
876 tree iv
, iv_after_increment
;
877 loop_p loop
= create_empty_loop_on_edge
878 (entry_edge
, lb
, stride
, ub
, ivvar
, &iv
, &iv_after_increment
,
879 outer
? outer
: entry_edge
->src
->loop_father
);
881 add_referenced_var (ivvar
);
885 compute_bounds_for_level (pbb
, level
, low
, up
);
886 save_clast_name_index (ip
->newivs_index
, stmt
->iterator
,
887 VEC_length (tree
, *(ip
->newivs
)), level
, low
, up
);
890 VEC_safe_push (tree
, heap
, *(ip
->newivs
), iv
);
894 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
895 induction variables of the loops around GBB in SESE. */
898 build_iv_mapping (VEC (tree
, heap
) *iv_map
, struct clast_user_stmt
*user_stmt
,
901 struct clast_stmt
*t
;
903 CloogStatement
*cs
= user_stmt
->statement
;
904 poly_bb_p pbb
= (poly_bb_p
) cloog_statement_usr (cs
);
905 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
906 mpz_t bound_one
, bound_two
;
908 mpz_init (bound_one
);
909 mpz_init (bound_two
);
911 for (t
= user_stmt
->substitutions
; t
; t
= t
->next
, depth
++)
913 struct clast_expr
*expr
= (struct clast_expr
*)
914 ((struct clast_assignment
*)t
)->RHS
;
915 tree type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
916 tree new_name
= clast_to_gcc_expression (type
, expr
, ip
);
917 loop_p old_loop
= gbb_loop_at_index (gbb
, ip
->region
, depth
);
919 VEC_replace (tree
, iv_map
, old_loop
->num
, new_name
);
922 mpz_clear (bound_one
);
923 mpz_clear (bound_two
);
926 /* Construct bb_pbb_def with BB and PBB. */
929 new_bb_pbb_def (basic_block bb
, poly_bb_p pbb
)
931 bb_pbb_def
*bb_pbb_p
;
933 bb_pbb_p
= XNEW (bb_pbb_def
);
940 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
943 mark_bb_with_pbb (poly_bb_p pbb
, basic_block bb
, htab_t bb_pbb_mapping
)
949 x
= htab_find_slot (bb_pbb_mapping
, &tmp
, INSERT
);
952 *x
= new_bb_pbb_def (bb
, pbb
);
955 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
958 find_pbb_via_hash (htab_t bb_pbb_mapping
, basic_block bb
)
964 slot
= htab_find_slot (bb_pbb_mapping
, &tmp
, NO_INSERT
);
967 return ((bb_pbb_def
*) *slot
)->pbb
;
972 /* Check data dependency in LOOP at level LEVEL.
973 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
977 dependency_in_loop_p (loop_p loop
, htab_t bb_pbb_mapping
, int level
)
980 basic_block
*bbs
= get_loop_body_in_dom_order (loop
);
982 for (i
= 0; i
< loop
->num_nodes
; i
++)
984 poly_bb_p pbb1
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[i
]);
989 for (j
= 0; j
< loop
->num_nodes
; j
++)
991 poly_bb_p pbb2
= find_pbb_via_hash (bb_pbb_mapping
, bbs
[j
]);
996 if (dependency_between_pbbs_p (pbb1
, pbb2
, level
))
1009 /* Translates a clast user statement STMT to gimple.
1011 - NEXT_E is the edge where new generated code should be attached.
1012 - CONTEXT_LOOP is the loop in which the generated code will be placed
1013 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1016 translate_clast_user (struct clast_user_stmt
*stmt
, edge next_e
,
1017 htab_t bb_pbb_mapping
, ivs_params_p ip
)
1021 poly_bb_p pbb
= (poly_bb_p
) cloog_statement_usr (stmt
->statement
);
1022 gimple_bb_p gbb
= PBB_BLACK_BOX (pbb
);
1023 VEC (tree
, heap
) *iv_map
;
1025 if (GBB_BB (gbb
) == ENTRY_BLOCK_PTR
)
1028 nb_loops
= number_of_loops ();
1029 iv_map
= VEC_alloc (tree
, heap
, nb_loops
);
1030 for (i
= 0; i
< nb_loops
; i
++)
1031 VEC_quick_push (tree
, iv_map
, NULL_TREE
);
1033 build_iv_mapping (iv_map
, stmt
, ip
);
1034 next_e
= copy_bb_and_scalar_dependences (GBB_BB (gbb
), ip
->region
,
1035 next_e
, iv_map
, &gloog_error
);
1036 VEC_free (tree
, heap
, iv_map
);
1038 new_bb
= next_e
->src
;
1039 mark_bb_with_pbb (pbb
, new_bb
, bb_pbb_mapping
);
1040 update_ssa (TODO_update_ssa
);
1045 /* Creates a new if region protecting the loop to be executed, if the execution
1046 count is zero (lb > ub). */
1049 graphite_create_new_loop_guard (edge entry_edge
, struct clast_for
*stmt
,
1050 tree
*type
, tree
*lb
, tree
*ub
,
1056 *type
= type_for_clast_for (stmt
, ip
);
1057 *lb
= clast_to_gcc_expression (*type
, stmt
->LB
, ip
);
1058 *ub
= clast_to_gcc_expression (*type
, stmt
->UB
, ip
);
1060 /* When ub is simply a constant or a parameter, use lb <= ub. */
1061 if (TREE_CODE (*ub
) == INTEGER_CST
|| TREE_CODE (*ub
) == SSA_NAME
)
1062 cond_expr
= fold_build2 (LE_EXPR
, boolean_type_node
, *lb
, *ub
);
1065 tree one
= (POINTER_TYPE_P (*type
)
1066 ? convert_to_ptrofftype (integer_one_node
)
1067 : fold_convert (*type
, integer_one_node
));
1068 /* Adding +1 and using LT_EXPR helps with loop latches that have a
1069 loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
1070 2^k-1 due to integer overflow, and the condition lb <= ub is true,
1071 even if we do not want this. However lb < ub + 1 is false, as
1073 tree ub_one
= fold_build2 (POINTER_TYPE_P (*type
) ? POINTER_PLUS_EXPR
1074 : PLUS_EXPR
, *type
, *ub
, one
);
1076 cond_expr
= fold_build2 (LT_EXPR
, boolean_type_node
, *lb
, ub_one
);
1079 exit_edge
= create_empty_if_region_on_edge (entry_edge
, cond_expr
);
1085 translate_clast (loop_p
, struct clast_stmt
*, edge
, htab_t
, int, ivs_params_p
);
1087 /* Create the loop for a clast for statement.
1089 - NEXT_E is the edge where new generated code should be attached.
1090 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1093 translate_clast_for_loop (loop_p context_loop
, struct clast_for
*stmt
,
1094 edge next_e
, htab_t bb_pbb_mapping
, int level
,
1095 tree type
, tree lb
, tree ub
, ivs_params_p ip
)
1097 struct loop
*loop
= graphite_create_new_loop (next_e
, stmt
, context_loop
,
1098 type
, lb
, ub
, level
, ip
);
1099 edge last_e
= single_exit (loop
);
1100 edge to_body
= single_succ_edge (loop
->header
);
1101 basic_block after
= to_body
->dest
;
1103 /* Create a basic block for loop close phi nodes. */
1104 last_e
= single_succ_edge (split_edge (last_e
));
1106 /* Translate the body of the loop. */
1107 next_e
= translate_clast (loop
, stmt
->body
, to_body
, bb_pbb_mapping
,
1109 redirect_edge_succ_nodup (next_e
, after
);
1110 set_immediate_dominator (CDI_DOMINATORS
, next_e
->dest
, next_e
->src
);
1112 if (flag_loop_parallelize_all
1113 && !dependency_in_loop_p (loop
, bb_pbb_mapping
, level
))
1114 loop
->can_be_parallel
= true;
1119 /* Translates a clast for statement STMT to gimple. First a guard is created
1120 protecting the loop, if it is executed zero times. In this guard we create
1121 the real loop structure.
1123 - NEXT_E is the edge where new generated code should be attached.
1124 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1127 translate_clast_for (loop_p context_loop
, struct clast_for
*stmt
, edge next_e
,
1128 htab_t bb_pbb_mapping
, int level
, ivs_params_p ip
)
1131 edge last_e
= graphite_create_new_loop_guard (next_e
, stmt
, &type
,
1133 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1135 translate_clast_for_loop (context_loop
, stmt
, true_e
, bb_pbb_mapping
, level
,
1140 /* Translates a clast assignment STMT to gimple.
1142 - NEXT_E is the edge where new generated code should be attached.
1143 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1146 translate_clast_assignment (struct clast_assignment
*stmt
, edge next_e
,
1147 int level
, ivs_params_p ip
)
1150 mpz_t bound_one
, bound_two
;
1151 tree type
, new_name
, var
;
1152 edge res
= single_succ_edge (split_edge (next_e
));
1153 struct clast_expr
*expr
= (struct clast_expr
*) stmt
->RHS
;
1155 mpz_init (bound_one
);
1156 mpz_init (bound_two
);
1157 type
= type_for_clast_expr (expr
, ip
, bound_one
, bound_two
);
1158 var
= create_tmp_var (type
, "graphite_var");
1159 new_name
= force_gimple_operand (clast_to_gcc_expression (type
, expr
, ip
),
1161 add_referenced_var (var
);
1164 gsi_insert_seq_on_edge (next_e
, stmts
);
1165 gsi_commit_edge_inserts ();
1168 save_clast_name_index (ip
->newivs_index
, stmt
->LHS
,
1169 VEC_length (tree
, *(ip
->newivs
)), level
,
1170 bound_one
, bound_two
);
1171 VEC_safe_push (tree
, heap
, *(ip
->newivs
), new_name
);
1173 mpz_clear (bound_one
);
1174 mpz_clear (bound_two
);
1179 /* Translates a clast guard statement STMT to gimple.
1181 - NEXT_E is the edge where new generated code should be attached.
1182 - CONTEXT_LOOP is the loop in which the generated code will be placed
1183 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1186 translate_clast_guard (loop_p context_loop
, struct clast_guard
*stmt
,
1187 edge next_e
, htab_t bb_pbb_mapping
, int level
,
1190 edge last_e
= graphite_create_new_guard (next_e
, stmt
, ip
);
1191 edge true_e
= get_true_edge_from_guard_bb (next_e
->dest
);
1193 translate_clast (context_loop
, stmt
->then
, true_e
, bb_pbb_mapping
, level
, ip
);
1197 /* Translates a CLAST statement STMT to GCC representation in the
1200 - NEXT_E is the edge where new generated code should be attached.
1201 - CONTEXT_LOOP is the loop in which the generated code will be placed
1202 - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping. */
1205 translate_clast (loop_p context_loop
, struct clast_stmt
*stmt
, edge next_e
,
1206 htab_t bb_pbb_mapping
, int level
, ivs_params_p ip
)
1211 if (CLAST_STMT_IS_A (stmt
, stmt_root
))
1214 else if (CLAST_STMT_IS_A (stmt
, stmt_user
))
1215 next_e
= translate_clast_user ((struct clast_user_stmt
*) stmt
,
1216 next_e
, bb_pbb_mapping
, ip
);
1218 else if (CLAST_STMT_IS_A (stmt
, stmt_for
))
1219 next_e
= translate_clast_for (context_loop
, (struct clast_for
*) stmt
,
1220 next_e
, bb_pbb_mapping
, level
, ip
);
1222 else if (CLAST_STMT_IS_A (stmt
, stmt_guard
))
1223 next_e
= translate_clast_guard (context_loop
, (struct clast_guard
*) stmt
,
1224 next_e
, bb_pbb_mapping
, level
, ip
);
1226 else if (CLAST_STMT_IS_A (stmt
, stmt_block
))
1227 next_e
= translate_clast (context_loop
, ((struct clast_block
*) stmt
)->body
,
1228 next_e
, bb_pbb_mapping
, level
, ip
);
1230 else if (CLAST_STMT_IS_A (stmt
, stmt_ass
))
1231 next_e
= translate_clast_assignment ((struct clast_assignment
*) stmt
,
1236 recompute_all_dominators ();
1239 return translate_clast (context_loop
, stmt
->next
, next_e
, bb_pbb_mapping
,
1243 /* Free the SCATTERING domain list. */
1246 free_scattering (CloogScatteringList
*scattering
)
1250 CloogScattering
*dom
= cloog_scattering (scattering
);
1251 CloogScatteringList
*next
= cloog_next_scattering (scattering
);
1253 cloog_scattering_free (dom
);
1259 /* Initialize Cloog's parameter names from the names used in GIMPLE.
1260 Initialize Cloog's iterator names, using 'graphite_iterator_%d'
1261 from 0 to scop_nb_loops (scop). */
1264 initialize_cloog_names (scop_p scop
, CloogProgram
*prog
)
1266 sese region
= SCOP_REGION (scop
);
1268 int nb_iterators
= scop_max_loop_depth (scop
);
1269 int nb_scattering
= cloog_program_nb_scattdims (prog
);
1270 int nb_parameters
= VEC_length (tree
, SESE_PARAMS (region
));
1271 char **iterators
= XNEWVEC (char *, nb_iterators
* 2);
1272 char **scattering
= XNEWVEC (char *, nb_scattering
);
1273 char **parameters
= XNEWVEC (char *, nb_parameters
);
1275 cloog_program_set_names (prog
, cloog_names_malloc ());
1277 for (i
= 0; i
< nb_parameters
; i
++)
1279 tree param
= VEC_index (tree
, SESE_PARAMS (region
), i
);
1280 const char *name
= get_name (param
);
1286 len
= strlen (name
);
1288 parameters
[i
] = XNEWVEC (char, len
+ 1);
1289 snprintf (parameters
[i
], len
, "%s_%d", name
, SSA_NAME_VERSION (param
));
1292 cloog_names_set_nb_parameters (cloog_program_names (prog
), nb_parameters
);
1293 cloog_names_set_parameters (cloog_program_names (prog
), parameters
);
1295 for (i
= 0; i
< nb_iterators
; i
++)
1298 iterators
[i
] = XNEWVEC (char, len
);
1299 snprintf (iterators
[i
], len
, "git_%d", i
);
1302 cloog_names_set_nb_iterators (cloog_program_names (prog
),
1304 cloog_names_set_iterators (cloog_program_names (prog
),
1307 for (i
= 0; i
< nb_scattering
; i
++)
1310 scattering
[i
] = XNEWVEC (char, len
);
1311 snprintf (scattering
[i
], len
, "scat_%d", i
);
1314 cloog_names_set_nb_scattering (cloog_program_names (prog
),
1316 cloog_names_set_scattering (cloog_program_names (prog
),
1320 /* Initialize a CLooG input file. */
1323 init_cloog_input_file (int scop_number
)
1325 FILE *graphite_out_file
;
1326 int len
= strlen (dump_base_name
);
1327 char *dumpname
= XNEWVEC (char, len
+ 25);
1328 char *s_scop_number
= XNEWVEC (char, 15);
1330 memcpy (dumpname
, dump_base_name
, len
+ 1);
1331 strip_off_ending (dumpname
, len
);
1332 sprintf (s_scop_number
, ".%d", scop_number
);
1333 strcat (dumpname
, s_scop_number
);
1334 strcat (dumpname
, ".cloog");
1335 graphite_out_file
= fopen (dumpname
, "w+b");
1337 if (graphite_out_file
== 0)
1338 fatal_error ("can%'t open %s for writing: %m", dumpname
);
1342 return graphite_out_file
;
1345 /* Build cloog program for SCoP. */
1348 build_cloog_prog (scop_p scop
, CloogProgram
*prog
,
1349 CloogOptions
*options
)
1352 int max_nb_loops
= scop_max_loop_depth (scop
);
1354 CloogLoop
*loop_list
= NULL
;
1355 CloogBlockList
*block_list
= NULL
;
1356 CloogScatteringList
*scattering
= NULL
;
1357 int nbs
= 2 * max_nb_loops
+ 1;
1360 cloog_program_set_context
1361 (prog
, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop
),
1362 scop_nb_params (scop
), cloog_state
));
1363 nbs
= unify_scattering_dimensions (scop
);
1364 scaldims
= (int *) xmalloc (nbs
* (sizeof (int)));
1365 cloog_program_set_nb_scattdims (prog
, nbs
);
1366 initialize_cloog_names (scop
, prog
);
1368 FOR_EACH_VEC_ELT (poly_bb_p
, SCOP_BBS (scop
), i
, pbb
)
1370 CloogStatement
*stmt
;
1374 /* Dead code elimination: when the domain of a PBB is empty,
1375 don't generate code for the PBB. */
1376 if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb
)))
1379 /* Build the new statement and its block. */
1380 stmt
= cloog_statement_alloc (cloog_state
, pbb_index (pbb
));
1381 dom
= new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb
),
1382 scop_nb_params (scop
),
1384 block
= cloog_block_alloc (stmt
, 0, NULL
, pbb_dim_iter_domain (pbb
));
1385 cloog_statement_set_usr (stmt
, pbb
);
1387 /* Build loop list. */
1389 CloogLoop
*new_loop_list
= cloog_loop_malloc (cloog_state
);
1390 cloog_loop_set_next (new_loop_list
, loop_list
);
1391 cloog_loop_set_domain (new_loop_list
, dom
);
1392 cloog_loop_set_block (new_loop_list
, block
);
1393 loop_list
= new_loop_list
;
1396 /* Build block list. */
1398 CloogBlockList
*new_block_list
= cloog_block_list_malloc ();
1400 cloog_block_list_set_next (new_block_list
, block_list
);
1401 cloog_block_list_set_block (new_block_list
, block
);
1402 block_list
= new_block_list
;
1405 /* Build scattering list. */
1407 /* XXX: Replace with cloog_domain_list_alloc(), when available. */
1408 CloogScatteringList
*new_scattering
1409 = (CloogScatteringList
*) xmalloc (sizeof (CloogScatteringList
));
1410 ppl_Polyhedron_t scat
;
1411 CloogScattering
*dom
;
1413 scat
= PBB_TRANSFORMED_SCATTERING (pbb
);
1414 dom
= new_Cloog_Scattering_from_ppl_Polyhedron
1415 (scat
, scop_nb_params (scop
), pbb_nb_scattering_transform (pbb
),
1418 cloog_set_next_scattering (new_scattering
, scattering
);
1419 cloog_set_scattering (new_scattering
, dom
);
1420 scattering
= new_scattering
;
1424 cloog_program_set_loop (prog
, loop_list
);
1425 cloog_program_set_blocklist (prog
, block_list
);
1427 for (i
= 0; i
< nbs
; i
++)
1430 cloog_program_set_scaldims (prog
, scaldims
);
1432 /* Extract scalar dimensions to simplify the code generation problem. */
1433 cloog_program_extract_scalars (prog
, scattering
, options
);
1435 /* Dump a .cloog input file, if requested. This feature is only
1436 enabled in the Graphite branch. */
1439 static size_t file_scop_number
= 0;
1440 FILE *cloog_file
= init_cloog_input_file (file_scop_number
);
1442 cloog_program_dump_cloog (cloog_file
, prog
, scattering
);
1446 /* Apply scattering. */
1447 cloog_program_scatter (prog
, scattering
, options
);
1448 free_scattering (scattering
);
1450 /* Iterators corresponding to scalar dimensions have to be extracted. */
1451 cloog_names_scalarize (cloog_program_names (prog
), nbs
,
1452 cloog_program_scaldims (prog
));
1454 /* Free blocklist. */
1456 CloogBlockList
*next
= cloog_program_blocklist (prog
);
1460 CloogBlockList
*toDelete
= next
;
1461 next
= cloog_block_list_next (next
);
1462 cloog_block_list_set_next (toDelete
, NULL
);
1463 cloog_block_list_set_block (toDelete
, NULL
);
1464 cloog_block_list_free (toDelete
);
1466 cloog_program_set_blocklist (prog
, NULL
);
1470 /* Return the options that will be used in GLOOG. */
1472 static CloogOptions
*
1473 set_cloog_options (void)
1475 CloogOptions
*options
= cloog_options_malloc (cloog_state
);
1477 /* Change cloog output language to C. If we do use FORTRAN instead, cloog
1478 will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1479 we pass an incomplete program to cloog. */
1480 options
->language
= CLOOG_LANGUAGE_C
;
1482 /* Enable complex equality spreading: removes dummy statements
1483 (assignments) in the generated code which repeats the
1484 substitution equations for statements. This is useless for
1489 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1492 /* Enable C pretty-printing mode: normalizes the substitution
1493 equations for statements. */
1497 /* Allow cloog to build strides with a stride width different to one.
1498 This example has stride = 4:
1500 for (i = 0; i < 20; i += 4)
1502 options
->strides
= 1;
1504 /* Disable optimizations and make cloog generate source code closer to the
1505 input. This is useful for debugging, but later we want the optimized
1508 XXX: We can not disable optimizations, as loop blocking is not working
1513 options
->l
= INT_MAX
;
1519 /* Prints STMT to STDERR. */
1522 print_clast_stmt (FILE *file
, struct clast_stmt
*stmt
)
1524 CloogOptions
*options
= set_cloog_options ();
1526 clast_pprint (file
, stmt
, 0, options
);
1527 cloog_options_free (options
);
1530 /* Prints STMT to STDERR. */
1533 debug_clast_stmt (struct clast_stmt
*stmt
)
1535 print_clast_stmt (stderr
, stmt
);
1538 /* Translate SCOP to a CLooG program and clast. These two
1539 representations should be freed together: a clast cannot be used
1540 without a program. */
1543 scop_to_clast (scop_p scop
)
1545 CloogOptions
*options
= set_cloog_options ();
1546 cloog_prog_clast pc
;
1548 /* Connect new cloog prog generation to graphite. */
1549 pc
.prog
= cloog_program_malloc ();
1550 build_cloog_prog (scop
, pc
.prog
, options
);
1551 pc
.prog
= cloog_program_generate (pc
.prog
, options
);
1552 pc
.stmt
= cloog_clast_create (pc
.prog
, options
);
1554 cloog_options_free (options
);
1558 /* Prints to FILE the code generated by CLooG for SCOP. */
1561 print_generated_program (FILE *file
, scop_p scop
)
1563 CloogOptions
*options
= set_cloog_options ();
1565 cloog_prog_clast pc
= scop_to_clast (scop
);
1567 fprintf (file
, " (prog: \n");
1568 cloog_program_print (file
, pc
.prog
);
1569 fprintf (file
, " )\n");
1571 fprintf (file
, " (clast: \n");
1572 clast_pprint (file
, pc
.stmt
, 0, options
);
1573 fprintf (file
, " )\n");
1575 cloog_options_free (options
);
1576 cloog_clast_free (pc
.stmt
);
1577 cloog_program_free (pc
.prog
);
1580 /* Prints to STDERR the code generated by CLooG for SCOP. */
1583 debug_generated_program (scop_p scop
)
1585 print_generated_program (stderr
, scop
);
1588 /* Add CLooG names to parameter index. The index is used to translate
1589 back from CLooG names to GCC trees. */
1592 create_params_index (scop_p scop
, htab_t index_table
, CloogProgram
*prog
) {
1593 CloogNames
* names
= cloog_program_names (prog
);
1594 int nb_parameters
= cloog_names_nb_parameters (names
);
1595 char **parameters
= cloog_names_parameters (names
);
1597 mpz_t bound_one
, bound_two
;
1599 mpz_init (bound_one
);
1600 mpz_init (bound_two
);
1602 for (i
= 0; i
< nb_parameters
; i
++)
1604 compute_bounds_for_param (scop
, i
, bound_one
, bound_two
);
1605 save_clast_name_index (index_table
, parameters
[i
], i
, i
,
1606 bound_one
, bound_two
);
1609 mpz_clear (bound_one
);
1610 mpz_clear (bound_two
);
1613 /* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1614 the given SCOP. Return true if code generation succeeded.
1615 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1619 gloog (scop_p scop
, htab_t bb_pbb_mapping
)
1621 VEC (tree
, heap
) *newivs
= VEC_alloc (tree
, heap
, 10);
1622 loop_p context_loop
;
1623 sese region
= SCOP_REGION (scop
);
1624 ifsese if_region
= NULL
;
1625 htab_t newivs_index
, params_index
;
1626 cloog_prog_clast pc
;
1627 struct ivs_params ip
;
1629 timevar_push (TV_GRAPHITE_CODE_GEN
);
1630 gloog_error
= false;
1632 pc
= scop_to_clast (scop
);
1634 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1636 fprintf (dump_file
, "\nCLAST generated by CLooG: \n");
1637 print_clast_stmt (dump_file
, pc
.stmt
);
1638 fprintf (dump_file
, "\n");
1641 recompute_all_dominators ();
1644 if_region
= move_sese_in_condition (region
);
1645 sese_insert_phis_for_liveouts (region
,
1646 if_region
->region
->exit
->src
,
1647 if_region
->false_region
->exit
,
1648 if_region
->true_region
->exit
);
1649 recompute_all_dominators ();
1652 context_loop
= SESE_ENTRY (region
)->src
->loop_father
;
1653 newivs_index
= htab_create (10, clast_name_index_elt_info
,
1654 eq_clast_name_indexes
, free_clast_name_index
);
1655 params_index
= htab_create (10, clast_name_index_elt_info
,
1656 eq_clast_name_indexes
, free_clast_name_index
);
1658 create_params_index (scop
, params_index
, pc
.prog
);
1660 ip
.newivs
= &newivs
;
1661 ip
.newivs_index
= newivs_index
;
1662 ip
.params
= SESE_PARAMS (region
);
1663 ip
.params_index
= params_index
;
1666 translate_clast (context_loop
, pc
.stmt
, if_region
->true_region
->entry
,
1667 bb_pbb_mapping
, 0, &ip
);
1670 recompute_all_dominators ();
1674 set_ifsese_condition (if_region
, integer_zero_node
);
1676 free (if_region
->true_region
);
1677 free (if_region
->region
);
1680 htab_delete (newivs_index
);
1681 htab_delete (params_index
);
1682 VEC_free (tree
, heap
, newivs
);
1683 cloog_clast_free (pc
.stmt
);
1684 cloog_program_free (pc
.prog
);
1685 timevar_pop (TV_GRAPHITE_CODE_GEN
);
1687 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1691 int num_no_dependency
= 0;
1693 FOR_EACH_LOOP (li
, loop
, 0)
1694 if (loop
->can_be_parallel
)
1695 num_no_dependency
++;
1697 fprintf (dump_file
, "\n%d loops carried no dependency.\n",
1701 return !gloog_error
;