* src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64
[official-gcc.git] / gcc / graphite-clast-to-gimple.c
blob6b6969be1e0f85b14c65e9daa3fd69a95c1621bd
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)
10 any later version.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "diagnostic-core.h"
25 #include "tree-flow.h"
26 #include "tree-dump.h"
27 #include "cfgloop.h"
28 #include "tree-chrec.h"
29 #include "tree-data-ref.h"
30 #include "tree-scalar-evolution.h"
31 #include "sese.h"
33 #ifdef HAVE_cloog
34 #include "cloog/cloog.h"
35 #include "ppl_c.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
45 #endif
47 /* This flag is set when an error occurred during the translation of
48 CLAST to Gimple. */
49 static bool gloog_error;
51 /* Verifies properties that GRAPHITE should maintain during translation. */
53 static inline void
54 graphite_verify (void)
56 #ifdef ENABLE_CHECKING
57 verify_loop_structure ();
58 verify_loop_closed_ssa (true);
59 #endif
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 {
67 int index;
68 int level;
69 mpz_t bound_one, bound_two;
70 const char *name;
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);
82 res->name = name;
83 res->level = level;
84 res->index = 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);
89 return res;
92 /* Free the memory taken by a clast_name_index struct. */
94 static void
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);
100 free (ptr);
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. */
108 static inline int
109 clast_name_to_level (clast_name_p name, htab_t index_table)
111 struct clast_name_index tmp;
112 PTR *slot;
114 #ifdef CLOOG_ORG
115 gcc_assert (name->type == clast_expr_name);
116 tmp.name = ((const struct clast_name *) name)->name;
117 #else
118 tmp.name = name;
119 #endif
121 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
123 if (slot && *slot)
124 return ((struct clast_name_index *) *slot)->level;
126 return -1;
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. */
133 static inline int
134 clast_name_to_index (clast_name_p name, htab_t index_table)
136 struct clast_name_index tmp;
137 PTR *slot;
139 #ifdef CLOOG_ORG
140 gcc_assert (name->type == clast_expr_name);
141 tmp.name = ((const struct clast_name *) name)->name;
142 #else
143 tmp.name = name;
144 #endif
146 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
148 if (slot && *slot)
149 return ((struct clast_name_index *) *slot)->index;
151 return -1;
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. */
158 static inline bool
159 clast_name_to_lb_ub (clast_name_p name, htab_t index_table, mpz_t bound_one,
160 mpz_t bound_two)
162 struct clast_name_index tmp;
163 PTR *slot;
165 #ifdef CLOOG_ORG
166 gcc_assert (name->type == clast_expr_name);
167 tmp.name = ((const struct clast_name *) name)->name;
168 #else
169 tmp.name = name;
170 #endif
172 slot = htab_find_slot (index_table, &tmp, NO_INSERT);
174 if (slot && *slot)
176 mpz_set (bound_one, ((struct clast_name_index *) *slot)->bound_one);
177 mpz_set (bound_two, ((struct clast_name_index *) *slot)->bound_two);
178 return true;
181 return false;
184 /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
186 static inline void
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;
191 PTR *slot;
193 tmp.name = name;
194 slot = htab_find_slot (index_table, &tmp, INSERT);
196 if (slot)
198 free (*slot);
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. */
214 static inline int
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;
234 sese region;
235 } *ivs_params_p;
237 /* Returns the tree variable from the name NAME that was given in
238 Cloog representation. */
240 static tree
241 clast_name_to_gcc (clast_name_p name, ivs_params_p ip)
243 int index;
245 if (ip->params && ip->params_index)
247 index = clast_name_to_index (name, ip->params_index);
249 if (index >= 0)
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. */
262 static tree
263 max_precision_type (tree type1, tree type2)
265 enum machine_mode mode;
266 int p1, p2, precision;
267 tree type;
269 if (POINTER_TYPE_P (type1))
270 return type1;
272 if (POINTER_TYPE_P (type2))
273 return 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);
282 if (p1 > p2)
283 precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
284 else
285 precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
287 if (precision > BITS_PER_WORD)
289 gloog_error = true;
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);
297 if (!type)
299 gloog_error = true;
300 return integer_type_node;
303 return type;
306 static tree
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. */
312 static tree
313 clast_to_gcc_expression_red (tree type, enum tree_code op,
314 struct clast_reduction *r, ivs_params_p ip)
316 int i;
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);
326 return res;
329 /* Converts a Cloog AST expression E back to a GCC expression tree of
330 type TYPE. */
332 static tree
333 clast_to_gcc_expression (tree type, struct clast_expr *e, ivs_params_p ip)
335 switch (e->type)
337 case clast_expr_term:
339 struct clast_term *t = (struct clast_term *) e;
341 if (t->var)
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);
351 return 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);
365 else
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);
378 gloog_error = true;
379 return cst;
382 else
383 return gmp_cst_to_tree (type, t->val);
386 case clast_expr_red:
388 struct clast_reduction *r = (struct clast_reduction *) e;
390 switch (r->type)
392 case clast_red_sum:
393 return clast_to_gcc_expression_red
394 (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
395 r, ip);
397 case clast_red_min:
398 return clast_to_gcc_expression_red (type, MIN_EXPR, r, ip);
400 case clast_red_max:
401 return clast_to_gcc_expression_red (type, MAX_EXPR, r, ip);
403 default:
404 gcc_unreachable ();
406 break;
409 case clast_expr_bin:
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);
416 switch (b->type)
418 case clast_bin_fdiv:
419 return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
421 case clast_bin_cdiv:
422 return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
424 case clast_bin_div:
425 return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
427 case clast_bin_mod:
428 return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
430 default:
431 gcc_unreachable ();
435 default:
436 gcc_unreachable ();
439 return NULL_TREE;
442 /* Return a type that could represent the values between BOUND_ONE and
443 BOUND_TWO. */
445 static tree
446 type_for_interval (mpz_t bound_one, mpz_t bound_two)
448 bool unsigned_p;
449 tree type;
450 enum machine_mode mode;
451 int wider_precision;
452 int precision = MAX (mpz_sizeinbase (bound_one, 2),
453 mpz_sizeinbase (bound_two, 2));
455 if (precision > BITS_PER_WORD)
457 gloog_error = true;
458 return integer_type_node;
461 if (mpz_cmp (bound_one, bound_two) <= 0)
462 unsigned_p = (mpz_sgn (bound_one) >= 0);
463 else
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)
474 unsigned_p = false;
476 type = build_nonstandard_integer_type (wider_precision, unsigned_p);
478 if (!type)
480 gloog_error = true;
481 return integer_type_node;
484 return type;
487 /* Return a type that could represent the integer value VAL, or
488 otherwise return NULL_TREE. */
490 static 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. */
499 static tree
500 type_for_clast_term (struct clast_term *t, ivs_params_p ip, mpz_t bound_one,
501 mpz_t bound_two)
503 clast_name_p name = t->var;
504 bool found = false;
506 gcc_assert (t->expr.type == clast_expr_term);
508 if (!name)
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);
518 if (!found)
520 gcc_assert (*(ip->newivs) && ip->newivs_index);
521 found = clast_name_to_lb_ub (name, ip->newivs_index,
522 bound_one, bound_two);
523 gcc_assert (found);
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));
532 static tree
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. */
538 static tree
539 type_for_clast_red (struct clast_reduction *r, ivs_params_p ip,
540 mpz_t bound_one, mpz_t bound_two)
542 int i;
543 tree type = type_for_clast_expr (r->elts[0], ip, bound_one, bound_two);
544 mpz_t b1, b2, m1, m2;
546 if (r->n == 1)
547 return type;
549 mpz_init (b1);
550 mpz_init (b2);
551 mpz_init (m1);
552 mpz_init (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);
559 switch (r->type)
561 case clast_red_sum:
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);
569 break;
571 case clast_red_min:
572 value_min (bound_one, bound_one, bound_two);
573 value_min (bound_two, b1, b2);
574 break;
576 case clast_red_max:
577 value_max (bound_one, bound_one, bound_two);
578 value_max (bound_two, b1, b2);
579 break;
581 default:
582 gcc_unreachable ();
583 break;
587 mpz_clear (b1);
588 mpz_clear (b2);
589 mpz_clear (m1);
590 mpz_clear (m2);
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. */
598 static tree
599 type_for_clast_bin (struct clast_binary *b, ivs_params_p ip, mpz_t bound_one,
600 mpz_t bound_two)
602 mpz_t 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);
608 switch (b->type)
610 case clast_bin_fdiv:
611 mpz_mdiv (bound_one, bound_one, b->RHS);
612 mpz_mdiv (bound_two, bound_two, b->RHS);
613 break;
615 case clast_bin_cdiv:
616 mpz_mdiv (bound_one, bound_one, b->RHS);
617 mpz_mdiv (bound_two, bound_two, b->RHS);
618 mpz_init (one);
619 mpz_add (bound_one, bound_one, one);
620 mpz_add (bound_two, bound_two, one);
621 mpz_clear (one);
622 break;
624 case clast_bin_div:
625 mpz_div (bound_one, bound_one, b->RHS);
626 mpz_div (bound_two, bound_two, b->RHS);
627 break;
629 case clast_bin_mod:
630 mpz_mod (bound_one, bound_one, b->RHS);
631 mpz_mod (bound_two, bound_two, b->RHS);
632 break;
634 default:
635 gcc_unreachable ();
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
643 STMT. */
645 static tree
646 type_for_clast_expr (struct clast_expr *e, ivs_params_p ip, mpz_t bound_one,
647 mpz_t bound_two)
649 switch (e->type)
651 case clast_expr_term:
652 return type_for_clast_term ((struct clast_term *) e, ip,
653 bound_one, bound_two);
655 case clast_expr_red:
656 return type_for_clast_red ((struct clast_reduction *) e, ip,
657 bound_one, bound_two);
659 case clast_expr_bin:
660 return type_for_clast_bin ((struct clast_binary *) e, ip,
661 bound_one, bound_two);
663 default:
664 gcc_unreachable ();
667 return NULL_TREE;
670 /* Returns the type for the equation CLEQ. */
672 static tree
673 type_for_clast_eq (struct clast_equation *cleq, ivs_params_p ip)
675 mpz_t bound_one, bound_two;
676 tree l, r;
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. */
691 static tree
692 graphite_translate_clast_equation (struct clast_equation *cleq,
693 ivs_params_p ip)
695 enum tree_code comp;
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);
700 if (cleq->sign == 0)
701 comp = EQ_EXPR;
703 else if (cleq->sign > 0)
704 comp = GE_EXPR;
706 else
707 comp = LE_EXPR;
709 return fold_build2 (comp, boolean_type_node, lhs, rhs);
712 /* Creates the test for the condition in STMT. */
714 static tree
715 graphite_create_guard_cond_expr (struct clast_guard *stmt,
716 ivs_params_p ip)
718 tree cond = NULL;
719 int i;
721 for (i = 0; i < stmt->n; i++)
723 tree eq = graphite_translate_clast_equation (&stmt->eq[i], ip);
725 if (cond)
726 cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
727 else
728 cond = eq;
731 return cond;
734 /* Creates a new if region corresponding to Cloog's guard. */
736 static edge
737 graphite_create_new_guard (edge entry_edge, struct clast_guard *stmt,
738 ivs_params_p ip)
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);
742 return exit_edge;
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. */
748 static void
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. */
768 static void
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
793 loop.
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++)
801 | if (i == 0)
802 | S1;
803 | S2;
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
810 CLooG-ISL. */
812 static struct clast_user_stmt *
813 clast_get_body_of_loop (struct clast_stmt *stmt)
815 if (!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);
831 gcc_unreachable ();
834 /* Returns the type for the induction variable for the loop translated
835 from STMT_FOR. */
837 static tree
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. */
863 static struct loop *
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)
868 mpz_t low, up;
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);
883 mpz_init (low);
884 mpz_init (up);
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);
888 mpz_clear (low);
889 mpz_clear (up);
890 VEC_safe_push (tree, heap, *(ip->newivs), iv);
891 return loop;
894 /* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
895 induction variables of the loops around GBB in SESE. */
897 static void
898 build_iv_mapping (VEC (tree, heap) *iv_map, struct clast_user_stmt *user_stmt,
899 ivs_params_p ip)
901 struct clast_stmt *t;
902 int depth = 0;
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. */
928 static bb_pbb_def *
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);
934 bb_pbb_p->bb = bb;
935 bb_pbb_p->pbb = pbb;
937 return bb_pbb_p;
940 /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
942 static void
943 mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
945 bb_pbb_def tmp;
946 PTR *x;
948 tmp.bb = bb;
949 x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
951 if (x && !*x)
952 *x = new_bb_pbb_def (bb, pbb);
955 /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
957 static poly_bb_p
958 find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
960 bb_pbb_def tmp;
961 PTR *slot;
963 tmp.bb = bb;
964 slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
966 if (slot && *slot)
967 return ((bb_pbb_def *) *slot)->pbb;
969 return NULL;
972 /* Check data dependency in LOOP at level LEVEL.
973 BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
974 mapping. */
976 static bool
977 dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping, int level)
979 unsigned i,j;
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]);
986 if (pbb1 == NULL)
987 continue;
989 for (j = 0; j < loop->num_nodes; j++)
991 poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]);
993 if (pbb2 == NULL)
994 continue;
996 if (dependency_between_pbbs_p (pbb1, pbb2, level))
998 free (bbs);
999 return true;
1004 free (bbs);
1006 return false;
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. */
1015 static edge
1016 translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
1017 htab_t bb_pbb_mapping, ivs_params_p ip)
1019 int i, nb_loops;
1020 basic_block new_bb;
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)
1026 return next_e;
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);
1042 return next_e;
1045 /* Creates a new if region protecting the loop to be executed, if the execution
1046 count is zero (lb > ub). */
1048 static edge
1049 graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
1050 tree *type, tree *lb, tree *ub,
1051 ivs_params_p ip)
1053 tree cond_expr;
1054 edge exit_edge;
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);
1063 else
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
1072 expected. */
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);
1081 return exit_edge;
1084 static edge
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. */
1092 static edge
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,
1108 level + 1, ip);
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;
1116 return last_e;
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. */
1126 static edge
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)
1130 tree type, lb, ub;
1131 edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
1132 &lb, &ub, ip);
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,
1136 type, lb, ub, ip);
1137 return last_e;
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. */
1145 static edge
1146 translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
1147 int level, ivs_params_p ip)
1149 gimple_seq stmts;
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),
1160 &stmts, true, var);
1161 add_referenced_var (var);
1162 if (stmts)
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);
1176 return res;
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. */
1185 static edge
1186 translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
1187 edge next_e, htab_t bb_pbb_mapping, int level,
1188 ivs_params_p ip)
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);
1194 return last_e;
1197 /* Translates a CLAST statement STMT to GCC representation in the
1198 context of a SESE.
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. */
1204 static edge
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)
1208 if (!stmt)
1209 return next_e;
1211 if (CLAST_STMT_IS_A (stmt, stmt_root))
1212 ; /* Do nothing. */
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,
1232 next_e, level, ip);
1233 else
1234 gcc_unreachable();
1236 recompute_all_dominators ();
1237 graphite_verify ();
1239 return translate_clast (context_loop, stmt->next, next_e, bb_pbb_mapping,
1240 level, ip);
1243 /* Free the SCATTERING domain list. */
1245 static void
1246 free_scattering (CloogScatteringList *scattering)
1248 while (scattering)
1250 CloogScattering *dom = cloog_scattering (scattering);
1251 CloogScatteringList *next = cloog_next_scattering (scattering);
1253 cloog_scattering_free (dom);
1254 free (scattering);
1255 scattering = next;
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). */
1263 static void
1264 initialize_cloog_names (scop_p scop, CloogProgram *prog)
1266 sese region = SCOP_REGION (scop);
1267 int i;
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);
1281 int len;
1283 if (!name)
1284 name = "T";
1286 len = strlen (name);
1287 len += 17;
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++)
1297 int len = 4 + 16;
1298 iterators[i] = XNEWVEC (char, len);
1299 snprintf (iterators[i], len, "git_%d", i);
1302 cloog_names_set_nb_iterators (cloog_program_names (prog),
1303 nb_iterators);
1304 cloog_names_set_iterators (cloog_program_names (prog),
1305 iterators);
1307 for (i = 0; i < nb_scattering; i++)
1309 int len = 5 + 16;
1310 scattering[i] = XNEWVEC (char, len);
1311 snprintf (scattering[i], len, "scat_%d", i);
1314 cloog_names_set_nb_scattering (cloog_program_names (prog),
1315 nb_scattering);
1316 cloog_names_set_scattering (cloog_program_names (prog),
1317 scattering);
1320 /* Initialize a CLooG input file. */
1322 static 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);
1340 free (dumpname);
1342 return graphite_out_file;
1345 /* Build cloog program for SCoP. */
1347 static void
1348 build_cloog_prog (scop_p scop, CloogProgram *prog,
1349 CloogOptions *options)
1351 int i;
1352 int max_nb_loops = scop_max_loop_depth (scop);
1353 poly_bb_p pbb;
1354 CloogLoop *loop_list = NULL;
1355 CloogBlockList *block_list = NULL;
1356 CloogScatteringList *scattering = NULL;
1357 int nbs = 2 * max_nb_loops + 1;
1358 int *scaldims;
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;
1371 CloogBlock *block;
1372 CloogDomain *dom;
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)))
1377 continue;
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),
1383 cloog_state);
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),
1416 cloog_state);
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++)
1428 scaldims[i] = 0 ;
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. */
1437 if (0)
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);
1443 ++file_scop_number;
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);
1458 while (next)
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
1485 GLooG. */
1486 options->esp = 1;
1488 #ifdef CLOOG_ORG
1489 /* Silence CLooG to avoid failing tests due to debug output to stderr. */
1490 options->quiet = 1;
1491 #else
1492 /* Enable C pretty-printing mode: normalizes the substitution
1493 equations for statements. */
1494 options->cpp = 1;
1495 #endif
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)
1501 A */
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
1506 code.
1508 XXX: We can not disable optimizations, as loop blocking is not working
1509 without them. */
1510 if (0)
1512 options->f = -1;
1513 options->l = INT_MAX;
1516 return options;
1519 /* Prints STMT to STDERR. */
1521 void
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. */
1532 DEBUG_FUNCTION void
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. */
1542 cloog_prog_clast
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);
1555 return pc;
1558 /* Prints to FILE the code generated by CLooG for SCOP. */
1560 void
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. */
1582 DEBUG_FUNCTION void
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. */
1591 static void
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);
1596 int i;
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.
1618 bool
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 ();
1642 graphite_verify ();
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 ();
1650 graphite_verify ();
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;
1664 ip.region = region;
1666 translate_clast (context_loop, pc.stmt, if_region->true_region->entry,
1667 bb_pbb_mapping, 0, &ip);
1668 graphite_verify ();
1669 scev_reset ();
1670 recompute_all_dominators ();
1671 graphite_verify ();
1673 if (gloog_error)
1674 set_ifsese_condition (if_region, integer_zero_node);
1676 free (if_region->true_region);
1677 free (if_region->region);
1678 free (if_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))
1689 loop_p loop;
1690 loop_iterator li;
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",
1698 num_no_dependency);
1701 return !gloog_error;
1703 #endif